Skip to content

Instantly share code, notes, and snippets.

@bradparks
Forked from gamedevsam/Events
Created April 12, 2013 11:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bradparks/5371513 to your computer and use it in GitHub Desktop.
Save bradparks/5371513 to your computer and use it in GitHub Desktop.
package ;
import haxe.ds.ObjectMap;
#if haxe2
typedef Map<String, T> = Hash<T>;
#end
class HxEvents
{
public static function addHandler(object:Dynamic, event:String, eventHandler:Dynamic -> Void, permanent:Bool = false) : Void
{
event = event.toLowerCase();
var handlers = delegates.get(event);
if (handlers == null)
{
handlers = new Array<Dynamic -> Void>();
delegates.set(event, handlers);
}
handlers.push(eventHandler);
// Keep track of { object, event, eventHandler } data, so we can remove event all of its event handlers.
if (object != null)
addEventHandler(new HxEventHandler(object, event, eventHandler), permanent);
}
public static function removeHandler(event:String, eventHandler:Dynamic -> Void) : Void
{
event = event.toLowerCase();
var handlers = delegates.get(event);
if (handlers != null && handlers.length > 0)
{
var succeeded = false;
var i = handlers.length - 1;
while (i >= 0)
{
if (handlers[i] == eventHandler)
{
handlers[i] = handlers[handlers.length - 1];
handlers.pop();
succeeded = true;
break;
}
i--;
}
}
}
// Use this if you have a lot of events being handled by one object and feel lazy
public static function removeObject(o:Dynamic) : Void
{
if (o == null)
return;
var arrHandlers = eventHandlers.get(o);
if (arrHandlers != null)
{
for ( eventHandler in arrHandlers )
removeHandler(eventHandler.event, eventHandler.handler);
}
}
public static function dispatch(e:String, data:Dynamic = null) : Void
{
e = e.toLowerCase();
var handlers = delegates.get(e);
if (handlers == null)
{
trace("Event ERROR: Could not find any handlers for the event '" + e + "'. Make sure you didn't mispell the event name");
return;
}
var i = handlers.length - 1;
while ( i >= 0 )
{
handlers[i--](data);
}
}
// Simple function that gets called after everything gets destroyed in the game (switch states)
public static function cleanup()
{
// Verify if there are any residual events
var it = delegates.keys();
var event = it.next();
while (event != null)
{
var handlers = delegates.get(event);
for (h in handlers)
{
var objectIt = eventHandlers.iterator();
var arrHandlers = objectIt.next();
while (arrHandlers != null)
{
for (o in arrHandlers)
{
if (o.event == event && o.handler == h)
{
var isPermanentHandler = false;
for (eHandler in permanentHandlers)
if (eHandler.event == event && eHandler.handler == h && eHandler.object == o.object)
isPermanentHandler = true;
if (!isPermanentHandler)
throw("Event ERROR: Handler for event '" + event + "' not cleaned up in " + o.object + "!");
}
}
arrHandlers = objectIt.next();
}
}
event = it.next();
}
// Just reset the objects list, it's the delegates that really matter
eventHandlers = new ObjectMap<Dynamic, Array<HxEventHandler>>();
// Restore permanent event handlers
for (eHandler in permanentHandlers)
addEventHandler(eHandler);
}
private static function addEventHandler(eventHandler:HxEventHandler, permanent:Bool = false):Void
{
if (permanent == true)
permanentHandlers.push(eventHandler);
var arrHandlers = eventHandlers.get(eventHandler.object);
if (arrHandlers != null)
arrHandlers.push(eventHandler);
else
eventHandlers.set(eventHandler.object, [ eventHandler ]);
}
private static var delegates:Map<String, Array<Dynamic -> Void>> = new Map<String, Array<Dynamic -> Void>>();
private static var eventHandlers:ObjectMap<Dynamic, Array<HxEventHandler>> = new ObjectMap<Dynamic, Array<HxEventHandler>>();
private static var permanentHandlers:Array<HxEventHandler> = new Array<HxEventHandler>();
}
private class HxEventHandler
{
public var event:String;
public var object:Dynamic;
public var handler:Dynamic -> Void;
public function new(o:Dynamic, e:String, h:Dynamic -> Void)
{
event = e;
object = o;
handler = h;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment