Skip to content

Commit 27e7d56

Browse files
committed
Fix virtual GDExtension method Ref<T> conversion
1 parent c217059 commit 27e7d56

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

godot-headers/godot/gdextension_interface.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ typedef const void *GDExtensionMethodBindPtr;
154154
typedef int64_t GDExtensionInt;
155155
typedef uint8_t GDExtensionBool;
156156
typedef uint64_t GDObjectInstanceID;
157+
typedef void *GDExtensionRefPtr;
158+
typedef const void *GDExtensionConstRefPtr;
157159

158160
/* VARIANT DATA I/O */
159161

@@ -551,6 +553,11 @@ typedef struct {
551553
GDExtensionObjectPtr (*object_get_instance_from_id)(GDObjectInstanceID p_instance_id);
552554
GDObjectInstanceID (*object_get_instance_id)(GDExtensionConstObjectPtr p_object);
553555

556+
/* REFERENCE */
557+
558+
GDExtensionObjectPtr (*ref_get_object)(GDExtensionConstRefPtr p_ref);
559+
void (*ref_set_object)(GDExtensionRefPtr p_ref, GDExtensionObjectPtr p_object);
560+
554561
/* SCRIPT INSTANCE */
555562

556563
GDExtensionScriptInstancePtr (*script_instance_create)(const GDExtensionScriptInstanceInfo *p_info, GDExtensionScriptInstanceDataPtr p_instance_data);

include/godot_cpp/classes/ref.hpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,13 +240,24 @@ class Ref {
240240
template <class T>
241241
struct PtrToArg<Ref<T>> {
242242
_FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) {
243-
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)));
243+
GDExtensionRefPtr ref = (GDExtensionRefPtr)p_ptr;
244+
ERR_FAIL_NULL_V(ref, Ref<T>());
245+
246+
T *obj = reinterpret_cast<T *>(godot::internal::gdn_interface->object_get_instance_binding(godot::internal::gdn_interface->ref_get_object(ref), godot::internal::token, &T::___binding_callbacks));
247+
return Ref<T>(obj);
244248
}
245249

246250
typedef Ref<T> EncodeT;
247251

248252
_FORCE_INLINE_ static void encode(Ref<T> p_val, void *p_ptr) {
249-
*reinterpret_cast<const GodotObject **>(p_ptr) = p_val->_owner;
253+
GDExtensionRefPtr ref = (GDExtensionRefPtr)p_ptr;
254+
ERR_FAIL_NULL(ref);
255+
256+
// This code assumes that p_ptr points to an unset Ref<T> variable on the Godot side
257+
// so we only set it if we have an object to set.
258+
if (p_val.is_valid()) {
259+
godot::internal::gdn_interface->ref_set_object(ref, p_val->_owner);
260+
}
250261
}
251262
};
252263

0 commit comments

Comments
 (0)