diff options
Diffstat (limited to 'core/object/object.cpp')
-rw-r--r-- | core/object/object.cpp | 107 |
1 files changed, 71 insertions, 36 deletions
diff --git a/core/object/object.cpp b/core/object/object.cpp index a2330ecd04..d6b7d7a7fe 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -605,7 +605,7 @@ Variant Object::_call_bind(const Variant **p_args, int p_argcount, Callable::Cal return Variant(); } - if (p_args[0]->get_type() != Variant::STRING_NAME && p_args[0]->get_type() != Variant::STRING) { + if (!p_args[0]->is_string()) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING_NAME; @@ -624,7 +624,7 @@ Variant Object::_call_deferred_bind(const Variant **p_args, int p_argcount, Call return Variant(); } - if (p_args[0]->get_type() != Variant::STRING_NAME && p_args[0]->get_type() != Variant::STRING) { + if (!p_args[0]->is_string()) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING_NAME; @@ -720,7 +720,7 @@ Variant Object::getvar(const Variant &p_key, bool *r_valid) const { *r_valid = false; } - if (p_key.get_type() == Variant::STRING_NAME || p_key.get_type() == Variant::STRING) { + if (p_key.is_string()) { return get(p_key, r_valid); } return Variant(); @@ -730,7 +730,7 @@ void Object::setvar(const Variant &p_key, const Variant &p_value, bool *r_valid) if (r_valid) { *r_valid = false; } - if (p_key.get_type() == Variant::STRING_NAME || p_key.get_type() == Variant::STRING) { + if (p_key.is_string()) { return set(p_key, p_value, r_valid); } } @@ -746,7 +746,7 @@ Variant Object::callv(const StringName &p_method, const Array &p_args) { } Callable::CallError ce; - Variant ret = callp(p_method, argptrs, p_args.size(), ce); + const Variant ret = callp(p_method, argptrs, p_args.size(), ce); if (ce.error != Callable::CallError::CALL_OK) { ERR_FAIL_V_MSG(Variant(), "Error calling method from 'callv': " + Variant::get_call_error_text(this, p_method, argptrs, p_args.size(), ce) + "."); } @@ -787,7 +787,7 @@ Variant Object::callp(const StringName &p_method, const Variant **p_args, int p_ if (script_instance) { ret = script_instance->callp(p_method, p_args, p_argcount, r_error); - //force jumptable + // Force jump table. switch (r_error.error) { case Callable::CallError::CALL_OK: return ret; @@ -1023,6 +1023,14 @@ void Object::remove_meta(const StringName &p_name) { set_meta(p_name, Variant()); } +void Object::merge_meta_from(const Object *p_src) { + List<StringName> meta_keys; + p_src->get_meta_list(&meta_keys); + for (const StringName &key : meta_keys) { + set_meta(key, p_src->get_meta(key)); + } +} + TypedArray<Dictionary> Object::_get_property_list_bind() const { List<PropertyInfo> lpi; get_property_list(&lpi); @@ -1096,7 +1104,7 @@ Error Object::_emit_signal(const Variant **p_args, int p_argcount, Callable::Cal ERR_FAIL_V(Error::ERR_INVALID_PARAMETER); } - if (unlikely(p_args[0]->get_type() != Variant::STRING_NAME && p_args[0]->get_type() != Variant::STRING)) { + if (unlikely(!p_args[0]->is_string())) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING_NAME; @@ -1716,33 +1724,65 @@ void Object::_bind_methods() { #define BIND_OBJ_CORE_METHOD(m_method) \ ::ClassDB::add_virtual_method(get_class_static(), m_method, true, Vector<String>(), true); - MethodInfo notification_mi("_notification", PropertyInfo(Variant::INT, "what")); - notification_mi.arguments_metadata.push_back(GodotTypeInfo::Metadata::METADATA_INT_IS_INT32); - BIND_OBJ_CORE_METHOD(notification_mi); - BIND_OBJ_CORE_METHOD(MethodInfo(Variant::BOOL, "_set", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value"))); + BIND_OBJ_CORE_METHOD(MethodInfo("_init")); + + BIND_OBJ_CORE_METHOD(MethodInfo(Variant::STRING, "_to_string")); + + { + MethodInfo mi("_notification"); + mi.arguments.push_back(PropertyInfo(Variant::INT, "what")); + mi.arguments_metadata.push_back(GodotTypeInfo::Metadata::METADATA_INT_IS_INT32); + BIND_OBJ_CORE_METHOD(mi); + } + + { + MethodInfo mi("_set"); + mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "property")); + mi.arguments.push_back(PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT)); + mi.return_val.type = Variant::BOOL; + BIND_OBJ_CORE_METHOD(mi); + } + #ifdef TOOLS_ENABLED - MethodInfo miget("_get", PropertyInfo(Variant::STRING_NAME, "property")); - miget.return_val.name = "Variant"; - miget.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; - BIND_OBJ_CORE_METHOD(miget); + { + MethodInfo mi("_get"); + mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "property")); + mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + BIND_OBJ_CORE_METHOD(mi); + } - MethodInfo plget("_get_property_list"); - plget.return_val.type = Variant::ARRAY; - plget.return_val.hint = PROPERTY_HINT_ARRAY_TYPE; - plget.return_val.hint_string = "Dictionary"; - BIND_OBJ_CORE_METHOD(plget); + { + MethodInfo mi("_get_property_list"); + mi.return_val.type = Variant::ARRAY; + mi.return_val.hint = PROPERTY_HINT_ARRAY_TYPE; + mi.return_val.hint_string = "Dictionary"; + BIND_OBJ_CORE_METHOD(mi); + } BIND_OBJ_CORE_METHOD(MethodInfo(Variant::NIL, "_validate_property", PropertyInfo(Variant::DICTIONARY, "property"))); BIND_OBJ_CORE_METHOD(MethodInfo(Variant::BOOL, "_property_can_revert", PropertyInfo(Variant::STRING_NAME, "property"))); - MethodInfo mipgr("_property_get_revert", PropertyInfo(Variant::STRING_NAME, "property")); - mipgr.return_val.name = "Variant"; - mipgr.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; - BIND_OBJ_CORE_METHOD(mipgr); + { + MethodInfo mi("_property_get_revert"); + mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "property")); + mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + BIND_OBJ_CORE_METHOD(mi); + } + + // These are actually `Variant` methods, but that doesn't matter since scripts can't inherit built-in types. + + BIND_OBJ_CORE_METHOD(MethodInfo(Variant::BOOL, "_iter_init", PropertyInfo(Variant::ARRAY, "iter"))); + + BIND_OBJ_CORE_METHOD(MethodInfo(Variant::BOOL, "_iter_next", PropertyInfo(Variant::ARRAY, "iter"))); + + { + MethodInfo mi("_iter_get"); + mi.arguments.push_back(PropertyInfo(Variant::NIL, "iter", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT)); + mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + BIND_OBJ_CORE_METHOD(mi); + } #endif - BIND_OBJ_CORE_METHOD(MethodInfo("_init")); - BIND_OBJ_CORE_METHOD(MethodInfo(Variant::STRING, "_to_string")); BIND_CONSTANT(NOTIFICATION_POSTINITIALIZE); BIND_CONSTANT(NOTIFICATION_PREDELETE); @@ -1904,7 +1944,7 @@ void Object::set_instance_binding(void *p_token, void *p_binding, const GDExtens void *Object::get_instance_binding(void *p_token, const GDExtensionInstanceBindingCallbacks *p_callbacks) { void *binding = nullptr; - _instance_binding_mutex.lock(); + MutexLock instance_binding_lock(_instance_binding_mutex); for (uint32_t i = 0; i < _instance_binding_count; i++) { if (_instance_bindings[i].token == p_token) { binding = _instance_bindings[i].binding; @@ -1935,14 +1975,12 @@ void *Object::get_instance_binding(void *p_token, const GDExtensionInstanceBindi _instance_binding_count++; } - _instance_binding_mutex.unlock(); - return binding; } bool Object::has_instance_binding(void *p_token) { bool found = false; - _instance_binding_mutex.lock(); + MutexLock instance_binding_lock(_instance_binding_mutex); for (uint32_t i = 0; i < _instance_binding_count; i++) { if (_instance_bindings[i].token == p_token) { found = true; @@ -1950,14 +1988,12 @@ bool Object::has_instance_binding(void *p_token) { } } - _instance_binding_mutex.unlock(); - return found; } void Object::free_instance_binding(void *p_token) { bool found = false; - _instance_binding_mutex.lock(); + MutexLock instance_binding_lock(_instance_binding_mutex); for (uint32_t i = 0; i < _instance_binding_count; i++) { if (!found && _instance_bindings[i].token == p_token) { if (_instance_bindings[i].free_callback) { @@ -1976,7 +2012,6 @@ void Object::free_instance_binding(void *p_token) { if (found) { _instance_binding_count--; } - _instance_binding_mutex.unlock(); } #ifdef TOOLS_ENABLED @@ -2294,7 +2329,7 @@ void ObjectDB::cleanup() { // Ensure calling the native classes because if a leaked instance has a script // that overrides any of those methods, it'd not be OK to call them at this point, // now the scripting languages have already been terminated. - MethodBind *node_get_name = ClassDB::get_method("Node", "get_name"); + MethodBind *node_get_path = ClassDB::get_method("Node", "get_path"); MethodBind *resource_get_path = ClassDB::get_method("Resource", "get_path"); Callable::CallError call_error; @@ -2304,7 +2339,7 @@ void ObjectDB::cleanup() { String extra_info; if (obj->is_class("Node")) { - extra_info = " - Node name: " + String(node_get_name->call(obj, nullptr, 0, call_error)); + extra_info = " - Node path: " + String(node_get_path->call(obj, nullptr, 0, call_error)); } if (obj->is_class("Resource")) { extra_info = " - Resource path: " + String(resource_get_path->call(obj, nullptr, 0, call_error)); |