Skip to content

Commit 79d1be7

Browse files
committed
Update for new NOTIFICATION_POSTINITIALIZE handling
1 parent d477589 commit 79d1be7

File tree

6 files changed

+91
-25
lines changed

6 files changed

+91
-25
lines changed

gdextension/gdextension_interface.h

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ typedef void (*GDExtensionClassReference)(GDExtensionClassInstancePtr p_instance
268268
typedef void (*GDExtensionClassUnreference)(GDExtensionClassInstancePtr p_instance);
269269
typedef void (*GDExtensionClassCallVirtual)(GDExtensionClassInstancePtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_ret);
270270
typedef GDExtensionObjectPtr (*GDExtensionClassCreateInstance)(void *p_class_userdata);
271+
typedef GDExtensionObjectPtr (*GDExtensionClassCreateInstance2)(void *p_class_userdata, bool p_notify_postinitialize);
271272
typedef void (*GDExtensionClassFreeInstance)(void *p_class_userdata, GDExtensionClassInstancePtr p_instance);
272273
typedef GDExtensionClassInstancePtr (*GDExtensionClassRecreateInstance)(void *p_class_userdata, GDExtensionObjectPtr p_object);
273274
typedef GDExtensionClassCallVirtual (*GDExtensionClassGetVirtual)(void *p_class_userdata, GDExtensionConstStringNamePtr p_name);
@@ -292,7 +293,7 @@ typedef struct {
292293
GDExtensionClassGetVirtual get_virtual_func; // Queries a virtual function by name and returns a callback to invoke the requested virtual function.
293294
GDExtensionClassGetRID get_rid_func;
294295
void *class_userdata; // Per-class user data, later accessible in instance bindings.
295-
} GDExtensionClassCreationInfo; // Deprecated. Use GDExtensionClassCreationInfo3 instead.
296+
} GDExtensionClassCreationInfo; // Deprecated. Use GDExtensionClassCreationInfo4 instead.
296297

297298
typedef struct {
298299
GDExtensionBool is_virtual;
@@ -325,7 +326,7 @@ typedef struct {
325326
GDExtensionClassCallVirtualWithData call_virtual_with_data_func;
326327
GDExtensionClassGetRID get_rid_func;
327328
void *class_userdata; // Per-class user data, later accessible in instance bindings.
328-
} GDExtensionClassCreationInfo2; // Deprecated. Use GDExtensionClassCreationInfo3 instead.
329+
} GDExtensionClassCreationInfo2; // Deprecated. Use GDExtensionClassCreationInfo4 instead.
329330

330331
typedef struct {
331332
GDExtensionBool is_virtual;
@@ -359,7 +360,41 @@ typedef struct {
359360
GDExtensionClassCallVirtualWithData call_virtual_with_data_func;
360361
GDExtensionClassGetRID get_rid_func;
361362
void *class_userdata; // Per-class user data, later accessible in instance bindings.
362-
} GDExtensionClassCreationInfo3;
363+
} GDExtensionClassCreationInfo3; // Deprecated. Use GDExtensionClassCreationInfo4 instead.
364+
365+
typedef struct {
366+
GDExtensionBool is_virtual;
367+
GDExtensionBool is_abstract;
368+
GDExtensionBool is_exposed;
369+
GDExtensionBool is_runtime;
370+
GDExtensionClassSet set_func;
371+
GDExtensionClassGet get_func;
372+
GDExtensionClassGetPropertyList get_property_list_func;
373+
GDExtensionClassFreePropertyList2 free_property_list_func;
374+
GDExtensionClassPropertyCanRevert property_can_revert_func;
375+
GDExtensionClassPropertyGetRevert property_get_revert_func;
376+
GDExtensionClassValidateProperty validate_property_func;
377+
GDExtensionClassNotification2 notification_func;
378+
GDExtensionClassToString to_string_func;
379+
GDExtensionClassReference reference_func;
380+
GDExtensionClassUnreference unreference_func;
381+
GDExtensionClassCreateInstance2 create_instance_func; // (Default) constructor; mandatory. If the class is not instantiable, consider making it virtual or abstract.
382+
GDExtensionClassFreeInstance free_instance_func; // Destructor; mandatory.
383+
GDExtensionClassRecreateInstance recreate_instance_func;
384+
// Queries a virtual function by name and returns a callback to invoke the requested virtual function.
385+
GDExtensionClassGetVirtual get_virtual_func;
386+
// Paired with `call_virtual_with_data_func`, this is an alternative to `get_virtual_func` for extensions that
387+
// need or benefit from extra data when calling virtual functions.
388+
// Returns user data that will be passed to `call_virtual_with_data_func`.
389+
// Returning `NULL` from this function signals to Godot that the virtual function is not overridden.
390+
// Data returned from this function should be managed by the extension and must be valid until the extension is deinitialized.
391+
// You should supply either `get_virtual_func`, or `get_virtual_call_data_func` with `call_virtual_with_data_func`.
392+
GDExtensionClassGetVirtualCallData get_virtual_call_data_func;
393+
// Used to call virtual functions when `get_virtual_call_data_func` is not null.
394+
GDExtensionClassCallVirtualWithData call_virtual_with_data_func;
395+
GDExtensionClassGetRID get_rid_func;
396+
void *class_userdata; // Per-class user data, later accessible in instance bindings.
397+
} GDExtensionClassCreationInfo4;
363398

