diff options
Diffstat (limited to 'core/extension/gdextension_interface.cpp')
-rw-r--r-- | core/extension/gdextension_interface.cpp | 210 |
1 files changed, 178 insertions, 32 deletions
diff --git a/core/extension/gdextension_interface.cpp b/core/extension/gdextension_interface.cpp index e02e7aa701..9b4aa98357 100644 --- a/core/extension/gdextension_interface.cpp +++ b/core/extension/gdextension_interface.cpp @@ -42,6 +42,8 @@ #include "core/variant/variant.h" #include "core/version.h" +#include <string.h> + class CallableCustomExtension : public CallableCustom { void *userdata; void *token; @@ -57,6 +59,8 @@ class CallableCustomExtension : public CallableCustom { GDExtensionCallableCustomToString to_string_func; + GDExtensionCallableCustomGetArgumentCount get_argument_count_func; + uint32_t _hash; static bool default_compare_equal(const CallableCustom *p_a, const CallableCustom *p_b) { @@ -141,6 +145,21 @@ public: return object; } + int get_argument_count(bool &r_is_valid) const override { + if (get_argument_count_func != nullptr) { + GDExtensionBool is_valid = false; + + GDExtensionInt ret = get_argument_count_func(userdata, &is_valid); + + if (is_valid) { + r_is_valid = true; + return ret; + } + } + r_is_valid = false; + return 0; + } + void *get_userdata(void *p_token) const { return (p_token == token) ? userdata : nullptr; } @@ -155,6 +174,7 @@ public: r_call_error.expected = error.expected; } +#ifndef DISABLE_DEPRECATED CallableCustomExtension(GDExtensionCallableCustomInfo *p_info) { userdata = p_info->callable_userdata; token = p_info->token; @@ -170,6 +190,35 @@ public: to_string_func = p_info->to_string_func; + get_argument_count_func = nullptr; + + // Pre-calculate the hash. + if (p_info->hash_func != nullptr) { + _hash = p_info->hash_func(userdata); + } else { + _hash = hash_murmur3_one_64((uint64_t)call_func); + _hash = hash_murmur3_one_64((uint64_t)userdata, _hash); + } + } +#endif + + CallableCustomExtension(GDExtensionCallableCustomInfo2 *p_info) { + userdata = p_info->callable_userdata; + token = p_info->token; + + object = p_info->object_id; + + call_func = p_info->call_func; + is_valid_func = p_info->is_valid_func; + free_func = p_info->free_func; + + equal_func = p_info->equal_func; + less_than_func = p_info->less_than_func; + + to_string_func = p_info->to_string_func; + + get_argument_count_func = p_info->get_argument_count_func; + // Pre-calculate the hash. if (p_info->hash_func != nullptr) { _hash = p_info->hash_func(userdata); @@ -1192,6 +1241,33 @@ static GDObjectInstanceID gdextension_object_get_instance_id(GDExtensionConstObj return (GDObjectInstanceID)o->get_instance_id(); } +static GDExtensionBool gdextension_object_has_script_method(GDExtensionConstObjectPtr p_object, GDExtensionConstStringNamePtr p_method) { + Object *o = (Object *)p_object; + const StringName method = *reinterpret_cast<const StringName *>(p_method); + + ScriptInstance *script_instance = o->get_script_instance(); + if (script_instance) { + return script_instance->has_method(method); + } + return false; +} + +static void gdextension_object_call_script_method(GDExtensionObjectPtr p_object, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionUninitializedVariantPtr r_return, GDExtensionCallError *r_error) { + Object *o = (Object *)p_object; + const StringName method = *reinterpret_cast<const StringName *>(p_method); + const Variant **args = (const Variant **)p_args; + + Callable::CallError error; + memnew_placement(r_return, Variant); + *(Variant *)r_return = o->callp(method, args, p_argument_count, error); + + if (r_error) { + r_error->error = (GDExtensionCallErrorType)(error.error); + r_error->argument = error.argument; + r_error->expected = error.expected; + } +} + static GDExtensionObjectPtr gdextension_ref_get_object(GDExtensionConstRefPtr p_ref) { const Ref<RefCounted> *ref = (const Ref<RefCounted> *)p_ref; if (ref == nullptr || ref->is_null()) { @@ -1211,43 +1287,86 @@ static void gdextension_ref_set_object(GDExtensionRefPtr p_ref, GDExtensionObjec #ifndef DISABLE_DEPRECATED static GDExtensionScriptInstancePtr gdextension_script_instance_create(const GDExtensionScriptInstanceInfo *p_info, GDExtensionScriptInstanceDataPtr p_instance_data) { - GDExtensionScriptInstanceInfo2 *info_2 = memnew(GDExtensionScriptInstanceInfo2); - info_2->set_func = p_info->set_func; - info_2->get_func = p_info->get_func; - info_2->get_property_list_func = p_info->get_property_list_func; - info_2->free_property_list_func = p_info->free_property_list_func; - info_2->get_class_category_func = nullptr; - info_2->property_can_revert_func = p_info->property_can_revert_func; - info_2->property_get_revert_func = p_info->property_get_revert_func; - info_2->get_owner_func = p_info->get_owner_func; - info_2->get_property_state_func = p_info->get_property_state_func; - info_2->get_method_list_func = p_info->get_method_list_func; - info_2->free_method_list_func = p_info->free_method_list_func; - info_2->get_property_type_func = p_info->get_property_type_func; - info_2->validate_property_func = nullptr; - info_2->has_method_func = p_info->has_method_func; - info_2->call_func = p_info->call_func; - info_2->notification_func = nullptr; - info_2->to_string_func = p_info->to_string_func; - info_2->refcount_incremented_func = p_info->refcount_incremented_func; - info_2->refcount_decremented_func = p_info->refcount_decremented_func; - info_2->get_script_func = p_info->get_script_func; - info_2->is_placeholder_func = p_info->is_placeholder_func; - info_2->set_fallback_func = p_info->set_fallback_func; - info_2->get_fallback_func = p_info->get_fallback_func; - info_2->get_language_func = p_info->get_language_func; - info_2->free_func = p_info->free_func; + GDExtensionScriptInstanceInfo3 *info_3 = memnew(GDExtensionScriptInstanceInfo3); + info_3->set_func = p_info->set_func; + info_3->get_func = p_info->get_func; + info_3->get_property_list_func = p_info->get_property_list_func; + info_3->free_property_list_func = nullptr; + info_3->get_class_category_func = nullptr; + info_3->property_can_revert_func = p_info->property_can_revert_func; + info_3->property_get_revert_func = p_info->property_get_revert_func; + info_3->get_owner_func = p_info->get_owner_func; + info_3->get_property_state_func = p_info->get_property_state_func; + info_3->get_method_list_func = p_info->get_method_list_func; + info_3->free_method_list_func = nullptr; + info_3->get_property_type_func = p_info->get_property_type_func; + info_3->validate_property_func = nullptr; + info_3->has_method_func = p_info->has_method_func; + info_3->get_method_argument_count_func = nullptr; + info_3->call_func = p_info->call_func; + info_3->notification_func = nullptr; + info_3->to_string_func = p_info->to_string_func; + info_3->refcount_incremented_func = p_info->refcount_incremented_func; + info_3->refcount_decremented_func = p_info->refcount_decremented_func; + info_3->get_script_func = p_info->get_script_func; + info_3->is_placeholder_func = p_info->is_placeholder_func; + info_3->set_fallback_func = p_info->set_fallback_func; + info_3->get_fallback_func = p_info->get_fallback_func; + info_3->get_language_func = p_info->get_language_func; + info_3->free_func = p_info->free_func; ScriptInstanceExtension *script_instance_extension = memnew(ScriptInstanceExtension); script_instance_extension->instance = p_instance_data; - script_instance_extension->native_info = info_2; + script_instance_extension->native_info = info_3; script_instance_extension->free_native_info = true; - script_instance_extension->deprecated_native_info.notification_func = p_info->notification_func; + script_instance_extension->deprecated_native_info = memnew(ScriptInstanceExtension::DeprecatedNativeInfo); + script_instance_extension->deprecated_native_info->notification_func = p_info->notification_func; + script_instance_extension->deprecated_native_info->free_property_list_func = p_info->free_property_list_func; + script_instance_extension->deprecated_native_info->free_method_list_func = p_info->free_method_list_func; return reinterpret_cast<GDExtensionScriptInstancePtr>(script_instance_extension); } -#endif // DISABLE_DEPRECATED static GDExtensionScriptInstancePtr gdextension_script_instance_create2(const GDExtensionScriptInstanceInfo2 *p_info, GDExtensionScriptInstanceDataPtr p_instance_data) { + GDExtensionScriptInstanceInfo3 *info_3 = memnew(GDExtensionScriptInstanceInfo3); + info_3->set_func = p_info->set_func; + info_3->get_func = p_info->get_func; + info_3->get_property_list_func = p_info->get_property_list_func; + info_3->free_property_list_func = nullptr; + info_3->get_class_category_func = nullptr; + info_3->property_can_revert_func = p_info->property_can_revert_func; + info_3->property_get_revert_func = p_info->property_get_revert_func; + info_3->get_owner_func = p_info->get_owner_func; + info_3->get_property_state_func = p_info->get_property_state_func; + info_3->get_method_list_func = p_info->get_method_list_func; + info_3->free_method_list_func = nullptr; + info_3->get_property_type_func = p_info->get_property_type_func; + info_3->validate_property_func = nullptr; + info_3->has_method_func = p_info->has_method_func; + info_3->get_method_argument_count_func = nullptr; + info_3->call_func = p_info->call_func; + info_3->notification_func = p_info->notification_func; + info_3->to_string_func = p_info->to_string_func; + info_3->refcount_incremented_func = p_info->refcount_incremented_func; + info_3->refcount_decremented_func = p_info->refcount_decremented_func; + info_3->get_script_func = p_info->get_script_func; + info_3->is_placeholder_func = p_info->is_placeholder_func; + info_3->set_fallback_func = p_info->set_fallback_func; + info_3->get_fallback_func = p_info->get_fallback_func; + info_3->get_language_func = p_info->get_language_func; + info_3->free_func = p_info->free_func; + + ScriptInstanceExtension *script_instance_extension = memnew(ScriptInstanceExtension); + script_instance_extension->instance = p_instance_data; + script_instance_extension->native_info = info_3; + script_instance_extension->free_native_info = true; + script_instance_extension->deprecated_native_info = memnew(ScriptInstanceExtension::DeprecatedNativeInfo); + script_instance_extension->deprecated_native_info->free_property_list_func = p_info->free_property_list_func; + script_instance_extension->deprecated_native_info->free_method_list_func = p_info->free_method_list_func; + return reinterpret_cast<GDExtensionScriptInstancePtr>(script_instance_extension); +} +#endif // DISABLE_DEPRECATED + +static GDExtensionScriptInstancePtr gdextension_script_instance_create3(const GDExtensionScriptInstanceInfo3 *p_info, GDExtensionScriptInstanceDataPtr p_instance_data) { ScriptInstanceExtension *script_instance_extension = memnew(ScriptInstanceExtension); script_instance_extension->instance = p_instance_data; script_instance_extension->native_info = p_info; @@ -1308,9 +1427,15 @@ static GDExtensionScriptInstancePtr gdextension_object_get_script_instance(GDExt return script_instance_extension->instance; } +#ifndef DISABLE_DEPRECATED static void gdextension_callable_custom_create(GDExtensionUninitializedTypePtr r_callable, GDExtensionCallableCustomInfo *p_custom_callable_info) { memnew_placement(r_callable, Callable(memnew(CallableCustomExtension(p_custom_callable_info)))); } +#endif + +static void gdextension_callable_custom_create2(GDExtensionUninitializedTypePtr r_callable, GDExtensionCallableCustomInfo2 *p_custom_callable_info) { + memnew_placement(r_callable, Callable(memnew(CallableCustomExtension(p_custom_callable_info)))); +} static void *gdextension_callable_custom_get_userdata(GDExtensionTypePtr p_callable, void *p_token) { const Callable &callable = *reinterpret_cast<const Callable *>(p_callable); @@ -1350,7 +1475,7 @@ static GDExtensionMethodBindPtr gdextension_classdb_get_method_bind(GDExtensionC static GDExtensionObjectPtr gdextension_classdb_construct_object(GDExtensionConstStringNamePtr p_classname) { const StringName classname = *reinterpret_cast<const StringName *>(p_classname); - return (GDExtensionObjectPtr)ClassDB::instantiate(classname); + return (GDExtensionObjectPtr)ClassDB::instantiate_no_placeholders(classname); } static void *gdextension_classdb_get_class_tag(GDExtensionConstStringNamePtr p_classname) { @@ -1373,7 +1498,20 @@ static void gdextension_editor_remove_plugin(GDExtensionConstStringNamePtr p_cla #endif } -#define REGISTER_INTERFACE_FUNC(m_name) GDExtension::register_interface_function(#m_name, (GDExtensionInterfaceFunctionPtr)&gdextension_##m_name) +static void gdextension_editor_help_load_xml_from_utf8_chars_and_len(const char *p_data, GDExtensionInt p_size) { +#ifdef TOOLS_ENABLED + GDExtensionEditorHelp::load_xml_buffer((const uint8_t *)p_data, p_size); +#endif +} + +static void gdextension_editor_help_load_xml_from_utf8_chars(const char *p_data) { +#ifdef TOOLS_ENABLED + size_t len = strlen(p_data); + gdextension_editor_help_load_xml_from_utf8_chars_and_len(p_data, len); +#endif +} + +#define REGISTER_INTERFACE_FUNC(m_name) GDExtension::register_interface_function(#m_name, (GDExtensionInterfaceFunctionPtr) & gdextension_##m_name) void gdextension_setup_interface() { REGISTER_INTERFACE_FUNC(get_godot_version); @@ -1500,22 +1638,30 @@ void gdextension_setup_interface() { REGISTER_INTERFACE_FUNC(object_cast_to); REGISTER_INTERFACE_FUNC(object_get_instance_from_id); REGISTER_INTERFACE_FUNC(object_get_instance_id); + REGISTER_INTERFACE_FUNC(object_has_script_method); + REGISTER_INTERFACE_FUNC(object_call_script_method); REGISTER_INTERFACE_FUNC(ref_get_object); REGISTER_INTERFACE_FUNC(ref_set_object); #ifndef DISABLE_DEPRECATED REGISTER_INTERFACE_FUNC(script_instance_create); -#endif // DISABLE_DEPRECATED REGISTER_INTERFACE_FUNC(script_instance_create2); +#endif // DISABLE_DEPRECATED + REGISTER_INTERFACE_FUNC(script_instance_create3); REGISTER_INTERFACE_FUNC(placeholder_script_instance_create); REGISTER_INTERFACE_FUNC(placeholder_script_instance_update); REGISTER_INTERFACE_FUNC(object_get_script_instance); +#ifndef DISABLE_DEPRECATED REGISTER_INTERFACE_FUNC(callable_custom_create); +#endif // DISABLE_DEPRECATED + REGISTER_INTERFACE_FUNC(callable_custom_create2); REGISTER_INTERFACE_FUNC(callable_custom_get_userdata); REGISTER_INTERFACE_FUNC(classdb_construct_object); REGISTER_INTERFACE_FUNC(classdb_get_method_bind); REGISTER_INTERFACE_FUNC(classdb_get_class_tag); REGISTER_INTERFACE_FUNC(editor_add_plugin); REGISTER_INTERFACE_FUNC(editor_remove_plugin); + REGISTER_INTERFACE_FUNC(editor_help_load_xml_from_utf8_chars); + REGISTER_INTERFACE_FUNC(editor_help_load_xml_from_utf8_chars_and_len); } #undef REGISTER_INTERFACE_FUNCTION |