diff options
| -rw-r--r-- | core/extension/gdnative_interface.h | 54 | ||||
| -rw-r--r-- | core/extension/native_extension.cpp | 109 | ||||
| -rw-r--r-- | core/extension/native_extension.h | 16 | ||||
| -rw-r--r-- | core/object/make_virtuals.py | 6 | ||||
| -rw-r--r-- | core/object/object.cpp | 3 | ||||
| -rw-r--r-- | core/object/object.h | 20 | ||||
| -rw-r--r-- | core/object/script_language_extension.h | 38 | 
7 files changed, 139 insertions, 107 deletions
diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h index eaad1791c3..68eed5a161 100644 --- a/core/extension/gdnative_interface.h +++ b/core/extension/gdnative_interface.h @@ -202,21 +202,21 @@ typedef uint64_t (*GDNativeExtensionClassGetRID)(GDExtensionClassInstancePtr p_i  typedef struct {  	GDNativeVariantType type; -	const char *name; -	const char *class_name; +	GDNativeStringNamePtr name; +	GDNativeStringNamePtr class_name;  	uint32_t hint; // Bitfield of `PropertyHint` (defined in `extension_api.json`) -	const char *hint_string; +	GDNativeStringPtr hint_string;  	uint32_t usage; // Bitfield of `PropertyUsageFlags` (defined in `extension_api.json`)  } GDNativePropertyInfo;  typedef struct { -	const char *name; +	GDNativeStringNamePtr name;  	GDNativePropertyInfo return_value;  	uint32_t flags; // Bitfield of `GDNativeExtensionClassMethodFlags`  	int32_t id; -	GDNativePropertyInfo *arguments; +	GDNativePropertyInfo *arguments; // array of `argument_count` size  	uint32_t argument_count; -	GDNativeVariantPtr default_arguments; +	GDNativeVariantPtr *default_arguments; // array of `default_argument_count` size  	uint32_t default_argument_count;  } GDNativeMethodInfo; @@ -225,13 +225,13 @@ typedef void (*GDNativeExtensionClassFreePropertyList)(GDExtensionClassInstanceP  typedef GDNativeBool (*GDNativeExtensionClassPropertyCanRevert)(GDExtensionClassInstancePtr p_instance, const GDNativeStringNamePtr p_name);  typedef GDNativeBool (*GDNativeExtensionClassPropertyGetRevert)(GDExtensionClassInstancePtr p_instance, const GDNativeStringNamePtr p_name, GDNativeVariantPtr r_ret);  typedef void (*GDNativeExtensionClassNotification)(GDExtensionClassInstancePtr p_instance, int32_t p_what); -typedef void (*GDNativeExtensionClassToString)(GDExtensionClassInstancePtr p_instance, GDNativeStringPtr p_out); +typedef void (*GDNativeExtensionClassToString)(GDExtensionClassInstancePtr p_instance, GDNativeBool *r_is_valid, GDNativeStringPtr p_out);  typedef void (*GDNativeExtensionClassReference)(GDExtensionClassInstancePtr p_instance);  typedef void (*GDNativeExtensionClassUnreference)(GDExtensionClassInstancePtr p_instance);  typedef void (*GDNativeExtensionClassCallVirtual)(GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret);  typedef GDNativeObjectPtr (*GDNativeExtensionClassCreateInstance)(void *p_userdata);  typedef void (*GDNativeExtensionClassFreeInstance)(void *p_userdata, GDExtensionClassInstancePtr p_instance); -typedef GDNativeExtensionClassCallVirtual (*GDNativeExtensionClassGetVirtual)(void *p_userdata, const char *p_name); +typedef GDNativeExtensionClassCallVirtual (*GDNativeExtensionClassGetVirtual)(void *p_userdata, const GDNativeStringNamePtr p_name);  typedef struct {  	GDNativeBool is_virtual; @@ -284,24 +284,21 @@ typedef enum {  typedef void (*GDNativeExtensionClassMethodCall)(void *method_userdata, GDExtensionClassInstancePtr p_instance, const GDNativeVariantPtr *p_args, const GDNativeInt p_argument_count, GDNativeVariantPtr r_return, GDNativeCallError *r_error);  typedef void (*GDNativeExtensionClassMethodPtrCall)(void *method_userdata, GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret); -/* passing -1 as argument in the following functions refers to the return type */ -typedef GDNativeVariantType (*GDNativeExtensionClassMethodGetArgumentType)(void *p_method_userdata, int32_t p_argument); -typedef void (*GDNativeExtensionClassMethodGetArgumentInfo)(void *p_method_userdata, int32_t p_argument, GDNativePropertyInfo *r_info); -typedef GDNativeExtensionClassMethodArgumentMetadata (*GDNativeExtensionClassMethodGetArgumentMetadata)(void *p_method_userdata, int32_t p_argument); -  typedef struct { -	const char *name; +	GDNativeStringNamePtr name;  	void *method_userdata;  	GDNativeExtensionClassMethodCall call_func;  	GDNativeExtensionClassMethodPtrCall ptrcall_func;  	uint32_t method_flags; // Bitfield of `GDNativeExtensionClassMethodFlags`  	uint32_t argument_count;  	GDNativeBool has_return_value; -	GDNativeExtensionClassMethodGetArgumentType get_argument_type_func; -	GDNativeExtensionClassMethodGetArgumentInfo get_argument_info_func; /* name and hint information for the argument can be omitted in release builds. Class name should always be present if it applies. */ -	GDNativeExtensionClassMethodGetArgumentMetadata get_argument_metadata_func; +	GDNativePropertyInfo *return_value_info; // Ignored if `has_return_value` is false +	GDNativeExtensionClassMethodArgumentMetadata return_value_metadata; // Ignored if `has_return_value` is false +	/* name and hint information for the argument can be omitted in release builds. Class name should always be present if it applies. */ +	GDNativePropertyInfo *aguments_info; // array of `argument_count` size +	GDNativeExtensionClassMethodArgumentMetadata *aguments_metadata; // array of `argument_count` size  	uint32_t default_argument_count; -	GDNativeVariantPtr *default_arguments; +	GDNativeVariantPtr *default_arguments; // array of `default_argument_count` size  } GDNativeExtensionClassMethodInfo;  /* SCRIPT INSTANCE EXTENSION */ @@ -312,7 +309,6 @@ typedef GDNativeBool (*GDNativeExtensionScriptInstanceSet)(GDNativeExtensionScri  typedef GDNativeBool (*GDNativeExtensionScriptInstanceGet)(GDNativeExtensionScriptInstanceDataPtr p_instance, const GDNativeStringNamePtr p_name, GDNativeVariantPtr r_ret);  typedef const GDNativePropertyInfo *(*GDNativeExtensionScriptInstanceGetPropertyList)(GDNativeExtensionScriptInstanceDataPtr p_instance, uint32_t *r_count);  typedef void (*GDNativeExtensionScriptInstanceFreePropertyList)(GDNativeExtensionScriptInstanceDataPtr p_instance, const GDNativePropertyInfo *p_list); -typedef GDNativeVariantType (*GDNativeExtensionScriptInstanceGetPropertyType)(GDNativeExtensionScriptInstanceDataPtr p_instance, const GDNativeStringNamePtr p_name, GDNativeBool *r_is_valid);  typedef GDNativeBool (*GDNativeExtensionScriptInstancePropertyCanRevert)(GDNativeExtensionScriptInstanceDataPtr p_instance, const GDNativeStringNamePtr p_name);  typedef GDNativeBool (*GDNativeExtensionScriptInstancePropertyGetRevert)(GDNativeExtensionScriptInstanceDataPtr p_instance, const GDNativeStringNamePtr p_name, GDNativeVariantPtr r_ret); @@ -328,7 +324,7 @@ typedef GDNativeBool (*GDNativeExtensionScriptInstanceHasMethod)(GDNativeExtensi  typedef void (*GDNativeExtensionScriptInstanceCall)(GDNativeExtensionScriptInstanceDataPtr p_self, const GDNativeStringNamePtr p_method, const GDNativeVariantPtr *p_args, const GDNativeInt p_argument_count, GDNativeVariantPtr r_return, GDNativeCallError *r_error);  typedef void (*GDNativeExtensionScriptInstanceNotification)(GDNativeExtensionScriptInstanceDataPtr p_instance, int32_t p_what); -typedef const char *(*GDNativeExtensionScriptInstanceToString)(GDNativeExtensionScriptInstanceDataPtr p_instance, GDNativeBool *r_is_valid); +typedef void (*GDNativeExtensionScriptInstanceToString)(GDNativeExtensionScriptInstanceDataPtr p_instance, GDNativeBool *r_is_valid, GDNativeStringPtr r_out);  typedef void (*GDNativeExtensionScriptInstanceRefCountIncremented)(GDNativeExtensionScriptInstanceDataPtr p_instance);  typedef GDNativeBool (*GDNativeExtensionScriptInstanceRefCountDecremented)(GDNativeExtensionScriptInstanceDataPtr p_instance); @@ -349,7 +345,6 @@ typedef struct {  	GDNativeExtensionScriptInstanceGet get_func;  	GDNativeExtensionScriptInstanceGetPropertyList get_property_list_func;  	GDNativeExtensionScriptInstanceFreePropertyList free_property_list_func; -	GDNativeExtensionScriptInstanceGetPropertyType get_property_type_func;  	GDNativeExtensionScriptInstancePropertyCanRevert property_can_revert_func;  	GDNativeExtensionScriptInstancePropertyGetRevert property_get_revert_func; @@ -546,14 +541,15 @@ typedef struct {  	/* CLASSDB EXTENSION */ -	void (*classdb_register_extension_class)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_parent_class_name, const GDNativeExtensionClassCreationInfo *p_extension_funcs); -	void (*classdb_register_extension_class_method)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info); -	void (*classdb_register_extension_class_integer_constant)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value, GDNativeBool p_is_bitfield); -	void (*classdb_register_extension_class_property)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativePropertyInfo *p_info, const char *p_setter, const char *p_getter); -	void (*classdb_register_extension_class_property_group)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_group_name, const char *p_prefix); -	void (*classdb_register_extension_class_property_subgroup)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_subgroup_name, const char *p_prefix); -	void (*classdb_register_extension_class_signal)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_signal_name, const GDNativePropertyInfo *p_argument_info, GDNativeInt p_argument_count); -	void (*classdb_unregister_extension_class)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name); /* Unregistering a parent class before a class that inherits it will result in failure. Inheritors must be unregistered first. */ +	// Provided parameters for `classdb_register_extension_*` can be safely freed once the function returns +	void (*classdb_register_extension_class)(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_parent_class_name, const GDNativeExtensionClassCreationInfo *p_extension_funcs); +	void (*classdb_register_extension_class_method)(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info); +	void (*classdb_register_extension_class_integer_constant)(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_enum_name, const GDNativeStringNamePtr p_constant_name, GDNativeInt p_constant_value, GDNativeBool p_is_bitfield); +	void (*classdb_register_extension_class_property)(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativePropertyInfo *p_info, const GDNativeStringNamePtr p_setter, const GDNativeStringNamePtr p_getter); +	void (*classdb_register_extension_class_property_group)(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringPtr p_group_name, const GDNativeStringPtr p_prefix); +	void (*classdb_register_extension_class_property_subgroup)(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringPtr p_subgroup_name, const GDNativeStringPtr p_prefix); +	void (*classdb_register_extension_class_signal)(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_signal_name, const GDNativePropertyInfo *p_argument_info, GDNativeInt p_argument_count); +	void (*classdb_unregister_extension_class)(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name); /* Unregistering a parent class before a class that inherits it will result in failure. Inheritors must be unregistered first. */  	void (*get_library_path)(const GDNativeExtensionClassLibraryPtr p_library, GDNativeStringPtr r_path); diff --git a/core/extension/native_extension.cpp b/core/extension/native_extension.cpp index cc019584a5..8bbb72fd82 100644 --- a/core/extension/native_extension.cpp +++ b/core/extension/native_extension.cpp @@ -42,26 +42,37 @@ String NativeExtension::get_extension_list_config_file() {  class NativeExtensionMethodBind : public MethodBind {  	GDNativeExtensionClassMethodCall call_func;  	GDNativeExtensionClassMethodPtrCall ptrcall_func; -	GDNativeExtensionClassMethodGetArgumentType get_argument_type_func; -	GDNativeExtensionClassMethodGetArgumentInfo get_argument_info_func; -	GDNativeExtensionClassMethodGetArgumentMetadata get_argument_metadata_func;  	void *method_userdata;  	bool vararg; +	PropertyInfo return_value_info; +	GodotTypeInfo::Metadata return_value_metadata; +	List<PropertyInfo> arguments_info; +	List<GodotTypeInfo::Metadata> arguments_metadata;  protected:  	virtual Variant::Type _gen_argument_type(int p_arg) const override { -		return Variant::Type(get_argument_type_func(method_userdata, p_arg)); +		if (p_arg < 0) { +			return return_value_info.type; +		} else { +			return arguments_info[p_arg].type; +		}  	}  	virtual PropertyInfo _gen_argument_type_info(int p_arg) const override { -		GDNativePropertyInfo pinfo; -		get_argument_info_func(method_userdata, p_arg, &pinfo); -		return PropertyInfo(pinfo); +		if (p_arg < 0) { +			return return_value_info; +		} else { +			return arguments_info[p_arg]; +		}  	}  public:  #ifdef DEBUG_METHODS_ENABLED  	virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override { -		return GodotTypeInfo::Metadata(get_argument_metadata_func(method_userdata, p_arg)); +		if (p_arg < 0) { +			return return_value_metadata; +		} else { +			return arguments_metadata[p_arg]; +		}  	}  #endif @@ -89,10 +100,17 @@ public:  		method_userdata = p_method_info->method_userdata;  		call_func = p_method_info->call_func;  		ptrcall_func = p_method_info->ptrcall_func; -		get_argument_type_func = p_method_info->get_argument_type_func; -		get_argument_info_func = p_method_info->get_argument_info_func; -		get_argument_metadata_func = p_method_info->get_argument_metadata_func; -		set_name(p_method_info->name); +		set_name(*reinterpret_cast<StringName *>(p_method_info->name)); + +		if (p_method_info->has_return_value) { +			return_value_info = PropertyInfo(*p_method_info->return_value_info); +			return_value_metadata = GodotTypeInfo::Metadata(p_method_info->return_value_metadata); +		} + +		for (uint32_t i = 0; i < p_method_info->argument_count; i++) { +			arguments_info.push_back(PropertyInfo(p_method_info->aguments_info[i])); +			arguments_metadata.push_back(GodotTypeInfo::Metadata(p_method_info->aguments_metadata[i])); +		}  		set_hint_flags(p_method_info->method_flags); @@ -117,15 +135,15 @@ public:  static GDNativeInterface gdnative_interface; -void NativeExtension::_register_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_parent_class_name, const GDNativeExtensionClassCreationInfo *p_extension_funcs) { +void NativeExtension::_register_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_parent_class_name, const GDNativeExtensionClassCreationInfo *p_extension_funcs) {  	NativeExtension *self = static_cast<NativeExtension *>(p_library); -	StringName class_name = p_class_name; +	StringName class_name = *reinterpret_cast<StringName *>(p_class_name); +	StringName parent_class_name = *reinterpret_cast<StringName *>(p_parent_class_name);  	ERR_FAIL_COND_MSG(!String(class_name).is_valid_identifier(), "Attempt to register extension class '" + class_name + "', which is not a valid class identifier.");  	ERR_FAIL_COND_MSG(ClassDB::class_exists(class_name), "Attempt to register extension class '" + class_name + "', which appears to be already registered.");  	Extension *parent_extension = nullptr; -	StringName parent_class_name = p_parent_class_name;  	if (self->extension_classes.has(parent_class_name)) {  		parent_extension = &self->extension_classes[parent_class_name]; @@ -172,11 +190,11 @@ void NativeExtension::_register_extension_class(const GDNativeExtensionClassLibr  	ClassDB::register_extension_class(&extension->native_extension);  } -void NativeExtension::_register_extension_class_method(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info) { +void NativeExtension::_register_extension_class_method(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info) {  	NativeExtension *self = static_cast<NativeExtension *>(p_library); -	StringName class_name = p_class_name; -	StringName method_name = p_method_info->name; +	StringName class_name = *reinterpret_cast<const StringName *>(p_class_name); +	StringName method_name = *reinterpret_cast<const StringName *>(p_method_info->name);  	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension method '" + String(method_name) + "' for unexisting class '" + class_name + "'.");  	//Extension *extension = &self->extension_classes[class_name]; @@ -186,56 +204,63 @@ void NativeExtension::_register_extension_class_method(const GDNativeExtensionCl  	ClassDB::bind_method_custom(class_name, method);  } -void NativeExtension::_register_extension_class_integer_constant(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value, GDNativeBool p_is_bitfield) { +void NativeExtension::_register_extension_class_integer_constant(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_enum_name, const GDNativeStringNamePtr p_constant_name, GDNativeInt p_constant_value, GDNativeBool p_is_bitfield) {  	NativeExtension *self = static_cast<NativeExtension *>(p_library); -	StringName class_name = p_class_name; -	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension constant '" + String(p_constant_name) + "' for unexisting class '" + class_name + "'."); - -	//Extension *extension = &self->extension_classes[class_name]; +	StringName class_name = *reinterpret_cast<const StringName *>(p_class_name); +	StringName enum_name = *reinterpret_cast<const StringName *>(p_enum_name); +	StringName constant_name = *reinterpret_cast<const StringName *>(p_constant_name); +	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension constant '" + constant_name + "' for unexisting class '" + class_name + "'."); -	ClassDB::bind_integer_constant(class_name, p_enum_name, p_constant_name, p_constant_value, p_is_bitfield); +	ClassDB::bind_integer_constant(class_name, enum_name, constant_name, p_constant_value, p_is_bitfield);  } -void NativeExtension::_register_extension_class_property(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativePropertyInfo *p_info, const char *p_setter, const char *p_getter) { +void NativeExtension::_register_extension_class_property(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativePropertyInfo *p_info, const GDNativeStringNamePtr p_setter, const GDNativeStringNamePtr p_getter) {  	NativeExtension *self = static_cast<NativeExtension *>(p_library); -	StringName class_name = p_class_name; -	String property_name = p_info->name; +	StringName class_name = *reinterpret_cast<const StringName *>(p_class_name); +	StringName setter = *reinterpret_cast<const StringName *>(p_setter); +	StringName getter = *reinterpret_cast<const StringName *>(p_getter); +	String property_name = *reinterpret_cast<const StringName *>(p_info->name);  	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class property '" + property_name + "' for unexisting class '" + class_name + "'.");  	//Extension *extension = &self->extension_classes[class_name];  	PropertyInfo pinfo(*p_info); -	ClassDB::add_property(class_name, pinfo, p_setter, p_getter); +	ClassDB::add_property(class_name, pinfo, setter, getter);  } -void NativeExtension::_register_extension_class_property_group(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_group_name, const char *p_prefix) { +void NativeExtension::_register_extension_class_property_group(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringPtr p_group_name, const GDNativeStringPtr p_prefix) {  	NativeExtension *self = static_cast<NativeExtension *>(p_library); -	StringName class_name = p_class_name; -	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class property group '" + String(p_group_name) + "' for unexisting class '" + class_name + "'."); +	StringName class_name = *reinterpret_cast<const StringName *>(p_class_name); +	String group_name = *reinterpret_cast<const String *>(p_group_name); +	String prefix = *reinterpret_cast<const String *>(p_prefix); +	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class property group '" + group_name + "' for unexisting class '" + class_name + "'."); -	ClassDB::add_property_group(class_name, p_group_name, p_prefix); +	ClassDB::add_property_group(class_name, group_name, prefix);  } -void NativeExtension::_register_extension_class_property_subgroup(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_subgroup_name, const char *p_prefix) { +void NativeExtension::_register_extension_class_property_subgroup(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringPtr p_subgroup_name, const GDNativeStringPtr p_prefix) {  	NativeExtension *self = static_cast<NativeExtension *>(p_library); -	StringName class_name = p_class_name; -	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class property subgroup '" + String(p_subgroup_name) + "' for unexisting class '" + class_name + "'."); +	StringName class_name = *reinterpret_cast<const StringName *>(p_class_name); +	String subgroup_name = *reinterpret_cast<const String *>(p_subgroup_name); +	String prefix = *reinterpret_cast<const String *>(p_prefix); +	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class property subgroup '" + subgroup_name + "' for unexisting class '" + class_name + "'."); -	ClassDB::add_property_subgroup(class_name, p_subgroup_name, p_prefix); +	ClassDB::add_property_subgroup(class_name, subgroup_name, prefix);  } -void NativeExtension::_register_extension_class_signal(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_signal_name, const GDNativePropertyInfo *p_argument_info, GDNativeInt p_argument_count) { +void NativeExtension::_register_extension_class_signal(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_signal_name, const GDNativePropertyInfo *p_argument_info, GDNativeInt p_argument_count) {  	NativeExtension *self = static_cast<NativeExtension *>(p_library); -	StringName class_name = p_class_name; -	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class signal '" + String(p_signal_name) + "' for unexisting class '" + class_name + "'."); +	StringName class_name = *reinterpret_cast<const StringName *>(p_class_name); +	StringName signal_name = *reinterpret_cast<const StringName *>(p_signal_name); +	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class signal '" + signal_name + "' for unexisting class '" + class_name + "'.");  	MethodInfo s; -	s.name = p_signal_name; +	s.name = signal_name;  	for (int i = 0; i < p_argument_count; i++) {  		PropertyInfo arg(p_argument_info[i]);  		s.arguments.push_back(arg); @@ -243,10 +268,10 @@ void NativeExtension::_register_extension_class_signal(const GDNativeExtensionCl  	ClassDB::add_signal(class_name, s);  } -void NativeExtension::_unregister_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name) { +void NativeExtension::_unregister_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name) {  	NativeExtension *self = static_cast<NativeExtension *>(p_library); -	StringName class_name = p_class_name; +	StringName class_name = *reinterpret_cast<const StringName *>(p_class_name);  	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to unregister unexisting extension class '" + class_name + "'.");  	Extension *ext = &self->extension_classes[class_name];  	ERR_FAIL_COND_MSG(ext->native_extension.children.size(), "Attempt to unregister class '" + class_name + "' while other extension classes inherit from it."); diff --git a/core/extension/native_extension.h b/core/extension/native_extension.h index b7238d2899..70f6f9f039 100644 --- a/core/extension/native_extension.h +++ b/core/extension/native_extension.h @@ -47,14 +47,14 @@ class NativeExtension : public Resource {  	HashMap<StringName, Extension> extension_classes; -	static void _register_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_parent_class_name, const GDNativeExtensionClassCreationInfo *p_extension_funcs); -	static void _register_extension_class_method(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info); -	static void _register_extension_class_integer_constant(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value, GDNativeBool p_is_bitfield); -	static void _register_extension_class_property(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativePropertyInfo *p_info, const char *p_setter, const char *p_getter); -	static void _register_extension_class_property_group(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_group_name, const char *p_prefix); -	static void _register_extension_class_property_subgroup(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_subgroup_name, const char *p_prefix); -	static void _register_extension_class_signal(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_signal_name, const GDNativePropertyInfo *p_argument_info, GDNativeInt p_argument_count); -	static void _unregister_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name); +	static void _register_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_parent_class_name, const GDNativeExtensionClassCreationInfo *p_extension_funcs); +	static void _register_extension_class_method(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info); +	static void _register_extension_class_integer_constant(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_enum_name, const GDNativeStringNamePtr p_constant_name, GDNativeInt p_constant_value, GDNativeBool p_is_bitfield); +	static void _register_extension_class_property(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativePropertyInfo *p_info, const GDNativeStringNamePtr p_setter, const GDNativeStringNamePtr p_getter); +	static void _register_extension_class_property_group(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_group_name, const GDNativeStringNamePtr p_prefix); +	static void _register_extension_class_property_subgroup(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_subgroup_name, const GDNativeStringNamePtr p_prefix); +	static void _register_extension_class_signal(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_signal_name, const GDNativePropertyInfo *p_argument_info, GDNativeInt p_argument_count); +	static void _unregister_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name);  	static void _get_library_path(const GDNativeExtensionClassLibraryPtr p_library, GDNativeStringPtr r_path);  	GDNativeInitialization initialization; diff --git a/core/object/make_virtuals.py b/core/object/make_virtuals.py index 326a9277ff..61bf6d900a 100644 --- a/core/object/make_virtuals.py +++ b/core/object/make_virtuals.py @@ -16,7 +16,8 @@ _FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\  		}    \\  	}\\      if (unlikely(_get_extension() && !_gdvirtual_##m_name##_initialized)) {\\ -        _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, #m_name) : (GDNativeExtensionClassCallVirtual) nullptr;\\ +        /* TODO: C-style cast because GDNativeStringNamePtr's const qualifier is broken (see https://github.com/godotengine/godot/pull/67751) */\\ +        _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, (GDNativeStringNamePtr)&_gdvirtual_##m_name##_sn) : (GDNativeExtensionClassCallVirtual) nullptr;\\          _gdvirtual_##m_name##_initialized = true;\\      }\\  	if (_gdvirtual_##m_name) {\\ @@ -40,7 +41,8 @@ _FORCE_INLINE_ bool _gdvirtual_##m_name##_overridden() const { \\  	    return _script_instance->has_method(_gdvirtual_##m_name##_sn);\\  	}\\      if (unlikely(_get_extension() && !_gdvirtual_##m_name##_initialized)) {\\ -        _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, #m_name) : (GDNativeExtensionClassCallVirtual) nullptr;\\ +        /* TODO: C-style cast because GDNativeStringNamePtr's const qualifier is broken (see https://github.com/godotengine/godot/pull/67751) */\\ +        _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, (GDNativeStringNamePtr)&_gdvirtual_##m_name##_sn) : (GDNativeExtensionClassCallVirtual) nullptr;\\          _gdvirtual_##m_name##_initialized = true;\\      }\\  	if (_gdvirtual_##m_name) {\\ diff --git a/core/object/object.cpp b/core/object/object.cpp index 540b9a8f19..d27e0d7621 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -808,7 +808,8 @@ String Object::to_string() {  	}  	if (_extension && _extension->to_string) {  		String ret; -		_extension->to_string(_extension_instance, &ret); +		GDNativeBool is_valid; +		_extension->to_string(_extension_instance, &is_valid, &ret);  		return ret;  	}  	return "<" + get_class() + "#" + itos(get_instance_id()) + ">"; diff --git a/core/object/object.h b/core/object/object.h index 8c647cda40..7bb88998a2 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -192,10 +192,10 @@ struct PropertyInfo {  	explicit PropertyInfo(const GDNativePropertyInfo &pinfo) :  			type((Variant::Type)pinfo.type), -			name(pinfo.name), -			class_name(pinfo.class_name), // can be null +			name(*reinterpret_cast<StringName *>(pinfo.name)), +			class_name(*reinterpret_cast<StringName *>(pinfo.class_name)),  			hint((PropertyHint)pinfo.hint), -			hint_string(pinfo.hint_string), // can be null +			hint_string(*reinterpret_cast<String *>(pinfo.hint_string)),  			usage(pinfo.usage) {}  	bool operator==(const PropertyInfo &p_info) const { @@ -242,6 +242,20 @@ struct MethodInfo {  	MethodInfo() {} +	explicit MethodInfo(const GDNativeMethodInfo &pinfo) : +			name(*reinterpret_cast<StringName *>(pinfo.name)), +			return_val(PropertyInfo(pinfo.return_value)), +			flags(pinfo.flags), +			id(pinfo.id) { +		for (uint32_t j = 0; j < pinfo.argument_count; j++) { +			arguments.push_back(PropertyInfo(pinfo.arguments[j])); +		} +		const Variant *def_values = (const Variant *)pinfo.default_arguments; +		for (uint32_t j = 0; j < pinfo.default_argument_count; j++) { +			default_arguments.push_back(def_values[j]); +		} +	} +  	void _push_params(const PropertyInfo &p_param) {  		arguments.push_back(p_param);  	} diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h index c32fb9d85b..c287a6f71a 100644 --- a/core/object/script_language_extension.h +++ b/core/object/script_language_extension.h @@ -681,16 +681,21 @@ public:  		}  	}  	virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = nullptr) const override { -		if (native_info->get_property_type_func) { -			GDNativeBool is_valid = 0; -			GDNativeVariantType type = native_info->get_property_type_func(instance, (const GDNativeStringNamePtr)&p_name, &is_valid); -			if (r_is_valid) { -				*r_is_valid = is_valid != 0; +		Variant::Type type = Variant::Type::NIL; +		if (native_info->get_property_list_func) { +			uint32_t pcount; +			const GDNativePropertyInfo *pinfo = native_info->get_property_list_func(instance, &pcount); +			for (uint32_t i = 0; i < pcount; i++) { +				if (p_name == *reinterpret_cast<StringName *>(pinfo->name)) { +					type = Variant::Type(pinfo->type); +					break; +				} +			} +			if (native_info->free_property_list_func) { +				native_info->free_property_list_func(instance, pinfo);  			} - -			return Variant::Type(type);  		} -		return Variant::NIL; +		return type;  	}  	virtual bool property_can_revert(const StringName &p_name) const override { @@ -727,19 +732,7 @@ public:  			uint32_t mcount;  			const GDNativeMethodInfo *minfo = native_info->get_method_list_func(instance, &mcount);  			for (uint32_t i = 0; i < mcount; i++) { -				MethodInfo m; -				m.name = minfo[i].name; -				m.flags = minfo[i].flags; -				m.id = minfo[i].id; -				m.return_val = PropertyInfo(minfo[i].return_value); -				for (uint32_t j = 0; j < minfo[i].argument_count; j++) { -					m.arguments.push_back(PropertyInfo(minfo[i].arguments[j])); -				} -				const Variant *def_values = (const Variant *)minfo[i].default_arguments; -				for (uint32_t j = 0; j < minfo[i].default_argument_count; j++) { -					m.default_arguments.push_back(def_values[j]); -				} -				p_list->push_back(m); +				p_list->push_back(MethodInfo(minfo[i]));  			}  			if (native_info->free_method_list_func) {  				native_info->free_method_list_func(instance, minfo); @@ -773,7 +766,8 @@ public:  	virtual String to_string(bool *r_valid) override {  		if (native_info->to_string_func) {  			GDNativeBool valid; -			String ret = native_info->to_string_func(instance, &valid); +			String ret; +			native_info->to_string_func(instance, &valid, reinterpret_cast<GDNativeStringPtr>(&ret));  			if (r_valid) {  				*r_valid = valid != 0;  			}  |