From 36273baa7e6210d9e353144442d2699659eb1684 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Fri, 2 Sep 2022 10:41:24 +0300 Subject: [PATCH] Change PropertyInfo members to String. --- include/godot_cpp/classes/ref.hpp | 12 ++-- include/godot_cpp/classes/wrapped.hpp | 6 +- include/godot_cpp/core/class_db.hpp | 7 ++ include/godot_cpp/core/method_bind.hpp | 48 +++++++++---- include/godot_cpp/core/property_info.hpp | 21 ++---- include/godot_cpp/core/type_info.hpp | 87 ++++++++++++++---------- src/core/class_db.cpp | 32 ++++++--- test/src/example.cpp | 19 +++++- test/src/example.h | 1 + 9 files changed, 145 insertions(+), 88 deletions(-) diff --git a/include/godot_cpp/classes/ref.hpp b/include/godot_cpp/classes/ref.hpp index 671551fd..0e65f48d 100644 --- a/include/godot_cpp/classes/ref.hpp +++ b/include/godot_cpp/classes/ref.hpp @@ -240,7 +240,7 @@ public: template struct PtrToArg> { _FORCE_INLINE_ static Ref convert(const void *p_ptr) { - return Ref(reinterpret_cast(godot::internal::gdn_interface->object_get_instance_binding(*(const GDNativeObjectPtr *)p_ptr, godot::internal::token, &T::___binding_callbacks))); + return Ref(reinterpret_cast(godot::internal::gdn_interface->object_get_instance_binding(*(const GDNativeObjectPtr *)p_ptr, godot::internal::token, &T::___binding_callbacks))); } typedef Ref EncodeT; @@ -255,7 +255,7 @@ struct PtrToArg &> { typedef Ref EncodeT; _FORCE_INLINE_ static Ref convert(const void *p_ptr) { - return Ref(reinterpret_cast(godot::internal::gdn_interface->object_get_instance_binding(*(const GDNativeObjectPtr *)p_ptr, godot::internal::token, &T::___binding_callbacks))); + return Ref(reinterpret_cast(godot::internal::gdn_interface->object_get_instance_binding(*(const GDNativeObjectPtr *)p_ptr, godot::internal::token, &T::___binding_callbacks))); } }; @@ -264,8 +264,8 @@ struct GetTypeInfo, typename EnableIf::value> static const GDNativeVariantType VARIANT_TYPE = GDNATIVE_VARIANT_TYPE_OBJECT; static const GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; - static inline PropertyInfo get_class_info() { - return PropertyInfo(GDNATIVE_VARIANT_TYPE_OBJECT, T::get_class_static()); + static inline GDNativePropertyInfo get_class_info() { + return make_property_info(GDNATIVE_VARIANT_TYPE_OBJECT, T::get_class_static()); } }; @@ -274,8 +274,8 @@ struct GetTypeInfo &, typename EnableIf static const GDNativeVariantType VARIANT_TYPE = GDNATIVE_VARIANT_TYPE_OBJECT; static const GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; - static inline PropertyInfo get_class_info() { - return PropertyInfo(GDNATIVE_VARIANT_TYPE_OBJECT, T::get_class_static()); + static inline GDNativePropertyInfo get_class_info() { + return make_property_info(GDNATIVE_VARIANT_TYPE_OBJECT, T::get_class_static()); } }; diff --git a/include/godot_cpp/classes/wrapped.hpp b/include/godot_cpp/classes/wrapped.hpp index cfbf6c0f..78813840 100644 --- a/include/godot_cpp/classes/wrapped.hpp +++ b/include/godot_cpp/classes/wrapped.hpp @@ -220,10 +220,10 @@ public: cls->plist_size = 0; \ for (const ::godot::PropertyInfo &E : list) { \ cls->plist[cls->plist_size].type = E.type; \ - cls->plist[cls->plist_size].name = _alloc_and_copy_cstr(E.name); \ + cls->plist[cls->plist_size].name = _alloc_and_copy_cstr(E.name.utf8().get_data()); \ cls->plist[cls->plist_size].hint = E.hint; \ - cls->plist[cls->plist_size].hint_string = _alloc_and_copy_cstr(E.hint_string); \ - cls->plist[cls->plist_size].class_name = _alloc_and_copy_cstr(E.class_name); \ + cls->plist[cls->plist_size].hint_string = _alloc_and_copy_cstr(E.hint_string.utf8().get_data()); \ + cls->plist[cls->plist_size].class_name = _alloc_and_copy_cstr(E.class_name.utf8().get_data()); \ cls->plist[cls->plist_size].usage = E.usage; \ cls->plist_size++; \ } \ diff --git a/include/godot_cpp/core/class_db.hpp b/include/godot_cpp/core/class_db.hpp index 02e7a795..fd8be1ec 100644 --- a/include/godot_cpp/core/class_db.hpp +++ b/include/godot_cpp/core/class_db.hpp @@ -99,6 +99,13 @@ private: static void initialize_class(const ClassInfo &cl); static void bind_method_godot(const char *p_class_name, MethodBind *p_method); + static _FORCE_INLINE_ char *_alloc_and_copy_cstr(const char *p_str) { + size_t size = strlen(p_str) + 1; + char *ret = reinterpret_cast(memalloc(size)); + memcpy(ret, p_str, size); + return ret; + } + public: template static void register_class(); diff --git a/include/godot_cpp/core/method_bind.hpp b/include/godot_cpp/core/method_bind.hpp index cc332f1c..1bf410be 100644 --- a/include/godot_cpp/core/method_bind.hpp +++ b/include/godot_cpp/core/method_bind.hpp @@ -136,16 +136,16 @@ class MethodBindVarArgBase : public MethodBind { protected: R(T::*method) (const Variant **, GDNativeInt, GDNativeCallError &); - MethodInfo method_info; + std::vector arguments; public: virtual GDNativePropertyInfo gen_argument_type_info(int p_arg) const { if (p_arg < 0) { return _gen_return_type_info(); - } else if (p_arg < method_info.arguments.size()) { - return method_info.arguments[p_arg]; + } else if (p_arg < arguments.size()) { + return arguments[p_arg]; } else { - return PropertyInfo(Variant::NIL, "vararg", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT); + return make_property_info(GDNATIVE_VARIANT_TYPE_NIL, "vararg", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT); } } @@ -161,31 +161,51 @@ public: ERR_FAIL(); // Can't call. } + static _FORCE_INLINE_ char *_alloc_and_copy_cstr(const char *p_str) { + size_t size = strlen(p_str) + 1; + char *ret = reinterpret_cast(memalloc(size)); + memcpy(ret, p_str, size); + return ret; + } + MethodBindVarArgBase( R (T::*p_method)(const Variant **, GDNativeInt, GDNativeCallError &), const MethodInfo &p_method_info, bool p_return_nil_is_variant) : - method(p_method), method_info(p_method_info) { + method(p_method) { set_vararg(true); set_const(true); - set_argument_count(method_info.arguments.size()); - if (method_info.arguments.size()) { + set_argument_count(p_method_info.arguments.size()); + if (p_method_info.arguments.size()) { std::vector names; - names.reserve(method_info.arguments.size()); - for (int i = 0; i < method_info.arguments.size(); i++) { - names.push_back(method_info.arguments[i].name); + names.reserve(p_method_info.arguments.size()); + for (int i = 0; i < p_method_info.arguments.size(); i++) { + names.push_back(p_method_info.arguments[i].name.utf8().get_data()); + arguments.push_back(GDNativePropertyInfo{ + static_cast(p_method_info.arguments[i].type), // uint32_t type; + _alloc_and_copy_cstr(p_method_info.arguments[i].name.utf8().get_data()), // const char *name; + _alloc_and_copy_cstr(p_method_info.arguments[i].class_name.utf8().get_data()), // const char *class_name; + p_method_info.arguments[i].hint, // NONE //uint32_t hint; + _alloc_and_copy_cstr(p_method_info.arguments[i].hint_string.utf8().get_data()), // const char *hint_string; + p_method_info.arguments[i].usage, // DEFAULT //uint32_t usage; + }); } set_argument_names(names); } - if (p_return_nil_is_variant) { - method_info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; - } - generate_argument_types((int)method_info.arguments.size()); + generate_argument_types((int)p_method_info.arguments.size()); set_return(should_returns); } + ~MethodBindVarArgBase() { + for (GDNativePropertyInfo &arg : arguments) { + memfree(const_cast(arg.name)); + memfree(const_cast(arg.class_name)); + memfree(const_cast(arg.hint_string)); + } + } + private: GDNativePropertyInfo _gen_return_type_info() const { return reinterpret_cast(this)->_gen_return_type_info_impl(); diff --git a/include/godot_cpp/core/property_info.hpp b/include/godot_cpp/core/property_info.hpp index 4bdf31a7..69d7fb51 100644 --- a/include/godot_cpp/core/property_info.hpp +++ b/include/godot_cpp/core/property_info.hpp @@ -45,26 +45,15 @@ namespace godot { struct PropertyInfo { Variant::Type type = Variant::NIL; - const char *name = nullptr; - const char *class_name = nullptr; + String name; + String class_name; uint32_t hint = 0; - const char *hint_string = nullptr; + String hint_string; uint32_t usage = 7; - operator GDNativePropertyInfo() const { - GDNativePropertyInfo info; - info.type = type; - info.name = name; - info.hint = hint; - info.hint_string = hint_string; - info.class_name = class_name; - info.usage = usage; - return info; - } - PropertyInfo() = default; - PropertyInfo(Variant::Type p_type, const char *p_name, PropertyHint p_hint = PROPERTY_HINT_NONE, const char *p_hint_string = "", uint32_t p_usage = PROPERTY_USAGE_DEFAULT, const char *p_class_name = "") : + PropertyInfo(Variant::Type p_type, const String &p_name, PropertyHint p_hint = PROPERTY_HINT_NONE, const String &p_hint_string = "", uint32_t p_usage = PROPERTY_USAGE_DEFAULT, const String &p_class_name = "") : type(p_type), name(p_name), hint(p_hint), @@ -77,7 +66,7 @@ struct PropertyInfo { } } - PropertyInfo(GDNativeVariantType p_type, const char *p_name, PropertyHint p_hint = PROPERTY_HINT_NONE, const char *p_hint_string = "", uint32_t p_usage = PROPERTY_USAGE_DEFAULT, const char *p_class_name = "") : + PropertyInfo(GDNativeVariantType p_type, const String &p_name, PropertyHint p_hint = PROPERTY_HINT_NONE, const String &p_hint_string = "", uint32_t p_usage = PROPERTY_USAGE_DEFAULT, const String &p_class_name = "") : PropertyInfo((Variant::Type)p_type, p_name, p_hint, p_hint_string, p_usage, p_class_name) {} }; diff --git a/include/godot_cpp/core/type_info.hpp b/include/godot_cpp/core/type_info.hpp index 99a8cbd2..5ee81f25 100644 --- a/include/godot_cpp/core/type_info.hpp +++ b/include/godot_cpp/core/type_info.hpp @@ -68,6 +68,21 @@ struct TypeInherits { !TypesAreSame::value; }; +static GDNativePropertyInfo make_property_info(GDNativeVariantType p_type, const char *p_name, uint32_t p_hint = PROPERTY_HINT_NONE, const char *p_hint_string = "", uint32_t p_usage = PROPERTY_USAGE_DEFAULT, const char *p_class_name = "") { + GDNativePropertyInfo info; + info.type = p_type; + info.name = p_name; + info.hint = p_hint; + info.hint_string = p_hint_string; + info.usage = p_usage; + if (p_hint == PROPERTY_HINT_RESOURCE_TYPE) { + info.class_name = p_hint_string; + } else { + info.class_name = p_class_name; + } + return info; +} + // If the compiler fails because it's trying to instantiate the primary 'GetTypeInfo' template // instead of one of the specializations, it's most likely because the type 'T' is not supported. // If 'T' is a class that inherits 'Object', make sure it can see the actual class declaration @@ -83,7 +98,7 @@ struct GetTypeInfo; static constexpr GDNativeVariantType VARIANT_TYPE = m_var_type; \ static constexpr GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; \ static inline GDNativePropertyInfo get_class_info() { \ - return PropertyInfo(VARIANT_TYPE, ""); \ + return make_property_info(VARIANT_TYPE, ""); \ } \ }; \ template <> \ @@ -91,7 +106,7 @@ struct GetTypeInfo; static constexpr GDNativeVariantType VARIANT_TYPE = m_var_type; \ static constexpr GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; \ static inline GDNativePropertyInfo get_class_info() { \ - return PropertyInfo(VARIANT_TYPE, ""); \ + return make_property_info(VARIANT_TYPE, ""); \ } \ }; @@ -101,7 +116,7 @@ struct GetTypeInfo; static constexpr GDNativeVariantType VARIANT_TYPE = m_var_type; \ static constexpr GDNativeExtensionClassMethodArgumentMetadata METADATA = m_metadata; \ static inline GDNativePropertyInfo get_class_info() { \ - return PropertyInfo(VARIANT_TYPE, ""); \ + return make_property_info(VARIANT_TYPE, ""); \ } \ }; \ template <> \ @@ -109,7 +124,7 @@ struct GetTypeInfo; static constexpr GDNativeVariantType VARIANT_TYPE = m_var_type; \ static constexpr GDNativeExtensionClassMethodArgumentMetadata METADATA = m_metadata; \ static inline GDNativePropertyInfo get_class_info() { \ - return PropertyInfo(VARIANT_TYPE, ""); \ + return make_property_info(VARIANT_TYPE, ""); \ } \ }; @@ -167,7 +182,7 @@ struct GetTypeInfo { static constexpr GDNativeVariantType VARIANT_TYPE = GDNATIVE_VARIANT_TYPE_NIL; static constexpr GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; static inline GDNativePropertyInfo get_class_info() { - return PropertyInfo(GDNATIVE_VARIANT_TYPE_NIL, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT); + return make_property_info(GDNATIVE_VARIANT_TYPE_NIL, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT); } }; @@ -176,7 +191,7 @@ struct GetTypeInfo { static constexpr GDNativeVariantType VARIANT_TYPE = GDNATIVE_VARIANT_TYPE_NIL; static constexpr GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; static inline GDNativePropertyInfo get_class_info() { - return PropertyInfo(GDNATIVE_VARIANT_TYPE_NIL, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT); + return make_property_info(GDNATIVE_VARIANT_TYPE_NIL, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT); } }; @@ -184,8 +199,8 @@ template struct GetTypeInfo::value>::type> { static const GDNativeVariantType VARIANT_TYPE = GDNATIVE_VARIANT_TYPE_OBJECT; static const GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; - static inline PropertyInfo get_class_info() { - return PropertyInfo(GDNATIVE_VARIANT_TYPE_OBJECT, T::get_class_static()); + static inline GDNativePropertyInfo get_class_info() { + return make_property_info(GDNATIVE_VARIANT_TYPE_OBJECT, T::get_class_static()); } }; @@ -193,19 +208,19 @@ template struct GetTypeInfo::value>::type> { static const GDNativeVariantType VARIANT_TYPE = GDNATIVE_VARIANT_TYPE_OBJECT; static const GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; - static inline PropertyInfo get_class_info() { - return PropertyInfo(GDNATIVE_VARIANT_TYPE_OBJECT, T::get_class_static()); + static inline GDNativePropertyInfo get_class_info() { + return make_property_info(GDNATIVE_VARIANT_TYPE_OBJECT, T::get_class_static()); } }; -#define TEMPL_MAKE_ENUM_TYPE_INFO(m_class, m_enum, m_impl) \ - template <> \ - struct GetTypeInfo { \ - static const Variant::Type VARIANT_TYPE = Variant::INT; \ - static const GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; \ - static inline GDNativePropertyInfo get_class_info() { \ - return PropertyInfo(GDNATIVE_VARIANT_TYPE_INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_ENUM, #m_class "." #m_enum); \ - } \ +#define TEMPL_MAKE_ENUM_TYPE_INFO(m_class, m_enum, m_impl) \ + template <> \ + struct GetTypeInfo { \ + static const Variant::Type VARIANT_TYPE = Variant::INT; \ + static const GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; \ + static inline GDNativePropertyInfo get_class_info() { \ + return make_property_info(GDNATIVE_VARIANT_TYPE_INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_ENUM, #m_class "." #m_enum); \ + } \ }; #define MAKE_ENUM_TYPE_INFO(m_class, m_enum) \ @@ -235,24 +250,24 @@ public: _FORCE_INLINE_ operator Variant() const { return value; } }; -#define TEMPL_MAKE_BITFIELD_TYPE_INFO(m_class, m_enum, m_impl) \ - template <> \ - struct GetTypeInfo { \ - static const Variant::Type VARIANT_TYPE = Variant::INT; \ - static const GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; \ - static inline GDNativePropertyInfo get_class_info() { \ - return PropertyInfo(GDNATIVE_VARIANT_TYPE_INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \ - #m_class "." #m_enum); \ - } \ - }; \ - template <> \ - struct GetTypeInfo> { \ - static const Variant::Type VARIANT_TYPE = Variant::INT; \ - static const GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; \ - static inline GDNativePropertyInfo get_class_info() { \ - return PropertyInfo(GDNATIVE_VARIANT_TYPE_INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \ - #m_class "." #m_enum); \ - } \ +#define TEMPL_MAKE_BITFIELD_TYPE_INFO(m_class, m_enum, m_impl) \ + template <> \ + struct GetTypeInfo { \ + static const Variant::Type VARIANT_TYPE = Variant::INT; \ + static const GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; \ + static inline GDNativePropertyInfo get_class_info() { \ + return make_property_info(GDNATIVE_VARIANT_TYPE_INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \ + #m_class "." #m_enum); \ + } \ + }; \ + template <> \ + struct GetTypeInfo> { \ + static const Variant::Type VARIANT_TYPE = Variant::INT; \ + static const GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; \ + static inline GDNativePropertyInfo get_class_info() { \ + return make_property_info(GDNATIVE_VARIANT_TYPE_INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \ + #m_class "." #m_enum); \ + } \ }; #define MAKE_BITFIELD_TYPE_INFO(m_class, m_enum) \ diff --git a/src/core/class_db.cpp b/src/core/class_db.cpp index 98cd4d03..93938158 100644 --- a/src/core/class_db.cpp +++ b/src/core/class_db.cpp @@ -69,7 +69,7 @@ void ClassDB::add_property(const char *p_class, const PropertyInfo &p_pinfo, con ClassInfo &info = classes[p_class]; - ERR_FAIL_COND_MSG(info.property_names.find(p_pinfo.name) != info.property_names.end(), "Property already exists in class."); + ERR_FAIL_COND_MSG(info.property_names.find(p_pinfo.name.utf8().get_data()) != info.property_names.end(), "Property already exists in class."); MethodBind *setter = nullptr; if (p_setter) { @@ -91,15 +91,15 @@ void ClassDB::add_property(const char *p_class, const PropertyInfo &p_pinfo, con } // register property with plugin - info.property_names.insert(p_pinfo.name); + info.property_names.insert(p_pinfo.name.utf8().get_data()); // register with Godot GDNativePropertyInfo prop_info = { - (uint32_t)p_pinfo.type, // uint32_t type; - p_pinfo.name, // const char *name; - p_pinfo.class_name, // const char *class_name; + static_cast(p_pinfo.type), // uint32_t type; + _alloc_and_copy_cstr(p_pinfo.name.utf8().get_data()), // const char *name; + _alloc_and_copy_cstr(p_pinfo.class_name.utf8().get_data()), // const char *class_name; p_pinfo.hint, // NONE //uint32_t hint; - p_pinfo.hint_string, // const char *hint_string; + _alloc_and_copy_cstr(p_pinfo.hint_string.utf8().get_data()), // const char *hint_string; p_pinfo.usage, // DEFAULT //uint32_t usage; }; @@ -112,6 +112,10 @@ void ClassDB::add_property(const char *p_class, const PropertyInfo &p_pinfo, con setget.type = p_pinfo.type; internal::gdn_interface->classdb_register_extension_class_property(internal::library, info.name, &prop_info, setget.setter, setget.getter); + + memfree(const_cast(prop_info.name)); + memfree(const_cast(prop_info.class_name)); + memfree(const_cast(prop_info.hint_string)); } MethodBind *ClassDB::get_method(const char *p_class, const char *p_method) { @@ -238,15 +242,21 @@ void ClassDB::add_signal(const char *p_class, const MethodInfo &p_signal) { for (const PropertyInfo &par : p_signal.arguments) { parameters.push_back(GDNativePropertyInfo{ static_cast(par.type), // uint32_t type; - par.name, // const char *name; - par.class_name, // const char *class_name; - par.hint, // uint32_t hint; - par.hint_string, // const char *hint_string; - par.usage, // uint32_t usage; + _alloc_and_copy_cstr(par.name.utf8().get_data()), // const char *name; + _alloc_and_copy_cstr(par.class_name.utf8().get_data()), // const char *class_name; + par.hint, // NONE //uint32_t hint; + _alloc_and_copy_cstr(par.hint_string.utf8().get_data()), // const char *hint_string; + par.usage, // DEFAULT //uint32_t usage; }); } internal::gdn_interface->classdb_register_extension_class_signal(internal::library, cl.name, p_signal.name, parameters.data(), parameters.size()); + + for (GDNativePropertyInfo &par : parameters) { + memfree(const_cast(par.name)); + memfree(const_cast(par.class_name)); + memfree(const_cast(par.hint_string)); + } } void ClassDB::bind_integer_constant(const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value, bool p_is_bitfield) { diff --git a/test/src/example.cpp b/test/src/example.cpp index 8375111d..09258f4c 100644 --- a/test/src/example.cpp +++ b/test/src/example.cpp @@ -38,7 +38,13 @@ void Example::_notification(int p_what) { } bool Example::_set(const StringName &p_name, const Variant &p_value) { - if (p_name == StringName("property_from_list")) { + String name = p_name; + if (name.begins_with("dproperty")) { + int index = name.get_slicec('_', 1).to_int(); + dprop[index] = p_value; + return true; + } + if (name == "property_from_list") { property_from_list = p_value; return true; } @@ -46,7 +52,13 @@ bool Example::_set(const StringName &p_name, const Variant &p_value) { } bool Example::_get(const StringName &p_name, Variant &r_ret) const { - if (p_name == StringName("property_from_list")) { + String name = p_name; + if (name.begins_with("dproperty")) { + int index = name.get_slicec('_', 1).to_int(); + r_ret = dprop[index]; + return true; + } + if (name == "property_from_list") { r_ret = property_from_list; return true; } @@ -59,6 +71,9 @@ String Example::_to_string() const { void Example::_get_property_list(List *p_list) const { p_list->push_back(PropertyInfo(Variant::VECTOR3, "property_from_list")); + for (int i = 0; i < 3; i++) { + p_list->push_back(PropertyInfo(Variant::VECTOR2, "dproperty_" + itos(i))); + } } bool Example::_property_can_revert(const StringName &p_name) const { diff --git a/test/src/example.h b/test/src/example.h index 08e1ccd9..5cc32a63 100644 --- a/test/src/example.h +++ b/test/src/example.h @@ -58,6 +58,7 @@ protected: private: Vector2 custom_position; Vector3 property_from_list; + Vector2 dprop[3]; public: // Constants.