http://d.puremagic.com/issues/show_bug.cgi?id=10821
--- Comment #5 from Andrej Mitrovic <[email protected]> 2013-08-17 11:00:42 PDT --- (In reply to comment #4) > I found > that the only way to keep things consistent without strange side-effects was > to > keep a list of to-be-deleted entries separately, and the delegate would never > modify the array of callbacks directly, but would append itself to the > to-be-deleted list if it wants to remove itself. Hmm yeah, it gets complicated real fast. Thanks for the insight. So here's a quick safer workaround implementation: ----- struct Signal { void connect(void delegate(int) func) { if (emitting) { funcsToAdd[func] = 1; } else { stderr.writefln("Func connect: %s", *cast(void**)&func); funcs[func] = 1; } } void disconnect(void delegate(int) func) { if (emitting) { funcsToDelete[func] = 1; } else { stderr.writefln("Func disconnect: %s", *cast(void**)&func); funcs.remove(func); } } void emit(int i) { emitting = true; scope(exit) emitting = false; foreach (func; funcs.byKey) { stderr.writefln("Calling: %s", *cast(void**)&func); func(i); } foreach (func; funcsToDelete.byKey()) funcs.remove(func); funcsToDelete = null; foreach (func; funcsToAdd.byKey()) funcs[func] = 1; funcsToAdd = null; } int[void delegate(int)] funcs; int[void delegate(int)] funcsToAdd; int[void delegate(int)] funcsToDelete; bool emitting; } void main() { Signal signal; void delegate(int) handler; handler = (int i) { signal.disconnect(handler); }; signal.connect(handler); signal.emit(1); signal.emit(2); signal.emit(3); signal.emit(4); } ----- Of course this still isn't perfect, there's no telling what a signal handler really wants to do, whether it actually wants to add/remove some other handler immediately or only schedule add/removal for later. I guess the bottom line is this stuff is more complicated than I thought. I wonder if that new signals implementation recently announced handles this sort of stuff. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
