|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- using System;
- using System.Reflection;
- using System.Runtime.InteropServices;
- using Svelto.Utilities;
-
- //careful, you must handle the destruction of the GCHandles!
- namespace Svelto.WeakEvents
- {
- public struct WeakActionStruct<T1, T2> : IEquatable<WeakActionStruct<T1, T2>>, IDisposable
- {
- public WeakActionStruct(Action<T1, T2> listener)
- {
- WeakActionStructUtility.Init(listener.Target, listener.GetMethodInfoEx(), out _objectRef, out _method);
- }
-
- public bool Invoke(object[] args)
- {
- return WeakActionStructUtility.Invoke(ref _objectRef, _method, args);
- }
-
- public bool Equals(WeakActionStruct<T1, T2> other)
- {
- return WeakActionStructUtility.IsMatch(_objectRef.Target, _method,
- other._objectRef.Target, other._method);
- }
-
- public void Dispose()
- {
- _objectRef.Free();
- }
-
- public bool IsMatch(object otherObject, MethodInfo otherMethod)
- {
- return WeakActionStructUtility.IsMatch(_objectRef.Target, _method,
- otherObject, otherMethod);
- }
-
- GCHandle _objectRef;
- readonly MethodInfo _method;
- }
-
- public struct WeakActionStruct<T> : IEquatable<WeakActionStruct<T>>, IDisposable
- {
- public WeakActionStruct(Action<T> listener)
- {
- WeakActionStructUtility.Init(listener.Target, listener.GetMethodInfoEx(),
- out _objectRef, out _method);
- }
-
- public bool Invoke(object[] args)
- {
- return WeakActionStructUtility.Invoke(ref _objectRef, _method, args);
- }
-
- public bool Equals(WeakActionStruct<T> other)
- {
- return WeakActionStructUtility.IsMatch(_objectRef.Target, _method,
- other._objectRef.Target, other._method);
- }
-
- public void Dispose()
- {
- _objectRef.Free();
- }
-
- public bool IsMatch(object otherObject, MethodInfo otherMethod)
- {
- return WeakActionStructUtility.IsMatch(_objectRef.Target, _method,
- otherObject, otherMethod);
- }
-
- GCHandle _objectRef;
- readonly MethodInfo _method;
- }
-
- public struct WeakActionStruct : IEquatable<WeakActionStruct>, IDisposable
- {
- public WeakActionStruct(Action listener)
- {
- WeakActionStructUtility.Init(listener.Target, listener.GetMethodInfoEx(),
- out _objectRef, out _method);
- }
-
- public bool Invoke()
- {
- return WeakActionStructUtility.Invoke(ref _objectRef, _method, null);
- }
-
- public bool Equals(WeakActionStruct other)
- {
- return WeakActionStructUtility.IsMatch(_objectRef.Target, _method,
- other._objectRef.Target, other._method);
- }
-
- public void Dispose()
- {
- _objectRef.Free();
- }
-
- public bool IsMatch(object otherObject, MethodInfo otherMethod)
- {
- return WeakActionStructUtility.IsMatch(_objectRef.Target, _method,
- otherObject, otherMethod);
- }
-
- GCHandle _objectRef;
- readonly MethodInfo _method;
- }
-
- static class WeakActionStructUtility
- {
- internal static void Init(object target, MethodInfo method,
- out GCHandle objectRef, out MethodInfo methodOut)
- {
- objectRef = GCHandle.Alloc(target, GCHandleType.Weak);
- methodOut = method;
-
- #if DEBUG && !PROFILER
- if (method.IsCompilerGenerated() == true)
- throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
- #endif
- }
-
- public static bool Invoke(ref GCHandle objectRef, MethodInfo method, object[] args)
- {
- if (objectRef.IsAllocated && objectRef.Target != null)
- {
- method.Invoke(objectRef.Target, args);
- return true;
- }
-
- Dispose(ref objectRef);
- return false;
- }
-
- public static void Dispose(ref GCHandle objectRef)
- {
- objectRef.Free();
- }
-
- public static bool IsMatch(object objectRef, MethodInfo method,
- object _objectRef, MethodInfo _method)
- {
- return _method.Equals(method) && objectRef.Equals(_objectRef);
- }
- }
- }
|