gdnative_core/object/
bounds.rs1use crate::object::memory::*;
7use crate::object::ownership::*;
8use crate::object::*;
9
10pub trait MemorySpec: Sized {
15 #[doc(hidden)]
17 type PtrWrapper: PtrWrapper;
18
19 #[doc(hidden)]
20 unsafe fn impl_from_maybe_ref_counted<T: GodotObject<Memory = Self>>(
21 ptr: NonNull<sys::godot_object>,
22 ) -> Option<Ref<T, Unique>>
23 where
24 Self: Memory;
25
26 #[doc(hidden)]
27 unsafe fn impl_assume_safe<'a, T: GodotObject<Memory = Self>>(
28 this: &Ref<T, Shared>,
29 ) -> TRef<'a, T, Shared>
30 where
31 Self: Memory;
32
33 #[doc(hidden)]
34 unsafe fn impl_assume_unique<T: GodotObject<Memory = Self>>(
35 this: Ref<T, Shared>,
36 ) -> Ref<T, Unique>
37 where
38 Self: Memory;
39
40 #[doc(hidden)]
41 unsafe fn maybe_add_ref<T: GodotObject<Memory = Self>>(raw: &RawObject<T>)
42 where
43 Self: Memory;
44
45 #[doc(hidden)]
46 unsafe fn maybe_init_ref<T: GodotObject<Memory = Self>>(raw: &RawObject<T>)
47 where
48 Self: Memory;
49}
50
51impl MemorySpec for ManuallyManaged {
52 type PtrWrapper = Forget;
53
54 #[inline(always)]
55 unsafe fn impl_from_maybe_ref_counted<T: GodotObject<Memory = Self>>(
56 ptr: NonNull<sys::godot_object>,
57 ) -> Option<Ref<T, Unique>> {
58 if RawObject::<ReferenceCountedClassPlaceholder>::try_from_sys_ref(ptr).is_some() {
59 drop(Ref::<ReferenceCountedClassPlaceholder, Unique>::init_from_sys(ptr));
60 None
61 } else {
62 let obj = Ref::<ManuallyManagedClassPlaceholder, Unique>::init_from_sys(ptr);
63
64 if obj.as_raw().is_class::<T>() {
65 Some(obj.cast_unchecked())
66 } else {
67 obj.free();
68 None
69 }
70 }
71 }
72
73 #[inline(always)]
74 unsafe fn impl_assume_safe<'a, T: GodotObject<Memory = Self>>(
75 this: &Ref<T, Shared>,
76 ) -> TRef<'a, T, Shared> {
77 debug_assert!(
78 this.is_instance_sane(),
79 "assume_safe called on an invalid pointer"
80 );
81 this.assume_safe_unchecked()
82 }
83
84 #[inline(always)]
85 unsafe fn impl_assume_unique<T: GodotObject<Memory = Self>>(
86 this: Ref<T, Shared>,
87 ) -> Ref<T, Unique> {
88 debug_assert!(
89 this.is_instance_sane(),
90 "assume_unique called on an invalid pointer"
91 );
92 this.cast_access()
93 }
94
95 #[inline]
96 unsafe fn maybe_add_ref<T: GodotObject<Memory = Self>>(_raw: &RawObject<T>) {}
97 #[inline]
98 unsafe fn maybe_init_ref<T: GodotObject<Memory = Self>>(_raw: &RawObject<T>) {}
99}
100
101impl MemorySpec for RefCounted {
102 type PtrWrapper = UnRef;
103
104 #[inline(always)]
105 unsafe fn impl_from_maybe_ref_counted<T: GodotObject<Memory = Self>>(
106 ptr: NonNull<sys::godot_object>,
107 ) -> Option<Ref<T, Unique>> {
108 if RawObject::<ReferenceCountedClassPlaceholder>::try_from_sys_ref(ptr).is_some() {
109 let obj = Ref::<ReferenceCountedClassPlaceholder, Unique>::init_from_sys(ptr);
110
111 if obj.as_raw().is_class::<T>() {
112 Some(obj.cast_unchecked())
113 } else {
114 None
115 }
116 } else {
117 RawObject::<ManuallyManagedClassPlaceholder>::from_sys_ref_unchecked(ptr).free();
118 None
119 }
120 }
121
122 #[inline(always)]
123 unsafe fn impl_assume_safe<'a, T: GodotObject<Memory = Self>>(
124 this: &Ref<T, Shared>,
125 ) -> TRef<'a, T, Shared> {
126 this.assume_safe_unchecked()
127 }
128
129 #[inline(always)]
130 unsafe fn impl_assume_unique<T: GodotObject<Memory = Self>>(
131 this: Ref<T, Shared>,
132 ) -> Ref<T, Unique> {
133 this.cast_access()
134 }
135
136 #[inline]
137 unsafe fn maybe_add_ref<T: GodotObject<Memory = Self>>(raw: &RawObject<T>) {
138 raw.add_ref();
139 }
140
141 #[inline]
142 unsafe fn maybe_init_ref<T: GodotObject<Memory = Self>>(raw: &RawObject<T>) {
143 raw.init_ref_count();
144 }
145}
146
147pub trait PtrWrapper {
152 fn new(ptr: NonNull<sys::godot_object>) -> Self;
153 fn as_non_null(&self) -> NonNull<sys::godot_object>;
154
155 #[inline]
156 fn as_ptr(&self) -> *mut sys::godot_object {
157 self.as_non_null().as_ptr()
158 }
159}
160
161#[derive(Copy, Clone)]
163pub struct Forget(NonNull<sys::godot_object>);
164impl PtrWrapper for Forget {
165 #[inline]
166 fn new(ptr: NonNull<sys::godot_object>) -> Self {
167 Forget(ptr)
168 }
169
170 #[inline]
171 fn as_non_null(&self) -> NonNull<sys::godot_object> {
172 self.0
173 }
174}
175
176pub struct UnRef(NonNull<sys::godot_object>);
178impl PtrWrapper for UnRef {
179 #[inline]
180 fn new(ptr: NonNull<sys::godot_object>) -> Self {
181 UnRef(ptr)
182 }
183
184 #[inline]
185 fn as_non_null(&self) -> NonNull<sys::godot_object> {
186 self.0
187 }
188}
189impl Drop for UnRef {
190 #[inline]
191 fn drop(&mut self) {
192 unsafe {
193 let raw = RawObject::<ReferenceCountedClassPlaceholder>::from_sys_ref_unchecked(self.0);
194 raw.unref_and_free_if_last();
195 }
196 }
197}
198
199pub trait LifetimeConstraint<Kind: Memory> {}
205
206#[doc(hidden)]
208pub struct AssumeSafeLifetime<'a, 'r> {
209 _marker: PhantomData<(&'a (), &'r ())>,
210}
211
212impl<'a, 'r> LifetimeConstraint<ManuallyManaged> for AssumeSafeLifetime<'a, 'r> {}
213impl<'a, 'r: 'a> LifetimeConstraint<RefCounted> for AssumeSafeLifetime<'a, 'r> {}
214
215pub unsafe trait SafeDeref<Kind: Memory, Own: Ownership> {
221 #[doc(hidden)]
223 fn impl_as_ref<T: GodotObject<Memory = Kind>>(this: &Ref<T, Own>) -> TRef<'_, T, Own>;
224}
225
226pub unsafe trait SafeAsRaw<Kind: Memory, Own: Ownership> {
228 #[doc(hidden)]
230 fn impl_as_raw<T: GodotObject<Memory = Kind>>(this: &Ref<T, Own>) -> &RawObject<T>;
231}
232
233pub struct RefImplBound {
238 _private: (),
239}
240
241unsafe impl SafeDeref<ManuallyManaged, Unique> for RefImplBound {
242 #[inline]
243 fn impl_as_ref<T: GodotObject<Memory = ManuallyManaged>>(
244 this: &Ref<T, Unique>,
245 ) -> TRef<'_, T, Unique> {
246 unsafe { this.assume_safe_unchecked() }
247 }
248}
249
250unsafe impl<Own: LocalThreadOwnership> SafeDeref<RefCounted, Own> for RefImplBound {
251 #[inline]
252 fn impl_as_ref<T: GodotObject<Memory = RefCounted>>(this: &Ref<T, Own>) -> TRef<'_, T, Own> {
253 unsafe { this.assume_safe_unchecked() }
254 }
255}
256
257unsafe impl SafeAsRaw<ManuallyManaged, Unique> for RefImplBound {
258 #[inline]
259 fn impl_as_raw<T: GodotObject<Memory = ManuallyManaged>>(
260 this: &Ref<T, Unique>,
261 ) -> &RawObject<T> {
262 unsafe { this.as_raw_unchecked() }
263 }
264}
265
266unsafe impl<Own: Ownership> SafeAsRaw<RefCounted, Own> for RefImplBound {
267 #[inline]
268 fn impl_as_raw<T: GodotObject<Memory = RefCounted>>(this: &Ref<T, Own>) -> &RawObject<T> {
269 unsafe { this.as_raw_unchecked() }
270 }
271}