| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 | using System;using System.Collections.Generic;using System.Linq;using System.Reflection;namespace OpenSEMI.Core.Publisher{	public class Publisher : IPublisher	{		internal class Handler		{			public Delegate Action			{				get;				set;			}			public WeakReference Sender			{				get;				set;			}			public Type Type			{				get;				set;			}		}		internal List<Handler> _handlers = new List<Handler>();		internal object _locker = new object();		public void Publish<T>(T data = default(T))		{			List<Handler> list = default(List<Handler>);			lock (_locker)			{				list = new List<Handler>(_handlers.Count);				List<Handler> list2 = new List<Handler>(_handlers.Count);				foreach (Handler handler in _handlers)				{					if (!handler.Sender.IsAlive)					{						list2.Add(handler);					}					else if (handler.Type.GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()))					{						list.Add(handler);					}				}				foreach (Handler item in list2)				{					_handlers.Remove(item);				}			}			foreach (Handler item2 in list)			{				((Action<T>)item2.Action)(data);			}		}		public void Subscribe<T>(Action<T> pHandler)		{			Subscribe(this, pHandler);		}		public void Subscribe<T>(object subscriber, Action<T> pHandler)		{			Handler handler = new Handler();			handler.Action = pHandler;			handler.Sender = new WeakReference(subscriber);			handler.Type = typeof(T);			Handler item = handler;			lock (_locker)			{				_handlers.Add(item);			}		}		public void Unsubscribe()		{			Unsubscribe(this);		}		public void Unsubscribe(object subscriber)		{			lock (_locker)			{				IEnumerable<Handler> source = from a in _handlers				where !a.Sender.IsAlive || a.Sender.Target.Equals(subscriber)				select a;				foreach (Handler item in source.ToList())				{					_handlers.Remove(item);				}			}		}		public void Unsubscribe<T>()		{			Unsubscribe((object)this, (Action<T>)null);		}		public void Unsubscribe<T>(Action<T> pHandler)		{			Unsubscribe(this, pHandler);		}		public void Unsubscribe<T>(object subscriber, Action<T> pHandler = null)		{			lock (_locker)			{				IEnumerable<Handler> source = from a in _handlers				where !a.Sender.IsAlive || (a.Sender.Target.Equals(subscriber) && a.Type == typeof(T))				select a;				if (pHandler != null)				{					source = from a in source					where a.Action.Equals(pHandler)					select a;				}				foreach (Handler item in source.ToList())				{					_handlers.Remove(item);				}			}		}	}}
 |