Last active
December 16, 2015 03:29
-
-
Save gamedevsam/5370635 to your computer and use it in GitHub Desktop.
A super simple string based event system.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ; | |
import flixel.FlxG; | |
import flixel.util.FlxPool; | |
import haxe.ds.ObjectMap; | |
class Events | |
{ | |
public static function addHandler(object:Dynamic, event:String, handler:Dynamic -> Void, permanent:Bool = false) | |
{ | |
// events are not case sensitive | |
event = event.toLowerCase(); | |
// recycle event handler object | |
var eventHandler:EventHandler = eventHandlerPool.get(); | |
eventHandler.init(object, event, handler, permanent); | |
// store handlers on string map, for fast dispatch | |
var handlers:EventHandlerArray = eventMap.get(event); | |
if (handlers == null) | |
{ | |
handlers = eventHandlerArrayPool.get(); | |
eventMap.set(event, handlers); | |
} | |
handlers.array.push(eventHandler); | |
// store handlers on object map as well, for fast removal of events from an object | |
if (object != null) | |
{ | |
handlers = objectMap.get(object); | |
if (handlers == null) | |
{ | |
handlers = eventHandlerArrayPool.get(); | |
objectMap.set(object, handlers); | |
} | |
handlers.array.push(eventHandler); | |
} | |
} | |
public static function removeHandler(object:Dynamic, event:String, handler:Dynamic -> Void) | |
{ | |
// events are not case sensitive | |
event = event.toLowerCase(); | |
var handlers:EventHandlerArray = eventMap.get(event); | |
if (handlers != null && handlers.array.length > 0) | |
{ | |
var i = handlers.array.length - 1; | |
while (i >= 0) | |
{ | |
var eventHandler:EventHandler = handlers.array[i--]; | |
if (eventHandler.handler == handler) | |
{ | |
if (object != null) | |
{ | |
var objHandlers:EventHandlerArray = objectMap.get(object); | |
if (objHandlers != null) | |
{ | |
objHandlers.array.remove(eventHandler); | |
if (objHandlers.array.length == 0) | |
{ | |
eventHandlerArrayPool.putUnsafe(objHandlers); | |
objectMap.remove(object); | |
} | |
} | |
} | |
handlers.array.remove(eventHandler); | |
eventHandlerPool.putUnsafe(eventHandler); | |
break; | |
} | |
} | |
if (handlers.array.length == 0) | |
{ | |
eventHandlerArrayPool.putUnsafe(handlers); | |
eventMap.remove(event); | |
} | |
} | |
} | |
// convenience function to remove all events registered to an object | |
public static function removeObject(object:Dynamic) | |
{ | |
var handlers:EventHandlerArray = objectMap.get(object); | |
if (handlers != null) | |
{ | |
for (eventHandler in handlers.array) | |
{ | |
removeHandler(null, eventHandler.event, eventHandler.handler); | |
} | |
eventHandlerArrayPool.putUnsafe(handlers); | |
objectMap.remove(object); | |
} | |
} | |
public static function dispatch(event:String, data:Dynamic = null #if(!FLX_NO_DEBUG), ?pos:haxe.PosInfos #end) | |
{ | |
// events are not case sensitive | |
event = event.toLowerCase(); | |
#if !FLX_NO_DEBUG | |
var msg = "Dispatch event: '" + event + "' from ["+pos.fileName+","+pos.lineNumber+"]"; | |
FlxG.log.add(msg); | |
//trace(msg); | |
#end | |
var handlers:EventHandlerArray = eventMap.get(event); | |
if (handlers != null) | |
{ | |
for (eventHandler in handlers.array) | |
{ | |
eventHandler.handler(data); | |
} | |
} | |
else | |
{ | |
var msg = "Could not find any handlers for the event '" + event + "'. Make sure you didn't mispell the event name"; | |
FlxG.log.warn(msg); | |
//trace(msg); | |
} | |
} | |
// simple function to ensure that all non-permanent events have been cleaned up | |
public static function cleanup() | |
{ | |
#if !FLX_NO_DEBUG | |
// Verify if there aren't any non-permanent events left | |
for (handlers in eventMap) | |
{ | |
for (handler in handlers.array) | |
{ | |
if (!handler.permanent) | |
{ | |
var msg = "Handler for event '" + handler.event + "' not cleaned up in " + handler.object + "!"; | |
FlxG.log.error(msg); | |
//trace(msg); | |
} | |
} | |
} | |
for (handlers in objectMap) | |
{ | |
for (handler in handlers.array) | |
{ | |
if (!handler.permanent) | |
{ | |
var msg = "Handler for event '" + handler.event + "' not cleaned up in " + handler.object + "!"; | |
FlxG.log.error(msg); | |
//trace(msg); | |
} | |
} | |
} | |
#end | |
} | |
private static var eventMap :Map<String, EventHandlerArray> = new Map<String, EventHandlerArray>(); | |
private static var objectMap :ObjectMap<Dynamic, EventHandlerArray> = new ObjectMap<Dynamic, EventHandlerArray>(); | |
private static var eventHandlerPool :FlxPool<EventHandler> = new FlxPool<EventHandler>(); | |
private static var eventHandlerArrayPool:FlxPool<EventHandlerArray> = new FlxPool<EventHandlerArray>(); | |
} | |
private class EventHandler | |
{ | |
public var event:String; | |
public var object:Dynamic; | |
public var handler:Dynamic -> Void; | |
public var permanent:Bool; | |
public function new() {} | |
public function init(o:Dynamic, e:String, h:Dynamic -> Void, p:Bool) | |
{ | |
event = e; | |
object = o; | |
handler = h; | |
permanent = p; | |
} | |
public function destroy() | |
{ | |
event = null; | |
object = null; | |
handler = null; | |
} | |
} | |
private class EventHandlerArray | |
{ | |
public var array:Array<EventHandler>; | |
public function new() { array = new Array<EventHandler>(); } | |
public function destroy() | |
{ | |
if (array.length > 0) | |
{ | |
#if(flash || cpp) | |
untyped array.length = 0; | |
#else | |
array = []; | |
#end | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment