浏览代码

Merge pull request #91364 from vnen/gdscript-implicit-ready-base-first

GDScript: Call implicit ready on base script first
Rémi Verschelde 1 年之前
父节点
当前提交
a7029e4c8a

+ 13 - 10
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);

+ 2 - 0
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; }
 

+ 18 - 0
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()

+ 3 - 0
modules/gdscript/tests/scripts/runtime/features/onready_base_before_subclass.out

@@ -0,0 +1,3 @@
+GDTEST_OK
+a
+b