public void Add(GlobalPriority globalPriority, int extensionId, EventPriority priority, EventRaiseHandler <T> callback) { SortedDictionary <int, SortedDictionary <EventPriority, List <EventRaiseHandler <T> > > > extensions; if (!this.TryGetValue(globalPriority, out extensions)) { extensions = new SortedDictionary <int, SortedDictionary <EventPriority, List <EventRaiseHandler <T> > > >(); this.Add(globalPriority, extensions); } SortedDictionary <EventPriority, List <EventRaiseHandler <T> > > priorities; if (!extensions.TryGetValue(extensionId, out priorities)) { priorities = new SortedDictionary <EventPriority, List <EventRaiseHandler <T> > >(); extensions.Add(extensionId, priorities); } List <EventRaiseHandler <T> > value; if (!priorities.TryGetValue(priority, out value)) { value = new List <EventRaiseHandler <T> >(); priorities.Add(priority, value); } value.Add(callback); }
public void PriorityTest() { var last = EventPriority.Highest; var check = new Action<EventPriority>(i => { if (last > i) Assert.Fail("Wrong order! Failed at: " + i); last = i; }); var lowest = new EventRaiseHandler<TestEvent>(e => check(EventPriority.Lowest)); var low = new EventRaiseHandler<TestEvent>(e => check(EventPriority.Low)); var normal = new EventRaiseHandler<TestEvent>(e => check(EventPriority.Normal)); var high = new EventRaiseHandler<TestEvent>(e => check(EventPriority.High)); var highest = new EventRaiseHandler<TestEvent>(e => check(EventPriority.Highest)); var botBits = new BotBitsClient(); TestEvent.Of(botBits).Bind(highest, EventPriority.Highest); TestEvent.Of(botBits).Bind(lowest, EventPriority.Lowest); TestEvent.Of(botBits).Bind(high, EventPriority.High); TestEvent.Of(botBits).Bind(low, EventPriority.Low); TestEvent.Of(botBits).Bind(normal); new TestEvent().RaiseIn(botBits); }
public bool Unbind(EventRaiseHandler <T> item) { lock (this._eventHandlers) { return(this._eventHandlers.Remove(item)); } }
public bool Contains(EventRaiseHandler <T> item) { lock (this._eventHandlers) { return(this._eventHandlers.Handlers.Any(h => h == item)); } }
public void Bind(EventRaiseHandler <T> callback, GlobalPriority globalPriority, EventPriority priority = EventPriority.Normal) { var assembly = callback.Method.DeclaringType?.Assembly; this.BindInternal(assembly, callback, globalPriority, priority); }
public void PriorityTest() { var last = EventPriority.Highest; var check = new Action <EventPriority>(i => { if (last > i) { Assert.Fail("Wrong order! Failed at: " + i); } last = i; }); var lowest = new EventRaiseHandler <TestEvent>(e => check(EventPriority.Lowest)); var low = new EventRaiseHandler <TestEvent>(e => check(EventPriority.Low)); var normal = new EventRaiseHandler <TestEvent>(e => check(EventPriority.Normal)); var high = new EventRaiseHandler <TestEvent>(e => check(EventPriority.High)); var highest = new EventRaiseHandler <TestEvent>(e => check(EventPriority.Highest)); var botBits = new BotBitsClient(); TestEvent.Of(botBits).Bind(highest, EventPriority.Highest); TestEvent.Of(botBits).Bind(lowest, EventPriority.Lowest); TestEvent.Of(botBits).Bind(high, EventPriority.High); TestEvent.Of(botBits).Bind(low, EventPriority.Low); TestEvent.Of(botBits).Bind(normal); new TestEvent().RaiseIn(botBits); }
private void ScanEvent <TEvent>(Assembly assembly) where TEvent : Event <TEvent> { var eventHandle = Event <TEvent> .Of(this.BotBits); var eventHandlersField = typeof(EventHandle <TEvent>).GetField("_eventHandlers", BindingFlags.NonPublic | BindingFlags.Instance); var eventHandlers = (SortedDictionary <GlobalPriority, SortedDictionary <int, SortedDictionary <EventPriority, IList <EventRaiseHandler <TEvent> > > > >) eventHandlersField.GetValue(eventHandle); foreach (var priority in eventHandlers.Values.SelectMany(ex => ex.Values.SelectMany(pr => pr))) { EventRaiseHandler <TEvent> last = null; foreach (var handler in priority.Value) { if (handler.GetMethodInfo().DeclaringType.Assembly == assembly) { if (last != null) { Console.WriteLine( "Duplicate usage for {0}({1}): {2} vs {3}", typeof(TEvent), priority.Key, GetString(last), GetString(handler)); } } last = handler; } } }
public void UnbindAllTest() { var botBits = new BotBitsClient(); var callback = new EventRaiseHandler <TestEvent>(delegate { }); TestEvent .Of(botBits) .Bind(callback); TestEvent .Of(botBits) .Bind(callback); TestEvent .Of(botBits) .Bind(callback, EventPriority.High); TestEvent .Of(botBits) .UnbindAll(); Assert.AreEqual(0, TestEvent .Of(botBits) .Count); }
public void Bind(EventRaiseHandler <T> callback, GlobalPriority globalPriority, EventPriority priority = EventPriority.Normal) { lock (this._eventHandlers) { var assembly = callback.Method.DeclaringType.Assembly; var extensionId = ExtensionServices.GetExtensionId(this.BotBits, assembly); this._eventHandlers.Add(globalPriority, extensionId ?? int.MaxValue, priority, callback); } }
internal void BindInternal([CanBeNull] Assembly assembly, EventRaiseHandler <T> callback, GlobalPriority globalPriority, EventPriority priority) { lock (this._eventHandlers) { var extensionId = ExtensionServices.GetExtensionId(this.BotBits, assembly); this._eventHandlers.Add(globalPriority, extensionId ?? int.MaxValue, priority, callback); } }
public void BindTest() { var botBits = new BotBitsClient(); var callback = new EventRaiseHandler <TestEvent>(delegate { }); TestEvent .Of(botBits) .Bind(callback); Assert.IsTrue( TestEvent .Of(botBits) .Contains(callback)); }
public void BindTest() { var botBits = new BotBitsClient(); var callback = new EventRaiseHandler<TestEvent>(delegate {}); TestEvent .Of(botBits) .Bind(callback); Assert.IsTrue( TestEvent .Of(botBits) .Contains(callback)); }
public void RaiseTest() { var isCalled = false; var callback = new EventRaiseHandler <TestEvent>(e => isCalled = true); var botBits = new BotBitsClient(); TestEvent .Of(botBits) .Bind(callback); new TestEvent() .RaiseIn(botBits); Assert.IsTrue(isCalled); }
private static Task <T> WaitOneAsyncInternal <T>( Assembly assembly, EventHandle <T> eventHandle, CancellationToken ct, GlobalPriority globalPriority, EventPriority priority = default(EventPriority)) where T : Event <T> { var tcs = new TaskCompletionSource <T>(); ct.Register(() => tcs.TrySetCanceled(), false); var raiseHandler = new EventRaiseHandler <T>(t => tcs.TrySetResult(t)); eventHandle.BindInternal(assembly, raiseHandler, globalPriority, priority); tcs.Task.ContinueWith(t => eventHandle.Unbind(raiseHandler), CancellationToken.None); return(tcs.Task); }
public static Task <T> WaitOneAsync <T>( this EventHandle <T> eventHandle, CancellationToken ct, EventPriority priority = default(EventPriority)) where T : Event <T> { var tcs = new TaskCompletionSource <T>(); ct.Register(() => tcs.TrySetCanceled(), false); var raiseHandler = new EventRaiseHandler <T>(t => tcs.TrySetResult(t)); eventHandle.Bind(raiseHandler, priority); tcs.Task.ContinueWith(t => eventHandle.Unbind(raiseHandler), CancellationToken.None); return(tcs.Task); }
public void CountTest() { var botBits = new BotBitsClient(); var callback = new EventRaiseHandler<TestEvent>(delegate { }); TestEvent .Of(botBits) .Bind(callback); Assert.AreEqual(1, TestEvent .Of(botBits) .Count); TestEvent .Of(botBits) .Unbind(callback); Assert.AreEqual(0, TestEvent .Of(botBits) .Count); }
/// <summary> /// Provides a bi-directional weak event handler management. /// </summary> /// <param name="list">A list of registrations to manage</param> /// <param name="handler">The actual handler to execute.</param> /// <param name="raise">The delegate used to raise <paramref name="handler"/> if it has not been collected.</param> /// <returns>A disposable that keeps the registration alive.</returns> /// <remarks> /// The bi-directional relation is defined by the fact that both the /// source and the target are weak. The source must be kept alive by /// another longer-lived reference, and the target is kept alive by the /// return disposable. /// /// If the returned disposable is collected, the handler will also be /// collected. Conversly, if the <paramref name="list"/> is collected /// raising the event will produce nothing. /// </remarks> internal static IDisposable RegisterEvent(IList <GenericEventHandler> list, Delegate handler, EventRaiseHandler raise) { var wr = new WeakReference(handler); GenericEventHandler genericHandler = null; // This weak reference ensure that the closure will not link // the caller and the callee, in the same way "newValueActionWeak" // does not link the callee to the caller. var instanceRef = new WeakReference <IList <GenericEventHandler> >(list); Action removeHandler = () => { var thatList = instanceRef.GetTarget(); if (thatList != null) { thatList.Remove(genericHandler); } }; genericHandler = (s, e) => { var weakHandler = wr.Target as Delegate; if (weakHandler != null) { raise(weakHandler, s, e); } else { removeHandler(); } }; list.Add(genericHandler); return(Disposable.Create(() => { removeHandler(); // Force a closure on the callback, to make its lifetime as long // as the subscription being held by the callee. handler = null; })); }
public void Bind(EventRaiseHandler <T> callback, EventPriority priority = EventPriority.Normal) { this.Bind(callback, GlobalPriority.Normal, priority); }
public void UnbindTest2() { var botBits = new BotBitsClient(); var callback = new EventRaiseHandler<TestEvent>(delegate { }); TestEvent .Of(botBits) .Bind(callback); TestEvent .Of(botBits) .Bind(callback); TestEvent .Of(botBits) .Bind(callback, EventPriority.High); TestEvent .Of(botBits) .Unbind(callback); Assert.AreEqual(2, TestEvent .Of(botBits) .Count); }
public bool Remove(EventRaiseHandler <T> callback) { return(this.Values.Any(ex => ex.Values.Any(pr => pr.Values.Any(p => p.Remove(callback))))); }
public void RaiseTest() { var isCalled = false; var callback = new EventRaiseHandler<TestEvent>(e => isCalled = true); var botBits = new BotBitsClient(); TestEvent .Of(botBits) .Bind(callback); new TestEvent() .RaiseIn(botBits); Assert.IsTrue(isCalled); }