-
Notifications
You must be signed in to change notification settings - Fork 332
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dangerous RemoveGadget/RemoveWidget usage #3900
Comments
Yes, though keep in mind that conversely, looping in reverse prevents InsertGadget in turn. See also beyond-all-reason/spring#835 |
In that case I think adding widgets to a queue and having them removed after the list looping is finished would be the best. Since some lists are looped in reverse, the same should be done for InsertWidget. |
I think RaiseGadget/Widget and LowerGadget/Widget can also cause problems when looping the list so a solution should also take those into account. |
This was already fixed by #3941 |
Description
As far as I can see, RemoveGadget, RemoveWidget shouldn't be used unless the callin list is being looped in reverse. check this comment. But this isn't generally done since sometimes we want to loop forward depending on how we want layer priority to behave (I believe). As far as I can see, doing it that way will mean the next element can be skipped.
Currently most of the traversing (90%) is done with ipairs, so it will skip elements.
I checked and some gadgets actually remove themselves in forward looping lists. For example, game_initial_spawn.lua is removing itself inside GameFrame, which is looped forwards with ipairs.
Luckily, most gadgets do this at Initialize, and that's ok, others may be doing it in rare situations, like when gl4 initialization fails. In most cases when this happens the skip of the next element will not be noticed since it can be something minor. Still, I think this should be fixed if I'm right and this is being done incorrectly.
In addition to this, all reordering methods suffer from the same issues, like RaiseGadget, LowerGadget... they can reorder the lists while they are traversed.
Expected Behaviour
Shouldn't skip callins when RemoveGadget is called.
Actual Behaviour
I think it skips elements.
Reproduction steps
This snippet should demonstrate the problem:
it will print:
Other
A possible solution is queue the removals until the callin list has been processed, this might have side effects in rare situations, but I think it should be ok.
Another posibility is reviewing everything and make sure no widgets delete themselves in at the "wrong moment".
Other possible solution is removing from tables inside ArrayRemove with
t[k] = nil
instead oftable.remove(t, k)
, but this only works when iterating with pairs, not with ipairs as is the case here (ipairs is more efficient so I don't think it's a good idea to switch to pairs).If you have other ideas pls post here :D
The text was updated successfully, but these errors were encountered: