Open xynanlee opened 5 months ago
ResourceCache works like WeakRef - if a resource is referenced somewhere, you can get it from cache. If it isn't, it will be loaded again. In your first example you don't store the Resource anywhere, so it gets unloaded. If all resources would stay in cache forever you'd run out of memory quickly.
Seems like the description of has_cached()
could clarify that.
ResourceCache works like WeakRef - if a resource is referenced somewhere, you can get it from cache. If it isn't, it will be loaded again. In your first example you don't store the Resource anywhere, so it gets unloaded. If all resources would stay in cache forever you'd run out of memory quickly.
Seems like the description of
has_cached()
could clarify that.
Alright, I think the documentation would need to further clarify on what the cache modes do, I currently have the impression of:
_non_cached_load
to return true
without my intervention to store the loaded asset. This behavior is exactly how Unreal handles their AssetManager
and PrimaryDataAsset
.Overall, my impression of the system is the ResourceLoader will own the assets in the form of hard references as a centralized loading mechanism and the loaded assets will return as a WeakRef. This architecture can also synergize with the Export WeakRef feature proposal. Since, I'm looking into ways to break cyclic reference.
I'll look forward to listen more on how should I use the ResourceLoader because I think my current impression of it has used it outside of its intended usage.
Edit: Currently I feel like the system works like CACHE_MODE_IGNORE, regardless of cache modes if I don't do manual caching myself.
ResourceCache is more like database or registry. When you load a Resource, as long as something references it (it's RefCounted, which means the instance is reference counted), loading the same resource will return the same instance. If the instance is unloaded, the cache entry for its path will be removed and you'll need to load it again.
If you want the Resource to persist, you need to store it in some more persistent place, e.g. node that exists while your game is running (usually autoload).
Cache modes are explained here: https://docs.godotengine.org/en/latest/classes/class_resourceloader.html#enum-resourceloader-cachemode. The stable docs are a bit outdated and the CACHE_MODE_REPLACE works differently in 4.3 (in more expected way).
I think the documentation can be further improved to emphasize on the having to store the loaded assets manually by ourselves since the documentation currently implies that the loaded assets are owned and managed internally.
Tested versions
System information
Godot v4.1.stable - Windows 10.0.19045 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 2070 SUPER (NVIDIA; 31.0.15.3623) - AMD Ryzen 7 3700X 8-Core Processor (16 Threads)
Issue description
The issue
ResourceLoader.load
doesn't seem to cache the asset within ResourceLoader itself even with CACHE_MODE_REUSE.The code that prints
false
inResourceLoader.has_cached
:The code below prints
true
inResourceLoader.has_cached
:_stack_cached_load()
works becausex
is still within scope in the function. The asset will fall out of scope as soon as it code execution exits the function.Expected behavior
_non_cached_load()
should returntrue
.Steps to reproduce
_non_cached_load
.Minimal reproduction project (MRP)
MRPLoadCacheBug.zip