瀏覽代碼

Fix _notification with parent and child classes

David Snopek 1 年之前
父節點
當前提交
23c010900c
共有 6 個文件被更改,包括 62 次插入2 次删除
  1. 7 2
      include/godot_cpp/classes/wrapped.hpp
  2. 8 0
      test/project/main.gd
  3. 2 0
      test/project/main.tscn
  4. 18 0
      test/src/example.cpp
  5. 25 0
      test/src/example.h
  6. 2 0
      test/src/register_types.cpp

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

@@ -239,11 +239,16 @@ public:
                                                                                                                                                                                        \
 	static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed) {                                                                \
 		if (p_instance && m_class::_get_notification()) {                                                                                                                              \
+			if (!p_reversed) {                                                                                                                                                         \
+				m_inherits::notification_bind(p_instance, p_what, p_reversed);                                                                                                         \
+			}                                                                                                                                                                          \
 			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);                                                                                                                                            \
+			}                                                                                                                                                                          \
+			if (p_reversed) {                                                                                                                                                          \
+				m_inherits::notification_bind(p_instance, p_what, p_reversed);                                                                                                         \
 			}                                                                                                                                                                          \
-			m_inherits::notification_bind(p_instance, p_what, p_reversed);                                                                                                             \
 		}                                                                                                                                                                              \
 	}                                                                                                                                                                                  \
                                                                                                                                                                                        \

+ 8 - 0
test/project/main.gd

@@ -245,6 +245,14 @@ func _ready():
 	assert_equal(example.test_virtual_implemented_in_script("Virtual", 939), "Implemented")
 	assert_equal(custom_signal_emitted, ["Virtual", 939])
 
+	# 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)
+	example_child.notification(NOTIFICATION_ENTER_TREE, true)
+	assert_equal(example_child.get_value1(), 11)
+	assert_equal(example_child.get_value2(), 22)
+
 	exit_with_status()
 
 func _on_Example_custom_signal(signal_name, value):

+ 2 - 0
test/project/main.tscn

@@ -24,4 +24,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

@@ -630,6 +630,24 @@ void Example::_input(const Ref<InputEvent> &event) {
 	}
 }
 
+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;
+	}
+}
+
 String Example::test_virtual_implemented_in_script(const String &p_name, int p_value) {
 	String ret;
 	if (GDVIRTUAL_CALL(_do_something_virtual, p_name, p_value, ret)) {

+ 25 - 0
test/src/example.h

@@ -220,6 +220,31 @@ protected:
 	virtual int test_function() override { return 25; }
 };
 
+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);
+};
+
 class ExampleRuntime : public Node {
 	GDCLASS(ExampleRuntime, Node);
 

+ 2 - 0
test/src/register_types.cpp

@@ -27,6 +27,8 @@ void initialize_example_module(ModuleInitializationLevel p_level) {
 	ClassDB::register_class<ExampleVirtual>(true);
 	ClassDB::register_abstract_class<ExampleAbstractBase>();
 	ClassDB::register_class<ExampleConcrete>();
+	ClassDB::register_class<ExampleBase>();
+	ClassDB::register_class<ExampleChild>();
 	ClassDB::register_runtime_class<ExampleRuntime>();
 }