Merge pull request #1381 from dsnopek/notification-hierarchy

Fix `_notification()` with parent and child classes
pull/1401/merge
David Snopek 2024-03-05 11:50:13 -06:00 committed by GitHub
commit cc1217a43c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 62 additions and 2 deletions

View File

@ -239,11 +239,16 @@ 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); \
} \ } \
} \ } \
\ \

View File

@ -245,6 +245,14 @@ func _ready():
assert_equal(example.test_virtual_implemented_in_script("Virtual", 939), "Implemented") assert_equal(example.test_virtual_implemented_in_script("Virtual", 939), "Implemented")
assert_equal(custom_signal_emitted, ["Virtual", 939]) 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() exit_with_status()
func _on_Example_custom_signal(signal_name, value): func _on_Example_custom_signal(signal_name, value):

View File

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

@ -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 Example::test_virtual_implemented_in_script(const String &p_name, int p_value) {
String ret; String ret;
if (GDVIRTUAL_CALL(_do_something_virtual, p_name, p_value, ret)) { if (GDVIRTUAL_CALL(_do_something_virtual, p_name, p_value, ret)) {

View File

@ -220,6 +220,31 @@ 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);
};
class ExampleRuntime : public Node { class ExampleRuntime : public Node {
GDCLASS(ExampleRuntime, Node); GDCLASS(ExampleRuntime, Node);

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>();
ClassDB::register_runtime_class<ExampleRuntime>(); ClassDB::register_runtime_class<ExampleRuntime>();
} }