Add is_instance_id_valid() method to allow GDNative ptr caching
Created by: Cygon
This adds a method is_instance_id_valid()
to the GDNative API that language bindings can use to detect when stored node pointers become invalid.
This achieves a small performance gain because the alternative is to store only the NodePath
and resolve (as well as cast) the node from the scene each time it needs to be accessed:
Without this is_instance_id_valid()
:
// Needs to follow a NodePath each frame and repeat the dynamic cast
godot::KinematicBody *get_kinematic_body_node() const {
const godot::Node *target = get_node_or_null(this->kinematic_body_node_path);
if(target == nullptr) {
return nullptr;
} else {
return godot::Object::cast_to<ComponentType>(target);
}
}
With is_instance_id_valid()
:
// Can reuse the pointer if the (also stored) id still checks out
godot::KinematicBody *get_kinematic_body_node() const {
if(this->kinematic_body_node != nullptr) {
if(godot::Object::is_instance_id_valid(this->kinematic_body_instance_id)) {
return this->kinematic_body_node;
}
}
// Stored pointer was null or id didn't check out
const godot::Node *node = get_node_or_null(this->kinematic_body_node_path);
if(node == nullptr) {
this->kinematic_body_node = nullptr;
} else {
this->kinematic_body_node = godot::Object::cast_to<godot::KinematicBody>(node);
if(this->kinematic_body_node != nullptr) {
this->kinematic_body_instance_id = this->kinematic_body_node->get_instance_id();
}
}
return this->kinematic_body_node;
}
This implements the changes proposed in #28478 (closed).
Note that I added a call to rw_lock->read_lock()
to both instance_id_validate()
and instance_validate()
as this seems to be the way all methods inside core/object.cpp
handle things (but perhaps the future could be a lock-free hash table if an implementation exists that works on all required platforms)