-
-
Notifications
You must be signed in to change notification settings - Fork 21.6k
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
Fix loading of cyclic scenes from GDScript #92326
Closed
adamscott
wants to merge
1
commit into
godotengine:master
from
adamscott:gdscript-cyclic-scenes-workaround
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If passing is required I'd pass a reference instead to make the requirement explicit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given there's no nuance to report about the error, I think returning a null
Ref
is enough, sor_error
can go away.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While we're at it, I'm not very sure about the "shallow" wording. Since this is async, by the time the caller deals with the resource, the completeness in its properties having been set and references to dependencies being filled ranges from none (we could call that "shallow") to full. Also, this wouldn't be thread safe, in the sense that there's no sync point with the potentially arbitrary loading thread, which can lead to the caller not only seeing an incomplete resource, but running into data races or race conditions.
Do you think it would be an option to wait for the full resource to be loaded? That would guarantee safety.
If the caller can be happy with the resource in a shallow state (that is, own properties set) the loader needs to be enhanced to support it properly. However, bear in mind that the caller can't safely access anything that can still change (references to external resources, properties already set but that will change due to one of those "queued update" callbacks running later, etc.).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For GDScript this doesn't matter in most cases. Only if the user
preload()
a currently loading resource and do something with the resource at the point. This is probably only possible in a static initializer (explicit or implicit).If we choose this approach, then we should add a comment that
ResourceLoader::get_loading_resource()
is intended for GDScript (due to how it works) and should not be used elsewhere in the engine.Alternatively, we could make such a "shallow" resource
null
until the end of loading. In both cases it will look unexpected to the user. Not sure which option is better, but probablynull
option is more explicit.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding a thought here: I think this only needs to be aware of other loads happening on the same thread (in other words, in the same stack). In that case,
ResourceLoader
could have a different function for that case explicitly that wouldn't involve any interaction with other threads. I could implement it if you think that'd do the trick.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's impossible. 99% of the time, the returned reference will be null. Hence why I force the error return value. We can't differentiate a successful and a failing request only by the returned reference, as both will be null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's a good idea. Like, I think we could push this technique to support cyclic loading elsewhere too (cyclic node scenes references?). But I agree that this function should have a warning or something like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Elaborating on that:
Since this PR is about a script that is cyclically referenced,
ResourceLoader
already has a data member that fits the bill:load_paths_stack
. That's unique per thread, so checking there is good as it keeps the concern within the dependency chain of the current load chain, deterministically as no threads are involved. However, that vector would need to be modified to it contains the resource references as well.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is more about anything that is cyclically referenced in the context of script loading.