package lime.app;


import haxe.macro.Context;
import haxe.macro.Expr;


class Event<T> {
	
	
	@:noCompletion public var listeners:Array<T>;
	
	private var priorities:Array<Int>;
	
	
	public function new () {
		
		listeners = new Array<T> ();
		priorities = new Array<Int> ();
		
	}
	
	
	public function add (listener:T, priority:Int = 0):Void {
		
		for (i in 0...priorities.length) {
			
			if (priority > priorities[i]) {
				
				listeners.insert (i, listener);
				priorities.insert (i, priority);
				return;
				
			}
			
		}
		
		listeners.push (listener);
		priorities.push (priority);
		
	}
	
	
	macro public function dispatch (ethis:Expr, args:Array<Expr>) {
		
		return macro {
			
			for (listener in $ethis.listeners) {
				
				listener ($a{args});
				
			}
			
		}
		
	}
	
	public function remove (listener:T):Void {
		
		var index = listeners.indexOf (listener);
		
		if (index > -1) {
			
			listeners.splice (index, 1);
			priorities.splice (index, 1);
			
		}
		
	}
	
	
}
package lime.app;


import haxe.macro.Context;
import haxe.macro.Expr;


class Event<T> {
	
	
	@:noCompletion public var listeners:Array<T>;
	@:noCompletion public var repeat:Array<Bool>;
	
	private var priorities:Array<Int>;
	
	
	public function new () {
		
		listeners = new Array<T> ();
		priorities = new Array<Int> ();
		repeat = new Array<Bool> ();
		
	}
	
	
	public function add (listener:T, once:Bool = false, priority:Int = 0):Void {
		
		for (i in 0...priorities.length) {
			
			if (priority > priorities[i]) {
				
				listeners.insert (i, listener);
				priorities.insert (i, priority);
				repeat.insert (i, !once);
				return;
				
			}
			
		}
		
		listeners.push (listener);
		priorities.push (priority);
		repeat.push (!once);
		
	}
	
	
	macro public function dispatch (ethis:Expr, args:Array<Expr>) {
		
		return macro {
			
			var listeners = $ethis.listeners;
			var repeat = $ethis.repeat;
			var length = listeners.length;
			var i = 0;
			
			while (i < length) {
				
				listeners[i] ($a{args});
				
				if (!repeat[i]) {
					
					$ethis.remove (listeners[i]);
					length--;
					
				} else {
					
					i++;
					
				}
				
			}
			
		}
		
	}
	
	
	public function remove (listener:T):Void {
		
		var index = listeners.indexOf (listener);
		
		if (index > -1) {
			
			listeners.splice (index, 1);
			priorities.splice (index, 1);
			repeat.splice (index, 1);
			
		}
		
	}
	
	
}
Add support for events that fire only once
Add support for events that fire only once

fbricker/lime,MinoGames/lime,madrazo/lime-1,madrazo/lime-1,madrazo/lime-1,fbricker/lime,fbricker/lime,madrazo/lime-1,player-03/lime,player-03/lime,MinoGames/lime,madrazo/lime-1,openfl/lime,openfl/lime,player-03/lime,MinoGames/lime,MinoGames/lime,fbricker/lime,MinoGames/lime,madrazo/lime-1,fbricker/lime,player-03/lime,openfl/lime,fbricker/lime,openfl/lime,player-03/lime,player-03/lime,madrazo/lime-1,openfl/lime,MinoGames/lime,MinoGames/lime,player-03/lime,openfl/lime,openfl/lime,fbricker/lime