From d8379adc99b1bdc342e0279c7a865c08b2ffc403 Mon Sep 17 00:00:00 2001 From: Kevin Leung Date: Thu, 15 Jan 2015 18:36:44 +0800 Subject: [PATCH 1/2] Fix iteration bug in FlxSignal This one is nasty.... --- flixel/util/FlxSignal.hx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/flixel/util/FlxSignal.hx b/flixel/util/FlxSignal.hx index 5cbb61ae7d..75b77d25c5 100644 --- a/flixel/util/FlxSignal.hx +++ b/flixel/util/FlxSignal.hx @@ -277,12 +277,18 @@ private class Macro { return macro { + var pendingRemove = []; for (handler in _handlers) { handler.listener($a{exprs}); if (handler.dispatchOnce) - remove(handler.listener); + pendingRemove.push(handler); + } + + for (handler in pendingRemove) + { + remove(handler.listener); } } } From 88cbb5cb73feb5d283237329b083310f170cf13d Mon Sep 17 00:00:00 2001 From: Kevin Leung Date: Thu, 15 Jan 2015 18:50:51 +0800 Subject: [PATCH 2/2] FlxSignal iteration bug: Better fix --- flixel/util/FlxSignal.hx | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/flixel/util/FlxSignal.hx b/flixel/util/FlxSignal.hx index 75b77d25c5..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,15 +288,17 @@ private class Macro { return macro { - var pendingRemove = []; - for (handler in _handlers) + processingListeners = true; + for (handler in handlers) { handler.listener($a{exprs}); if (handler.dispatchOnce) - pendingRemove.push(handler); + remove(handler.listener); } + processingListeners = false; + for (handler in pendingRemove) { remove(handler.listener);