// if the listener object is reclaimed you may stop receiving messages because // the handler may then also be GCed, so the caller is responsible for keeping it alive private void AddListener <T>(out MessageListener <T> listener, MessageHandler <T> handler, object key, bool keyIsWeak) { if (handler == null) { throw new ArgumentNullException("handler"); } List <HandlerEntry> entries; int? keyHash = null; WeakReference weakKey = null; if (key == null) { if (!untargeted.TryGetValue(typeof(T), out entries)) { entries = new List <HandlerEntry>(); untargeted.Add(typeof(T), entries); } } else { Dictionary <int, List <HandlerEntry> > entryLists; if (!targeted.TryGetValue(typeof(T), out entryLists)) { entryLists = new Dictionary <int, List <HandlerEntry> >(); targeted.Add(typeof(T), entryLists); } keyHash = key.GetHashCode(); if (!entryLists.TryGetValue(keyHash.Value, out entries)) { entries = new List <HandlerEntry>(); entryLists.Add(keyHash.Value, entries); } if (keyIsWeak) { weakKey = new WeakReference(key); key = null; } } entries.Add(new HandlerEntry(new WeakReference(handler), weakKey, key)); listener = new MessageListener <T>(handler, keyHash); }
// remove listeners explicitly using this method when they are no longer wanted, // because waiting for the GC to reclaim your handler is highly undeterministic public bool RemoveListener <T>(ref MessageListener <T> listener) { List <HandlerEntry> entries; if (!listener.KeyHashCode.HasValue) { if (!untargeted.TryGetValue(typeof(T), out entries)) { return(false); } } else { Dictionary <int, List <HandlerEntry> > entryLists; if (!targeted.TryGetValue(typeof(T), out entryLists)) { return(false); } if (!entryLists.TryGetValue(listener.KeyHashCode.Value, out entries)) { return(false); } } for (int i = 0; i < entries.Count; ++i) { var entry = entries[i]; object handler = entry.Handler.Target; if (handler == null) { entries.RemoveAt(i--); continue; } if (handler.Equals(listener.Handler)) { entries.RemoveAt(i); listener = new MessageListener <T>(null, null); return(true); } } return(false); }
public void AddListenerWithWeakKey <T>(object key, out MessageListener <T> listener, MessageHandler <T> handler) { AddListener(out listener, handler, key, true); }
public void AddListenerWithStrongKey <T>(object key, out MessageListener <T> listener, MessageHandler <T> handler) { AddListener(out listener, handler, key, false); }
public void AddListener <T>(out MessageListener <T> listener, MessageHandler <T> handler) { AddListener(out listener, handler, null, false); }