Click here to Skip to main content
15,896,557 members
Articles / Programming Languages / C#

Tweaked Events

Rate me:
Please Sign up or sign in to vote.
4.83/5 (12 votes)
18 Dec 2010MIT18 min read 34.8K   289   41  
Framework for customizing events. Comes with Weak Events and Synced Events
using System;
using System.ComponentModel;
using System.Linq;
using System.Threading;
using System.Reflection;
using System.Text;

namespace JpLabs.TweakedEvents
{
	public static class TweakedEvent
	{
		public static BaseEventEntry<EventHandler> ToSynced(object syncObj, EventHandler handler)
		{
			return SyncedEvent<EventHandler>.CreateEntry(handler, syncObj);
		}

		public static BaseEventEntry<EventHandler<T>> ToSynced<T>(object syncObj, EventHandler<T> handler) where T : EventArgs
		{
			return SyncedEvent<EventHandler<T>>.CreateEntry(handler, syncObj);
		}

		public static BaseEventEntry<TEH> ToSynced<TEH>(object syncObj, TEH handler) where TEH : class
		{
			return SyncedEvent<TEH>.CreateEntry(handler, syncObj);
		}


		public static BaseEventEntry<EventHandler> ToWeak(EventHandler handler)
		{
		    return new WeakEventEntry<EventHandler>(handler);
		}

		public static BaseEventEntry<EventHandler<T>> ToWeak<T>(EventHandler<T> handler) where T : EventArgs
		{
			return new WeakEventEntry<EventHandler<T>>(handler);
		}

		public static BaseEventEntry<TEH> ToWeak<TEH>(TEH handler) where TEH : class
		{
			return new WeakEventEntry<TEH>(handler);
		}


		public static BaseEventEntry<EventHandler> ToWeakSynced(object syncObj, EventHandler handler)
		{
			//return new WeakSyncedEventEntry<EventHandler>(handler, syncObj);
			IEventEntry<EventHandler> weakEvent = new WeakEventEntry<EventHandler>(handler);
			return SyncedEvent<EventHandler>.CreateEntry(weakEvent, syncObj);
		}

		public static BaseEventEntry<EventHandler<T>> ToWeakSynced<T>(object syncObj, EventHandler<T> handler) where T : EventArgs
		{
			//return new WeakSyncedEventEntry<EventHandler<T>>(handler, syncObj);
			IEventEntry<EventHandler<T>> weakEvent = new WeakEventEntry<EventHandler<T>>(handler);
			return SyncedEvent<EventHandler<T>>.CreateEntry(weakEvent, syncObj);
		}

		public static BaseEventEntry<TEH> ToWeakSynced<TEH>(object syncObj, TEH handler) where TEH : class
		{
			//return new WeakSyncedEventEntry<TEH>(handler, syncObj);
			IEventEntry<TEH> weakEvent = new WeakEventEntry<TEH>(handler);
			return SyncedEvent<TEH>.CreateEntry(weakEvent, syncObj);
		}


		public static BaseEventEntry<EventHandler> ToDisposable(EventHandler handler)
		{
			return new StrongEventEntry<EventHandler>(handler);
		}

		public static BaseEventEntry<EventHandler<T>> ToDisposable<T>(EventHandler<T> handler) where T : EventArgs
		{
			return new StrongEventEntry<EventHandler<T>>(handler);
		}

		public static BaseEventEntry<TEH> ToDisposable<TEH>(TEH handler) where TEH : class
		{
			return new StrongEventEntry<TEH>(handler);
		}

		
		public static void Raise(this ITweakedEvent twEvent, object sender, EventArgs e)
		{
			#if DEBUG
			try {
			#endif
				if (twEvent != null) twEvent.Raise(sender, e);
			#if DEBUG
			} catch (Exception ex) {
				System.Diagnostics.Trace.WriteLine("-- // --");
				System.Diagnostics.Trace.WriteLine(ex);
				System.Diagnostics.Trace.WriteLine("-- // --");
				throw;
			}
			#endif
		}

		static internal TweakedEvent<TEH> Add<TEH>(this TweakedEvent<TEH> twEvent, TEH handler) where TEH : class
		{
			//Default to a StrongEvent
			if (twEvent == null) twEvent = StrongEvent<TEH>.Empty;
			
			//Combine with handler
		    return (TweakedEvent<TEH>)twEvent.Combine(handler);
		}

