gdnative_core/object/
as_arg.rs

1use crate::export::user_data::Map;
2use crate::export::NativeClass;
3use crate::object::ownership::{Ownership, Shared, Unique};
4use crate::object::{GodotObject, Instance, Null, Ref, SubClass, TInstance, TRef};
5
6/// Trait for safe conversion from Godot object references into API method arguments. This is
7/// a sealed trait with no public interface.
8///
9/// In order to enforce thread safety statically, the ability to be passed to the engine is only
10/// given to some reference types. Specifically, they are:
11///
12/// - All *owned* `Ref<T, Unique>` references. The `Unique` access is lost if passed into a
13///   method.
14/// - Owned and borrowed `Shared` references, including temporary ones (`TRef`).
15///
16/// It's unsound to pass `ThreadLocal` references to the engine because there is no guarantee
17/// that the reference will stay on the same thread.
18///
19/// To explicitly pass a null reference to the engine, use `Null::null` or `GodotObject::null`.
20pub trait AsArg<T>: private::Sealed {
21    #[doc(hidden)]
22    fn as_arg_ptr(&self) -> *mut sys::godot_object;
23
24    #[doc(hidden)]
25    #[inline]
26    unsafe fn to_arg_variant(&self) -> crate::core_types::Variant {
27        crate::core_types::Variant::from_object_ptr(self.as_arg_ptr())
28    }
29}
30
31/// Trait for safe conversion from Godot object references into Variant. This is
32/// a sealed trait with no public interface.
33///
34/// Used for `Variant` methods and implementations as a trait bound to improve type inference.
35pub trait AsVariant: AsArg<<Self as AsVariant>::Target> {
36    type Target;
37}
38
39// ----------------------------------------------------------------------------------------------------------------------------------------------
40// Sealed
41
42mod private {
43    pub trait Sealed {}
44}
45
46// Null
47impl<T> private::Sealed for Null<T> {}
48
49// Temporary references (shared ownership)
50impl<'a, T: GodotObject> private::Sealed for TRef<'a, T, Shared> {}
51impl<'a, T: GodotObject> private::Sealed for &'a Ref<T, Shared> {}
52impl<'a, T: NativeClass> private::Sealed for TInstance<'a, T, Shared> {}
53impl<'a, T: NativeClass> private::Sealed for &'a Instance<T, Shared> {}
54
55// Persistent references (any ownership)
56impl<T: GodotObject, Own: Ownership> private::Sealed for Ref<T, Own> {}
57impl<T: NativeClass, Own: Ownership> private::Sealed for Instance<T, Own> {}
58
59// ----------------------------------------------------------------------------------------------------------------------------------------------
60// Null
61
62impl<T: GodotObject> AsArg<T> for Null<T> {
63    #[inline]
64    fn as_arg_ptr(&self) -> *mut sys::godot_object {
65        std::ptr::null_mut()
66    }
67}
68
69impl<T: GodotObject> AsVariant for Null<T> {
70    type Target = T;
71}
72
73// ----------------------------------------------------------------------------------------------------------------------------------------------
74// TRef
75
76impl<'a, T, U> AsArg<U> for TRef<'a, T, Shared>
77where
78    T: GodotObject + SubClass<U>,
79    U: GodotObject,
80{
81    #[inline]
82    fn as_arg_ptr(&self) -> *mut sys::godot_object {
83        self.as_ptr()
84    }
85}
86
87impl<'a, T: GodotObject> AsVariant for TRef<'a, T, Shared> {
88    type Target = T;
89}
90
91// ----------------------------------------------------------------------------------------------------------------------------------------------
92// Ref
93
94impl<T, U> AsArg<U> for Ref<T, Shared>
95where
96    T: GodotObject + SubClass<U>,
97    U: GodotObject,
98{
99    #[inline]
100    fn as_arg_ptr(&self) -> *mut sys::godot_object {
101        self.as_ptr()
102    }
103}
104
105impl<T, U> AsArg<U> for Ref<T, Unique>
106where
107    T: GodotObject + SubClass<U>,
108    U: GodotObject,
109{
110    #[inline]
111    fn as_arg_ptr(&self) -> *mut sys::godot_object {
112        self.as_ptr()
113    }
114}
115
116impl<T: GodotObject> AsVariant for Ref<T, Unique> {
117    type Target = T;
118}
119
120impl<'a, T, U> AsArg<U> for &'a Ref<T, Shared>
121where
122    T: GodotObject + SubClass<U>,
123    U: GodotObject,
124{
125    #[inline]
126    fn as_arg_ptr(&self) -> *mut sys::godot_object {
127        self.as_ptr()
128    }
129}
130
131impl<T: GodotObject> AsVariant for Ref<T, Shared> {
132    type Target = T;
133}
134
135impl<'a, T: GodotObject> AsVariant for &'a Ref<T, Shared> {
136    type Target = T;
137}
138
139// ----------------------------------------------------------------------------------------------------------------------------------------------
140// TInstance
141
142impl<'a, T, U> AsArg<U> for TInstance<'a, T, Shared>
143where
144    T: NativeClass,
145    T::Base: GodotObject + SubClass<U>,
146    T::UserData: Map,
147    U: GodotObject,
148{
149    #[inline]
150    fn as_arg_ptr(&self) -> *mut sys::godot_object {
151        self.as_base_ptr()
152    }
153}
154
155// ----------------------------------------------------------------------------------------------------------------------------------------------
156// Instance
157
158impl<T, U, Own: Ownership> AsArg<U> for Instance<T, Own>
159where
160    T: NativeClass,
161    T::Base: GodotObject + SubClass<U>,
162    T::UserData: Map,
163    U: GodotObject,
164{
165    #[inline]
166    fn as_arg_ptr(&self) -> *mut sys::godot_object {
167        self.as_base_ptr()
168    }
169}
170
171impl<'a, T, U> AsArg<U> for &'a Instance<T, Shared>
172where
173    T: NativeClass,
174    T::Base: GodotObject + SubClass<U>,
175    T::UserData: Map,
176    U: GodotObject,
177{
178    #[inline]
179    fn as_arg_ptr(&self) -> *mut sys::godot_object {
180        self.as_base_ptr()
181    }
182}