Skip to content

Commit

Permalink
Fix Object::notification order
Browse files Browse the repository at this point in the history
For the notification-order to work correctly, it is necessary to
allow the `p_reversed` argument to be used within cpp.
This PR changes the necessary bindings.
  • Loading branch information
Sauermann committed Aug 10, 2023
1 parent 5834e16 commit cc10911
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 6 deletions.
42 changes: 42 additions & 0 deletions gdextension/gdextension_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,29 @@ typedef struct {
void *class_userdata; // Per-class user data, later accessible in instance bindings.
} GDExtensionClassCreationInfo;

typedef void (*GDExtensionClassNotification2)(GDExtensionClassInstancePtr p_instance, int32_t p_what, bool p_reversed);

typedef struct {
GDExtensionBool is_virtual;
GDExtensionBool is_abstract;
GDExtensionClassSet set_func;
GDExtensionClassGet get_func;
GDExtensionClassGetPropertyList get_property_list_func;
GDExtensionClassFreePropertyList free_property_list_func;
GDExtensionClassPropertyCanRevert property_can_revert_func;
GDExtensionClassPropertyGetRevert property_get_revert_func;
GDExtensionClassNotification notification_func; // Deprecated - should be nullptr. Only kept for backward compatibility.
GDExtensionClassNotification2 notification_func2;
GDExtensionClassToString to_string_func;
GDExtensionClassReference reference_func;
GDExtensionClassUnreference unreference_func;
GDExtensionClassCreateInstance create_instance_func; // (Default) constructor; mandatory. If the class is not instantiable, consider making it virtual or abstract.
GDExtensionClassFreeInstance free_instance_func; // Destructor; mandatory.
GDExtensionClassGetVirtual get_virtual_func; // Queries a virtual function by name and returns a callback to invoke the requested virtual function.
GDExtensionClassGetRID get_rid_func;
void *class_userdata; // Per-class user data, later accessible in instance bindings.
} GDExtensionClassCreationInfo2;

typedef void *GDExtensionClassLibraryPtr;

/* Method */
Expand Down Expand Up @@ -367,6 +390,7 @@ typedef GDExtensionBool (*GDExtensionScriptInstanceHasMethod)(GDExtensionScriptI

typedef void (*GDExtensionScriptInstanceCall)(GDExtensionScriptInstanceDataPtr p_self, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error);
typedef void (*GDExtensionScriptInstanceNotification)(GDExtensionScriptInstanceDataPtr p_instance, int32_t p_what);
typedef void (*GDExtensionScriptInstanceNotification2)(GDExtensionScriptInstanceDataPtr p_instance, int32_t p_what, bool p_reversed);
typedef void (*GDExtensionScriptInstanceToString)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out);

typedef void (*GDExtensionScriptInstanceRefCountIncremented)(GDExtensionScriptInstanceDataPtr p_instance);
Expand Down Expand Up @@ -403,6 +427,7 @@ typedef struct {

GDExtensionScriptInstanceCall call_func;
GDExtensionScriptInstanceNotification notification_func;
GDExtensionScriptInstanceNotification2 notification_func2;

GDExtensionScriptInstanceToString to_string_func;

Expand Down Expand Up @@ -2178,13 +2203,30 @@ typedef void *(*GDExtensionInterfaceClassdbGetClassTag)(GDExtensionConstStringNa
*
* Provided struct can be safely freed once the function returns.
*
* This is deprecated. Use `classdb_register_extension_class2` instead.
*
* @param p_library A pointer the library received by the GDExtension's entry point function.
* @param p_class_name A pointer to a StringName with the class name.
* @param p_parent_class_name A pointer to a StringName with the parent class name.
* @param p_extension_funcs A pointer to a GDExtensionClassCreationInfo struct.
*/
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo *p_extension_funcs);

/**
* @name classdb_register_extension_class2
* @since 4.2
*
* Registers an extension class in the ClassDB.
*
* Provided struct can be safely freed once the function returns.
*
* @param p_library A pointer the library received by the GDExtension's entry point function.
* @param p_class_name A pointer to a StringName with the class name.
* @param p_parent_class_name A pointer to a StringName with the parent class name.
* @param p_extension_funcs A pointer to a GDExtensionClassCreationInfo2 struct.
*/
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass2)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo2 *p_extension_funcs);

