I am attaching a zip of my test project that I recreated the problem in. I am using a central object that is an event dispatcher that certain objects can register to events for. But it seems that in some circumstances, some event listeners don't get called correctly. If you run the project, I'd expect the traces to be this:
1. MainModel:init()
2. GameModel:init()
Click the stage
3. onMouseDown
4. MainModel.onGameWon
5. GameModel.onGameWon
6. After dispatch
But instead the order is
1. MainModel:init()
2. GameModel:init()
Click the stage
3. onMouseDown
4. MainModel.onGameWon
5. After dispatch
As you can see, GameModel which is also listening for the GAME_WON event never gets fired at all. This seems to be a huge issue unless I'm misunderstanding things. This has caused us to MAJORLY overhaul our game structure and has caused us to have to couple a lot of things together that we'd rather not do. Is this intended behavior? If so can you explain why it is? And if there is a workaround?
Comments
Until then, I think you'll have to not use removeEventListener() within an event hander for the same event.
best regards
Best regards
In your example in your MainModelClass:onGameWon() handler function you are removing the GAME_WON handler for the MainModelObject. However, that handler is probably stored in a list called "GAME_WON" associated with the EventStream class object.
At the the point you are removing this handler, Gideros is likely to be traversing that list. This fiddling around with the contents may affect any other GAME_WON handlers that are also on the same list, e.g. the one for the gameModel object.
Anyway, we probably should wait for @atilim to confirm. In the meantime, try the workaround:
Actually, @atilim or @ar2rsawseen, you might want to consider adding this feature (or something like it) to the system or the EasyGideros init library. I have found it to be very useful in the past (and not just to workaround bugs). In a previous system I worked with it was called postToInputQueue() and took a block of code to be executed next time the UI input thread was serviced.
Among other things it can be useful for queueing up stuff to happen once an app is fully initialised and the UI loop has started processing events.
best regards
Likes: atilim
Here is my simplified test code:
Anyway, now I fixed it. You can expect a new release in 3-4 days. Thank you for reporting.
Timer.delayedCall(0, function() dispatcher:removeEventListener("foo", foo1) end)
be a workaround?
Maybe if there is a function names nextTick(func) can do it more efficiently.
Likes: hgvyas123
https://sites.google.com/site/xraystudiogame