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.

104 lines
2.7KB

  1. using System;
  2. using System.Reflection;
  3. using System.Runtime.CompilerServices;
  4. namespace Svelto.WeakEvents
  5. {
  6. public class WeakAction<T1, T2> : WeakAction
  7. {
  8. public WeakAction(Action<T1, T2> listener)
  9. #if NETFX_CORE
  10. : base(listener.Target, listener.GetMethodInfo())
  11. #else
  12. : base(listener.Target, listener.Method)
  13. #endif
  14. {}
  15. public void Invoke(T1 data1, T2 data2)
  16. {
  17. _data[0] = data1;
  18. _data[1] = data2;
  19. Invoke_Internal(_data);
  20. }
  21. readonly object[] _data = new object[2];
  22. }
  23. public class WeakAction<T> : WeakActionBase
  24. {
  25. public WeakAction(Action<T> listener)
  26. #if NETFX_CORE
  27. : base(listener.Target, listener.GetMethodInfo())
  28. #else
  29. : base(listener.Target, listener.Method)
  30. #endif
  31. {}
  32. public void Invoke(T data)
  33. {
  34. _data[0] = data;
  35. Invoke_Internal(_data);
  36. }
  37. readonly object[] _data = new object[1];
  38. }
  39. public class WeakAction : WeakActionBase
  40. {
  41. public WeakAction(Action listener) : base(listener)
  42. {}
  43. public WeakAction(object listener, MethodInfo method) : base(listener, method)
  44. {}
  45. public void Invoke()
  46. {
  47. Invoke_Internal(null);
  48. }
  49. }
  50. public abstract class WeakActionBase
  51. {
  52. protected readonly DataStructures.WeakReference<object> ObjectRef;
  53. protected readonly MethodInfo Method;
  54. public bool IsValid
  55. {
  56. get { return ObjectRef.IsValid; }
  57. }
  58. protected WeakActionBase(Action listener)
  59. #if NETFX_CORE
  60. : this(listener.Target, listener.GetMethodInfo())
  61. #else
  62. : this(listener.Target, listener.Method)
  63. #endif
  64. {}
  65. protected WeakActionBase(object listener, MethodInfo method)
  66. {
  67. ObjectRef = new DataStructures.WeakReference<object>(listener);
  68. Method = method;
  69. #if NETFX_CORE
  70. var attributes = (CompilerGeneratedAttribute[])method.GetType().GetTypeInfo().GetCustomAttributes(typeof(CompilerGeneratedAttribute), false);
  71. if (attributes.Length != 0)
  72. throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
  73. #else
  74. if (method.DeclaringType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Length != 0)
  75. throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
  76. #endif
  77. }
  78. protected void Invoke_Internal(object[] data)
  79. {
  80. if (ObjectRef.IsValid)
  81. Method.Invoke(ObjectRef.Target, data);
  82. else
  83. Utility.Console.LogWarning("Target of weak action has been garbage collected");
  84. }
  85. }
  86. }