Skip to content

Conversation

@TruelyMostWanted
Copy link

@TruelyMostWanted TruelyMostWanted commented Nov 4, 2025

Hey, this is my first PR / contribution to the engine 👋

Description:

This PR extends the ResourceLoader by 4 public methods for retrieval of either all or only filtered cached paths in C++, GDScript and C#.

Note A Resource is considered cached when it has a Reference Count > 0. This means it got assigned to exported fields in inspector or via set(...) / set_deferred(...) in code.

Usages:

extends Node
class_name GdScriptTestNode

@export var resources : Array[Resource]

func _ready() -> void:
	var allPathsArray = ResourceLoader.get_cached_paths()
	print(JSON.stringify(allPathsArray, "\t"))

	var allPathsDict = ResourceLoader.get_cached_paths_typed();
	print(JSON.stringify(allPathsDict, "\t"));

	var allImgPaths = ResourceLoader.get_cached_paths_by_filter(
		ResourceLoader.FilterTarget.FILTER_TARGET_TYPE_HINT,
		ResourceLoader.FilterComparator.FILTER_COMP_EQUALS,
		"Image"
	);
	print(JSON.stringify(allImgPaths, "\t"))
	
	var resPaths = ResourceLoader.get_cached_paths_typed_by_filter(
		ResourceLoader.FilterTarget.FILTER_TARGET_PATH,
		ResourceLoader.FILTER_COMP_BEGINS_WITH,
		"res://new"
	);
	print(JSON.stringify(resPaths, "\t"))
using Godot;
using Godot.Collections;

[GlobalClass]
public partial class TestNode : Node
{
    [Export] public Array<Resource> Resources;

    public override void _Ready()
    {
        var allPathsArray = ResourceLoader.GetCachedPaths();
        GD.Print(Json.Stringify(allPathsArray, "\t"));
        
        var allPathsDict  = ResourceLoader.GetCachedPathsTyped();
        GD.Print(Json.Stringify(allPathsDict, "\t"));
        
        var allImgPaths  = ResourceLoader.GetCachedPathsByFilter(
            ResourceLoader.FilterTarget.TypeHint, 
            ResourceLoader.FilterComparator.Equals, 
            "Image"
        );
        GD.Print(Json.Stringify(allImgPaths, "\t"));
        
        var allResPaths  = ResourceLoader.GetCachedPathsTypedByFilter(
            ResourceLoader.FilterTarget.Path, 
            ResourceLoader.FilterComparator.BeginsWith, 
            "res://new"
        );
        GD.Print(Json.Stringify(allResPaths, "\t"));
    }
}

Result:

With the above GDScript/C# and my list of resources (on the left) assigned to export variables i get the following result:
image

Documentation with Examples In-Engine

image

I hope this helps a lot of your projects out! ✨
Feel free to give me any feedback on the idea, the PR, the description/text of the PR and such

