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.

WeakActionStruct.cs 4.4KB

7 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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.GetMethodInfo();
  15. var attributes = (CompilerGeneratedAttribute[])Method.GetType().GetTypeInfo().GetCustomAttributes(typeof(CompilerGeneratedAttribute), false);
  16. if(attributes.Length != 0)
  17. throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
  18. #else
  19. Method = listener.Method;
  20. if (Method.DeclaringType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Length != 0)
  21. throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
  22. #endif
  23. }
  24. public bool Invoke(T1 data1, T2 data2)
  25. {
  26. if (ObjectRef.IsAllocated && ObjectRef.Target != null)
  27. {
  28. Method.Invoke(ObjectRef.Target, new object[] { data1, data2 });
  29. return true;
  30. }
  31. Release();
  32. return false;
  33. }
  34. public bool Equals(WeakAction<T1, T2> other)
  35. {
  36. return (Method.Equals(other.Method));
  37. }
  38. public void Release()
  39. {
  40. ObjectRef.Free();
  41. }
  42. readonly GCHandle ObjectRef;
  43. readonly MethodInfo Method;
  44. }
  45. public struct WeakAction<T> : IEquatable<WeakAction<T>>
  46. {
  47. public WeakAction(Action<T> listener)
  48. {
  49. ObjectRef = GCHandle.Alloc(listener.Target, GCHandleType.Weak);
  50. #if NETFX_CORE
  51. Method = listener.GetMethodInfo();
  52. var attributes = (CompilerGeneratedAttribute[])Method.GetType().GetTypeInfo().GetCustomAttributes(typeof(CompilerGeneratedAttribute), false);
  53. if(attributes.Length != 0)
  54. throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
  55. #else
  56. Method = listener.Method;
  57. if (Method.DeclaringType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Length != 0)
  58. throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
  59. #endif
  60. }
  61. public bool Invoke(T data)
  62. {
  63. if (ObjectRef.IsAllocated && ObjectRef.Target != null)
  64. {
  65. Method.Invoke(ObjectRef.Target, new object[] { data });
  66. return true;
  67. }
  68. Release();
  69. return false;
  70. }
  71. public bool Equals(WeakAction<T> other)
  72. {
  73. return (Method.Equals(other.Method));
  74. }
  75. public void Release()
  76. {
  77. ObjectRef.Free();
  78. }
  79. readonly GCHandle ObjectRef;
  80. readonly MethodInfo Method;
  81. }
  82. public struct WeakAction : IEquatable<WeakAction>
  83. {
  84. public WeakAction(Action listener)
  85. {
  86. ObjectRef = GCHandle.Alloc(listener.Target, GCHandleType.Weak);
  87. #if NETFX_CORE
  88. Method = listener.GetMethodInfo();
  89. var attributes = (CompilerGeneratedAttribute[])Method.GetType().GetTypeInfo().GetCustomAttributes(typeof(CompilerGeneratedAttribute), false);
  90. if(attributes.Length != 0)
  91. throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
  92. #else
  93. Method = listener.Method;
  94. if (Method.DeclaringType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Length != 0)
  95. throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
  96. #endif
  97. }
  98. public bool Invoke()
  99. {
  100. if (ObjectRef.IsAllocated && ObjectRef.Target != null)
  101. {
  102. Method.Invoke(ObjectRef.Target, null);
  103. return true;
  104. }
  105. Release();
  106. return false;
  107. }
  108. public bool Equals(WeakAction other)
  109. {
  110. return (Method.Equals(other.Method));
  111. }
  112. public void Release()
  113. {
  114. ObjectRef.Free();
  115. }
  116. readonly GCHandle ObjectRef;
  117. readonly MethodInfo Method;
  118. }
  119. }