/**
* @name classdb_register_extension_class_method
* @since 4.1
Expand Down
6 changes: 3 additions & 3 deletions include/godot_cpp/classes/wrapped.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class Wrapped {
bool _property_get_revert(const StringName &p_name, Variant &r_property) const { return false; }
String _to_string() const { return "[" + String(get_class_static()) + ":" + itos(get_instance_id()) + "]"; }

static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what) {}
static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what, bool p_reversed) {}
static GDExtensionBool set_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value) { return false; }
static GDExtensionBool get_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret) { return false; }
static const GDExtensionPropertyInfo *get_property_list_bind(GDExtensionClassInstancePtr p_instance, uint32_t *r_count) { return nullptr; }
Expand Down Expand Up @@ -187,13 +187,13 @@ public:
return new_object->_owner; \
} \
\
static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what) { \
static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what, bool p_reversed) { \
if (p_instance && m_class::_get_notification()) { \
if (m_class::_get_notification() != m_inherits::_get_notification()) { \
m_class *cls = reinterpret_cast<m_class *>(p_instance); \
return cls->_notification(p_what); \
} \
m_inherits::notification_bind(p_instance, p_what); \
m_inherits::notification_bind(p_instance, p_what, p_reversed); \
} \
} \
\
Expand Down
7 changes: 4 additions & 3 deletions include/godot_cpp/core/class_db.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ void ClassDB::_register_class(bool p_virtual) {
class_register_order.push_back(cl.name);

// Register this class with Godot
GDExtensionClassCreationInfo class_info = {
GDExtensionClassCreationInfo2 class_info = {
p_virtual, // GDExtensionBool is_virtual;
is_abstract, // GDExtensionBool is_abstract;
T::set_bind, // GDExtensionClassSet set_func;
Expand All @@ -183,7 +183,8 @@ void ClassDB::_register_class(bool p_virtual) {
T::free_property_list_bind, // GDExtensionClassFreePropertyList free_property_list_func;
T::property_can_revert_bind, // GDExtensionClassPropertyCanRevert property_can_revert_func;
T::property_get_revert_bind, // GDExtensionClassPropertyGetRevert property_get_revert_func;
T::notification_bind, // GDExtensionClassNotification notification_func;
nullptr, // Deprecated. GDExtensionClassNotification notification_func;
T::notification_bind, // GDExtensionClassNotification2 notification_func2;
T::to_string_bind, // GDExtensionClassToString to_string_func;
nullptr, // GDExtensionClassReference reference_func;
nullptr, // GDExtensionClassUnreference unreference_func;
Expand All @@ -194,7 +195,7 @@ void ClassDB::_register_class(bool p_virtual) {
(void *)&T::get_class_static(), // void *class_userdata;
};

internal::gdextension_interface_classdb_register_extension_class(internal::library, cl.name._native_ptr(), cl.parent_name._native_ptr(), &class_info);
internal::gdextension_interface_classdb_register_extension_class2(internal::library, cl.name._native_ptr(), cl.parent_name._native_ptr(), &class_info);

// call bind_methods etc. to register all members of the class
T::initialize_class();
Expand Down
1 change: 1 addition & 0 deletions include/godot_cpp/godot.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ extern "C" GDExtensionInterfaceClassdbConstructObject gdextension_interface_clas
extern "C" GDExtensionInterfaceClassdbGetMethodBind gdextension_interface_classdb_get_method_bind;
extern "C" GDExtensionInterfaceClassdbGetClassTag gdextension_interface_classdb_get_class_tag;
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClass gdextension_interface_classdb_register_extension_class;
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClass2 gdextension_interface_classdb_register_extension_class2;
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_method;
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant gdextension_interface_classdb_register_extension_class_integer_constant;
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassProperty gdextension_interface_classdb_register_extension_class_property;
Expand Down
2 changes: 2 additions & 0 deletions src/godot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ GDExtensionInterfaceClassdbConstructObject gdextension_interface_classdb_constru
GDExtensionInterfaceClassdbGetMethodBind gdextension_interface_classdb_get_method_bind = nullptr;
GDExtensionInterfaceClassdbGetClassTag gdextension_interface_classdb_get_class_tag = nullptr;
GDExtensionInterfaceClassdbRegisterExtensionClass gdextension_interface_classdb_register_extension_class = nullptr;
GDExtensionInterfaceClassdbRegisterExtensionClass2 gdextension_interface_classdb_register_extension_class2 = nullptr;
GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_method = nullptr;
GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant gdextension_interface_classdb_register_extension_class_integer_constant = nullptr;
GDExtensionInterfaceClassdbRegisterExtensionClassProperty gdextension_interface_classdb_register_extension_class_property = nullptr;
Expand Down Expand Up @@ -360,6 +361,7 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
LOAD_PROC_ADDRESS(classdb_get_method_bind, GDExtensionInterfaceClassdbGetMethodBind);
LOAD_PROC_ADDRESS(classdb_get_class_tag, GDExtensionInterfaceClassdbGetClassTag);
LOAD_PROC_ADDRESS(classdb_register_extension_class, GDExtensionInterfaceClassdbRegisterExtensionClass);
LOAD_PROC_ADDRESS(classdb_register_extension_class2, GDExtensionInterfaceClassdbRegisterExtensionClass2);
LOAD_PROC_ADDRESS(classdb_register_extension_class_method, GDExtensionInterfaceClassdbRegisterExtensionClassMethod);
LOAD_PROC_ADDRESS(classdb_register_extension_class_integer_constant, GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant);
LOAD_PROC_ADDRESS(classdb_register_extension_class_property, GDExtensionInterfaceClassdbRegisterExtensionClassProperty);
Expand Down

0 comments on commit cc10911

Please sign in to comment.