@TruelyMostWanted TruelyMostWanted requested review from a team as code owners November 4, 2025 04:03
@TruelyMostWanted TruelyMostWanted changed the title Extend ResourceLoader API for retrieval of all cached paths (+ filter queries) in (C++, C#, GDScript) Extend ResourceLoader API for retrieval of (all / only filtered) cached paths in (C++, C#, GDScript) Nov 4, 2025
@Chaosus Chaosus added this to the 4.x milestone Nov 4, 2025
Copy link
Member

@AThousandShips AThousandShips left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks promising and quite minimal in scope, just doing a form pass

Copy link
Member

@AThousandShips AThousandShips left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks promising and quite minimal in scope, just doing a form pass

TruelyMostWanted and others added 8 commits November 4, 2025 15:54
Co-authored-by: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
Co-authored-by: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
Co-authored-by: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
Co-authored-by: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
Co-authored-by: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
@AThousandShips
Copy link
Member

Please apply all the suggestions locally and push once to reduce noise, if you weren't a first time contributor this would have triggered several runs of CI unnecessarily

TruelyMostWanted and others added 3 commits November 4, 2025 16:54
Co-authored-by: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
@TruelyMostWanted
Copy link
Author

TruelyMostWanted commented Nov 4, 2025

Please apply all the suggestions locally and push once to reduce noise, if you weren't a first time contributor this would have triggered several runs of CI unnecessarily

Oh thats really good to know!
For me this was the first time having an actual code review on GitHub, so once again something learned, thanks!
The next thing i have to learn is rebasing commits into one. Reducing the commit history as seen above

But aside from that, my commits are done @AThousandShips

@AThousandShips
Copy link
Member

AThousandShips commented Nov 4, 2025

You've skipped several suggestions, and didn't quite follow the suggestions given, but will do a second pass of review after you've added the missing ones (the very first one about spacing)

TruelyMostWanted and others added 2 commits November 4, 2025 17:12
Co-authored-by: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
Copy link
Author

@TruelyMostWanted TruelyMostWanted left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code has been updated and all comments resolved.
Even though it shows me a (2) towards "Review changes" i dont see any further ones with status "Pending" or where i have the button to "Add changes to batch"

@TruelyMostWanted
Copy link
Author

TruelyMostWanted commented Nov 4, 2025

You've skipped several suggestions, and didn't quite follow the suggestions given, but will do a second pass of review after you've added the missing ones (the very first one about spacing)

But i did revert the file(s), adding in only what i changed, adding whitespaces between my methods and applied clang-format
There is definitly something missing on my side.

@AThousandShips
Copy link
Member

Check the "changed files" and you'll see the changes that are left there, in resource.h and core_bind.cpp

I'll do another review tomorrow

@TruelyMostWanted
Copy link
Author

Check the "changed files" and you'll see the changes that are left there, in resource.h and core_bind.cpp

I'll do another review tomorrow

Alrighty, thanks for your help though! Appreciate it very much!

Added mutex lock for thread safety

Fixed Tags Usage in Docs

Adjusted paragraphs

Improved readability by added more references
@TruelyMostWanted
Copy link
Author

TruelyMostWanted commented Nov 4, 2025

Yey, my first rebase of commits worked, nice!
Now i get the hang of it

While working:

  • Check on the styling/design guidelines in the docs (e.g., usage of auto, formatting the docs)

Pre-Commit:

  • Run clang-format to enforce style guide

Rules for Commits and Pushs:

  • Commit as much as i need locally but DO NOT PUSH IMMEDIATLY
  • Then git rebase all commits into a single Squash Commit with a reworded commit message
  • Push the Squashed commit (commit only when everything is really done) --> Note: After no longer being a First-Time Contributer, this will automatically trigger the CI/Actions and its Checks

Side note:
Find the right moment to open the Pull-Request. Knowledge extends, Discussions and Feedback happen and maybe even Code Reviews cause you to rewrite code and documentation. Thereby always follow the 3 steps above

Now i'm really done committing on this feature

@TruelyMostWanted
Copy link
Author

TruelyMostWanted commented Nov 5, 2025

Hey, i've made a test and noticed a difference in behaviours which we should talk about:
image

Behaviour (1) and (1.1):

❓(Questionable) Every Resource that gets loaded via any of the specific classes (e.g., AudioStreamWAV, AudioStreamMP3, Image, etc.. ) and their load_from_file(path) method is not automatically considered cached upon assignment to any variable in code.
It needs a manual assignment of the resource_path in GDScript or C#.

Behaviour (2):

✅ (Works as intended) Resource loaded via the ResourceLoader.load(path, typeHint, cacheMode) are automatically considered cached when assigned to any variable in code. This happens due to their internal call and assignment of the resource_path via

load_task.resource->set_path(load_task.local_path); //resource_loader.cpp, Line 446

which lead to resource.cpp handling the existence in ResourceCache::resources

void Resource::set_path(const String &p_path, bool p_take_over) { //resource.cpp, Line 70

Question

How should we handle this?
Shouldn't the different load_from_file(const String &p_path)methods automatically set the resource_path to the path given in their p_path parameter? It would only need 1 line of code in each of them to fix this:

resource->set_path(p_path);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add retrieval methods to ResourceLoader for querying cached resource paths (C++, C#, GDScript)

3 participants