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);
- }
- }
- }
- }
- }
|