mapeditor/tiled

Do you want to work on this issue?

You can request for a bounty in order to promote it!

Crash occurs with multiple iterations of instantiating TileMap objects via tiled.registerMapFormat. #4193

deadowl posted onGitHub

Describe the bug The initial load of the World file works as expected. Upon unload and any subsequent reload, Tiled crashes. If you uninstall and reinstall Tiled, the World file will load without issue. If you rename the World file to a filename not previously seen by Tiled, the World file will load without issue.

To Reproduce Steps to reproduce the behavior:

  1. Load world using an API registered map format.
  2. Unload the world.
  3. Reload the world.
  4. Tiled crashes

Expected behavior The world will load just as it did upon its initial load.

Specifications:

  • OS: Windows 11
  • Tiled Version: Reproduced on 1.11.0 and 1.11.2

If Tiled crashes from the use of a subsequent filename, and following this crash, the file is renamed using a prior filename in which Tiled also crashed, it will load as expected using the prior filename.

posted by deadowl 12 days ago

In my code, it looks like it's happening in the read function with the line "var tileMap = new TileMap();" and only when reloading a world with the registered map format.

The read function of the registered map format performs a number of tasks before getting to the crash point. It loads and reads the config file fine, it loads and reads the tsx tileset file specified in the config file fine, and it loads and reads the foreign map file fine. Then when converting the foreign map to an actual tilemap--and on the specific line instantiating a TileMap object--that's where it crashes. If I comment out anything related to instantiating the TileMap object, my error handling manages the level being undefined fine.

posted by deadowl 12 days ago

Just to provide an update--this didn't resolve the issue, but I realized I was doing something silly by loading my extension config (which basically just defines a default tileset because the level doesn't come with one) and instantiating a new tileset (being a native Tiled tileset, even when it had been previously instantiated from the same file) every time I loaded a new tilemap via registerMapFormat. Updated my extension code to lazy load and keep the config and default tileset in memory. Thought this could be something. Unfortunately, same thing is still happening (Tiled crashes on loading a new tilemap after loading so many tilemaps). Also noting this isn't strictly related to reloading a world file and updated the issue title to reflect that.

posted by deadowl 8 days ago

I pared down my code enough to identify that when I eliminate code references to WeakMap, the problem no longer occurs; I'm running my code through a Babel transpiler and Babel uses WeakMap in relation to private class properties. Could be a Qt Javascript Runtime bug. I've previously also found that the Qt Javascript Runtime doesn't like if you use Proxy on an Array.

posted by deadowl 7 days ago

It appears that the WeakMap references should be garbage collected by the Javascript Runtime Environment once other references to the class instance are dead, and I don't see any other reason for the crashes than that the garbage collection simply isn't happening, or isn't happening in a timely manner. (https://infinitejs.com/posts/common-pitfalls-weakmap-weakset-js/)

Qt has some documentation on Memory Management and Javascript Engine Configuration, and if no changes to garbage collection configuration would resolve the issue, this might be considered to be a Qt bug.

https://doc.qt.io/qt-6/qtqml-javascript-memory.html https://doc.qt.io/qt-6/qtqml-javascript-finetuning.html

posted by deadowl 6 days ago

Fund this Issue

$0.00
Funded
Only logged in users can fund an issue

Pull requests