Skip to content

Commit f595a2c

Browse files
Set instance and instance binding in Wrapped constructor.
1 parent ad307e4 commit f595a2c

File tree

3 files changed

+46
-30
lines changed

3 files changed

+46
-30
lines changed

include/godot_cpp/classes/wrapped.hpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@ class Wrapped {
5252
friend class ClassDB;
5353
friend void postinitialize_handler(Wrapped *);
5454

55+
template <typename T, std::enable_if_t<std::is_base_of<::godot::Wrapped, T>::value, bool>>
56+
friend _ALWAYS_INLINE_ void _pre_initialize();
57+
58+
thread_local static const StringName *constructing_extension_class_name;
59+
thread_local static const GDExtensionInstanceBindingCallbacks *constructing_extension_class_binds_callbacks;
60+
61+
void _initialize();
62+
5563
protected:
5664
#ifdef HOT_RELOAD_ENABLED
5765
struct RecreateInstance {
@@ -62,9 +70,6 @@ class Wrapped {
6270
inline static RecreateInstance *recreate_instance = nullptr;
6371
#endif
6472

65-
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.
66-
virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const = 0;
67-
6873
void _notification(int p_what) {}
6974
bool _set(const StringName &p_name, const Variant &p_property) { return false; }
7075
bool _get(const StringName &p_name, Variant &r_property) const { return false; }
@@ -95,6 +100,8 @@ class Wrapped {
95100
virtual ~Wrapped() {}
96101

97102
public:
103+
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.
104+
98105
static StringName &get_class_static() {
99106
static StringName string_name = StringName("Wrapped");
100107
return string_name;
@@ -108,6 +115,12 @@ class Wrapped {
108115
GodotObject *_owner = nullptr;
109116
};
110117

118+
template <typename T, std::enable_if_t<std::is_base_of<::godot::Wrapped, T>::value, bool> = true>
119+
_ALWAYS_INLINE_ void _pre_initialize() {
120+
Wrapped::constructing_extension_class_name = T::_get_extension_class_name();
121+
Wrapped::constructing_extension_class_binds_callbacks = &T::_gde_binding_callbacks;
122+
}
123+
111124
_FORCE_INLINE_ void snarray_add_str(Vector<StringName> &arr) {
112125
}
113126

@@ -162,15 +175,6 @@ private:
162175
friend class ::godot::ClassDB; \
163176
\
164177
protected: \
165-
virtual const ::godot::StringName *_get_extension_class_name() const override { \
166-
static ::godot::StringName string_name = get_class_static(); \
167-
return &string_name; \
168-
} \
169-
\
170-
virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \
171-
return &_gde_binding_callbacks; \
172-
} \
173-
\
174178
static void (*_get_bind_methods())() { \
175179
return &m_class::_bind_methods; \
176180
} \
@@ -213,6 +217,11 @@ protected:
213217
} \
214218
\
215219
public: \
220+
static const ::godot::StringName *_get_extension_class_name() { \
221+
static ::godot::StringName string_name = get_class_static(); \
222+
return &string_name; \
223+
} \
224+
\
216225
typedef m_class self_type; \
217226
\
218227
static void initialize_class() { \
@@ -383,10 +392,6 @@ private:
383392
void operator=(const m_class &p_rval) {} \
384393
\
385394
protected: \
386-
virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \
387-
return &_gde_binding_callbacks; \
388-
} \
389-
\
390395
m_class(const char *p_godot_class) : m_inherits(p_godot_class) {} \
391396
m_class(GodotObject *p_godot_object) : m_inherits(p_godot_object) {} \
392397
\

include/godot_cpp/core/memory.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ class Memory {
8282
static void free_static(void *p_ptr, bool p_pad_align = false);
8383
};
8484

85+
template <typename T, std::enable_if_t<!std::is_base_of_v<Wrapped, T>, bool> = true>
86+
_ALWAYS_INLINE_ void _pre_initialize() {}
87+
8588
_ALWAYS_INLINE_ void postinitialize_handler(void *) {}
8689

8790
template <typename T>
@@ -94,10 +97,10 @@ _ALWAYS_INLINE_ T *_post_initialize(T *p_obj) {
9497
#define memrealloc(m_mem, m_size) ::godot::Memory::realloc_static(m_mem, m_size)
9598
#define memfree(m_mem) ::godot::Memory::free_static(m_mem)
9699

97-
#define memnew(m_class) ::godot::_post_initialize(new ("", "") m_class)
100+
#define memnew(m_class) (::godot::_pre_initialize<std::remove_pointer_t<decltype(new ("", "") m_class)>>(), ::godot::_post_initialize(new ("", "") m_class))
98101

99-
#define memnew_allocator(m_class, m_allocator) ::godot::_post_initialize(new ("", m_allocator::alloc) m_class)
100-
#define memnew_placement(m_placement, m_class) ::godot::_post_initialize(new ("", m_placement, sizeof(m_class), "") m_class)
102+
#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))
103+
#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))
101104

102105
// Generic comparator used in Map, List, etc.
103106
template <typename T>

src/classes/wrapped.cpp

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,29 @@
3939
#include <godot_cpp/core/class_db.hpp>
4040

4141
namespace godot {
42+
thread_local const StringName *Wrapped::constructing_extension_class_name = nullptr;
43+
thread_local const GDExtensionInstanceBindingCallbacks *Wrapped::constructing_extension_class_binds_callbacks = nullptr;
4244

43-
const StringName *Wrapped::_get_extension_class_name() const {
45+
const StringName *Wrapped::_get_extension_class_name() {
4446
return nullptr;
4547
}
4648

47-
void Wrapped::_postinitialize() {
48-
const StringName *extension_class = _get_extension_class_name();
49-
if (extension_class) {
50-
godot::internal::gdextension_interface_object_set_instance(_owner, reinterpret_cast<GDExtensionConstStringNamePtr>(extension_class), this);
49+
void Wrapped::_initialize() {
50+
if (constructing_extension_class_name) {
51+
godot::internal::gdextension_interface_object_set_instance(_owner, reinterpret_cast<GDExtensionConstStringNamePtr>(constructing_extension_class_name), this);
52+
constructing_extension_class_name = nullptr;
5153
}
52-
godot::internal::gdextension_interface_object_set_instance_binding(_owner, godot::internal::token, this, _get_bindings_callbacks());
53-
if (extension_class) {
54-
Object *obj = dynamic_cast<Object *>(this);
55-
if (obj) {
56-
obj->notification(Object::NOTIFICATION_POSTINITIALIZE);
57-
}
54+
55+
if (constructing_extension_class_binds_callbacks) {
56+
godot::internal::gdextension_interface_object_set_instance_binding(_owner, godot::internal::token, this, constructing_extension_class_binds_callbacks);
57+
constructing_extension_class_binds_callbacks = nullptr;
58+
}
59+
}
60+
61+
void Wrapped::_postinitialize() {
62+
Object *obj = dynamic_cast<Object *>(this);
63+
if (obj) {
64+
obj->notification(Object::NOTIFICATION_POSTINITIALIZE);
5865
}
5966
}
6067

@@ -79,6 +86,7 @@ Wrapped::Wrapped(const StringName p_godot_class) {
7986
}
8087
#endif
8188
_owner = godot::internal::gdextension_interface_classdb_construct_object(reinterpret_cast<GDExtensionConstStringNamePtr>(p_godot_class._native_ptr()));
89+
_initialize();
8290
}
8391

8492
Wrapped::Wrapped(GodotObject *p_godot_object) {

0 commit comments

Comments
 (0)