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

Fix preload cyclic references #65672

Closed

Conversation

adamscott
Copy link
Member

@adamscott adamscott commented Sep 11, 2022

Edit: This PR has been replaced with #67714
Edit: Currently not working as intended. Will post updates.

This simple PR makes it possible to use cyclic references with preloaded scripts.

After trying to load completely a script using ResourceLoader::load() (that calls down the line ResourceFormatLoaderGDScript::load() then right after GDScriptCache::get_full_script()), if the reference is null (which means that the script is not yet compiled), then we use instead the GDScriptCache::get_shallow_script().

The beauty of GDScriptCache::get_shallow_script() is that it gives back the result of GDScriptCache::get_full_script() if it has been fully loaded once.

So, this code works with this PR, which returns this error on master: Constant value uses script from "res://b.gd" which is loaded but not compiled.:

# main.gd
const A = preload("res://a.gd")

func _ready() -> void:
	A.hello()  # The console will print: "A.HELLO_WORLD: hello, world!"

# a.gd
extends Node

const B = preload("res://b.gd")

const HELLO_WORLD: = "hello, world!"

static func test() -> void:
	B.test()

# b.gd
extends Node

const A = preload("res://a.gd")

static func test() -> void:
	prints("A.HELLO_WORLD:", A.HELLO_WORLD)

Minimal reproduction project:
cyclic3.zip

Fixes #58181, fixes #61043, fixes #32165

@adamscott adamscott requested a review from a team as a code owner September 11, 2022 23:23
@adamscott adamscott force-pushed the fix-preload-cyclic-references branch 2 times, most recently from 97c07a5 to 402c3a1 Compare September 11, 2022 23:55
@Calinou Calinou added this to the 4.0 milestone Sep 12, 2022
@adamscott adamscott force-pushed the fix-preload-cyclic-references branch from 402c3a1 to b04a70f Compare September 12, 2022 01:43
@adamscott adamscott marked this pull request as draft September 12, 2022 02:02
@Chaosus Chaosus requested a review from vnen September 12, 2022 06:01
@@ -3192,8 +3192,7 @@ void GDScriptAnalyzer::reduce_preload(GDScriptParser::PreloadNode *p_preload) {
if (!FileAccess::exists(p_preload->resolved_path)) {
push_error(vformat(R"(Preload file "%s" does not exist.)", p_preload->resolved_path), p_preload->path);
} else {
// TODO: Don't load if validating: use completion cache.
p_preload->resource = ResourceLoader::load(p_preload->resolved_path);
p_preload->resource = GDScriptCache::get_shallow_script(p_preload->resolved_path, parser->script_path);
Copy link
Member Author

Choose a reason for hiding this comment

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

I know that I need to add a check to see if the preloaded path is a script or not before using GDScriptCache.

@adamscott adamscott force-pushed the fix-preload-cyclic-references branch 2 times, most recently from bf9d8c1 to 8c9a65c Compare September 12, 2022 17:34
@@ -3192,8 +3192,7 @@ void GDScriptAnalyzer::reduce_preload(GDScriptParser::PreloadNode *p_preload) {
if (!FileAccess::exists(p_preload->resolved_path)) {
push_error(vformat(R"(Preload file "%s" does not exist.)", p_preload->resolved_path), p_preload->path);
} else {
// TODO: Don't load if validating: use completion cache.
p_preload->resource = ResourceLoader::load(p_preload->resolved_path);
p_preload->resource = GDScriptCache::get_shallow_script(p_preload->resolved_path, parser->script_path);
Copy link
Member Author

Choose a reason for hiding this comment

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

This is where it gets weird. There's two behaviors, depending on the code on this line.

  1. With GDScriptCache::get_shallow_script() as is:
    • my minimal reproduction project ✔️ ;
    • the new test cases ❌ ;
    • modules/gdscript/tests/scripts/analyzer/features/preload_constant_types_are_inferred.gd ❌ ;
    • build does not fail due to memory leaks ✔️ .
  2. With ResourceLoader::load() and then GDScriptCache::get_shallow_script() if p_preload->resource.is_null():
    • my minimal reproduction project ❌ ;
    • the new test cases ✔️ ;
    • modules/gdscript/tests/scripts/analyzer/features/preload_constant_types_are_inferred.gd ✔️ ;
    • build fails due to memory leaks ⚠️

@adamscott adamscott force-pushed the fix-preload-cyclic-references branch from 8c9a65c to 98ce4b2 Compare September 13, 2022 14:18
@adamscott adamscott closed this Sep 13, 2022
@adamscott adamscott force-pushed the fix-preload-cyclic-references branch from 98ce4b2 to 22a09fe Compare September 13, 2022 14:19
@adamscott
Copy link
Member Author

@Calinou Could you reopen my PR? I messed up my rebases and erased my code, even force pushed it. I recovered it, but I cannot reopen my PR myself.

@akien-mga
Copy link
Member

It can't be reopened because at some time the contents of your branch were identical to the master branch, so GitHub force closed it, and it can't be reopened in such case.

image

That's actually a bug because I see you did fix the branch already and there's now a commit, but GitHub doesn't notice. So you'll have to open a new PR.

@MewPurPur
Copy link
Contributor

#67714 This is the current PR with this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants