Mirror of Svelto.ECS because we're a fan of it
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
4.2KB

  1. using System;
  2. using System.Reflection;
  3. using System.Runtime.CompilerServices;
  4. using System.Runtime.InteropServices;
  5. //careful, you must handle the destruction of the GCHandles!
  6. namespace BetterWeakEvents
  7. {
  8. public struct WeakAction<T1, T2> : IEquatable<WeakAction<T1, T2>>
  9. {
  10. public WeakAction(Action<T1, T2> listener)
  11. {
  12. ObjectRef = GCHandle.Alloc(listener.Target, GCHandleType.Weak);
  13. #if !NETFX_CORE
  14. Method = listener.Method;
  15. if (Method.DeclaringType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Length != 0)
  16. throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
  17. #else
  18. Method = listener.GetMethodInfo();
  19. if (CustomAttributeExtensions.IsDefined(Method, typeof(CompilerGeneratedAttribute), false) == false)
  20. throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
  21. #endif
  22. }
  23. public bool Invoke(T1 data1, T2 data2)
  24. {
  25. if (ObjectRef.IsAllocated && ObjectRef.Target != null)
  26. {
  27. Method.Invoke(ObjectRef.Target, new object[] { data1, data2 });
  28. return true;
  29. }
  30. Release();
  31. return false;
  32. }
  33. public bool Equals(WeakAction<T1, T2> other)
  34. {
  35. return (Method.Equals(other.Method));
  36. }
  37. public void Release()
  38. {
  39. ObjectRef.Free();
  40. }
  41. readonly GCHandle ObjectRef;
  42. readonly MethodInfo Method;
  43. }
  44. public struct WeakAction<T> : IEquatable<WeakAction<T>>
  45. {
  46. public WeakAction(Action<T> listener)
  47. {
  48. ObjectRef = GCHandle.Alloc(listener.Target, GCHandleType.Weak);
  49. #if !NETFX_CORE
  50. Method = listener.Method;
  51. if (Method.DeclaringType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Length != 0)
  52. throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
  53. #else
  54. Method = listener.GetMethodInfo();
  55. if (CustomAttributeExtensions.IsDefined(Method, typeof(CompilerGeneratedAttribute), false) == false)
  56. throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
  57. #endif
  58. }
  59. public bool Invoke(T data)
  60. {
  61. if (ObjectRef.IsAllocated && ObjectRef.Target != null)
  62. {
  63. Method.Invoke(ObjectRef.Target, new object[] { data });
  64. return true;
  65. }
  66. Release();
  67. return false;
  68. }
  69. public bool Equals(WeakAction<T> other)
  70. {
  71. return (Method.Equals(other.Method));
  72. }
  73. public void Release()
  74. {
  75. ObjectRef.Free();
  76. }
  77. readonly GCHandle ObjectRef;
  78. readonly MethodInfo Method;
  79. }
  80. public struct WeakAction : IEquatable<WeakAction>
  81. {
  82. public WeakAction(Action listener)
  83. {
  84. ObjectRef = GCHandle.Alloc(listener.Target, GCHandleType.Weak);
  85. #if !NETFX_CORE
  86. Method = listener.Method;
  87. if (Method.DeclaringType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Length != 0)
  88. throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
  89. #else
  90. Method = listener.GetMethodInfo();
  91. if (CustomAttributeExtensions.IsDefined(Method, typeof(CompilerGeneratedAttribute), false) == false)
  92. throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
  93. #endif
  94. }
  95. public bool Invoke()
  96. {
  97. if (ObjectRef.IsAllocated && ObjectRef.Target != null)
  98. {
  99. Method.Invoke(ObjectRef.Target, null);
  100. return true;
  101. }
  102. Release();
  103. return false;
  104. }
  105. public bool Equals(WeakAction other)
  106. {
  107. return (Method.Equals(other.Method));
  108. }
  109. public void Release()
  110. {
  111. ObjectRef.Free();
  112. }
  113. readonly GCHandle ObjectRef;
  114. readonly MethodInfo Method;
  115. }
  116. }