diff --git a/flixel/util/FlxSignal.hx b/flixel/util/FlxSignal.hx index 5cbb61ae7d..1e52f36f46 100644 --- a/flixel/util/FlxSignal.hx +++ b/flixel/util/FlxSignal.hx @@ -99,11 +99,15 @@ private class FlxBaseSignal implements IFlxSignal */ public var dispatch:T; - private var _handlers:Array>; + private var handlers:Array>; + private var pendingRemove:Array>; + private var processingListeners:Bool = false; + public function new() { - _handlers = []; + handlers = []; + pendingRemove = []; } public function add(listener:T) @@ -123,13 +127,20 @@ private class FlxBaseSignal implements IFlxSignal if (listener != null) { var handler = getHandler(listener); + if (handler != null) { - _handlers.remove(handler); - handler.destroy(); - handler = null; + if (processingListeners) + pendingRemove.push(handler); + else + { + handlers.remove(handler); + handler.destroy(); + handler = null; + } } } + } public function has(listener:T):Bool @@ -141,13 +152,13 @@ private class FlxBaseSignal implements IFlxSignal public inline function removeAll():Void { - FlxDestroyUtil.destroyArray(_handlers); + FlxDestroyUtil.destroyArray(handlers); } public function destroy():Void { removeAll(); - _handlers = null; + handlers = null; } private function registerListener(listener:T, dispatchOnce:Bool):FlxSignalHandler @@ -157,7 +168,7 @@ private class FlxBaseSignal implements IFlxSignal if (handler == null) { handler = new FlxSignalHandler(listener, dispatchOnce); - _handlers.push(handler); + handlers.push(handler); return handler; } else @@ -173,7 +184,7 @@ private class FlxBaseSignal implements IFlxSignal private function getHandler(listener:T):FlxSignalHandler { - for (handler in _handlers) + for (handler in handlers) { if ( #if neko // simply comparing the functions doesn't do the trick on neko @@ -277,13 +288,21 @@ private class Macro { return macro { - for (handler in _handlers) + processingListeners = true; + for (handler in handlers) { handler.listener($a{exprs}); if (handler.dispatchOnce) remove(handler.listener); } + + processingListeners = false; + + for (handler in pendingRemove) + { + remove(handler.listener); + } } } }