|
@@ -51,6 +51,15 @@ class Wrapped {
|
|
|
friend void postinitialize_handler(Wrapped *);
|
|
|
|
|
|
protected:
|
|
|
+#ifdef HOT_RELOAD_ENABLED
|
|
|
+ struct RecreateInstance {
|
|
|
+ GDExtensionClassInstancePtr wrapper;
|
|
|
+ GDExtensionObjectPtr owner;
|
|
|
+ RecreateInstance *next;
|
|
|
+ };
|
|
|
+ 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;
|
|
|
|
|
@@ -106,6 +115,17 @@ void free_c_property_list(GDExtensionPropertyInfo *plist);
|
|
|
|
|
|
} // namespace godot
|
|
|
|
|
|
+#ifdef HOT_RELOAD_ENABLED
|
|
|
+#define _GDCLASS_RECREATE(m_class, m_inherits) \
|
|
|
+ m_class *new_instance = (m_class *)memalloc(sizeof(m_class)); \
|
|
|
+ Wrapped::RecreateInstance recreate_data = { new_instance, obj, Wrapped::recreate_instance }; \
|
|
|
+ Wrapped::recreate_instance = &recreate_data; \
|
|
|
+ memnew_placement(new_instance, m_class); \
|
|
|
+ return new_instance;
|
|
|
+#else
|
|
|
+#define _GDCLASS_RECREATE(m_class, m_inherits) return nullptr;
|
|
|
+#endif
|
|
|
+
|
|
|
// Use this on top of your own classes.
|
|
|
// Note: the trail of `***` is to keep sane diffs in PRs, because clang-format otherwise moves every `\` which makes
|
|
|
// every line of the macro different
|
|
@@ -193,6 +213,10 @@ public:
|
|
|
return new_object->_owner; \
|
|
|
} \
|
|
|
\
|
|
|
+ static GDExtensionClassInstancePtr recreate(void *data, GDExtensionObjectPtr obj) { \
|
|
|
+ _GDCLASS_RECREATE(m_class, m_inherits); \
|
|
|
+ } \
|
|
|
+ \
|
|
|
static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed) { \
|
|
|
if (p_instance && m_class::_get_notification()) { \
|
|
|
if (m_class::_get_notification() != m_inherits::_get_notification()) { \
|