Skip to content
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

ResourceLoader: Add method to show list of Resources still stored after unresolved load_threaded_request(path) calls #7866

Open
mithost opened this issue Sep 26, 2023 · 0 comments

Comments

@mithost
Copy link

mithost commented Sep 26, 2023

Describe the project you are working on

I am working on an adventure game which involves the player quickly navigating between many small rooms interconnected via loading triggers (e.g. metroidvania). ResourceLoader.load_threaded_request(path) is used to preload each room the player can access from the room they are currently in in the background, reducing/eliminating time spent loading during room transitions (Each room is it's own .tscn file/PackedScene). References to the loaded scenes are then given to their respective loading triggers to hold onto via ResourceLoader.load_threaded_get() once the load is complete..

While my specific use-case is a metroidvania-style game, the proposed feature would be helpful in any projects that load assets in the background during gameplay or otherwise rely on ResourceLoader.load_threaded_request(path) in dynamic situations.

Describe the problem or limitation you are having in your project

When a resource is requested using ResourceLoader.load_threaded_request(path), it will remain referenced in internal memory until it is specifically retrieved in a script by ResourceLoader.load_threaded_get(path) (or if the game is closed). If a resource is requested via ResourceLoader.load_threaded_request(path) but the script receiving it is interrupted before it can call ResourceLoader.load_threaded_get(path), the loaded resource will be stuck in memory until another script attempts to load the resource from the same path. If this path was generated dynamically or is exclusive to a section of the game that is not accessed regularly, it's likely that this resource won't leave internal memory until the player restarts the game.

Resources requested by ResourceLoader.load_threaded_request(path) can be manually freed by calling ResourceLoader.load_threaded_get(path) and assigning it to a temporary variable (or calling it with no assignment), but this requires already knowing the path of the resource you would like to free. ResourceLoader does not allow you to check what resources are currently stored from threaded requests, so if you do not already know what resources could be stuck in this limbo you are unable to interact with or free them.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

I would like to propose adding a method (or array) to ResourceLoader which returns a list of paths for each resource that is waiting to be retrieved by a ResourceLoader.load_threaded_get() call.

A list of these paths is already maintained in resource_loader.cpp as the String keys of the user_load_tokens Hashmap, but this is not currently accessible to GDScript or C# scripts.

If developers were able to check what resources are waiting for a ResourceLoader.load_threaded_get() call and get their paths, they could detect and resolve any issues they encounter with stray threaded load requests easily on their own.

For example if the proposed method returned a list of paths, developers could compare each path in the list to what their current game state expects to be preloaded, then call ResourceLoader.load_threaded_get() with the path grabbed from the proposed method's return list to free up any unneeded entries.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

A method would be added to ResourceLoader which returns an array of strings containing the path of each resource currently accessible via ResourceLoader.load_threaded_get()/ResourceLoader.load_threaded_get_status(), and make that method accessible to GDScript and C# scripts.

resource_loader.cpp uses a HashMap<String, ResourceLoader::LoadToken> named user_load_tokens to store all resources that meet the criteria we are looking for. The String used for the HashMap entry's key is the unmodified path parameter used to request and get the thread-loaded resource listed. Returning a list that contains the key of each item in user_load_tokens would be enough for this method to fulfill it's purpose (though if better methods of retrieving these paths from user_load_tokens exists, that would also work perfectly fine!).

Note: If user_load_tokens contains entries that have different load statuses that are NOT yet successful loads (in progress, failing, invalid, etc) this proposed method would have the same use case and no changes would be needed. Use of the function would just require paths be optionally validated with ResourceLoader.load_threaded_get_status() before determining what to do with them.

If this enhancement will not be used often, can it be worked around with a few lines of script?

To work around it, developers would need to write code that keeps track of every path used as a parameter for ResourceLoader.load_threaded_request() across each of their functions, and routinely try calling ResourceLoader.load_threaded_get() or ResourceLoader.load_threaded_get_status() against every entry in that maintained list paths to free up entries. Alternatively the same tests can be ran against every resource path the developer expects could possibly be loaded on a thread during runtime to hopefully build a similar list.

Neither of these workarounds can confirm with absolute certainty that there are no stray resources loaded in ResourceLoader, and they each require a lot of additional management to be integrated into scripts to maintain a hopefully semi-accurate request path list.

Is there a reason why this should be core and not an add-on in the asset library?

Being able to check what resources ResourceLoader is holding onto is an important tool for any project making use of threaded loading. Any project that uses threaded loading for resources can benefit from being able to retrieve a list of pending assets they have loaded, as recovering from losing track of what paths were active is currently requires blindly checking over dozens or hundreds of potential paths.

Additionally, Adding this method to ResourceLoader should not run any risk of breaking projects or scripts that make use of ResourceLoader, nor would it force any workflow changes on Godot users.

@mithost mithost changed the title ResourceLoader: Add method to show list of Resources stored via unresolved load_threaded_request(path) calls ResourceLoader: Add method to show list of Resources still stored after unresolved load_threaded_request(path) calls Sep 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants