diff options
author | Daylily-Zeleen <daylily-zeleen@foxmail.com> | 2024-04-24 22:14:33 +0800 |
---|---|---|
committer | Daylily-Zeleen <daylily-zeleen@foxmail.com> | 2024-05-28 22:59:37 +0800 |
commit | 76cbc66785104756d6b37d16e8eb85dccc0497e8 (patch) | |
tree | 54797bab01c125f8eb51d98e37a747f9cbd0fceb /include | |
parent | b697ba8896e5fd0966274f00798c55a5bfed4e74 (diff) | |
download | redot-cpp-76cbc66785104756d6b37d16e8eb85dccc0497e8.tar.gz |
Set instance and instance binding in Wrapped constructor.
Diffstat (limited to 'include')
-rw-r--r-- | include/godot_cpp/classes/wrapped.hpp | 42 | ||||
-rw-r--r-- | include/godot_cpp/core/memory.hpp | 9 |
2 files changed, 35 insertions, 16 deletions
diff --git a/include/godot_cpp/classes/wrapped.hpp b/include/godot_cpp/classes/wrapped.hpp index 8702fb1..9cc1d39 100644 --- a/include/godot_cpp/classes/wrapped.hpp +++ b/include/godot_cpp/classes/wrapped.hpp @@ -46,13 +46,31 @@ class ClassDB; typedef void GodotObject; +template <typename T, std::enable_if_t<std::is_base_of<::godot::Wrapped, T>::value, bool> = true> +_ALWAYS_INLINE_ void _pre_initialize(); + // Base for all engine classes, to contain the pointer to the engine instance. class Wrapped { friend class GDExtensionBinding; friend class ClassDB; friend void postinitialize_handler(Wrapped *); + template <typename T, std::enable_if_t<std::is_base_of<::godot::Wrapped, T>::value, bool>> + friend _ALWAYS_INLINE_ void _pre_initialize(); + + thread_local static const StringName *_constructing_extension_class_name; + thread_local static const GDExtensionInstanceBindingCallbacks *_constructing_class_binding_callbacks; + + template <typename T> + _ALWAYS_INLINE_ static void _set_construct_info() { + _constructing_extension_class_name = T::_get_extension_class_name(); + _constructing_class_binding_callbacks = &T::_gde_binding_callbacks; + } + protected: + virtual bool _is_extension_class() const { return false; } + static const StringName *_get_extension_class_name(); // This is needed to retrieve the class name before the godot object has its _extension and _extension_instance members assigned. + #ifdef HOT_RELOAD_ENABLED struct RecreateInstance { GDExtensionClassInstancePtr wrapper; @@ -62,9 +80,6 @@ protected: inline static RecreateInstance *recreate_instance = nullptr; #endif - virtual const StringName *_get_extension_class_name() const; // This is needed to retrieve the class name before the godot object has its _extension and _extension_instance members assigned. - virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const = 0; - void _notification(int p_what) {} bool _set(const StringName &p_name, const Variant &p_property) { return false; } bool _get(const StringName &p_name, Variant &r_property) const { return false; } @@ -109,6 +124,11 @@ public: GodotObject *_owner = nullptr; }; +template <typename T, std::enable_if_t<std::is_base_of<::godot::Wrapped, T>::value, bool>> +_ALWAYS_INLINE_ void _pre_initialize() { + Wrapped::_set_construct_info<T>(); +} + _FORCE_INLINE_ void snarray_add_str(Vector<StringName> &arr) { } @@ -161,15 +181,14 @@ struct EngineClassRegistration { private: \ void operator=(const m_class &p_rval) {} \ friend class ::godot::ClassDB; \ + friend class ::godot::Wrapped; \ \ protected: \ - virtual const ::godot::StringName *_get_extension_class_name() const override { \ - static ::godot::StringName string_name = get_class_static(); \ - return &string_name; \ - } \ + virtual bool _is_extension_class() const override { return true; } \ \ - virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \ - return &_gde_binding_callbacks; \ + static const ::godot::StringName *_get_extension_class_name() { \ + const ::godot::StringName &string_name = get_class_static(); \ + return &string_name; \ } \ \ static void (*_get_bind_methods())() { \ @@ -388,12 +407,9 @@ private: inline static ::godot::internal::EngineClassRegistration<m_class> _gde_engine_class_registration_helper; \ void operator=(const m_class &p_rval) {} \ friend class ::godot::ClassDB; \ + friend class ::godot::Wrapped; \ \ protected: \ - virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \ - return &_gde_binding_callbacks; \ - } \ - \ m_class(const char *p_godot_class) : m_inherits(p_godot_class) {} \ m_class(GodotObject *p_godot_object) : m_inherits(p_godot_object) {} \ \ diff --git a/include/godot_cpp/core/memory.hpp b/include/godot_cpp/core/memory.hpp index 3c98c19..1934ee4 100644 --- a/include/godot_cpp/core/memory.hpp +++ b/include/godot_cpp/core/memory.hpp @@ -82,6 +82,9 @@ public: static void free_static(void *p_ptr, bool p_pad_align = false); }; +template <typename T, std::enable_if_t<!std::is_base_of<::godot::Wrapped, T>::value, bool> = true> +_ALWAYS_INLINE_ void _pre_initialize() {} + _ALWAYS_INLINE_ void postinitialize_handler(void *) {} template <typename T> @@ -94,10 +97,10 @@ _ALWAYS_INLINE_ T *_post_initialize(T *p_obj) { #define memrealloc(m_mem, m_size) ::godot::Memory::realloc_static(m_mem, m_size) #define memfree(m_mem) ::godot::Memory::free_static(m_mem) -#define memnew(m_class) ::godot::_post_initialize(new ("", "") m_class) +#define memnew(m_class) (::godot::_pre_initialize<std::remove_pointer_t<decltype(new ("", "") m_class)>>(), ::godot::_post_initialize(new ("", "") m_class)) -#define memnew_allocator(m_class, m_allocator) ::godot::_post_initialize(new ("", m_allocator::alloc) m_class) -#define memnew_placement(m_placement, m_class) ::godot::_post_initialize(new ("", m_placement, sizeof(m_class), "") m_class) +#define memnew_allocator(m_class, m_allocator) (::godot::_pre_initialize<std::remove_pointer_t<decltype(new ("", "") m_class)>>(), ::godot::_post_initialize(new ("", m_allocator::alloc) m_class)) +#define memnew_placement(m_placement, m_class) (::godot::_pre_initialize<std::remove_pointer_t<decltype(new ("", "") m_class)>>(), ::godot::_post_initialize(new ("", m_placement, sizeof(m_class), "") m_class)) // Generic comparator used in Map, List, etc. template <typename T> |