Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow implementing Object::_validate_property() from GDExtension #81515

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions core/extension/gdextension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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->property_can_revert_func, // GDExtensionClassPropertyCanRevert property_can_revert_func;
p_extension_funcs->property_get_revert_func, // GDExtensionClassPropertyGetRevert property_get_revert_func;
nullptr, // GDExtensionClassValidateProperty validate_property_func;
nullptr, // GDExtensionClassNotification2 notification_func;
p_extension_funcs->to_string_func, // GDExtensionClassToString to_string_func;
p_extension_funcs->reference_func, // GDExtensionClassReference reference_func;
Expand Down Expand Up @@ -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.property_can_revert = p_extension_funcs->property_can_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
if (p_deprecated_funcs) {
extension->gdextension.notification = p_deprecated_funcs->notification_func;
Expand Down
2 changes: 2 additions & 0 deletions core/extension/gdextension_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ typedef const GDExtensionPropertyInfo *(*GDExtensionClassGetPropertyList)(GDExte
typedef void (*GDExtensionClassFreePropertyList)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list);
typedef GDExtensionBool (*GDExtensionClassPropertyCanRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name);
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 (*GDExtensionClassNotification2)(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed);
typedef void (*GDExtensionClassToString)(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr p_out);
Expand Down Expand Up @@ -297,6 +298,7 @@ typedef struct {
GDExtensionClassFreePropertyList free_property_list_func;
GDExtensionClassPropertyCanRevert property_can_revert_func;
GDExtensionClassPropertyGetRevert property_get_revert_func;
GDExtensionClassValidateProperty validate_property_func;
GDExtensionClassNotification2 notification_func;
GDExtensionClassToString to_string_func;
GDExtensionClassReference reference_func;
Expand Down
21 changes: 21 additions & 0 deletions core/object/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
_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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding these StringName manipulations, should we share similar concerns to other extended Object methods around here? There is this whole preprocessor pragma guard every time we cast to GDExtensionStringNamePtr. We don't do it here, not directly at least, but maybe we should? And maybe we should add the same guards?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the #pragma stuff is about the constness in those casts. In the code added in this PR, we don't need to mess with const, so I think it's OK? And running locally with GCC, I don't see any warnings.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, sounds fine then. I don't really understand this myself, so I'm trusting you :)

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.
script_instance->validate_property(p_property);
}
Expand Down
1 change: 1 addition & 0 deletions core/object/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ struct ObjectGDExtension {
GDExtensionClassFreePropertyList free_property_list;
GDExtensionClassPropertyCanRevert property_can_revert;
GDExtensionClassPropertyGetRevert property_get_revert;
GDExtensionClassValidateProperty validate_property;
#ifndef DISABLE_DEPRECATED
GDExtensionClassNotification notification;
#endif // DISABLE_DEPRECATED
Expand Down
4 changes: 3 additions & 1 deletion core/object/script_language_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -689,9 +689,11 @@ class ScriptInstanceExtension : public ScriptInstance {
}
virtual void validate_property(PropertyInfo &p_property) const override {
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 = {
(GDExtensionVariantType)p_property.type,
&p_property.name,
&prop_name,
&p_property.class_name,
(uint32_t)p_property.hint,
&p_property.hint_string,
Expand Down
Loading