364399
typedef void *GDExtensionClassLibraryPtr;
365400

@@ -2680,6 +2715,7 @@ typedef void *(*GDExtensionInterfaceCallableCustomGetUserData)(GDExtensionConstT
26802715
/**
26812716
* @name classdb_construct_object
26822717
* @since 4.1
2718+
* @deprecated in Godot 4.4. Use `classdb_construct_object2` instead.
26832719
*
26842720
* Constructs an Object of the requested class.
26852721
*
@@ -2691,6 +2727,22 @@ typedef void *(*GDExtensionInterfaceCallableCustomGetUserData)(GDExtensionConstT
26912727
*/
26922728
typedef GDExtensionObjectPtr (*GDExtensionInterfaceClassdbConstructObject)(GDExtensionConstStringNamePtr p_classname);
26932729

2730+
/**
2731+
* @name classdb_construct_object2
2732+
* @since 4.4
2733+
*
2734+
* Constructs an Object of the requested class.
2735+
*
2736+
* The passed class must be a built-in godot class, or an already-registered extension class. In both cases, object_set_instance() should be called to fully initialize the object.
2737+
*
2738+
* "NOTIFICATION_POSTINITIALIZE" must be sent after construction.
2739+
*
2740+
* @param p_classname A pointer to a StringName with the class name.
2741+
*
2742+
* @return A pointer to the newly created Object.
2743+
*/
2744+
typedef GDExtensionObjectPtr (*GDExtensionInterfaceClassdbConstructObject2)(GDExtensionConstStringNamePtr p_classname);
2745+
26942746
/**
26952747
* @name classdb_get_method_bind
26962748
* @since 4.1
@@ -2722,7 +2774,7 @@ typedef void *(*GDExtensionInterfaceClassdbGetClassTag)(GDExtensionConstStringNa
27222774
/**
27232775
* @name classdb_register_extension_class
27242776
* @since 4.1
2725-
* @deprecated in Godot 4.2. Use `classdb_register_extension_class3` instead.
2777+
* @deprecated in Godot 4.2. Use `classdb_register_extension_class4` instead.
27262778
*
27272779
* Registers an extension class in the ClassDB.
27282780
*
@@ -2738,7 +2790,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass)(GDExtensionCla
27382790
/**
27392791
* @name classdb_register_extension_class2
27402792
* @since 4.2
2741-
* @deprecated in Godot 4.3. Use `classdb_register_extension_class3` instead.
2793+
* @deprecated in Godot 4.3. Use `classdb_register_extension_class4` instead.
27422794
*
27432795
* Registers an extension class in the ClassDB.
27442796
*
@@ -2754,6 +2806,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass2)(GDExtensionCl
27542806
/**
27552807
* @name classdb_register_extension_class3
27562808
* @since 4.3
2809+
* @deprecated in Godot 4.4. Use `classdb_register_extension_class4` instead.
27572810
*
27582811
* Registers an extension class in the ClassDB.
27592812
*
@@ -2766,6 +2819,21 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass2)(GDExtensionCl
27662819
*/
27672820
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass3)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo3 *p_extension_funcs);
27682821

