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.

WeakAction.cs 2.2KB

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