Allow implementing `Object::_validate_property()` from GDExtension

This commit is contained in:
David Snopek 2023-09-09 13:05:16 -05:00
parent fc99492d30
commit abef8e3874
5 changed files with 29 additions and 1 deletions

View File

@ -292,6 +292,7 @@ void GDExtension::_register_extension_class(GDExtensionClassLibraryPtr p_library
p_extension_funcs->free_property_list_func, // GDExtensionClassFreePropertyList free_property_list_func; p_extension_funcs->free_property_list_func, // GDExtensionClassFreePropertyList free_property_list_func;
p_extension_funcs->property_can_revert_func, // GDExtensionClassPropertyCanRevert property_can_revert_func; p_extension_funcs->property_can_revert_func, // GDExtensionClassPropertyCanRevert property_can_revert_func;
p_extension_funcs->property_get_revert_func, // GDExtensionClassPropertyGetRevert property_get_revert_func; p_extension_funcs->property_get_revert_func, // GDExtensionClassPropertyGetRevert property_get_revert_func;
nullptr, // GDExtensionClassValidateProperty validate_property_func;
nullptr, // GDExtensionClassNotification2 notification_func; nullptr, // GDExtensionClassNotification2 notification_func;
p_extension_funcs->to_string_func, // GDExtensionClassToString to_string_func; p_extension_funcs->to_string_func, // GDExtensionClassToString to_string_func;
p_extension_funcs->reference_func, // GDExtensionClassReference reference_func; p_extension_funcs->reference_func, // GDExtensionClassReference reference_func;
@ -358,6 +359,7 @@ void GDExtension::_register_extension_class_internal(GDExtensionClassLibraryPtr
extension->gdextension.free_property_list = p_extension_funcs->free_property_list_func; extension->gdextension.free_property_list = p_extension_funcs->free_property_list_func;
extension->gdextension.property_can_revert = p_extension_funcs->property_can_revert_func; extension->gdextension.property_can_revert = p_extension_funcs->property_can_revert_func;
extension->gdextension.property_get_revert = p_extension_funcs->property_get_revert_func; extension->gdextension.property_get_revert = p_extension_funcs->property_get_revert_func;
extension->gdextension.validate_property = p_extension_funcs->validate_property_func;
#ifndef DISABLE_DEPRECATED #ifndef DISABLE_DEPRECATED
if (p_deprecated_funcs) { if (p_deprecated_funcs) {
extension->gdextension.notification = p_deprecated_funcs->notification_func; extension->gdextension.notification = p_deprecated_funcs->notification_func;

View File

@ -258,6 +258,7 @@ typedef const GDExtensionPropertyInfo *(*GDExtensionClassGetPropertyList)(GDExte
typedef void (*GDExtensionClassFreePropertyList)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list); typedef void (*GDExtensionClassFreePropertyList)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list);
typedef GDExtensionBool (*GDExtensionClassPropertyCanRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name); typedef GDExtensionBool (*GDExtensionClassPropertyCanRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name);
typedef GDExtensionBool (*GDExtensionClassPropertyGetRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret); typedef GDExtensionBool (*GDExtensionClassPropertyGetRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
typedef GDExtensionBool (*GDExtensionClassValidateProperty)(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property);
typedef void (*GDExtensionClassNotification)(GDExtensionClassInstancePtr p_instance, int32_t p_what); // Deprecated. Use GDExtensionClassNotification2 instead. typedef void (*GDExtensionClassNotification)(GDExtensionClassInstancePtr p_instance, int32_t p_what); // Deprecated. Use GDExtensionClassNotification2 instead.
typedef void (*GDExtensionClassNotification2)(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed); typedef void (*GDExtensionClassNotification2)(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed);
typedef void (*GDExtensionClassToString)(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr p_out); typedef void (*GDExtensionClassToString)(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr p_out);
@ -297,6 +298,7 @@ typedef struct {
GDExtensionClassFreePropertyList free_property_list_func; GDExtensionClassFreePropertyList free_property_list_func;
GDExtensionClassPropertyCanRevert property_can_revert_func; GDExtensionClassPropertyCanRevert property_can_revert_func;
GDExtensionClassPropertyGetRevert property_get_revert_func; GDExtensionClassPropertyGetRevert property_get_revert_func;
GDExtensionClassValidateProperty validate_property_func;
GDExtensionClassNotification2 notification_func; GDExtensionClassNotification2 notification_func;
GDExtensionClassToString to_string_func; GDExtensionClassToString to_string_func;
GDExtensionClassReference reference_func; GDExtensionClassReference reference_func;

View File

@ -527,6 +527,27 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons
void Object::validate_property(PropertyInfo &p_property) const { void Object::validate_property(PropertyInfo &p_property) const {
_validate_propertyv(p_property); _validate_propertyv(p_property);
if (_extension && _extension->validate_property) {
// GDExtension uses a StringName rather than a String for property name.
StringName prop_name = p_property.name;
GDExtensionPropertyInfo gdext_prop = {
(GDExtensionVariantType)p_property.type,
&prop_name,
&p_property.class_name,
(uint32_t)p_property.hint,
&p_property.hint_string,
p_property.usage,
};
if (_extension->validate_property(_extension_instance, &gdext_prop)) {
p_property.type = (Variant::Type)gdext_prop.type;
p_property.name = *reinterpret_cast<StringName *>(gdext_prop.name);
p_property.class_name = *reinterpret_cast<StringName *>(gdext_prop.class_name);
p_property.hint = (PropertyHint)gdext_prop.hint;
p_property.hint_string = *reinterpret_cast<String *>(gdext_prop.hint_string);
p_property.usage = gdext_prop.usage;
};
}
if (script_instance) { // Call it last to allow user altering already validated properties. if (script_instance) { // Call it last to allow user altering already validated properties.
script_instance->validate_property(p_property); script_instance->validate_property(p_property);
} }

View File

@ -321,6 +321,7 @@ struct ObjectGDExtension {
GDExtensionClassFreePropertyList free_property_list; GDExtensionClassFreePropertyList free_property_list;
GDExtensionClassPropertyCanRevert property_can_revert; GDExtensionClassPropertyCanRevert property_can_revert;
GDExtensionClassPropertyGetRevert property_get_revert; GDExtensionClassPropertyGetRevert property_get_revert;
GDExtensionClassValidateProperty validate_property;
#ifndef DISABLE_DEPRECATED #ifndef DISABLE_DEPRECATED
GDExtensionClassNotification notification; GDExtensionClassNotification notification;
#endif // DISABLE_DEPRECATED #endif // DISABLE_DEPRECATED

View File

@ -689,9 +689,11 @@ public:
} }
virtual void validate_property(PropertyInfo &p_property) const override { virtual void validate_property(PropertyInfo &p_property) const override {
if (native_info->validate_property_func) { if (native_info->validate_property_func) {
// GDExtension uses a StringName rather than a String for property name.
StringName prop_name = p_property.name;
GDExtensionPropertyInfo gdext_prop = { GDExtensionPropertyInfo gdext_prop = {
(GDExtensionVariantType)p_property.type, (GDExtensionVariantType)p_property.type,
&p_property.name, &prop_name,
&p_property.class_name, &p_property.class_name,
(uint32_t)p_property.hint, (uint32_t)p_property.hint,
&p_property.hint_string, &p_property.hint_string,