Jelajahi Sumber

Fix _notification with parent and child classes

(cherry picked from commit 23c010900c9a09c5c99bfbb0d465cd468aa74b6c)
David Snopek 1 tahun lalu
induk
melakukan
f7a9d32f32

+ 2 - 2
include/godot_cpp/classes/wrapped.hpp

@@ -201,11 +201,11 @@ public:
                                                                                                                                                                                        \
 	static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what) {                                                                                            \
 		if (p_instance && m_class::_get_notification()) {                                                                                                                              \
+			m_inherits::notification_bind(p_instance, p_what);                                                                                                                         \
 			if (m_class::_get_notification() != m_inherits::_get_notification()) {                                                                                                     \
 				m_class *cls = reinterpret_cast<m_class *>(p_instance);                                                                                                                \
-				return cls->_notification(p_what);                                                                                                                                     \
+				cls->_notification(p_what);                                                                                                                                            \
 			}                                                                                                                                                                          \
-			m_inherits::notification_bind(p_instance, p_what);                                                                                                                         \
 		}                                                                                                                                                                              \
 	}                                                                                                                                                                                  \
                                                                                                                                                                                        \

+ 5 - 0
test/project/main.gd

@@ -174,6 +174,11 @@ func _ready():
 	assert_equal(new_example_ref.was_post_initialized(), true)
 	assert_equal(example.test_post_initialize(), true)
 
+	# Test that notifications happen on both parent and child classes.
+	var example_child = $ExampleChild
+	assert_equal(example_child.get_value1(), 11)
+	assert_equal(example_child.get_value2(), 33)
+
 	exit_with_status()
 
 func _on_Example_custom_signal(signal_name, value):

+ 2 - 0
test/project/main.tscn

@@ -22,4 +22,6 @@ offset_right = 79.0
 offset_bottom = 29.0
 text = "Click me!"
 
+[node name="ExampleChild" type="ExampleChild" parent="."]
+
 [connection signal="custom_signal" from="Example" to="." method="_on_Example_custom_signal"]

+ 18 - 0
test/src/example.cpp

@@ -455,3 +455,21 @@ void Example::_input(const Ref<InputEvent> &event) {
 		emit_custom_signal(String("_input: ") + key_event->get_key_label(), key_event->get_unicode());
 	}
 }
+
+void ExampleBase::_bind_methods() {
+	ClassDB::bind_method(D_METHOD("get_value1"), &ExampleBase::get_value1);
+	ClassDB::bind_method(D_METHOD("get_value2"), &ExampleBase::get_value2);
+}
+
+void ExampleBase::_notification(int p_what) {
+	if (p_what == NOTIFICATION_ENTER_TREE) {
+		value1 = 11;
+		value2 = 22;
+	}
+}
+
+void ExampleChild::_notification(int p_what) {
+	if (p_what == NOTIFICATION_ENTER_TREE) {
+		value2 = 33;
+	}
+}

+ 25 - 0
test/src/example.h

@@ -186,4 +186,29 @@ protected:
 	static void _bind_methods() {}
 };
 
+class ExampleBase : public Node {
+	GDCLASS(ExampleBase, Node);
+
+protected:
+	int value1 = 0;
+	int value2 = 0;
+
+	static void _bind_methods();
+
+	void _notification(int p_what);
+
+public:
+	int get_value1() { return value1; }
+	int get_value2() { return value2; }
+};
+
+class ExampleChild : public ExampleBase {
+	GDCLASS(ExampleChild, ExampleBase);
+
+protected:
+	static void _bind_methods() {}
+
+	void _notification(int p_what);
+};
+
 #endif // EXAMPLE_CLASS_H

+ 2 - 0
test/src/register_types.cpp

@@ -26,6 +26,8 @@ void initialize_example_module(ModuleInitializationLevel p_level) {
 	ClassDB::register_class<Example>();
 	ClassDB::register_class<ExampleVirtual>(true);
 	ClassDB::register_abstract_class<ExampleAbstract>();
+	ClassDB::register_class<ExampleBase>();
+	ClassDB::register_class<ExampleChild>();
 }
 
 void uninitialize_example_module(ModuleInitializationLevel p_level) {