ResourceLoader: Add method to show list of Resources still stored after unresolved load_threaded_request(path)
calls
#7866
Labels
load_threaded_request(path)
calls
#7866
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 viaResourceLoader.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 byResourceLoader.load_threaded_get(path)
(or if the game is closed). If a resource is requested viaResourceLoader.load_threaded_request(path)
but the script receiving it is interrupted before it can callResourceLoader.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 callingResourceLoader.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 theuser_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>
nameduser_load_tokens
to store all resources that meet the criteria we are looking for. TheString
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 inuser_load_tokens
would be enough for this method to fulfill it's purpose (though if better methods of retrieving these paths fromuser_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 withResourceLoader.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 callingResourceLoader.load_threaded_get()
orResourceLoader.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.
The text was updated successfully, but these errors were encountered: