Skip to content

Commit aa6867e

Browse files
committed
Support _validate_property()
1 parent 16ffb27 commit aa6867e

File tree

7 files changed

+55
-0
lines changed

7 files changed

+55
-0
lines changed

gdextension/gdextension_interface.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ typedef const GDExtensionPropertyInfo *(*GDExtensionClassGetPropertyList)(GDExte
258258
typedef void (*GDExtensionClassFreePropertyList)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list);
259259
typedef GDExtensionBool (*GDExtensionClassPropertyCanRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name);
260260
typedef GDExtensionBool (*GDExtensionClassPropertyGetRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
261+
typedef GDExtensionBool (*GDExtensionClassValidateProperty)(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property);
261262
typedef void (*GDExtensionClassNotification)(GDExtensionClassInstancePtr p_instance, int32_t p_what); // Deprecated. Use GDExtensionClassNotification2 instead.
262263
typedef void (*GDExtensionClassNotification2)(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed);
263264
typedef void (*GDExtensionClassToString)(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr p_out);
@@ -298,6 +299,7 @@ typedef struct {
298299
GDExtensionClassFreePropertyList free_property_list_func;
299300
GDExtensionClassPropertyCanRevert property_can_revert_func;
300301
GDExtensionClassPropertyGetRevert property_get_revert_func;
302+
GDExtensionClassValidateProperty validate_property_func;
301303
GDExtensionClassNotification2 notification_func;
302304
GDExtensionClassToString to_string_func;
303305
GDExtensionClassReference reference_func;
@@ -374,6 +376,7 @@ typedef GDExtensionBool (*GDExtensionScriptInstanceGet)(GDExtensionScriptInstanc
374376
typedef const GDExtensionPropertyInfo *(*GDExtensionScriptInstanceGetPropertyList)(GDExtensionScriptInstanceDataPtr p_instance, uint32_t *r_count);
375377
typedef void (*GDExtensionScriptInstanceFreePropertyList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionPropertyInfo *p_list);
376378
typedef GDExtensionVariantType (*GDExtensionScriptInstanceGetPropertyType)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionBool *r_is_valid);
379+
typedef GDExtensionBool (*GDExtensionScriptInstanceValidateProperty)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionPropertyInfo *p_property);
377380

378381
typedef GDExtensionBool (*GDExtensionScriptInstancePropertyCanRevert)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name);
379382
typedef GDExtensionBool (*GDExtensionScriptInstancePropertyGetRevert)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
@@ -460,6 +463,7 @@ typedef struct {
460463
GDExtensionScriptInstanceGetMethodList get_method_list_func;
461464
GDExtensionScriptInstanceFreeMethodList free_method_list_func;
462465
GDExtensionScriptInstanceGetPropertyType get_property_type_func;
466+
GDExtensionScriptInstanceValidateProperty validate_property_func;
463467

464468
GDExtensionScriptInstanceHasMethod has_method_func;
465469

include/godot_cpp/classes/wrapped.hpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class Wrapped {
6060
void _get_property_list(List<PropertyInfo> *p_list) const {}
6161
bool _property_can_revert(const StringName &p_name) const { return false; }
6262
bool _property_get_revert(const StringName &p_name, Variant &r_property) const { return false; }
63+
void _validate_property(PropertyInfo &p_property) const {}
6364
String _to_string() const { return "[" + String(get_class_static()) + ":" + itos(get_instance_id()) + "]"; }
6465

6566
static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed) {}
@@ -69,6 +70,7 @@ class Wrapped {
6970
static void free_property_list_bind(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list) {}
7071
static GDExtensionBool property_can_revert_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name) { return false; }
7172
static GDExtensionBool property_get_revert_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret) { return false; }
73+
static GDExtensionBool validate_property_bind(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property) { return false; }
7274
static void to_string_bind(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out) {}
7375

7476
// 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:
150152
return (bool(::godot::Wrapped::*)(const ::godot::StringName &p_name, ::godot::Variant &) const) & m_class::_property_get_revert; \
151153
} \
152154
\
155+
static void (::godot::Wrapped::*_get_validate_property())(::godot::PropertyInfo & p_property) const { \
156+
return (void(::godot::Wrapped::*)(::godot::PropertyInfo & p_property) const) & m_class::_validate_property; \
157+
} \
158+
\
153159
static ::godot::String (::godot::Wrapped::*_get_to_string())() const { \
154160
return (::godot::String(::godot::Wrapped::*)() const) & m_class::_to_string; \
155161
} \
@@ -267,6 +273,21 @@ public:
267273
return false; \
268274
} \
269275
\
276+
static GDExtensionBool validate_property_bind(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property) { \
277+
bool ret = false; \
278+
if (p_instance && m_class::_get_validate_property()) { \
279+
ret = m_inherits::validate_property_bind(p_instance, p_property); \
280+
if (m_class::_get_validate_property() != m_inherits::_get_validate_property()) { \
281+
m_class *cls = reinterpret_cast<m_class *>(p_instance); \
282+
::godot::PropertyInfo info(p_property); \
283+
cls->_validate_property(info); \
284+
info._update(p_property); \
285+
return true; \
286+
} \
287+
} \
288+
return ret; \
289+
} \
290+
\
270291
static void to_string_bind(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out) { \
271292
if (p_instance && m_class::_get_to_string()) { \
272293
if (m_class::_get_to_string() != m_inherits::_get_to_string()) { \
@@ -345,6 +366,10 @@ protected:
345366
return nullptr; \
346367
} \
347368
\
369+
static void (Wrapped::*_get_validate_property())(::godot::PropertyInfo & p_property) const { \
370+
return nullptr; \
371+
} \
372+
\
348373
static String (Wrapped::*_get_to_string())() const { \
349374
return nullptr; \
350375
} \

include/godot_cpp/core/class_db.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ void ClassDB::_register_class(bool p_virtual, bool p_exposed) {
186186
T::free_property_list_bind, // GDExtensionClassFreePropertyList free_property_list_func;
187187
T::property_can_revert_bind, // GDExtensionClassPropertyCanRevert property_can_revert_func;
188188
T::property_get_revert_bind, // GDExtensionClassPropertyGetRevert property_get_revert_func;
189+
T::validate_property_bind, // GDExtensionClassValidateProperty validate_property_func;
189190
T::notification_bind, // GDExtensionClassNotification2 notification_func;
190191
T::to_string_bind, // GDExtensionClassToString to_string_func;
191192
nullptr, // GDExtensionClassReference reference_func;

include/godot_cpp/core/property_info.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,18 @@ struct PropertyInfo {
6868

6969
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 = "") :
7070
PropertyInfo((Variant::Type)p_type, p_name, p_hint, p_hint_string, p_usage, p_class_name) {}
71+
72+
PropertyInfo(const GDExtensionPropertyInfo *p_info) :
73+
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)) {}
74+
75+
void _update(GDExtensionPropertyInfo *p_info) {
76+
p_info->type = (GDExtensionVariantType)type;
77+
*(reinterpret_cast<StringName *>(p_info->name)) = name;
78+
p_info->hint = hint;
79+
*(reinterpret_cast<String *>(p_info->hint_string)) = hint_string;
80+
p_info->usage = usage;
81+
*(reinterpret_cast<StringName *>(p_info->class_name)) = class_name;
82+
}
7183
};
7284

7385
} // namespace godot

test/project/main.gd

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ func _ready():
2323
# Property list.
2424
example.property_from_list = Vector3(100, 200, 300)
2525
assert_equal(example.property_from_list, Vector3(100, 200, 300))
26+
var prop_list = example.get_property_list()
27+
for prop_info in prop_list:
28+
if prop_info['name'] == 'mouse_filter':
29+
assert_equal(prop_info['usage'], PROPERTY_USAGE_NO_EDITOR)
2630

2731
# Call simple methods.
2832
example.simple_func()

test/src/example.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,14 @@ bool Example::_property_get_revert(const StringName &p_name, Variant &r_property
117117
}
118118
};
119119

120+
void Example::_validate_property(PropertyInfo &p_property) const {
121+
String name = p_property.name;
122+
// Test hiding the "mouse_filter" property from the editor.
123+
if (name == "mouse_filter") {
124+
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
125+
}
126+
}
127+
120128
void Example::_bind_methods() {
121129
// Methods.
122130
ClassDB::bind_method(D_METHOD("simple_func"), &Example::simple_func);

test/src/example.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class Example : public Control {
6565
void _get_property_list(List<PropertyInfo> *p_list) const;
6666
bool _property_can_revert(const StringName &p_name) const;
6767
bool _property_get_revert(const StringName &p_name, Variant &r_property) const;
68+
void _validate_property(PropertyInfo &p_property) const;
6869

6970
String _to_string() const;
7071

0 commit comments

Comments
 (0)