From 318343d25ee8322ea6a0f8668a68d99f8484d6a1 Mon Sep 17 00:00:00 2001 From: Chris Cranford Date: Sat, 14 Sep 2024 11:30:05 -0400 Subject: [PATCH] GH-807 Support named lookup of signals, used by `await` keyword --- src/script/instances/script_instance.cpp | 30 ++++++++++++++++-------- src/script/vm/script_vm.cpp | 16 +++++++++++++ src/script/vm/script_vm.h | 15 ++++++++++++ 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/script/instances/script_instance.cpp b/src/script/instances/script_instance.cpp index 84ff8d6e..e2878b63 100644 --- a/src/script/instances/script_instance.cpp +++ b/src/script/instances/script_instance.cpp @@ -122,23 +122,33 @@ bool OScriptInstance::set(const StringName& p_name, const Variant& p_value, Prop bool OScriptInstance::get(const StringName& p_name, Variant& p_value, PropertyError* r_err) { + // First check if we have a member variable const String variable_name = _get_variable_name_from_path(p_name); - - OScriptVirtualMachine::Variable* variable = _vm.get_variable(variable_name); - if (!variable || !variable->exported) + if (_vm.has_variable(variable_name)) { + OScriptVirtualMachine::Variable* variable = _vm.get_variable(variable_name); + if (!variable || !variable->exported) + { + if (r_err) + *r_err = PROP_NOT_FOUND; + return false; + } + if (r_err) - *r_err = PROP_NOT_FOUND; + *r_err = PROP_OK; - return false; + p_value = variable->value; + return true; } - if (r_err) - *r_err = PROP_OK; - - p_value = variable->value; + // Next check signals - for named access, i.e. "await obj.signal" + if (_vm.has_signal(p_name)) + { + p_value = _vm.get_signal(p_name); + return true; + } - return true; + return false; } GDExtensionPropertyInfo* OScriptInstance::get_property_list(uint32_t* r_count) diff --git a/src/script/vm/script_vm.cpp b/src/script/vm/script_vm.cpp index 58b53c39..dbf45181 100644 --- a/src/script/vm/script_vm.cpp +++ b/src/script/vm/script_vm.cpp @@ -948,6 +948,11 @@ bool OScriptVirtualMachine::register_variable(const Ref& p_vari return true; } +bool OScriptVirtualMachine::has_variable(const StringName& p_name) const +{ + return _variables.has(p_name); +} + OScriptVirtualMachine::Variable* OScriptVirtualMachine::get_variable(const StringName& p_name) const { const HashMap::ConstIterator E = _variables.find(p_name); @@ -976,6 +981,17 @@ bool OScriptVirtualMachine::set_variable(const StringName& p_name, const Variant return true; } +bool OScriptVirtualMachine::has_signal(const StringName& p_name) const +{ + return _script->has_script_signal(p_name); +} + +Variant OScriptVirtualMachine::get_signal(const StringName& p_name) +{ + ERR_FAIL_COND_V_MSG(!_script->has_script_signal(p_name), Variant(), "No signal with name '" + p_name + "' found."); + return Signal(get_owner(), p_name); +} + bool OScriptVirtualMachine::register_function(const Ref& p_function) { ERR_FAIL_COND_V_MSG(!p_function.is_valid(), false, "Cannot register function that is invalid."); diff --git a/src/script/vm/script_vm.h b/src/script/vm/script_vm.h index 204343f4..85c5d8c4 100644 --- a/src/script/vm/script_vm.h +++ b/src/script/vm/script_vm.h @@ -207,6 +207,11 @@ class OScriptVirtualMachine /// @return true if the variable was registered successfully, false otherwise bool register_variable(const Ref& p_variable); + /// Check whether the script has a variable + /// @param p_name the variable name + /// @return true if the variable exists, false otherwise + bool has_variable(const StringName& p_name) const; + /// Gets the variable by name /// @param p_name the variable name /// @return the variable if found, otherwise returns null @@ -224,6 +229,16 @@ class OScriptVirtualMachine /// @return true if the value was set, false otherwise bool set_variable(const StringName& p_name, const Variant& p_value); + /// Check whether the script instance has such a signal + /// @param p_name the signal name + /// @return true if the signal exists, false otherwise + bool has_signal(const StringName& p_name) const; + + /// Get the signal instance for the given name. + /// @param p_name the signal name + /// @return the signal instance, should not be called without verifying signal exists + Variant get_signal(const StringName& p_name); + /// Register a function /// @param p_function the function to be registered /// @return true if the function was registered successfully, false othrewise