GDExtension: Pass count when freeing method and property lists for script instances

This commit is contained in:
David Snopek 2024-03-01 09:56:19 -06:00
parent df78c0636d
commit 0badf07657
3 changed files with 161 additions and 43 deletions

View file

@ -1240,43 +1240,84 @@ 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->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);
}
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->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_create2(const GDExtensionScriptInstanceInfo2 *p_info, GDExtensionScriptInstanceDataPtr p_instance_data) {
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;
@ -1548,8 +1589,9 @@ void gdextension_setup_interface() {
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);

View file

@ -480,7 +480,8 @@ typedef void *GDExtensionScriptInstanceDataPtr; // Pointer to custom ScriptInsta
typedef GDExtensionBool (*GDExtensionScriptInstanceSet)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value);
typedef GDExtensionBool (*GDExtensionScriptInstanceGet)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
typedef const GDExtensionPropertyInfo *(*GDExtensionScriptInstanceGetPropertyList)(GDExtensionScriptInstanceDataPtr p_instance, uint32_t *r_count);
typedef void (*GDExtensionScriptInstanceFreePropertyList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionPropertyInfo *p_list);
typedef void (*GDExtensionScriptInstanceFreePropertyList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionPropertyInfo *p_list); // Deprecated. Use GDExtensionScriptInstanceFreePropertyList2 instead.
typedef void (*GDExtensionScriptInstanceFreePropertyList2)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionPropertyInfo *p_list, uint32_t p_count);
typedef GDExtensionBool (*GDExtensionScriptInstanceGetClassCategory)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionPropertyInfo *p_class_category);
typedef GDExtensionVariantType (*GDExtensionScriptInstanceGetPropertyType)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionBool *r_is_valid);
@ -494,7 +495,8 @@ typedef void (*GDExtensionScriptInstancePropertyStateAdd)(GDExtensionConstString
typedef void (*GDExtensionScriptInstanceGetPropertyState)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionScriptInstancePropertyStateAdd p_add_func, void *p_userdata);
typedef const GDExtensionMethodInfo *(*GDExtensionScriptInstanceGetMethodList)(GDExtensionScriptInstanceDataPtr p_instance, uint32_t *r_count);
typedef void (*GDExtensionScriptInstanceFreeMethodList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionMethodInfo *p_list);
typedef void (*GDExtensionScriptInstanceFreeMethodList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionMethodInfo *p_list); // Deprecated. Use GDExtensionScriptInstanceFreeMethodList2 instead.
typedef void (*GDExtensionScriptInstanceFreeMethodList2)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionMethodInfo *p_list, uint32_t p_count);
typedef GDExtensionBool (*GDExtensionScriptInstanceHasMethod)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name);
@ -554,7 +556,7 @@ typedef struct {
GDExtensionScriptInstanceFree free_func;
} GDExtensionScriptInstanceInfo; // Deprecated. Use GDExtensionScriptInstanceInfo2 instead.
} GDExtensionScriptInstanceInfo; // Deprecated. Use GDExtensionScriptInstanceInfo3 instead.
typedef struct {
GDExtensionScriptInstanceSet set_func;
@ -595,7 +597,48 @@ typedef struct {
GDExtensionScriptInstanceFree free_func;
} GDExtensionScriptInstanceInfo2;
} GDExtensionScriptInstanceInfo2; // Deprecated. Use GDExtensionScriptInstanceInfo3 instead.
typedef struct {
GDExtensionScriptInstanceSet set_func;
GDExtensionScriptInstanceGet get_func;
GDExtensionScriptInstanceGetPropertyList get_property_list_func;
GDExtensionScriptInstanceFreePropertyList2 free_property_list_func;
GDExtensionScriptInstanceGetClassCategory get_class_category_func; // Optional. Set to NULL for the default behavior.
GDExtensionScriptInstancePropertyCanRevert property_can_revert_func;
GDExtensionScriptInstancePropertyGetRevert property_get_revert_func;
GDExtensionScriptInstanceGetOwner get_owner_func;
GDExtensionScriptInstanceGetPropertyState get_property_state_func;
GDExtensionScriptInstanceGetMethodList get_method_list_func;
GDExtensionScriptInstanceFreeMethodList2 free_method_list_func;
GDExtensionScriptInstanceGetPropertyType get_property_type_func;
GDExtensionScriptInstanceValidateProperty validate_property_func;
GDExtensionScriptInstanceHasMethod has_method_func;
GDExtensionScriptInstanceCall call_func;
GDExtensionScriptInstanceNotification2 notification_func;
GDExtensionScriptInstanceToString to_string_func;
GDExtensionScriptInstanceRefCountIncremented refcount_incremented_func;
GDExtensionScriptInstanceRefCountDecremented refcount_decremented_func;
GDExtensionScriptInstanceGetScript get_script_func;
GDExtensionScriptInstanceIsPlaceholder is_placeholder_func;
GDExtensionScriptInstanceSet set_fallback_func;
GDExtensionScriptInstanceGet get_fallback_func;
GDExtensionScriptInstanceGetLanguage get_language_func;
GDExtensionScriptInstanceFree free_func;
} GDExtensionScriptInstanceInfo3;
/* INITIALIZATION */
@ -2380,7 +2423,7 @@ typedef void (*GDExtensionInterfaceRefSetObject)(GDExtensionRefPtr p_ref, GDExte
/**
* @name script_instance_create
* @since 4.1
* @deprecated in Godot 4.2. Use `script_instance_create2` instead.
* @deprecated in Godot 4.2. Use `script_instance_create3` instead.
*
* Creates a script instance that contains the given info and instance data.
*
@ -2394,6 +2437,7 @@ typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate)
/**
* @name script_instance_create2
* @since 4.2
* @deprecated in Godot 4.3. Use `script_instance_create3` instead.
*
* Creates a script instance that contains the given info and instance data.
*
@ -2404,6 +2448,19 @@ typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate)
*/
typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate2)(const GDExtensionScriptInstanceInfo2 *p_info, GDExtensionScriptInstanceDataPtr p_instance_data);
/**
* @name script_instance_create3
* @since 4.3
*
* Creates a script instance that contains the given info and instance data.
*
* @param p_info A pointer to a GDExtensionScriptInstanceInfo3 struct.
* @param p_instance_data A pointer to a data representing the script instance in the GDExtension. This will be passed to all the function pointers on p_info.
*
* @return A pointer to a ScriptInstanceExtension object.
*/
typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate3)(const GDExtensionScriptInstanceInfo3 *p_info, GDExtensionScriptInstanceDataPtr p_instance_data);
/**
* @name placeholder_script_instance_create
* @since 4.2

View file

@ -655,11 +655,17 @@ VARIANT_ENUM_CAST(ScriptLanguageExtension::CodeCompletionLocation)
class ScriptInstanceExtension : public ScriptInstance {
public:
const GDExtensionScriptInstanceInfo2 *native_info;
const GDExtensionScriptInstanceInfo3 *native_info;
#ifndef DISABLE_DEPRECATED
bool free_native_info = false;
struct {
struct DeprecatedNativeInfo {
GDExtensionScriptInstanceNotification notification_func = nullptr;
} deprecated_native_info;
GDExtensionScriptInstanceFreePropertyList free_property_list_func = nullptr;
GDExtensionScriptInstanceFreeMethodList free_method_list_func = nullptr;
};
DeprecatedNativeInfo *deprecated_native_info = nullptr;
#endif // DISABLE_DEPRECATED
GDExtensionScriptInstanceDataPtr instance = nullptr;
@ -706,7 +712,11 @@ public:
p_list->push_back(PropertyInfo(pinfo[i]));
}
if (native_info->free_property_list_func) {
native_info->free_property_list_func(instance, pinfo);
native_info->free_property_list_func(instance, pinfo, pcount);
#ifndef DISABLE_DEPRECATED
} else if (deprecated_native_info && deprecated_native_info->free_property_list_func) {
deprecated_native_info->free_property_list_func(instance, pinfo);
#endif // DISABLE_DEPRECATED
}
}
}
@ -781,7 +791,11 @@ public:
p_list->push_back(MethodInfo(minfo[i]));
}
if (native_info->free_method_list_func) {
native_info->free_method_list_func(instance, minfo);
native_info->free_method_list_func(instance, minfo, mcount);
#ifndef DISABLE_DEPRECATED
} else if (deprecated_native_info && deprecated_native_info->free_method_list_func) {
deprecated_native_info->free_method_list_func(instance, minfo);
#endif // DISABLE_DEPRECATED
}
}
}
@ -808,8 +822,8 @@ public:
if (native_info->notification_func) {
native_info->notification_func(instance, p_notification, p_reversed);
#ifndef DISABLE_DEPRECATED
} else if (deprecated_native_info.notification_func) {
deprecated_native_info.notification_func(instance, p_notification);
} else if (deprecated_native_info && deprecated_native_info->notification_func) {
deprecated_native_info->notification_func(instance, p_notification);
#endif // DISABLE_DEPRECATED
}
}
@ -885,9 +899,14 @@ public:
if (native_info->free_func) {
native_info->free_func(instance);
}
#ifndef DISABLE_DEPRECATED
if (free_native_info) {
memfree(const_cast<GDExtensionScriptInstanceInfo2 *>(native_info));
memfree(const_cast<GDExtensionScriptInstanceInfo3 *>(native_info));
}
if (deprecated_native_info) {
memfree(deprecated_native_info);
}
#endif // DISABLE_DEPRECATED
}
#if defined(__GNUC__) && !defined(__clang__)