diff options
Diffstat (limited to 'core/object/object.cpp')
-rw-r--r-- | core/object/object.cpp | 395 |
1 files changed, 185 insertions, 210 deletions
diff --git a/core/object/object.cpp b/core/object/object.cpp index 0912ea55f0..cfac36127c 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -38,6 +38,7 @@ #include "core/os/os.h" #include "core/string/print_string.h" #include "core/string/translation.h" +#include "core/variant/typed_array.h" #ifdef DEBUG_ENABLED @@ -102,8 +103,8 @@ PropertyInfo PropertyInfo::from_dict(const Dictionary &p_dict) { return pi; } -Array convert_property_list(const List<PropertyInfo> *p_list) { - Array va; +TypedArray<Dictionary> convert_property_list(const List<PropertyInfo> *p_list) { + TypedArray<Dictionary> va; for (const List<PropertyInfo>::Element *E = p_list->front(); E; E = E->next()) { va.push_back(Dictionary(E->get())); } @@ -161,167 +162,11 @@ MethodInfo MethodInfo::from_dict(const Dictionary &p_dict) { return mi; } -MethodInfo::MethodInfo() : - flags(METHOD_FLAG_NORMAL) {} - -MethodInfo::MethodInfo(const String &p_name) : - name(p_name), - flags(METHOD_FLAG_NORMAL) { -} - -MethodInfo::MethodInfo(const String &p_name, const PropertyInfo &p_param1) : - name(p_name), - flags(METHOD_FLAG_NORMAL) { - arguments.push_back(p_param1); -} - -MethodInfo::MethodInfo(const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2) : - name(p_name), - flags(METHOD_FLAG_NORMAL) { - arguments.push_back(p_param1); - arguments.push_back(p_param2); -} - -MethodInfo::MethodInfo(const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3) : - name(p_name), - flags(METHOD_FLAG_NORMAL) { - arguments.push_back(p_param1); - arguments.push_back(p_param2); - arguments.push_back(p_param3); -} - -MethodInfo::MethodInfo(const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4) : - name(p_name), - flags(METHOD_FLAG_NORMAL) { - arguments.push_back(p_param1); - arguments.push_back(p_param2); - arguments.push_back(p_param3); - arguments.push_back(p_param4); -} - -MethodInfo::MethodInfo(const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4, const PropertyInfo &p_param5) : - name(p_name), - flags(METHOD_FLAG_NORMAL) { - arguments.push_back(p_param1); - arguments.push_back(p_param2); - arguments.push_back(p_param3); - arguments.push_back(p_param4); - arguments.push_back(p_param5); -} - -MethodInfo::MethodInfo(Variant::Type ret) : - flags(METHOD_FLAG_NORMAL) { - return_val.type = ret; -} - -MethodInfo::MethodInfo(Variant::Type ret, const String &p_name) : - name(p_name), - flags(METHOD_FLAG_NORMAL) { - return_val.type = ret; -} - -MethodInfo::MethodInfo(Variant::Type ret, const String &p_name, const PropertyInfo &p_param1) : - name(p_name), - flags(METHOD_FLAG_NORMAL) { - return_val.type = ret; - arguments.push_back(p_param1); -} - -MethodInfo::MethodInfo(Variant::Type ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2) : - name(p_name), - flags(METHOD_FLAG_NORMAL) { - return_val.type = ret; - arguments.push_back(p_param1); - arguments.push_back(p_param2); -} - -MethodInfo::MethodInfo(Variant::Type ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3) : - name(p_name), - flags(METHOD_FLAG_NORMAL) { - return_val.type = ret; - arguments.push_back(p_param1); - arguments.push_back(p_param2); - arguments.push_back(p_param3); -} - -MethodInfo::MethodInfo(Variant::Type ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4) : - name(p_name), - flags(METHOD_FLAG_NORMAL) { - return_val.type = ret; - arguments.push_back(p_param1); - arguments.push_back(p_param2); - arguments.push_back(p_param3); - arguments.push_back(p_param4); -} - -MethodInfo::MethodInfo(Variant::Type ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4, const PropertyInfo &p_param5) : - name(p_name), - flags(METHOD_FLAG_NORMAL) { - return_val.type = ret; - arguments.push_back(p_param1); - arguments.push_back(p_param2); - arguments.push_back(p_param3); - arguments.push_back(p_param4); - arguments.push_back(p_param5); -} - -MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name) : - name(p_name), - return_val(p_ret), - flags(METHOD_FLAG_NORMAL) { -} - -MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1) : - name(p_name), - return_val(p_ret), - flags(METHOD_FLAG_NORMAL) { - arguments.push_back(p_param1); -} - -MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2) : - name(p_name), - return_val(p_ret), - flags(METHOD_FLAG_NORMAL) { - arguments.push_back(p_param1); - arguments.push_back(p_param2); -} - -MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3) : - name(p_name), - return_val(p_ret), - flags(METHOD_FLAG_NORMAL) { - arguments.push_back(p_param1); - arguments.push_back(p_param2); - arguments.push_back(p_param3); -} - -MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4) : - name(p_name), - return_val(p_ret), - flags(METHOD_FLAG_NORMAL) { - arguments.push_back(p_param1); - arguments.push_back(p_param2); - arguments.push_back(p_param3); - arguments.push_back(p_param4); -} - -MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4, const PropertyInfo &p_param5) : - name(p_name), - return_val(p_ret), - flags(METHOD_FLAG_NORMAL) { - arguments.push_back(p_param1); - arguments.push_back(p_param2); - arguments.push_back(p_param3); - arguments.push_back(p_param4); - arguments.push_back(p_param5); -} - Object::Connection::operator Variant() const { Dictionary d; d["signal"] = signal; d["callable"] = callable; d["flags"] = flags; - d["binds"] = binds; return d; } @@ -344,9 +189,6 @@ Object::Connection::Connection(const Variant &p_variant) { if (d.has("flags")) { flags = d["flags"]; } - if (d.has("binds")) { - binds = d["binds"]; - } } bool Object::_predelete() { @@ -391,7 +233,7 @@ void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wignored-qualifiers" #endif - if (_extension->set(_extension_instance, (const GDNativeStringNamePtr)&p_name, (const GDNativeVariantPtr)&p_value)) { + if (_extension->set(_extension_instance, (const GDExtensionStringNamePtr)&p_name, (const GDExtensionVariantPtr)&p_value)) { if (r_valid) { *r_valid = true; } @@ -479,7 +321,7 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const { #pragma GCC diagnostic ignored "-Wignored-qualifiers" #endif - if (_extension->get(_extension_instance, (const GDNativeStringNamePtr)&p_name, (GDNativeVariantPtr)&ret)) { + if (_extension->get(_extension_instance, (const GDExtensionStringNamePtr)&p_name, (GDExtensionVariantPtr)&ret)) { if (r_valid) { *r_valid = true; } @@ -631,12 +473,11 @@ Variant Object::get_indexed(const Vector<StringName> &p_names, bool *r_valid) co void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) const { if (script_instance && p_reversed) { - p_list->push_back(PropertyInfo(Variant::NIL, "Script Variables", PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY)); script_instance->get_property_list(p_list); } if (_extension) { - const ObjectNativeExtension *current_extension = _extension; + const ObjectGDExtension *current_extension = _extension; while (current_extension) { p_list->push_back(PropertyInfo(Variant::NIL, current_extension->class_name, PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY)); ClassDB::get_property_list(current_extension->class_name, p_list, true, this); @@ -646,9 +487,9 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons if (_extension && _extension->get_property_list) { uint32_t pcount; - const GDNativePropertyInfo *pinfo = _extension->get_property_list(_extension_instance, &pcount); + const GDExtensionPropertyInfo *pinfo = _extension->get_property_list(_extension_instance, &pcount); for (uint32_t i = 0; i < pcount; i++) { - p_list->push_back(PropertyInfo(Variant::Type(pinfo[i].type), pinfo[i].class_name, PropertyHint(pinfo[i].hint), pinfo[i].hint_string, pinfo[i].usage, pinfo[i].class_name)); + p_list->push_back(PropertyInfo(pinfo[i])); } if (_extension->free_property_list) { _extension->free_property_list(_extension_instance, pinfo); @@ -662,7 +503,6 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons } if (script_instance && !p_reversed) { - p_list->push_back(PropertyInfo(Variant::NIL, "Script Variables", PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY)); script_instance->get_property_list(p_list); } @@ -676,7 +516,61 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons } } -void Object::_validate_property(PropertyInfo &property) const { +void Object::validate_property(PropertyInfo &p_property) const { + _validate_propertyv(p_property); +} + +bool Object::property_can_revert(const StringName &p_name) const { + if (script_instance) { + if (script_instance->property_can_revert(p_name)) { + return true; + } + } + +// C style pointer casts should never trigger a compiler warning because the risk is assumed by the user, so GCC should keep quiet about it. +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wignored-qualifiers" +#endif + if (_extension && _extension->property_can_revert) { + if (_extension->property_can_revert(_extension_instance, (const GDExtensionStringNamePtr)&p_name)) { + return true; + } + } +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + + return _property_can_revertv(p_name); +} + +Variant Object::property_get_revert(const StringName &p_name) const { + Variant ret; + + if (script_instance) { + if (script_instance->property_get_revert(p_name, ret)) { + return ret; + } + } + +// C style pointer casts should never trigger a compiler warning because the risk is assumed by the user, so GCC should keep quiet about it. +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wignored-qualifiers" +#endif + if (_extension && _extension->property_get_revert) { + if (_extension->property_get_revert(_extension_instance, (const GDExtensionStringNamePtr)&p_name, (GDExtensionVariantPtr)&ret)) { + return ret; + } + } +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + + if (_property_get_revertv(p_name, ret)) { + return ret; + } + return Variant(); } void Object::get_method_list(List<MethodInfo> *p_list) const { @@ -824,6 +718,7 @@ Variant Object::callp(const StringName &p_method, const Variant **p_args, int p_ case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: + case Callable::CallError::CALL_ERROR_METHOD_NOT_CONST: return ret; case Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL: { } @@ -843,6 +738,54 @@ Variant Object::callp(const StringName &p_method, const Variant **p_args, int p_ return ret; } +Variant Object::call_const(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { + r_error.error = Callable::CallError::CALL_OK; + + if (p_method == CoreStringNames::get_singleton()->_free) { + // Free is not const, so fail. + r_error.error = Callable::CallError::CALL_ERROR_METHOD_NOT_CONST; + return Variant(); + } + + Variant ret; + OBJ_DEBUG_LOCK + + if (script_instance) { + ret = script_instance->call_const(p_method, p_args, p_argcount, r_error); + //force jumptable + switch (r_error.error) { + case Callable::CallError::CALL_OK: + return ret; + case Callable::CallError::CALL_ERROR_INVALID_METHOD: + break; + case Callable::CallError::CALL_ERROR_METHOD_NOT_CONST: + break; + case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: + case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: + case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: + return ret; + case Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL: { + } + } + } + + //extension does not need this, because all methods are registered in MethodBind + + MethodBind *method = ClassDB::get_method(get_class_name(), p_method); + + if (method) { + if (!method->is_const()) { + r_error.error = Callable::CallError::CALL_ERROR_METHOD_NOT_CONST; + return ret; + } + ret = method->call(this, p_args, p_argcount, r_error); + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; + } + + return ret; +} + void Object::notification(int p_notification, bool p_reversed) { _notificationv(p_notification, p_reversed); @@ -865,10 +808,11 @@ String Object::to_string() { } if (_extension && _extension->to_string) { String ret; - _extension->to_string(_extension_instance, &ret); + GDExtensionBool is_valid; + _extension->to_string(_extension_instance, &is_valid, &ret); return ret; } - return "[" + get_class() + ":" + itos(get_instance_id()) + "]"; + return "<" + get_class() + "#" + itos(get_instance_id()) + ">"; } void Object::set_script_and_instance(const Variant &p_script, ScriptInstance *p_instance) { @@ -970,16 +914,16 @@ void Object::remove_meta(const StringName &p_name) { set_meta(p_name, Variant()); } -Array Object::_get_property_list_bind() const { +TypedArray<Dictionary> Object::_get_property_list_bind() const { List<PropertyInfo> lpi; get_property_list(&lpi); return convert_property_list(&lpi); } -Array Object::_get_method_list_bind() const { +TypedArray<Dictionary> Object::_get_method_list_bind() const { List<MethodInfo> ml; get_method_list(&ml); - Array ret; + TypedArray<Dictionary> ret; for (List<MethodInfo>::Element *E = ml.front(); E; E = E->next()) { Dictionary d = E->get(); @@ -1079,8 +1023,6 @@ Error Object::emit_signalp(const StringName &p_name, const Variant **p_args, int OBJ_DEBUG_LOCK - Vector<const Variant *> bind_mem; - Error err = OK; for (int i = 0; i < ssize; i++) { @@ -1095,28 +1037,13 @@ Error Object::emit_signalp(const StringName &p_name, const Variant **p_args, int const Variant **args = p_args; int argc = p_argcount; - if (c.binds.size()) { - //handle binds - bind_mem.resize(p_argcount + c.binds.size()); - - for (int j = 0; j < p_argcount; j++) { - bind_mem.write[j] = p_args[j]; - } - for (int j = 0; j < c.binds.size(); j++) { - bind_mem.write[p_argcount + j] = &c.binds[j]; - } - - args = (const Variant **)bind_mem.ptr(); - argc = bind_mem.size(); - } - if (c.flags & CONNECT_DEFERRED) { MessageQueue::get_singleton()->push_callablep(c.callable, args, argc, true); } else { Callable::CallError ce; _emitting = true; Variant ret; - c.callable.call(args, argc, ret, ce); + c.callable.callp(args, argc, ret, ce); _emitting = false; if (ce.error != Callable::CallError::CALL_OK) { @@ -1134,7 +1061,7 @@ Error Object::emit_signalp(const StringName &p_name, const Variant **p_args, int } } - bool disconnect = c.flags & CONNECT_ONESHOT; + bool disconnect = c.flags & CONNECT_ONE_SHOT; #ifdef TOOLS_ENABLED if (disconnect && (c.flags & CONNECT_PERSIST) && Engine::get_singleton()->is_editor_hint()) { //this signal was connected from the editor, and is being edited. just don't disconnect for now @@ -1184,11 +1111,11 @@ void Object::_add_user_signal(const String &p_name, const Array &p_args) { add_user_signal(mi); } -Array Object::_get_signal_list() const { +TypedArray<Dictionary> Object::_get_signal_list() const { List<MethodInfo> signal_list; get_signal_list(&signal_list); - Array ret; + TypedArray<Dictionary> ret; for (const MethodInfo &E : signal_list) { ret.push_back(Dictionary(E)); } @@ -1196,11 +1123,11 @@ Array Object::_get_signal_list() const { return ret; } -Array Object::_get_signal_connection_list(const String &p_signal) const { +TypedArray<Dictionary> Object::_get_signal_connection_list(const StringName &p_signal) const { List<Connection> conns; get_all_signal_connections(&conns); - Array ret; + TypedArray<Dictionary> ret; for (const Connection &c : conns) { if (c.signal.get_name() == p_signal) { @@ -1211,8 +1138,8 @@ Array Object::_get_signal_connection_list(const String &p_signal) const { return ret; } -Array Object::_get_incoming_connections() const { - Array ret; +TypedArray<Dictionary> Object::_get_incoming_connections() const { + TypedArray<Dictionary> ret; int connections_amount = connections.size(); for (int idx_conn = 0; idx_conn < connections_amount; idx_conn++) { ret.push_back(connections[idx_conn]); @@ -1302,7 +1229,7 @@ void Object::get_signals_connected_to_this(List<Connection> *p_connections) cons } } -Error Object::connect(const StringName &p_signal, const Callable &p_callable, const Vector<Variant> &p_binds, uint32_t p_flags) { +Error Object::connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags) { ERR_FAIL_COND_V_MSG(p_callable.is_null(), ERR_INVALID_PARAMETER, "Cannot connect to '" + p_signal + "': the provided callable is null."); Object *target_object = p_callable.get_object(); @@ -1350,7 +1277,6 @@ Error Object::connect(const StringName &p_signal, const Callable &p_callable, co conn.callable = target; conn.signal = ::Signal(this, p_signal); conn.flags = p_flags; - conn.binds = p_binds; slot.conn = conn; slot.cE = target_object->connections.push_back(conn); if (p_flags & CONNECT_REFERENCE_COUNTED) { @@ -1422,11 +1348,11 @@ void Object::_disconnect(const StringName &p_signal, const Callable &p_callable, } } -void Object::_set_bind(const String &p_set, const Variant &p_value) { +void Object::_set_bind(const StringName &p_set, const Variant &p_value) { set(p_set, p_value); } -Variant Object::_get_bind(const String &p_name) const { +Variant Object::_get_bind(const StringName &p_name) const { return get(p_name); } @@ -1543,10 +1469,12 @@ void Object::_bind_methods() { ClassDB::bind_method(D_METHOD("is_class", "class"), &Object::is_class); ClassDB::bind_method(D_METHOD("set", "property", "value"), &Object::_set_bind); ClassDB::bind_method(D_METHOD("get", "property"), &Object::_get_bind); - ClassDB::bind_method(D_METHOD("set_indexed", "property", "value"), &Object::_set_indexed_bind); - ClassDB::bind_method(D_METHOD("get_indexed", "property"), &Object::_get_indexed_bind); + ClassDB::bind_method(D_METHOD("set_indexed", "property_path", "value"), &Object::_set_indexed_bind); + ClassDB::bind_method(D_METHOD("get_indexed", "property_path"), &Object::_get_indexed_bind); ClassDB::bind_method(D_METHOD("get_property_list"), &Object::_get_property_list_bind); ClassDB::bind_method(D_METHOD("get_method_list"), &Object::_get_method_list_bind); + ClassDB::bind_method(D_METHOD("property_can_revert", "property"), &Object::property_can_revert); + ClassDB::bind_method(D_METHOD("property_get_revert", "property"), &Object::property_get_revert); ClassDB::bind_method(D_METHOD("notification", "what", "reversed"), &Object::notification, DEFVAL(false)); ClassDB::bind_method(D_METHOD("to_string"), &Object::to_string); ClassDB::bind_method(D_METHOD("get_instance_id"), &Object::get_instance_id); @@ -1598,7 +1526,7 @@ void Object::_bind_methods() { ClassDB::bind_method(D_METHOD("get_signal_connection_list", "signal"), &Object::_get_signal_connection_list); ClassDB::bind_method(D_METHOD("get_incoming_connections"), &Object::_get_incoming_connections); - ClassDB::bind_method(D_METHOD("connect", "signal", "callable", "binds", "flags"), &Object::connect, DEFVAL(Array()), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("connect", "signal", "callable", "flags"), &Object::connect, DEFVAL(0)); ClassDB::bind_method(D_METHOD("disconnect", "signal", "callable"), &Object::disconnect); ClassDB::bind_method(D_METHOD("is_connected", "signal", "callable"), &Object::is_connected); @@ -1630,10 +1558,17 @@ void Object::_bind_methods() { BIND_OBJ_CORE_METHOD(miget); 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); + 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); + #endif BIND_OBJ_CORE_METHOD(MethodInfo("_init")); BIND_OBJ_CORE_METHOD(MethodInfo(Variant::STRING, "_to_string")); @@ -1643,7 +1578,7 @@ void Object::_bind_methods() { BIND_ENUM_CONSTANT(CONNECT_DEFERRED); BIND_ENUM_CONSTANT(CONNECT_PERSIST); - BIND_ENUM_CONSTANT(CONNECT_ONESHOT); + BIND_ENUM_CONSTANT(CONNECT_ONE_SHOT); BIND_ENUM_CONSTANT(CONNECT_REFERENCE_COUNTED); } @@ -1766,7 +1701,7 @@ uint32_t Object::get_edited_version() const { } #endif -void Object::set_instance_binding(void *p_token, void *p_binding, const GDNativeInstanceBindingCallbacks *p_callbacks) { +void Object::set_instance_binding(void *p_token, void *p_binding, const GDExtensionInstanceBindingCallbacks *p_callbacks) { // This is only meant to be used on creation by the binder. ERR_FAIL_COND(_instance_bindings != nullptr); _instance_bindings = (InstanceBinding *)memalloc(sizeof(InstanceBinding)); @@ -1777,7 +1712,7 @@ void Object::set_instance_binding(void *p_token, void *p_binding, const GDNative _instance_binding_count = 1; } -void *Object::get_instance_binding(void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks) { +void *Object::get_instance_binding(void *p_token, const GDExtensionInstanceBindingCallbacks *p_callbacks) { void *binding = nullptr; _instance_binding_mutex.lock(); for (uint32_t i = 0; i < _instance_binding_count; i++) { @@ -1924,6 +1859,46 @@ void ObjectDB::debug_objects(DebugFunc p_func) { } void Object::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { + if (p_idx == 0) { + if (p_function == "connect" || p_function == "is_connected" || p_function == "disconnect" || p_function == "emit_signal" || p_function == "has_signal") { + List<MethodInfo> signals; + get_signal_list(&signals); + for (const MethodInfo &E : signals) { + r_options->push_back(E.name.quote()); + } + } else if (p_function == "call" || p_function == "call_deferred" || p_function == "callv" || p_function == "has_method") { + List<MethodInfo> methods; + get_method_list(&methods); + for (const MethodInfo &E : methods) { + if (E.name.begins_with("_") && !(E.flags & METHOD_FLAG_VIRTUAL)) { + continue; + } + r_options->push_back(E.name.quote()); + } + } else if (p_function == "set" || p_function == "set_deferred" || p_function == "get") { + List<PropertyInfo> properties; + get_property_list(&properties); + for (const PropertyInfo &E : properties) { + if (E.usage & PROPERTY_USAGE_DEFAULT && !(E.usage & PROPERTY_USAGE_INTERNAL)) { + r_options->push_back(E.name.quote()); + } + } + } else if (p_function == "set_meta" || p_function == "get_meta" || p_function == "has_meta" || p_function == "remove_meta") { + for (const KeyValue<StringName, Variant> &K : metadata) { + r_options->push_back(String(K.key).quote()); + } + } + } else if (p_idx == 2) { + if (p_function == "connect") { + // Ideally, the constants should be inferred by the parameter. + // But a parameter's PropertyInfo does not store the enum they come from, so this will do for now. + List<StringName> constants; + ClassDB::get_enum_constants("Object", "ConnectFlags", &constants); + for (const StringName &E : constants) { + r_options->push_back(String(E)); + } + } + } } SpinLock ObjectDB::spin_lock; |