Add support for event canceling

This commit is contained in:
Joshua Granick
2015-12-16 11:25:52 -08:00
parent bd629f3a45
commit d98f2724e1

View File

@@ -16,18 +16,20 @@ using haxe.macro.Tools;
class Event<T> { class Event<T> {
@:noCompletion @:dox(hide) public var listeners:Array<T>; public var canceled (default, null):Bool;
@:noCompletion @:dox(hide) public var repeat:Array<Bool>;
private var priorities:Array<Int>; @:noCompletion @:dox(hide) public var __listeners:Array<T>;
@:noCompletion @:dox(hide) public var __repeat:Array<Bool>;
private var __priorities:Array<Int>;
public function new () { public function new () {
#if !macro #if !macro
listeners = new Array (); canceled = false;
priorities = new Array<Int> (); __listeners = new Array ();
repeat = new Array<Bool> (); __priorities = new Array<Int> ();
__repeat = new Array<Bool> ();
#end #end
} }
@@ -36,22 +38,22 @@ class Event<T> {
public function add (listener:T, once:Bool = false, priority:Int = 0):Void { public function add (listener:T, once:Bool = false, priority:Int = 0):Void {
#if !macro #if !macro
for (i in 0...priorities.length) { for (i in 0...__priorities.length) {
if (priority > priorities[i]) { if (priority > __priorities[i]) {
listeners.insert (i, cast listener); __listeners.insert (i, cast listener);
priorities.insert (i, priority); __priorities.insert (i, priority);
repeat.insert (i, !once); __repeat.insert (i, !once);
return; return;
} }
} }
listeners.push (cast listener); __listeners.push (cast listener);
priorities.push (priority); __priorities.push (priority);
repeat.push (!once); __repeat.push (!once);
#end #end
} }
@@ -132,8 +134,10 @@ class Event<T> {
var dispatch = macro { var dispatch = macro {
var listeners = this.listeners; canceled = false;
var repeat = this.repeat;
var listeners = __listeners;
var repeat = __repeat;
var i = 0; var i = 0;
while (i < listeners.length) { while (i < listeners.length) {
@@ -150,6 +154,12 @@ class Event<T> {
} }
if (canceled) {
break;
}
} }
} }
@@ -161,7 +171,7 @@ class Event<T> {
field = fields[i]; field = fields[i];
if (field.name == "listeners" || field.name == "dispatch") { if (field.name == "__listeners" || field.name == "dispatch") {
fields.remove (field); fields.remove (field);
@@ -173,7 +183,7 @@ class Event<T> {
} }
fields.push ( { name: "listeners", access: [ APublic ], kind: FVar (TPath ({ pack: [], name: "Array", params: [ TPType (typeParam.toComplexType ()) ] })), pos: pos } ); fields.push ( { name: "__listeners", access: [ APublic ], kind: FVar (TPath ({ pack: [], name: "Array", params: [ TPType (typeParam.toComplexType ()) ] })), pos: pos } );
fields.push ( { name: "dispatch", access: [ APublic ], kind: FFun ( { args: args, expr: dispatch, params: [], ret: macro :Void } ), pos: pos } ); fields.push ( { name: "dispatch", access: [ APublic ], kind: FFun ( { args: args, expr: dispatch, params: [], ret: macro :Void } ), pos: pos } );
Context.defineType ({ Context.defineType ({
@@ -196,6 +206,13 @@ class Event<T> {
#end #end
public function cancel ():Void {
canceled = true;
}
public var dispatch:Dynamic; public var dispatch:Dynamic;
//macro public function dispatch (ethis:Expr, args:Array<Expr>):Void { //macro public function dispatch (ethis:Expr, args:Array<Expr>):Void {
@@ -230,7 +247,7 @@ class Event<T> {
public function has (listener:T):Bool { public function has (listener:T):Bool {
#if !macro #if !macro
for (l in listeners) { for (l in __listeners) {
if (Reflect.compareMethods (l, listener)) return true; if (Reflect.compareMethods (l, listener)) return true;
@@ -245,15 +262,15 @@ class Event<T> {
public function remove (listener:T):Void { public function remove (listener:T):Void {
#if !macro #if !macro
var i = listeners.length; var i = __listeners.length;
while (--i >= 0) { while (--i >= 0) {
if (Reflect.compareMethods (listeners[i], listener)) { if (Reflect.compareMethods (__listeners[i], listener)) {
listeners.splice (i, 1); __listeners.splice (i, 1);
priorities.splice (i, 1); __priorities.splice (i, 1);
repeat.splice (i, 1); __repeat.splice (i, 1);
} }