Skip to content

Instantly share code, notes, and snippets.

@SirTony
Last active August 29, 2015 14:05
Show Gist options
  • Save SirTony/fe2f7b033efc53a13232 to your computer and use it in GitHub Desktop.
Save SirTony/fe2f7b033efc53a13232 to your computer and use it in GitHub Desktop.
A simple wrapper to handle both delegates and functions for the purposes of event callbacks, akin to .NET-style events.
module eventhandler;
/+
EventHandler implementation.
+/
struct EventHandler( TArgs... )
{
private import std.algorithm;
public alias void delegate( TArgs ) DelegateType;
public alias void function( TArgs ) FunctionType;
private FunctionType[] functions;
private DelegateType[] delegates;
public void opAssign( T... )( T args )
{
throw new Exception( "EventHandler objects may not be assigned to directly, please use += or -= instead." );
}
public void opOpAssign( string op )( FunctionType fn ) if( op == "+" )
{
this.functions ~= fn;
}
public void opOpAssign( string op )( DelegateType dg ) if( op == "+" )
{
this.delegates ~= dg;
}
public void opOpAssign( string op )( FunctionType fn ) if( op == "-" )
{
if( !this.functions.canFind( fn ) )
return;
else
this.functions = this.functions.remove!( x => x == fn );
}
public void opOpAssign( string op )( DelegateType dg ) if( op == "-" )
{
if( !this.delegates.canFind( dg ) )
return;
else
this.delegates = this.delegates.remove!( x => x == dg );
}
public void opCall( TArgs args )
{
int len = max( this.delegates.length, this.functions.length );
for( int i = 0; i < len; ++ i )
{
if( i < this.functions.length )
this.functions[i]( args );
if( i < this.delegates.length )
this.delegates[i]( args );
}
}
}
/+
A simple example showing usage of the
EventHandler struct.
+/
import eventhandler;
import std.stdio;
class List( T )
{
private alias EventHandler!( T ) AddedHandler;
private AddedHandler onItemAdded;
public ref AddedHandler ItemAdded() @property
{
return this.onItemAdded;
}
private T[] array;
public T[] Items() @property
{
return this.array.dup;
}
public void Add( T item )
{
this.array ~= item;
this.onItemAdded( item );
}
}
void printNewItem( string item )
{
"'%s' was added to the list.".writefln( item );
}
void main()
{
auto list = new List!( string );
list.ItemAdded += &printNewItem;
list.Add( "foo" );
// Output: 'foo' was added to the list.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment