summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2024-05-02 17:31:32 +0200
committerRémi Verschelde <rverschelde@gmail.com>2024-05-02 17:31:32 +0200
commita7029e4c8a0714400deb40ec6d57b31c2025d22e (patch)
treead6ea405eb88d80fcba45e43c02f06d7eab065d2
parent7a968c619d478f06d1ab94de8b0f1afffb985d28 (diff)
parent99b702ea3d12952b842055a4d5d4b1928ed69186 (diff)
downloadredot-engine-a7029e4c8a0714400deb40ec6d57b31c2025d22e.tar.gz
Merge pull request #91364 from vnen/gdscript-implicit-ready-base-first
GDScript: Call implicit ready on base script first
-rw-r--r--modules/gdscript/gdscript.cpp23
-rw-r--r--modules/gdscript/gdscript.h2
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/onready_base_before_subclass.gd18
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/onready_base_before_subclass.out3
4 files changed, 36 insertions, 10 deletions
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index f238958f25..73abf71bde 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -1958,19 +1958,22 @@ int GDScriptInstance::get_method_argument_count(const StringName &p_method, bool
return 0;
}
+void GDScriptInstance::_call_implicit_ready_recursively(GDScript *p_script) {
+ // Call base class first.
+ if (p_script->_base) {
+ _call_implicit_ready_recursively(p_script->_base);
+ }
+ if (p_script->implicit_ready) {
+ Callable::CallError err;
+ p_script->implicit_ready->call(this, nullptr, 0, err);
+ }
+}
+
Variant GDScriptInstance::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
GDScript *sptr = script.ptr();
if (unlikely(p_method == SNAME("_ready"))) {
- // Call implicit ready first, including for the super classes.
- while (sptr) {
- if (sptr->implicit_ready) {
- sptr->implicit_ready->call(this, nullptr, 0, r_error);
- }
- sptr = sptr->_base;
- }
-
- // Reset this back for the regular call.
- sptr = script.ptr();
+ // Call implicit ready first, including for the super classes recursively.
+ _call_implicit_ready_recursively(sptr);
}
while (sptr) {
HashMap<StringName, GDScriptFunction *>::Iterator E = sptr->member_functions.find(p_method);
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h
index 7bd68ac0b1..51267ecb84 100644
--- a/modules/gdscript/gdscript.h
+++ b/modules/gdscript/gdscript.h
@@ -365,6 +365,8 @@ class GDScriptInstance : public ScriptInstance {
SelfList<GDScriptFunctionState>::List pending_func_states;
+ void _call_implicit_ready_recursively(GDScript *p_script);
+
public:
virtual Object *get_owner() { return owner; }
diff --git a/modules/gdscript/tests/scripts/runtime/features/onready_base_before_subclass.gd b/modules/gdscript/tests/scripts/runtime/features/onready_base_before_subclass.gd
new file mode 100644
index 0000000000..99156adb28
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/onready_base_before_subclass.gd
@@ -0,0 +1,18 @@
+#GH-63329
+class A extends Node:
+ @onready var a := get_value("a")
+
+ func get_value(var_name: String) -> String:
+ print(var_name)
+ return var_name
+
+class B extends A:
+ @onready var b := get_value("b")
+
+ func _ready():
+ pass
+
+func test():
+ var node := B.new()
+ node._ready()
+ node.free()
diff --git a/modules/gdscript/tests/scripts/runtime/features/onready_base_before_subclass.out b/modules/gdscript/tests/scripts/runtime/features/onready_base_before_subclass.out
new file mode 100644
index 0000000000..b417ce67ca
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/onready_base_before_subclass.out
@@ -0,0 +1,3 @@
+GDTEST_OK
+a
+b