Merge pull request #1239 from dsnopek/gdextension-validate-property-object
Support `_validate_property()`pull/1242/head
commit
6caf4909d4
|
@ -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);
|
||||||
|
@ -298,6 +299,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;
|
||||||
|
@ -374,6 +376,7 @@ typedef GDExtensionBool (*GDExtensionScriptInstanceGet)(GDExtensionScriptInstanc
|
||||||
typedef const GDExtensionPropertyInfo *(*GDExtensionScriptInstanceGetPropertyList)(GDExtensionScriptInstanceDataPtr p_instance, uint32_t *r_count);
|
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);
|
||||||
typedef GDExtensionVariantType (*GDExtensionScriptInstanceGetPropertyType)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionBool *r_is_valid);
|
typedef GDExtensionVariantType (*GDExtensionScriptInstanceGetPropertyType)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionBool *r_is_valid);
|
||||||
|
typedef GDExtensionBool (*GDExtensionScriptInstanceValidateProperty)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionPropertyInfo *p_property);
|
||||||
|
|
||||||
typedef GDExtensionBool (*GDExtensionScriptInstancePropertyCanRevert)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name);
|
typedef GDExtensionBool (*GDExtensionScriptInstancePropertyCanRevert)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name);
|
||||||
typedef GDExtensionBool (*GDExtensionScriptInstancePropertyGetRevert)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
|
typedef GDExtensionBool (*GDExtensionScriptInstancePropertyGetRevert)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
|
||||||
|
@ -460,6 +463,7 @@ typedef struct {
|
||||||
GDExtensionScriptInstanceGetMethodList get_method_list_func;
|
GDExtensionScriptInstanceGetMethodList get_method_list_func;
|
||||||
GDExtensionScriptInstanceFreeMethodList free_method_list_func;
|
GDExtensionScriptInstanceFreeMethodList free_method_list_func;
|
||||||
GDExtensionScriptInstanceGetPropertyType get_property_type_func;
|
GDExtensionScriptInstanceGetPropertyType get_property_type_func;
|
||||||
|
GDExtensionScriptInstanceValidateProperty validate_property_func;
|
||||||
|
|
||||||
GDExtensionScriptInstanceHasMethod has_method_func;
|
GDExtensionScriptInstanceHasMethod has_method_func;
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ protected:
|
||||||
void _get_property_list(List<PropertyInfo> *p_list) const {}
|
void _get_property_list(List<PropertyInfo> *p_list) const {}
|
||||||
bool _property_can_revert(const StringName &p_name) const { return false; }
|
bool _property_can_revert(const StringName &p_name) const { return false; }
|
||||||
bool _property_get_revert(const StringName &p_name, Variant &r_property) const { return false; }
|
bool _property_get_revert(const StringName &p_name, Variant &r_property) const { return false; }
|
||||||
|
void _validate_property(PropertyInfo &p_property) const {}
|
||||||
String _to_string() const { return "[" + String(get_class_static()) + ":" + itos(get_instance_id()) + "]"; }
|
String _to_string() const { return "[" + String(get_class_static()) + ":" + itos(get_instance_id()) + "]"; }
|
||||||
|
|
||||||
static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed) {}
|
static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed) {}
|
||||||
|
@ -69,6 +70,7 @@ protected:
|
||||||
static void free_property_list_bind(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list) {}
|
static void free_property_list_bind(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list) {}
|
||||||
static GDExtensionBool property_can_revert_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name) { return false; }
|
static GDExtensionBool property_can_revert_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name) { return false; }
|
||||||
static GDExtensionBool property_get_revert_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret) { return false; }
|
static GDExtensionBool property_get_revert_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret) { return false; }
|
||||||
|
static GDExtensionBool validate_property_bind(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property) { return false; }
|
||||||
static void to_string_bind(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out) {}
|
static void to_string_bind(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out) {}
|
||||||
|
|
||||||
// The only reason this has to be held here, is when we return results of `_get_property_list` to Godot, we pass
|
// The only reason this has to be held here, is when we return results of `_get_property_list` to Godot, we pass
|
||||||
|
@ -150,6 +152,10 @@ protected:
|
||||||
return (bool(::godot::Wrapped::*)(const ::godot::StringName &p_name, ::godot::Variant &) const) & m_class::_property_get_revert; \
|
return (bool(::godot::Wrapped::*)(const ::godot::StringName &p_name, ::godot::Variant &) const) & m_class::_property_get_revert; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
|
static void (::godot::Wrapped::*_get_validate_property())(::godot::PropertyInfo & p_property) const { \
|
||||||
|
return (void(::godot::Wrapped::*)(::godot::PropertyInfo & p_property) const) & m_class::_validate_property; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
static ::godot::String (::godot::Wrapped::*_get_to_string())() const { \
|
static ::godot::String (::godot::Wrapped::*_get_to_string())() const { \
|
||||||
return (::godot::String(::godot::Wrapped::*)() const) & m_class::_to_string; \
|
return (::godot::String(::godot::Wrapped::*)() const) & m_class::_to_string; \
|
||||||
} \
|
} \
|
||||||
|
@ -267,6 +273,21 @@ public:
|
||||||
return false; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
|
static GDExtensionBool validate_property_bind(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property) { \
|
||||||
|
bool ret = false; \
|
||||||
|
if (p_instance && m_class::_get_validate_property()) { \
|
||||||
|
ret = m_inherits::validate_property_bind(p_instance, p_property); \
|
||||||
|
if (m_class::_get_validate_property() != m_inherits::_get_validate_property()) { \
|
||||||
|
m_class *cls = reinterpret_cast<m_class *>(p_instance); \
|
||||||
|
::godot::PropertyInfo info(p_property); \
|
||||||
|
cls->_validate_property(info); \
|
||||||
|
info._update(p_property); \
|
||||||
|
return true; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
return ret; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
static void to_string_bind(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out) { \
|
static void to_string_bind(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out) { \
|
||||||
if (p_instance && m_class::_get_to_string()) { \
|
if (p_instance && m_class::_get_to_string()) { \
|
||||||
if (m_class::_get_to_string() != m_inherits::_get_to_string()) { \
|
if (m_class::_get_to_string() != m_inherits::_get_to_string()) { \
|
||||||
|
@ -345,6 +366,10 @@ protected:
|
||||||
return nullptr; \
|
return nullptr; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
|
static void (Wrapped::*_get_validate_property())(::godot::PropertyInfo & p_property) const { \
|
||||||
|
return nullptr; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
static String (Wrapped::*_get_to_string())() const { \
|
static String (Wrapped::*_get_to_string())() const { \
|
||||||
return nullptr; \
|
return nullptr; \
|
||||||
} \
|
} \
|
||||||
|
|
|
@ -186,6 +186,7 @@ void ClassDB::_register_class(bool p_virtual, bool p_exposed) {
|
||||||
T::free_property_list_bind, // GDExtensionClassFreePropertyList free_property_list_func;
|
T::free_property_list_bind, // GDExtensionClassFreePropertyList free_property_list_func;
|
||||||
T::property_can_revert_bind, // GDExtensionClassPropertyCanRevert property_can_revert_func;
|
T::property_can_revert_bind, // GDExtensionClassPropertyCanRevert property_can_revert_func;
|
||||||
T::property_get_revert_bind, // GDExtensionClassPropertyGetRevert property_get_revert_func;
|
T::property_get_revert_bind, // GDExtensionClassPropertyGetRevert property_get_revert_func;
|
||||||
|
T::validate_property_bind, // GDExtensionClassValidateProperty validate_property_func;
|
||||||
T::notification_bind, // GDExtensionClassNotification2 notification_func;
|
T::notification_bind, // GDExtensionClassNotification2 notification_func;
|
||||||
T::to_string_bind, // GDExtensionClassToString to_string_func;
|
T::to_string_bind, // GDExtensionClassToString to_string_func;
|
||||||
nullptr, // GDExtensionClassReference reference_func;
|
nullptr, // GDExtensionClassReference reference_func;
|
||||||
|
|
|
@ -68,6 +68,18 @@ struct PropertyInfo {
|
||||||
|
|
||||||
PropertyInfo(GDExtensionVariantType p_type, const StringName &p_name, PropertyHint p_hint = PROPERTY_HINT_NONE, const String &p_hint_string = "", uint32_t p_usage = PROPERTY_USAGE_DEFAULT, const StringName &p_class_name = "") :
|
PropertyInfo(GDExtensionVariantType p_type, const StringName &p_name, PropertyHint p_hint = PROPERTY_HINT_NONE, const String &p_hint_string = "", uint32_t p_usage = PROPERTY_USAGE_DEFAULT, const StringName &p_class_name = "") :
|
||||||
PropertyInfo((Variant::Type)p_type, p_name, p_hint, p_hint_string, p_usage, p_class_name) {}
|
PropertyInfo((Variant::Type)p_type, p_name, p_hint, p_hint_string, p_usage, p_class_name) {}
|
||||||
|
|
||||||
|
PropertyInfo(const GDExtensionPropertyInfo *p_info) :
|
||||||
|
PropertyInfo(p_info->type, *reinterpret_cast<StringName *>(p_info->name), (PropertyHint)p_info->hint, *reinterpret_cast<String *>(p_info->hint_string), p_info->usage, *reinterpret_cast<StringName *>(p_info->class_name)) {}
|
||||||
|
|
||||||
|
void _update(GDExtensionPropertyInfo *p_info) {
|
||||||
|
p_info->type = (GDExtensionVariantType)type;
|
||||||
|
*(reinterpret_cast<StringName *>(p_info->name)) = name;
|
||||||
|
p_info->hint = hint;
|
||||||
|
*(reinterpret_cast<String *>(p_info->hint_string)) = hint_string;
|
||||||
|
p_info->usage = usage;
|
||||||
|
*(reinterpret_cast<StringName *>(p_info->class_name)) = class_name;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|
|
@ -23,6 +23,10 @@ func _ready():
|
||||||
# Property list.
|
# Property list.
|
||||||
example.property_from_list = Vector3(100, 200, 300)
|
example.property_from_list = Vector3(100, 200, 300)
|
||||||
assert_equal(example.property_from_list, Vector3(100, 200, 300))
|
assert_equal(example.property_from_list, Vector3(100, 200, 300))
|
||||||
|
var prop_list = example.get_property_list()
|
||||||
|
for prop_info in prop_list:
|
||||||
|
if prop_info['name'] == 'mouse_filter':
|
||||||
|
assert_equal(prop_info['usage'], PROPERTY_USAGE_NO_EDITOR)
|
||||||
|
|
||||||
# Call simple methods.
|
# Call simple methods.
|
||||||
example.simple_func()
|
example.simple_func()
|
||||||
|
|
|
@ -117,6 +117,14 @@ bool Example::_property_get_revert(const StringName &p_name, Variant &r_property
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void Example::_validate_property(PropertyInfo &p_property) const {
|
||||||
|
String name = p_property.name;
|
||||||
|
// Test hiding the "mouse_filter" property from the editor.
|
||||||
|
if (name == "mouse_filter") {
|
||||||
|
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Example::_bind_methods() {
|
void Example::_bind_methods() {
|
||||||
// Methods.
|
// Methods.
|
||||||
ClassDB::bind_method(D_METHOD("simple_func"), &Example::simple_func);
|
ClassDB::bind_method(D_METHOD("simple_func"), &Example::simple_func);
|
||||||
|
|
|
@ -65,6 +65,7 @@ protected:
|
||||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||||
bool _property_can_revert(const StringName &p_name) const;
|
bool _property_can_revert(const StringName &p_name) const;
|
||||||
bool _property_get_revert(const StringName &p_name, Variant &r_property) const;
|
bool _property_get_revert(const StringName &p_name, Variant &r_property) const;
|
||||||
|
void _validate_property(PropertyInfo &p_property) const;
|
||||||
|
|
||||||
String _to_string() const;
|
String _to_string() const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue