diff --git a/include/godot_cpp/classes/wrapped.hpp b/include/godot_cpp/classes/wrapped.hpp index 0ffd783f..a0bcec7b 100644 --- a/include/godot_cpp/classes/wrapped.hpp +++ b/include/godot_cpp/classes/wrapped.hpp @@ -61,6 +61,10 @@ class Wrapped { thread_local static const StringName *_constructing_extension_class_name; thread_local static const GDExtensionInstanceBindingCallbacks *_constructing_class_binding_callbacks; +#ifdef HOT_RELOAD_ENABLED + thread_local static GDExtensionObjectPtr _constructing_recreate_owner; +#endif + template _ALWAYS_INLINE_ static void _set_construct_info() { _constructing_extension_class_name = T::_get_extension_class_name(); @@ -71,15 +75,6 @@ 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; - GDExtensionObjectPtr owner; - RecreateInstance *next; - }; - inline static RecreateInstance *recreate_instance = nullptr; -#endif - 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; } diff --git a/include/godot_cpp/core/class_db.hpp b/include/godot_cpp/core/class_db.hpp index 988277b0..85bc0fb7 100644 --- a/include/godot_cpp/core/class_db.hpp +++ b/include/godot_cpp/core/class_db.hpp @@ -129,9 +129,8 @@ private: static GDExtensionClassInstancePtr _recreate_instance_func(void *data, GDExtensionObjectPtr obj) { if constexpr (!std::is_abstract_v) { #ifdef HOT_RELOAD_ENABLED + Wrapped::_constructing_recreate_owner = obj; T *new_instance = (T *)memalloc(sizeof(T)); - Wrapped::RecreateInstance recreate_data = { new_instance, obj, Wrapped::recreate_instance }; - Wrapped::recreate_instance = &recreate_data; memnew_placement(new_instance, T); return new_instance; #else diff --git a/src/classes/wrapped.cpp b/src/classes/wrapped.cpp index ffca4f97..d397d46d 100644 --- a/src/classes/wrapped.cpp +++ b/src/classes/wrapped.cpp @@ -42,6 +42,10 @@ namespace godot { thread_local const StringName *Wrapped::_constructing_extension_class_name = nullptr; thread_local const GDExtensionInstanceBindingCallbacks *Wrapped::_constructing_class_binding_callbacks = nullptr; +#ifdef HOT_RELOAD_ENABLED +thread_local GDExtensionObjectPtr Wrapped::_constructing_recreate_owner = nullptr; +#endif + const StringName *Wrapped::_get_extension_class_name() { return nullptr; } @@ -55,25 +59,14 @@ void Wrapped::_postinitialize() { Wrapped::Wrapped(const StringName p_godot_class) { #ifdef HOT_RELOAD_ENABLED - if (unlikely(Wrapped::recreate_instance)) { - RecreateInstance *recreate_data = Wrapped::recreate_instance; - RecreateInstance *previous = nullptr; - while (recreate_data) { - if (recreate_data->wrapper == this) { - _owner = recreate_data->owner; - if (previous) { - previous->next = recreate_data->next; - } else { - Wrapped::recreate_instance = recreate_data->next; - } - return; - } - previous = recreate_data; - recreate_data = recreate_data->next; - } - } + if (unlikely(Wrapped::_constructing_recreate_owner)) { + _owner = Wrapped::_constructing_recreate_owner; + Wrapped::_constructing_recreate_owner = nullptr; + } else #endif - _owner = godot::internal::gdextension_interface_classdb_construct_object(reinterpret_cast(p_godot_class._native_ptr())); + { + _owner = godot::internal::gdextension_interface_classdb_construct_object(reinterpret_cast(p_godot_class._native_ptr())); + } if (_constructing_extension_class_name) { godot::internal::gdextension_interface_object_set_instance(_owner, reinterpret_cast(_constructing_extension_class_name), this);