2822+
/**
2823+
* @name classdb_register_extension_class4
2824+
* @since 4.4
2825+
*
2826+
* Registers an extension class in the ClassDB.
2827+
*
2828+
* Provided struct can be safely freed once the function returns.
2829+
*
2830+
* @param p_library A pointer the library received by the GDExtension's entry point function.
2831+
* @param p_class_name A pointer to a StringName with the class name.
2832+
* @param p_parent_class_name A pointer to a StringName with the parent class name.
2833+
* @param p_extension_funcs A pointer to a GDExtensionClassCreationInfo2 struct.
2834+
*/
2835+
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass4)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo4 *p_extension_funcs);
2836+
27692837
/**
27702838
* @name classdb_register_extension_class_method
27712839
* @since 4.1

include/godot_cpp/classes/wrapped.hpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ class Wrapped {
104104
::godot::List<::godot::PropertyInfo> plist_owned;
105105

106106
void _postinitialize();
107-
virtual void _notificationv(int32_t p_what, bool p_reversed = false) {}
108107

109108
Wrapped(const StringName p_godot_class);
110109
Wrapped(GodotObject *p_godot_object);
@@ -398,11 +397,6 @@ public:
398397
_gde_binding_reference_callback, \
399398
}; \
400399
\
401-
protected: \
402-
virtual void _notificationv(int32_t p_what, bool p_reversed = false) override { \
403-
m_class::notification_bind(this, p_what, p_reversed); \
404-
} \
405-
\
406400
private:
407401

408402
// Don't use this for your classes, use GDCLASS() instead.

include/godot_cpp/core/class_db.hpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,13 @@ class ClassDB {
116116
static void _register_class(bool p_virtual = false, bool p_exposed = true, bool p_runtime = false);
117117

118118
template <typename T>
119-
static GDExtensionObjectPtr _create_instance_func(void *data) {
119+
static GDExtensionObjectPtr _create_instance_func(void *data, bool p_notify_postinitialize) {
120120
if constexpr (!std::is_abstract_v<T>) {
121-
T *new_object = memnew(T);
121+
Wrapped::_set_construct_info<T>();
122+
T *new_object = new ("", "") T;
123+
if (p_notify_postinitialize) {
124+
new_object->_postinitialize();
125+
}
122126
return new_object->_owner;
123127
} else {
124128
return nullptr;
@@ -239,7 +243,7 @@ void ClassDB::_register_class(bool p_virtual, bool p_exposed, bool p_runtime) {
239243
class_register_order.push_back(cl.name);
240244

241245
// Register this class with Godot
242-
GDExtensionClassCreationInfo3 class_info = {
246+
GDExtensionClassCreationInfo4 class_info = {
243247
p_virtual, // GDExtensionBool is_virtual;
244248
is_abstract, // GDExtensionBool is_abstract;
245249
p_exposed, // GDExtensionBool is_exposed;
@@ -265,7 +269,7 @@ void ClassDB::_register_class(bool p_virtual, bool p_exposed, bool p_runtime) {
265269
(void *)&T::get_class_static(), // void *class_userdata;
266270
};
267271

268-
internal::gdextension_interface_classdb_register_extension_class3(internal::library, cl.name._native_ptr(), cl.parent_name._native_ptr(), &class_info);
272+
internal::gdextension_interface_classdb_register_extension_class4(internal::library, cl.name._native_ptr(), cl.parent_name._native_ptr(), &class_info);
269273

270274
// call bind_methods etc. to register all members of the class
271275
T::initialize_class();

include/godot_cpp/godot.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,10 @@ extern "C" GDExtensionInterfaceRefSetObject gdextension_interface_ref_set_object
179179
extern "C" GDExtensionInterfaceScriptInstanceCreate3 gdextension_interface_script_instance_create3;
180180
extern "C" GDExtensionInterfacePlaceHolderScriptInstanceCreate gdextension_interface_placeholder_script_instance_create;
181181
extern "C" GDExtensionInterfacePlaceHolderScriptInstanceUpdate gdextension_interface_placeholder_script_instance_update;
182-
extern "C" GDExtensionInterfaceClassdbConstructObject gdextension_interface_classdb_construct_object;
182+
extern "C" GDExtensionInterfaceClassdbConstructObject2 gdextension_interface_classdb_construct_object2;
183183
extern "C" GDExtensionInterfaceClassdbGetMethodBind gdextension_interface_classdb_get_method_bind;
184184
extern "C" GDExtensionInterfaceClassdbGetClassTag gdextension_interface_classdb_get_class_tag;
185-
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClass3 gdextension_interface_classdb_register_extension_class3;
185+
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClass4 gdextension_interface_classdb_register_extension_class4;
186186
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_method;
187187
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod gdextension_interface_classdb_register_extension_class_virtual_method;
188188
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant gdextension_interface_classdb_register_extension_class_integer_constant;

src/classes/wrapped.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ const StringName *Wrapped::_get_extension_class_name() {
4747
}
4848

4949
void Wrapped::_postinitialize() {
50-
// Only send NOTIFICATION_POSTINITIALIZE for extension classes.
51-
if (_is_extension_class()) {
52-
_notificationv(Object::NOTIFICATION_POSTINITIALIZE);
50+
Object *obj = dynamic_cast<Object *>(this);
51+
if (obj) {
52+
obj->notification(Object::NOTIFICATION_POSTINITIALIZE);
5353
}
5454
}
5555

@@ -73,7 +73,7 @@ Wrapped::Wrapped(const StringName p_godot_class) {
7373
}
7474
}
7575
#endif
76-
_owner = godot::internal::gdextension_interface_classdb_construct_object(reinterpret_cast<GDExtensionConstStringNamePtr>(p_godot_class._native_ptr()));
76+
_owner = godot::internal::gdextension_interface_classdb_construct_object2(reinterpret_cast<GDExtensionConstStringNamePtr>(p_godot_class._native_ptr()));
7777

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

src/godot.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,10 @@ GDExtensionInterfaceRefSetObject gdextension_interface_ref_set_object = nullptr;
185185
GDExtensionInterfaceScriptInstanceCreate3 gdextension_interface_script_instance_create3 = nullptr;
186186
GDExtensionInterfacePlaceHolderScriptInstanceCreate gdextension_interface_placeholder_script_instance_create = nullptr;
187187
GDExtensionInterfacePlaceHolderScriptInstanceUpdate gdextension_interface_placeholder_script_instance_update = nullptr;
188-
GDExtensionInterfaceClassdbConstructObject gdextension_interface_classdb_construct_object = nullptr;
188+
GDExtensionInterfaceClassdbConstructObject2 gdextension_interface_classdb_construct_object2 = nullptr;
189189
GDExtensionInterfaceClassdbGetMethodBind gdextension_interface_classdb_get_method_bind = nullptr;
190190
GDExtensionInterfaceClassdbGetClassTag gdextension_interface_classdb_get_class_tag = nullptr;
191-
GDExtensionInterfaceClassdbRegisterExtensionClass3 gdextension_interface_classdb_register_extension_class3 = nullptr;
191+
GDExtensionInterfaceClassdbRegisterExtensionClass4 gdextension_interface_classdb_register_extension_class4 = nullptr;
192192
GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_method = nullptr;
193193
GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod gdextension_interface_classdb_register_extension_class_virtual_method = nullptr;
194194
GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant gdextension_interface_classdb_register_extension_class_integer_constant = nullptr;
@@ -464,10 +464,10 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
464464
LOAD_PROC_ADDRESS(script_instance_create3, GDExtensionInterfaceScriptInstanceCreate3);
465465
LOAD_PROC_ADDRESS(placeholder_script_instance_create, GDExtensionInterfacePlaceHolderScriptInstanceCreate);
466466
LOAD_PROC_ADDRESS(placeholder_script_instance_update, GDExtensionInterfacePlaceHolderScriptInstanceUpdate);
467-
LOAD_PROC_ADDRESS(classdb_construct_object, GDExtensionInterfaceClassdbConstructObject);
467+
LOAD_PROC_ADDRESS(classdb_construct_object2, GDExtensionInterfaceClassdbConstructObject2);
468468
LOAD_PROC_ADDRESS(classdb_get_method_bind, GDExtensionInterfaceClassdbGetMethodBind);
469469
LOAD_PROC_ADDRESS(classdb_get_class_tag, GDExtensionInterfaceClassdbGetClassTag);
470-
LOAD_PROC_ADDRESS(classdb_register_extension_class3, GDExtensionInterfaceClassdbRegisterExtensionClass3);
470+
LOAD_PROC_ADDRESS(classdb_register_extension_class4, GDExtensionInterfaceClassdbRegisterExtensionClass4);
471471
LOAD_PROC_ADDRESS(classdb_register_extension_class_method, GDExtensionInterfaceClassdbRegisterExtensionClassMethod);
472472
LOAD_PROC_ADDRESS(classdb_register_extension_class_virtual_method, GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod);
473473
LOAD_PROC_ADDRESS(classdb_register_extension_class_integer_constant, GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant);

0 commit comments

Comments
 (0)