Skip to content
Merged
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
7 changes: 7 additions & 0 deletions godot-headers/godot/gdextension_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ typedef const void *GDExtensionMethodBindPtr;
typedef int64_t GDExtensionInt;
typedef uint8_t GDExtensionBool;
typedef uint64_t GDObjectInstanceID;
typedef void *GDExtensionRefPtr;
typedef const void *GDExtensionConstRefPtr;

/* VARIANT DATA I/O */

Expand Down Expand Up @@ -551,6 +553,11 @@ typedef struct {
GDExtensionObjectPtr (*object_get_instance_from_id)(GDObjectInstanceID p_instance_id);
GDObjectInstanceID (*object_get_instance_id)(GDExtensionConstObjectPtr p_object);

/* REFERENCE */

GDExtensionObjectPtr (*ref_get_object)(GDExtensionConstRefPtr p_ref);
void (*ref_set_object)(GDExtensionRefPtr p_ref, GDExtensionObjectPtr p_object);

/* SCRIPT INSTANCE */

GDExtensionScriptInstancePtr (*script_instance_create)(const GDExtensionScriptInstanceInfo *p_info, GDExtensionScriptInstanceDataPtr p_instance_data);
Expand Down
15 changes: 13 additions & 2 deletions include/godot_cpp/classes/ref.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,13 +240,24 @@ class Ref {
template <class T>
struct PtrToArg<Ref<T>> {
_FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) {
return Ref<T>(reinterpret_cast<T *>(godot::internal::gde_interface->object_get_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr)), godot::internal::token, &T::___binding_callbacks)));
GDExtensionRefPtr ref = (GDExtensionRefPtr)p_ptr;
ERR_FAIL_NULL_V(ref, Ref<T>());

T *obj = reinterpret_cast<T *>(godot::internal::gde_interface->object_get_instance_binding(godot::internal::gde_interface->ref_get_object(ref), godot::internal::token, &T::___binding_callbacks));
return Ref<T>(obj);
}

typedef Ref<T> EncodeT;

_FORCE_INLINE_ static void encode(Ref<T> p_val, void *p_ptr) {
*reinterpret_cast<const GodotObject **>(p_ptr) = p_val->_owner;
GDExtensionRefPtr ref = (GDExtensionRefPtr)p_ptr;
ERR_FAIL_NULL(ref);

// This code assumes that p_ptr points to an unset Ref<T> variable on the Godot side
// so we only set it if we have an object to set.
if (p_val.is_valid()) {
godot::internal::gde_interface->ref_set_object(ref, p_val->_owner);
}
}
};

Expand Down