Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability for extensions to clear object instance bindings #67285

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions core/extension/gdextension_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,11 @@ static void gdextension_object_set_instance_binding(GDExtensionObjectPtr p_objec
o->set_instance_binding(p_token, p_binding, p_callbacks);
}

static void gdextension_object_clear_instance_binding(GDExtensionObjectPtr p_object, void *p_token) {
Object *o = (Object *)p_object;
o->clear_instance_binding(p_token);
}

static void gdextension_object_set_instance(GDExtensionObjectPtr p_object, GDExtensionConstStringNamePtr p_classname, GDExtensionClassInstancePtr p_instance) {
const StringName classname = *reinterpret_cast<const StringName *>(p_classname);
Object *o = (Object *)p_object;
Expand Down Expand Up @@ -1051,6 +1056,7 @@ void gdextension_setup_interface(GDExtensionInterface *p_interface) {
gde_interface.global_get_singleton = gdextension_global_get_singleton;
gde_interface.object_get_instance_binding = gdextension_object_get_instance_binding;
gde_interface.object_set_instance_binding = gdextension_object_set_instance_binding;
gde_interface.object_clear_instance_binding = gdextension_object_clear_instance_binding;
gde_interface.object_set_instance = gdextension_object_set_instance;

gde_interface.object_cast_to = gdextension_object_cast_to;
Expand Down
1 change: 1 addition & 0 deletions core/extension/gdextension_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,7 @@ typedef struct {

void *(*object_get_instance_binding)(GDExtensionObjectPtr p_o, void *p_token, const GDExtensionInstanceBindingCallbacks *p_callbacks);
void (*object_set_instance_binding)(GDExtensionObjectPtr p_o, void *p_token, void *p_binding, const GDExtensionInstanceBindingCallbacks *p_callbacks);
void (*object_clear_instance_binding)(GDExtensionObjectPtr p_o, void *p_token);

void (*object_set_instance)(GDExtensionObjectPtr p_o, GDExtensionConstStringNamePtr p_classname, GDExtensionClassInstancePtr p_instance); /* p_classname should be a registered extension class and should extend the p_o object's class. */

Expand Down
12 changes: 12 additions & 0 deletions core/object/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1744,6 +1744,18 @@ void *Object::get_instance_binding(void *p_token, const GDExtensionInstanceBindi
return binding;
}

void Object::clear_instance_binding(void *p_token) {
ERR_FAIL_COND(_instance_bindings == nullptr);
for (uint32_t i = 0; i < _instance_binding_count; i++) {
InstanceBinding &instance_binding = _instance_bindings[i];
if (instance_binding.token == p_token) {
instance_binding.free_callback(p_token, this, instance_binding.binding);
instance_binding = InstanceBinding();
break;
}
}
}

bool Object::has_instance_binding(void *p_token) {
bool found = false;
_instance_binding_mutex.lock();
Expand Down
2 changes: 2 additions & 0 deletions core/object/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,8 @@ class Object {
void *get_instance_binding(void *p_token, const GDExtensionInstanceBindingCallbacks *p_callbacks);
// Used on creation by binding only.
void set_instance_binding(void *p_token, void *p_binding, const GDExtensionInstanceBindingCallbacks *p_callbacks);
// Used on unloading by binding only.
void clear_instance_binding(void *p_token);
bool has_instance_binding(void *p_token);

void clear_internal_resource_paths();
Expand Down