Fix _notification with parent and child classes

(cherry picked from commit 23c010900c)
pull/1410/head
David Snopek 2024-02-02 10:07:45 -06:00
parent cae4bf58ac
commit 7ddd278dea
6 changed files with 62 additions and 2 deletions

View File

@ -218,12 +218,17 @@ public:
\ \
static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed) { \ static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed) { \
if (p_instance && m_class::_get_notification()) { \ 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()) { \ if (m_class::_get_notification() != m_inherits::_get_notification()) { \
m_class *cls = reinterpret_cast<m_class *>(p_instance); \ 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); \
} \ } \
} \
} \ } \
\ \
static GDExtensionBool set_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value) { \ static GDExtensionBool set_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value) { \

View File

@ -241,6 +241,14 @@ func _ready():
assert_equal(new_example_ref.was_post_initialized(), true) assert_equal(new_example_ref.was_post_initialized(), true)
assert_equal(example.test_post_initialize(), 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)
example_child.notification(NOTIFICATION_ENTER_TREE, true)
assert_equal(example_child.get_value1(), 11)
assert_equal(example_child.get_value2(), 22)
exit_with_status() exit_with_status()
func _on_Example_custom_signal(signal_name, value): func _on_Example_custom_signal(signal_name, value):

View File

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

View File

@ -626,3 +626,21 @@ void Example::_input(const Ref<InputEvent> &event) {
emit_custom_signal(String("_input: ") + key_event->get_key_label(), key_event->get_unicode()); 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;
}
}

View File

@ -216,4 +216,29 @@ protected:
virtual int test_function() override { return 25; } 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);
};
#endif // EXAMPLE_CLASS_H #endif // EXAMPLE_CLASS_H

View File

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