		static internal TweakedEvent<TEH> Remove<TEH>(this TweakedEvent<TEH> twEvent, TEH handler) where TEH : class
		{
			//Default to a StrongEvent
			if (twEvent == null) twEvent = StrongEvent<TEH>.Empty;
			
			//Take handler off
		    return (TweakedEvent<TEH>)twEvent.Subtract(handler);
		}

		static internal TweakedEvent<TEH> Add<TEH>(this TweakedEvent<TEH> twEvent, IEventEntry<TEH> entry) where TEH : class
		{
			//Default to a StrongEvent
			if (twEvent == null) twEvent = StrongEvent<TEH>.Empty;
			
			//Combine with entry
		    return (TweakedEvent<TEH>)twEvent.Combine(entry);
		}

		static internal TweakedEvent<TEH> Remove<TEH>(this TweakedEvent<TEH> twEvent, IEventEntry<TEH> entry) where TEH : class
		{
			//Default to a StrongEvent
			if (twEvent == null) twEvent = StrongEvent<TEH>.Empty;
			
			//Take entry off
		    return (TweakedEvent<TEH>)twEvent.Subtract(entry);
		}

		public static TweakedEvent<TEH> Add<TEH>(ref TweakedEvent<TEH> refTweakedEvent, TEH handler) where TEH : class
		{
			TweakedEvent<TEH> valueBeforeCombine;
			TweakedEvent<TEH> valueBeforeAttribution = refTweakedEvent;
			do
			{
				valueBeforeCombine = valueBeforeAttribution;
				var newValue = valueBeforeCombine.Add(handler);
				valueBeforeAttribution = Interlocked.CompareExchange(ref refTweakedEvent, newValue, valueBeforeCombine);
			}
			while (valueBeforeAttribution != valueBeforeCombine);
			
			return refTweakedEvent;
		}

		public static TweakedEvent<TEH> Remove<TEH>(ref TweakedEvent<TEH> refTweakedEvent, TEH handler) where TEH : class
		{
			TweakedEvent<TEH> valueBeforeRemove;
			TweakedEvent<TEH> valueBeforeAttribution = refTweakedEvent;
			do
			{
				valueBeforeRemove = valueBeforeAttribution;
				var newValue = valueBeforeRemove.Remove(handler);
				valueBeforeAttribution = Interlocked.CompareExchange(ref refTweakedEvent, newValue, valueBeforeRemove);
			}
			while (valueBeforeAttribution != valueBeforeRemove);
			
			return refTweakedEvent;
		}

		public static TweakedEvent<TEH> Add<TEH>(ref TweakedEvent<TEH> refTweakedEvent, IEventEntry<TEH> entry) where TEH : class
		{
			TweakedEvent<TEH> valueBeforeCombine;
			TweakedEvent<TEH> valueBeforeAttribution = refTweakedEvent;
			do
			{
				valueBeforeCombine = valueBeforeAttribution;
				var newValue = valueBeforeCombine.Add(entry);
				valueBeforeAttribution = Interlocked.CompareExchange(ref refTweakedEvent, newValue, valueBeforeCombine);
			}
			while (valueBeforeAttribution != valueBeforeCombine);
			
			return refTweakedEvent;
		}

		public static TweakedEvent<TEH> Remove<TEH>(ref TweakedEvent<TEH> refTweakedEvent, IEventEntry<TEH> entry) where TEH : class
		{
			TweakedEvent<TEH> valueBeforeRemove;
			TweakedEvent<TEH> valueBeforeAttribution = refTweakedEvent;
			do
			{
				valueBeforeRemove = valueBeforeAttribution;
				var newValue = valueBeforeRemove.Remove(entry);
				valueBeforeAttribution = Interlocked.CompareExchange(ref refTweakedEvent, newValue, valueBeforeRemove);
			}
			while (valueBeforeAttribution != valueBeforeRemove);
			
			return refTweakedEvent;
		}

		public static TweakedEvent<TEH> Mutate<TEH>(ref TweakedEvent<TEH> refTweakedEvent, Func<TweakedEvent<TEH>,TweakedEvent<TEH>> mutateFunc) where TEH : class
		{
			TweakedEvent<TEH> valueBeforeMutation;
			TweakedEvent<TEH> valueBeforeAttribution = refTweakedEvent;
			do
			{
				valueBeforeMutation = valueBeforeAttribution;
				var newValue = mutateFunc(valueBeforeMutation);
				valueBeforeAttribution = Interlocked.CompareExchange(ref refTweakedEvent, newValue, valueBeforeMutation);
			}
			while (valueBeforeAttribution != valueBeforeMutation);
			
			return refTweakedEvent;
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
Software Developer (Senior) ThoughtWorks
Brazil Brazil
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions