Skip to content

Commit a98d41f

Browse files
authored
Merge pull request #1590 from dsnopek/reload-instance-bindings
Correctly set instance bindings on reload
2 parents 96675a8 + cb543c1 commit a98d41f

File tree

3 files changed

+16
-29
lines changed

3 files changed

+16
-29
lines changed

include/godot_cpp/classes/wrapped.hpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ class Wrapped {
6161
thread_local static const StringName *_constructing_extension_class_name;
6262
thread_local static const GDExtensionInstanceBindingCallbacks *_constructing_class_binding_callbacks;
6363

64+
#ifdef HOT_RELOAD_ENABLED
65+
thread_local static GDExtensionObjectPtr _constructing_recreate_owner;
66+
#endif
67+
6468
template <typename T>
6569
_ALWAYS_INLINE_ static void _set_construct_info() {
6670
_constructing_extension_class_name = T::_get_extension_class_name();
@@ -71,15 +75,6 @@ class Wrapped {
7175
virtual bool _is_extension_class() const { return false; }
7276
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.
7377

74-
#ifdef HOT_RELOAD_ENABLED
75-
struct RecreateInstance {
76-
GDExtensionClassInstancePtr wrapper;
77-
GDExtensionObjectPtr owner;
78-
RecreateInstance *next;
79-
};
80-
inline static RecreateInstance *recreate_instance = nullptr;
81-
#endif
82-
8378
void _notification(int p_what) {}
8479
bool _set(const StringName &p_name, const Variant &p_property) { return false; }
8580
bool _get(const StringName &p_name, Variant &r_property) const { return false; }

include/godot_cpp/core/class_db.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,8 @@ class ClassDB {
129129
static GDExtensionClassInstancePtr _recreate_instance_func(void *data, GDExtensionObjectPtr obj) {
130130
if constexpr (!std::is_abstract_v<T>) {
131131
#ifdef HOT_RELOAD_ENABLED
132+
Wrapped::_constructing_recreate_owner = obj;
132133
T *new_instance = (T *)memalloc(sizeof(T));
133-
Wrapped::RecreateInstance recreate_data = { new_instance, obj, Wrapped::recreate_instance };
134-
Wrapped::recreate_instance = &recreate_data;
135134
memnew_placement(new_instance, T);
136135
return new_instance;
137136
#else

src/classes/wrapped.cpp

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ namespace godot {
4242
thread_local const StringName *Wrapped::_constructing_extension_class_name = nullptr;
4343
thread_local const GDExtensionInstanceBindingCallbacks *Wrapped::_constructing_class_binding_callbacks = nullptr;
4444

45+
#ifdef HOT_RELOAD_ENABLED
46+
thread_local GDExtensionObjectPtr Wrapped::_constructing_recreate_owner = nullptr;
47+
#endif
48+
4549
const StringName *Wrapped::_get_extension_class_name() {
4650
return nullptr;
4751
}
@@ -55,25 +59,14 @@ void Wrapped::_postinitialize() {
5559

5660
Wrapped::Wrapped(const StringName p_godot_class) {
5761
#ifdef HOT_RELOAD_ENABLED
58-
if (unlikely(Wrapped::recreate_instance)) {
59-
RecreateInstance *recreate_data = Wrapped::recreate_instance;
60-
RecreateInstance *previous = nullptr;
61-
while (recreate_data) {
62-
if (recreate_data->wrapper == this) {
63-
_owner = recreate_data->owner;
64-
if (previous) {
65-
previous->next = recreate_data->next;
66-
} else {
67-
Wrapped::recreate_instance = recreate_data->next;
68-
}
69-
return;
70-
}
71-
previous = recreate_data;
72-
recreate_data = recreate_data->next;
73-
}
74-
}
62+
if (unlikely(Wrapped::_constructing_recreate_owner)) {
63+
_owner = Wrapped::_constructing_recreate_owner;
64+
Wrapped::_constructing_recreate_owner = nullptr;
65+
} else
7566
#endif
76-
_owner = godot::internal::gdextension_interface_classdb_construct_object(reinterpret_cast<GDExtensionConstStringNamePtr>(p_godot_class._native_ptr()));
67+
{
68+
_owner = godot::internal::gdextension_interface_classdb_construct_object(reinterpret_cast<GDExtensionConstStringNamePtr>(p_godot_class._native_ptr()));
69+
}
7770

7871
if (_constructing_extension_class_name) {
7972
godot::internal::gdextension_interface_object_set_instance(_owner, reinterpret_cast<GDExtensionConstStringNamePtr>(_constructing_extension_class_name), this);

0 commit comments

Comments
 (0)