Fix call queue problems when loading TileSet #89493
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When TileSet is being loaded, it will load every TileSetAtlasSource and it will emit
changed
signal for every tile and tile property. The signal is connected to_queue_update_padded_texture()
, which doesn't have any safeguard against multiple calls, which means that it did a deferred call every time. So for my tileset with 40+ sources, 50+ tiles each that's like... 2000 deferred calls.The fix in this PR is twofold:
_queue_update_padded_texture()
to prevent multiple deferred callschanged
emissions while the TileSet is being loadedFixes the memory problem in #87593, effectively resolving the issue, as the project can load (albeit it's still extremely slow). The problem was that the deferred calls would build up and never get flushed, because many scenes were loaded one after another and the TileSet was repeatedly freed and loaded again (which is also why it takes so long). I have ~500 scenes that use this TileSet, so if you do the maths, it's obvious why the queue couldn't hold it.
Unfortunately it still results in some deferred calls that will very slowly clog up message queue, but since this makes like 100x less of them, it's much less likely to run out of memory. Not sure how to prevent it completely; we could maybe remove deferred call from queue manually by the TileSetAtlasSource if it's being deleted, but MessageQueue has no method for that AFAIK.