gdnative_core/object/
mod.rs

1//! Provides types to interact with the Godot `Object` class hierarchy
2//!
3//! This module contains wrappers and helpers to interact with Godot objects.
4//! In Godot, classes stand in an inheritance relationship, with the root at `Object`.
5//!
6//! If you are looking for how to manage user-defined types (native scripts),
7//! check out the [`export`][crate::export] module.
8
9use std::borrow::Borrow;
10use std::ffi::CString;
11use std::fmt::{self, Debug};
12use std::hash::{Hash, Hasher};
13use std::marker::PhantomData;
14use std::ops::Deref;
15use std::ptr::NonNull;
16
17use bounds::{
18    AssumeSafeLifetime, LifetimeConstraint, MemorySpec, PtrWrapper, RefImplBound, SafeAsRaw,
19    SafeDeref,
20};
21use memory::{ManuallyManaged, Memory, RefCounted};
22use ownership::{NonUniqueOwnership, Ownership, Shared, ThreadLocal, Unique};
23
24use crate::export::NativeClass;
25use crate::private::{get_api, ManuallyManagedClassPlaceholder, ReferenceCountedClassPlaceholder};
26use crate::sys;
27
28pub use as_arg::*;
29pub use instance::*;
30pub use new_ref::NewRef;
31pub use raw::RawObject;
32
33pub mod bounds;
34pub mod memory;
35pub mod ownership;
36
37mod as_arg;
38mod instance;
39mod new_ref;
40mod raw;
41
42/// Trait for Godot API objects. This trait is sealed, and implemented for generated wrapper
43/// types.
44///
45/// Bare `GodotObject` references, like `&Node`, can be used safely, but do not track thread
46/// access states, which limits their usefulness to some extent. It's not, for example, possible
47/// to pass a `&Node` into an API method because it might have came from a `Unique` reference.
48/// As such, it's usually better to use `Ref` and `TRef`s whenever possible.
49///
50/// For convenience. it's possible to use bare references as `owner` arguments in exported
51/// methods when using NativeScript, but the limitations above should be kept in mind. See
52/// the `OwnerArg` for more information.
53///
54/// IF it's ever needed to obtain persistent references out of bare references, the `assume_`
55/// methods can be used.
56pub unsafe trait GodotObject: Sized + crate::private::godot_object::Sealed {
57    /// The memory management kind of this type. This modifies the behavior of the
58    /// [`Ref`](struct.Ref.html) smart pointer. See its type-level documentation for more
59    /// information.
60    type Memory: Memory;
61
62    fn class_name() -> &'static str;
63
64    /// Creates an explicitly null reference of `Self` as a method argument. This makes type
65    /// inference easier for the compiler compared to `Option`.
66    #[inline]
67    fn null() -> Null<Self> {
68        Null::null()
69    }
70
71    /// Creates a new instance of `Self` using a zero-argument constructor, as a `Unique`
72    /// reference.
73    #[inline]
74    fn new() -> Ref<Self, Unique>
75    where
76        Self: Instanciable,
77    {
78        Ref::new()
79    }
80
81    /// Performs a dynamic reference downcast to target type.
82    ///
83    /// The `cast` method can only be used for downcasts. For statically casting to a
84    /// supertype, use `upcast` instead.
85    ///
86    /// This method is only for conversion between engine types. To downcast to a `NativeScript`
87    /// type from its base type, see `Ref::cast_instance` and `TRef::cast_instance`.
88    #[inline]
89    fn cast<T>(&self) -> Option<&T>
90    where
91        T: GodotObject + SubClass<Self>,
92    {
93        self.as_raw().cast().map(T::cast_ref)
94    }
95
96    /// Performs a static reference upcast to a supertype that is guaranteed to be valid.
97    ///
98    /// This is guaranteed to be a no-op at runtime.
99    #[inline(always)]
100    fn upcast<T>(&self) -> &T
101    where
102        T: GodotObject,
103        Self: SubClass<T>,
104    {
105        unsafe { T::cast_ref(self.as_raw().cast_unchecked()) }
106    }
107
108    /// Creates a reference to `Self` given a `RawObject` reference. This is an internal
109    /// interface,
110    #[doc(hidden)]
111    #[inline]
112    fn cast_ref(raw: &RawObject<Self>) -> &Self {
113        unsafe { &*(raw as *const _ as *const _) }
114    }
115
116    /// Casts `self` to `RawObject`. This is an internal interface.
117    #[doc(hidden)]
118    #[inline]
119    fn as_raw(&self) -> &RawObject<Self> {
120        unsafe { &*(self as *const _ as *const _) }
121    }
122
123    /// Casts `self` to a raw pointer. This is an internal interface.
124    #[doc(hidden)]
125    #[inline]
126    fn as_ptr(&self) -> *mut sys::godot_object {
127        self.as_raw().sys().as_ptr()
128    }
129
130    /// Creates a persistent reference to the same Godot object with shared thread access.
131    ///
132    /// # Safety
133    ///
134    /// There must not be any `Unique` or `ThreadLocal` references of the object when this
135    /// is called. This causes undefined behavior otherwise.
136    #[inline]
137    unsafe fn assume_shared(&self) -> Ref<Self, Shared>
138    where
139        Self: Sized,
140    {
141        Ref::from_sys(self.as_raw().sys())
142    }
143
144    /// Creates a persistent reference to the same Godot object with thread-local thread access.
145    ///
146    /// # Safety
147    ///
148    /// There must not be any `Unique` or `Shared` references of the object when this
149    /// is called. This causes undefined behavior otherwise.
150    #[inline]
151    unsafe fn assume_thread_local(&self) -> Ref<Self, ThreadLocal>
152    where
153        Self: Sized + GodotObject<Memory = RefCounted>,
154    {
155        Ref::from_sys(self.as_raw().sys())
156    }
157
158    /// Creates a persistent reference to the same Godot object with unique access.
159    ///
160    /// # Safety
161    ///
162    /// **Use with care.** `Unique` is a very strong assumption that can easily be
163    /// violated. Only use this when you are **absolutely** sure you have the only reference.
164    ///
165    /// There must be no other references of the object when this is called. This causes
166    /// undefined behavior otherwise.
167    #[inline]
168    unsafe fn assume_unique(&self) -> Ref<Self, Unique>
169    where
170        Self: Sized,
171    {
172        Ref::from_sys(self.as_raw().sys())
173    }
174
175    /// Recovers a instance ID previously returned by `Object::get_instance_id` if the object is
176    /// still alive. See also `TRef::try_from_instance_id`.
177    ///
178    /// # Safety
179    ///
180    /// During the entirety of `'a`, the thread from which `try_from_instance_id` is called must
181    /// have exclusive access to the underlying object, if it is still alive.
182    #[inline]
183    unsafe fn try_from_instance_id<'a>(id: i64) -> Option<TRef<'a, Self, Shared>> {
184        TRef::try_from_instance_id(id)
185    }
186
187    /// Recovers a instance ID previously returned by `Object::get_instance_id` if the object is
188    /// still alive, and panics otherwise. This does **NOT** guarantee that the resulting
189    /// reference is safe to use.
190    ///
191    /// # Panics
192    ///
193    /// Panics if the given id refers to a destroyed object. For a non-panicking version, see
194    /// `try_from_instance_id`.
195    ///
196    /// # Safety
197    ///
198    /// During the entirety of `'a`, the thread from which `try_from_instance_id` is called must
199    /// have exclusive access to the underlying object, if it is still alive.
200    #[inline]
201    unsafe fn from_instance_id<'a>(id: i64) -> TRef<'a, Self, Shared> {
202        TRef::from_instance_id(id)
203    }
204}
205
206/// Marker trait for API types that are subclasses of another type. This trait is implemented
207/// by the bindings generator, and has no public interface. Users should not attempt to
208/// implement this trait.
209pub unsafe trait SubClass<A: GodotObject>: GodotObject {}
210unsafe impl<T: GodotObject> SubClass<T> for T {}
211
212/// GodotObjects that have a zero argument constructor.
213pub trait Instanciable: GodotObject {
214    fn construct() -> Ref<Self, Unique>;
215}
216
217/// Manually managed Godot classes implementing `queue_free`. This trait has no public
218/// interface. See `Ref::queue_free`.
219pub trait QueueFree: GodotObject {
220    /// Deallocate the object in the near future.
221    ///
222    /// # Safety
223    ///
224    /// When this function is dequeued no references to this
225    /// object must be held and dereferenced.
226    #[doc(hidden)]
227    unsafe fn godot_queue_free(sys: *mut sys::godot_object);
228}
229
230/// A polymorphic smart pointer for Godot objects whose behavior changes depending on the
231/// memory management method of the underlying type and the thread access status.
232///
233/// # Manually-managed types
234///
235/// `Shared` references to manually-managed types, like `Ref<Node, Shared>`, act like raw
236/// pointers. They are safe to alias, can be sent between threads, and can also be taken as
237/// method arguments (converted from `Variant`). They can't be used directly. Instead, it's
238/// required to obtain a safe view first. See the "Obtaining a safe view" section below for
239/// more information.
240///
241/// `ThreadLocal` references to manually-managed types cannot normally be obtained, since
242/// it does not add anything over `Shared` ones.
243///
244/// `Unique` references to manually-managed types, like `Ref<Node, Unique>`, can't be aliased
245/// or sent between threads, but can be used safely. However, they *won't* be automatically
246/// freed on drop, and are *leaked* if not passed to the engine or freed manually with `free`.
247/// `Unique` references can be obtained through constructors safely, or `assume_unique` in
248/// unsafe contexts.
249///
250/// # Reference-counted types
251///
252/// `Shared` references to reference-counted types, like `Ref<Reference, Shared>`, act like
253/// `Arc` smart pointers. New references can be created with `Clone`, and they can be sent
254/// between threads. The pointer is presumed to be always valid. As such, more operations
255/// are available even when thread safety is not assumed. However, API methods still can't be
256/// used directly, and users are required to obtain a safe view first. See the "Obtaining a
257/// safe view" section below for more information.
258///
259/// `ThreadLocal` reference to reference-counted types, like `Ref<Reference, ThreadLocal>`, add
260/// the ability to call API methods safely. Unlike `Unique` references, it's unsafe to convert
261/// them to `Shared` because there might be other `ThreadLocal` references in existence.
262///
263/// # Obtaining a safe view
264///
265/// In a lot of cases, references obtained from the engine as return values or arguments aren't
266/// safe to use, due to lack of pointer validity and thread safety guarantees in the API. As
267/// such, it's usually required to use `unsafe` code to obtain safe views of the same object
268/// before API methods can be called. The ways to cast between different reference types are as
269/// follows:
270///
271/// | From | To | Method | Note |
272/// | - | - | - | - |
273/// | `Unique` | `&'a T` | `Deref` (API methods can be called directly) / `as_ref` | - |
274/// | `ThreadLocal` | `&'a T` | `Deref` (API methods can be called directly) / `as_ref` | Only if `T` is a reference-counted type. |
275/// | `Shared` | `&'a T` | `unsafe assume_safe::<'a>` | The underlying object must be valid, and exclusive to this thread during `'a`. |
276/// | `Unique` | `ThreadLocal` | `into_thread_local` | - |
277/// | `Unique` | `Shared` | `into_shared` | - |
278/// | `Shared` | `ThreadLocal` | `unsafe assume_thread_local` | The reference must be local to the current thread. |
279/// | `Shared` / `ThreadLocal` | `Unique` | `unsafe assume_unique` | The reference must be unique. |
280/// | `ThreadLocal` | `Shared` | `unsafe assume_unique().into_shared()` | The reference must be unique. |
281///
282/// # Using as method arguments or return values
283///
284/// In order to enforce thread safety statically, the ability to be passed to the engine is only
285/// given to some reference types. Specifically, they are:
286///
287/// - All *owned* `Ref<T, Unique>` references. The `Unique` access is lost if passed into a
288///   method.
289/// - Owned and borrowed `Shared` references, including temporary ones (`TRef`).
290///
291/// It's unsound to pass `ThreadLocal` references to the engine because there is no guarantee
292/// that the reference will stay on the same thread.
293///
294/// # Conditional trait implementations
295///
296/// Many trait implementations for `Ref` are conditional, dependent on the type parameters.
297/// When viewing rustdoc documentation, you may expand the documentation on their respective
298/// `impl` blocks  for more detailed explanations of the trait bounds.
299pub struct Ref<T: GodotObject, Own: Ownership = Shared> {
300    ptr: <T::Memory as MemorySpec>::PtrWrapper,
301    _marker: PhantomData<(*const T, Own)>,
302}
303
304/// `Ref` is `Send` if the thread access is `Shared` or `Unique`.
305unsafe impl<T: GodotObject, Own: Ownership + Send> Send for Ref<T, Own> {}
306
307/// `Ref` is `Sync` if the thread access is `Shared`.
308unsafe impl<T: GodotObject, Own: Ownership + Sync> Sync for Ref<T, Own> {}
309
310/// `Ref` is `Copy` if the underlying object is manually-managed, and the access is not
311/// `Unique`.
312impl<T, Own> Copy for Ref<T, Own>
313where
314    T: GodotObject<Memory = ManuallyManaged>,
315    Own: NonUniqueOwnership,
316{
317}
318
319/// `Ref` is `Clone` if the access is not `Unique`.
320impl<T, Own> Clone for Ref<T, Own>
321where
322    T: GodotObject,
323    Own: NonUniqueOwnership,
324{
325    #[inline]
326    fn clone(&self) -> Self {
327        unsafe { Ref::from_sys(self.ptr.as_non_null()) }
328    }
329}
330
331impl<T: GodotObject + Instanciable> Ref<T, Unique> {
332    /// Creates a new instance of `T`.
333    ///
334    /// The lifetime of the returned object is *not* automatically managed if `T` is a manually-
335    /// managed type.
336    #[inline]
337    #[allow(clippy::new_without_default)]
338    pub fn new() -> Self {
339        T::construct()
340    }
341}
342
343impl<T: GodotObject> Ref<T, Unique> {
344    /// Creates a new instance of a sub-class of `T` by its class name. Returns `None` if the
345    /// class does not exist, cannot be constructed, has a different `Memory` from, or is not
346    /// a sub-class of `T`.
347    ///
348    /// The lifetime of the returned object is *not* automatically managed if `T` is a manually-
349    /// managed type. This means that if `Object` is used as the type parameter, any `Reference`
350    /// objects created, if returned, will be leaked. As a result, such calls will return `None`.
351    /// Casting between `Object` and `Reference` is possible on `TRef` and bare references.
352    #[inline]
353    pub fn by_class_name(class_name: &str) -> Option<Self> {
354        unsafe {
355            // Classes with NUL-bytes in their names can not exist
356            let class_name = CString::new(class_name).ok()?;
357            let ctor = (get_api().godot_get_class_constructor)(class_name.as_ptr())?;
358            let ptr = NonNull::new(ctor() as *mut sys::godot_object)?;
359            <T::Memory as MemorySpec>::impl_from_maybe_ref_counted(ptr)
360        }
361    }
362}
363
364/// Method for references that can be safely used.
365impl<T: GodotObject, Own: Ownership> Ref<T, Own>
366where
367    RefImplBound: SafeDeref<T::Memory, Own>,
368{
369    /// Returns a safe temporary reference that tracks thread access.
370    ///
371    /// `Ref<T, Own>` can be safely dereferenced if either:
372    ///
373    /// - `T` is reference-counted and `Ownership` is not `Shared`,
374    /// - or, `T` is manually-managed and `Ownership` is `Unique`.
375    #[inline]
376    pub fn as_ref(&self) -> TRef<'_, T, Own> {
377        RefImplBound::impl_as_ref(self)
378    }
379}
380
381/// `Ref<T, Own>` can be safely dereferenced if either:
382///
383/// - `T` is reference-counted and `Ownership` is not `Shared`,
384/// - or, `T` is manually-managed and `Ownership` is `Unique`.
385impl<T: GodotObject, Own: Ownership> Deref for Ref<T, Own>
386where
387    RefImplBound: SafeDeref<T::Memory, Own>,
388{
389    type Target = T;
390
391    #[inline]
392    fn deref(&self) -> &Self::Target {
393        RefImplBound::impl_as_ref(self).obj
394    }
395}
396
397/// `Ref<T, Own>` can be safely dereferenced if either:
398///
399/// - `T` is reference-counted and `Ownership` is not `Shared`,
400/// - or, `T` is manually-managed and `Ownership` is `Unique`.
401impl<T: GodotObject, Own: Ownership> Borrow<T> for Ref<T, Own>
402where
403    RefImplBound: SafeDeref<T::Memory, Own>,
404{
405    #[inline]
406    fn borrow(&self) -> &T {
407        RefImplBound::impl_as_ref(self).obj
408    }
409}
410
411/// Methods for references that point to valid objects, but are not necessarily safe to use.
412///
413/// - All `Ref`s to reference-counted types always point to valid objects.
414/// - `Ref` to manually-managed types are only guaranteed to be valid if `Unique`.
415impl<T: GodotObject, Own: Ownership> Ref<T, Own>
416where
417    RefImplBound: SafeAsRaw<T::Memory, Own>,
418{
419    /// Cast to a `RawObject` reference safely. This is an internal interface.
420    #[inline]
421    #[doc(hidden)]
422    pub fn as_raw(&self) -> &RawObject<T> {
423        unsafe { self.as_raw_unchecked() }
424    }
425
426    /// Performs a dynamic reference cast to target type, keeping the reference count.
427    /// Shorthand for `try_cast().ok()`.
428    ///
429    /// The `cast` method can only be used for downcasts. For statically casting to a
430    /// supertype, use `upcast` instead.
431    ///
432    /// This is only possible between types with the same `Memory`s, since otherwise the
433    /// reference can get leaked. Casting between `Object` and `Reference` is possible on
434    /// `TRef` and bare references.
435    #[inline]
436    pub fn cast<U>(self) -> Option<Ref<U, Own>>
437    where
438        U: GodotObject<Memory = T::Memory> + SubClass<T>,
439    {
440        self.try_cast().ok()
441    }
442
443    /// Performs a static reference upcast to a supertype, keeping the reference count.
444    /// This is guaranteed to be valid.
445    ///
446    /// This is only possible between types with the same `Memory`s, since otherwise the
447    /// reference can get leaked. Casting between `Object` and `Reference` is possible on
448    /// `TRef` and bare references.
449    #[inline]
450    pub fn upcast<U>(self) -> Ref<U, Own>
451    where
452        U: GodotObject<Memory = T::Memory>,
453        T: SubClass<U>,
454    {
455        unsafe { self.cast_unchecked() }
456    }
457
458    /// Performs a dynamic reference cast to target type, keeping the reference count.
459    ///
460    /// This is only possible between types with the same `Memory`s, since otherwise the
461    /// reference can get leaked. Casting between `Object` and `Reference` is possible on
462    /// `TRef` and bare references.
463    ///
464    /// # Errors
465    ///
466    /// Returns `Err(self)` if the cast failed.
467    #[inline]
468    pub fn try_cast<U>(self) -> Result<Ref<U, Own>, Self>
469    where
470        U: GodotObject<Memory = T::Memory> + SubClass<T>,
471    {
472        if self.as_raw().is_class::<U>() {
473            Ok(unsafe { self.cast_unchecked() })
474        } else {
475            Err(self)
476        }
477    }
478
479    /// Performs an unchecked cast.
480    unsafe fn cast_unchecked<U>(self) -> Ref<U, Own>
481    where
482        U: GodotObject<Memory = T::Memory>,
483    {
484        let ret = Ref::move_from_sys(self.ptr.as_non_null());
485        std::mem::forget(self);
486        ret
487    }
488
489    /// Performs a downcast to a `NativeClass` instance, keeping the reference count.
490    /// Shorthand for `try_cast_instance().ok()`.
491    ///
492    /// The resulting `Instance` is not necessarily safe to use directly.
493    #[inline]
494    pub fn cast_instance<C>(self) -> Option<Instance<C, Own>>
495    where
496        C: NativeClass<Base = T>,
497    {
498        self.try_cast_instance().ok()
499    }
500
501    /// Performs a downcast to a `NativeClass` instance, keeping the reference count.
502    ///
503    /// # Errors
504    ///
505    /// Returns `Err(self)` if the cast failed.
506    #[inline]
507    pub fn try_cast_instance<C>(self) -> Result<Instance<C, Own>, Self>
508    where
509        C: NativeClass<Base = T>,
510    {
511        Instance::try_from_base(self)
512    }
513}
514
515/// Methods for references that can't be used directly, and have to be assumed safe `unsafe`ly.
516impl<T: GodotObject> Ref<T, Shared> {
517    /// Assume that `self` is safe to use, returning a reference that can be used to call API
518    /// methods.
519    ///
520    /// This is guaranteed to be a no-op at runtime if `debug_assertions` is disabled. Runtime
521    /// sanity checks may be added in debug builds to help catch bugs.
522    ///
523    /// # Safety
524    ///
525    /// Suppose that the lifetime of the returned reference is `'a`. It's safe to call
526    /// `assume_safe` only if:
527    ///
528    /// 1. During the entirety of `'a`, the underlying object will always be valid.
529    ///
530    ///     *This is always true for reference-counted types.* For them, the `'a` lifetime will
531    ///     be constrained to the lifetime of `&self`.
532    ///
533    ///     This means that any methods called on the resulting reference will not free it,
534    ///     unless it's the last operation within the lifetime.
535    ///
536    ///     If any script methods are called, the code ran as a consequence will also not free
537    ///     it. This can happen via virtual method calls on other objects, or signals connected
538    ///     in a non-deferred way.
539    ///
540    /// 2. During the entirety of 'a, the thread from which `assume_safe` is called has
541    ///    exclusive access to the underlying object.
542    ///
543    ///     This is because all Godot objects have "interior mutability" in Rust parlance,
544    ///     and can't be shared across threads. The best way to guarantee this is to follow
545    ///     the official [thread-safety guidelines][thread-safety] across the codebase.
546    ///
547    /// Failure to satisfy either of the conditions will lead to undefined behavior.
548    ///
549    /// [thread-safety]: https://docs.godotengine.org/en/stable/tutorials/threads/thread_safe_apis.html
550    #[inline(always)]
551    pub unsafe fn assume_safe<'a, 'r>(&'r self) -> TRef<'a, T, Shared>
552    where
553        AssumeSafeLifetime<'a, 'r>: LifetimeConstraint<T::Memory>,
554    {
555        T::Memory::impl_assume_safe(self)
556    }
557
558    /// Assume that `self` is the unique reference to the underlying object.
559    ///
560    /// This is guaranteed to be a no-op at runtime if `debug_assertions` is disabled. Runtime
561    /// sanity checks may be added in debug builds to help catch bugs.
562    ///
563    /// # Safety
564    ///
565    /// Calling `assume_unique` when `self` isn't the unique reference is instant undefined
566    /// behavior. This is a much stronger assumption than `assume_safe` and should be used with
567    /// care.
568    #[inline(always)]
569    pub unsafe fn assume_unique(self) -> Ref<T, Unique> {
570        T::Memory::impl_assume_unique(self)
571    }
572}
573
574/// Extra methods with explicit sanity checks for manually-managed unsafe references.
575impl<T: GodotObject<Memory = ManuallyManaged>> Ref<T, Shared> {
576    /// Returns `true` if the pointer currently points to a valid object of the correct type.
577    /// **This does NOT guarantee that it's safe to use this pointer.**
578    ///
579    /// # Safety
580    ///
581    /// This thread must have exclusive access to the object during the call.
582    #[inline]
583    #[allow(clippy::trivially_copy_pass_by_ref)]
584    pub unsafe fn is_instance_sane(&self) -> bool {
585        let api = get_api();
586        if !(api.godot_is_instance_valid)(self.as_ptr()) {
587            return false;
588        }
589
590        self.as_raw_unchecked().is_class::<T>()
591    }
592
593    /// Assume that `self` is safe to use, if a sanity check using `is_instance_sane` passed.
594    ///
595    /// # Safety
596    ///
597    /// The same safety constraints as `assume_safe` applies. **The sanity check does NOT
598    /// guarantee that the operation is safe.**
599    #[inline]
600    #[allow(clippy::trivially_copy_pass_by_ref)]
601    pub unsafe fn assume_safe_if_sane<'a>(&self) -> Option<TRef<'a, T, Shared>> {
602        if self.is_instance_sane() {
603            Some(self.assume_safe_unchecked())
604        } else {
605            None
606        }
607    }
608
609    /// Assume that `self` is the unique reference to the underlying object, if a sanity check
610    /// using `is_instance_sane` passed.
611    ///
612    /// # Safety
613    ///
614    /// Calling `assume_unique_if_sane` when `self` isn't the unique reference is instant
615    /// undefined behavior. This is a much stronger assumption than `assume_safe` and should be
616    /// used with care.
617    #[inline]
618    pub unsafe fn assume_unique_if_sane(self) -> Option<Ref<T, Unique>> {
619        if self.is_instance_sane() {
620            Some(self.cast_access())
621        } else {
622            None
623        }
624    }
625}
626
627/// Methods for conversion from `Shared` to `ThreadLocal` access. This is only available for
628/// reference-counted types.
629impl<T: GodotObject<Memory = RefCounted>> Ref<T, Shared> {
630    /// Assume that all references to the underlying object is local to the current thread.
631    ///
632    /// This is guaranteed to be a no-op at runtime.
633    ///
634    /// # Safety
635    ///
636    /// Calling `assume_thread_local` when there are references on other threads is instant
637    /// undefined behavior. This is a much stronger assumption than `assume_safe` and should
638    /// be used with care.
639    #[inline(always)]
640    pub unsafe fn assume_thread_local(self) -> Ref<T, ThreadLocal> {
641        self.cast_access()
642    }
643}
644
645/// Methods for conversion from `Unique` to `ThreadLocal` access. This is only available for
646/// reference-counted types.
647impl<T: GodotObject<Memory = RefCounted>> Ref<T, Unique> {
648    /// Convert to a thread-local reference.
649    ///
650    /// This is guaranteed to be a no-op at runtime.
651    #[inline(always)]
652    pub fn into_thread_local(self) -> Ref<T, ThreadLocal> {
653        unsafe { self.cast_access() }
654    }
655}
656
657/// Methods for conversion from `Unique` to `Shared` access.
658impl<T: GodotObject> Ref<T, Unique> {
659    /// Convert to a shared reference.
660    ///
661    /// This is guaranteed to be a no-op at runtime.
662    #[inline(always)]
663    pub fn into_shared(self) -> Ref<T, Shared> {
664        unsafe { self.cast_access() }
665    }
666}
667
668/// Methods for freeing `Unique` references to manually-managed objects.
669impl<T: GodotObject<Memory = ManuallyManaged>> Ref<T, Unique> {
670    /// Manually frees the object.
671    ///
672    /// Manually-managed objects are not free-on-drop *even when the access is unique*, because
673    /// it's impossible to know whether methods take "ownership" of them or not. It's up to the
674    /// user to decide when they should be freed.
675    ///
676    /// This is only available for `Unique` references. If you have a `Ref` with another access,
677    /// and you are sure that it is unique, use `assume_unique` to convert it to a `Unique` one.
678    #[inline]
679    pub fn free(self) {
680        unsafe {
681            self.as_raw().free();
682        }
683    }
684}
685
686/// Methods for freeing `Unique` references to manually-managed objects.
687impl<T: GodotObject<Memory = ManuallyManaged> + QueueFree> Ref<T, Unique> {
688    /// Queues the object for deallocation in the near future. This is preferable for `Node`s
689    /// compared to `Ref::free`.
690    ///
691    /// This is only available for `Unique` references. If you have a `Ref` with another access,
692    /// and you are sure that it is unique, use `assume_unique` to convert it to a `Unique` one.
693    #[inline]
694    pub fn queue_free(self) {
695        unsafe { T::godot_queue_free(self.as_ptr()) }
696    }
697}
698
699/// Reference equality.
700impl<T: GodotObject, Own: Ownership> Eq for Ref<T, Own> {}
701
702/// Reference equality.
703impl<T, Own, RhsOws> PartialEq<Ref<T, RhsOws>> for Ref<T, Own>
704where
705    T: GodotObject,
706    Own: Ownership,
707    RhsOws: Ownership,
708{
709    #[inline]
710    fn eq(&self, other: &Ref<T, RhsOws>) -> bool {
711        self.ptr.as_non_null() == other.ptr.as_non_null()
712    }
713}
714
715/// Ordering of the raw pointer value.
716impl<T: GodotObject, Own: Ownership> Ord for Ref<T, Own> {
717    #[inline]
718    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
719        self.ptr.as_non_null().cmp(&other.ptr.as_non_null())
720    }
721}
722
723/// Ordering of the raw pointer value.
724impl<T: GodotObject, Own: Ownership> PartialOrd for Ref<T, Own> {
725    #[inline]
726    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
727        self.ptr.as_non_null().partial_cmp(&other.ptr.as_non_null())
728    }
729}
730
731/// Hashes the raw pointer.
732impl<T: GodotObject, Own: Ownership> Hash for Ref<T, Own> {
733    #[inline]
734    fn hash<H: Hasher>(&self, state: &mut H) {
735        state.write_usize(self.ptr.as_ptr() as usize)
736    }
737}
738
739impl<T: GodotObject, Own: Ownership> Debug for Ref<T, Own> {
740    #[inline]
741    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
742        write!(f, "{}({:p})", T::class_name(), self.ptr.as_ptr())
743    }
744}
745
746impl<T: GodotObject, Own: Ownership> Ref<T, Own> {
747    /// Convert to a nullable raw pointer.
748    #[doc(hidden)]
749    #[inline]
750    pub fn sys(&self) -> *mut sys::godot_object {
751        self.ptr.as_ptr()
752    }
753
754    /// Convert to a nullable raw pointer.
755    #[doc(hidden)]
756    #[inline]
757    pub fn as_ptr(&self) -> *mut sys::godot_object {
758        self.ptr.as_ptr()
759    }
760
761    /// Convert to a `RawObject` reference.
762    ///
763    /// # Safety
764    ///
765    /// `self` must point to a valid object of the correct type.
766    #[doc(hidden)]
767    #[inline]
768    pub unsafe fn as_raw_unchecked<'a>(&self) -> &'a RawObject<T> {
769        RawObject::from_sys_ref_unchecked(self.ptr.as_non_null())
770    }
771
772    /// Convert from a pointer returned from a ptrcall. For reference-counted types, this takes
773    /// the ownership of the returned reference, in Rust parlance. For non-reference-counted
774    /// types, its behavior should be exactly the same as `from_sys`. This is needed for
775    /// reference-counted types to be properly freed, since any references returned from
776    /// ptrcalls are leaked in the process of being cast into a pointer.
777    ///
778    /// # Safety
779    ///
780    /// `obj` must point to a valid object of the correct type.
781    #[doc(hidden)]
782    #[inline]
783    pub unsafe fn move_from_sys(obj: NonNull<sys::godot_object>) -> Self {
784        Ref {
785            ptr: <T::Memory as MemorySpec>::PtrWrapper::new(obj),
786            _marker: PhantomData,
787        }
788    }
789
790    /// Convert from a raw pointer, incrementing the reference counter if reference-counted.
791    ///
792    /// # Safety
793    ///
794    /// `obj` must point to a valid object of the correct type.
795    #[doc(hidden)]
796    #[inline]
797    pub unsafe fn from_sys(obj: NonNull<sys::godot_object>) -> Self {
798        let ret = Self::move_from_sys(obj);
799        <T::Memory as MemorySpec>::maybe_add_ref(ret.as_raw_unchecked());
800        ret
801    }
802
803    /// Convert from a pointer returned from a constructor of a reference-counted type. For
804    /// non-reference-counted types, its behavior should be exactly the same as `from_sys`.
805    ///
806    /// # Safety
807    ///
808    /// `obj` must point to a valid object of the correct type, and must be the only reference.
809    #[doc(hidden)]
810    #[inline]
811    pub unsafe fn init_from_sys(obj: NonNull<sys::godot_object>) -> Self {
812        let ret = Self::move_from_sys(obj);
813        <T::Memory as MemorySpec>::maybe_init_ref(ret.as_raw_unchecked());
814        ret
815    }
816
817    /// Casts the access type of `self` to `TargetAccess`, moving the reference.
818    ///
819    /// # Safety
820    ///
821    /// The cast must be valid.
822    unsafe fn cast_access<TargetOws: Ownership>(self) -> Ref<T, TargetOws> {
823        let ret = Ref::move_from_sys(self.ptr.as_non_null());
824        std::mem::forget(self);
825        ret
826    }
827
828    /// Assume that the reference is safe in an `unsafe` context even if it can be used safely.
829    /// For internal use in macros.
830    ///
831    /// This is guaranteed to be a no-op at runtime.
832    ///
833    /// # Safety
834    ///
835    /// The same safety constraints as `assume_safe` applies.
836    #[doc(hidden)]
837    #[inline(always)]
838    pub unsafe fn assume_safe_unchecked<'a>(&self) -> TRef<'a, T, Own> {
839        TRef::new(T::cast_ref(self.as_raw_unchecked()))
840    }
841}
842
843/// A temporary safe pointer to Godot objects that tracks thread access status. `TRef` can be
844/// coerced into bare references with `Deref`.
845///
846/// See the type-level documentation on `Ref` for detailed documentation on the reference
847/// system of `godot-rust`.
848///
849/// # Using as method arguments or return values
850///
851/// `TRef<T, Shared>` can be passed into methods.
852///
853/// # Using as `owner` arguments in NativeScript methods
854///
855/// It's possible to use `TRef` as the `owner` argument in NativeScript methods. This can make
856/// passing `owner` to methods easier.
857pub struct TRef<'a, T: GodotObject, Own: Ownership = Shared> {
858    obj: &'a T,
859    _marker: PhantomData<Own>,
860}
861
862impl<'a, T: GodotObject, Own: Ownership> Copy for TRef<'a, T, Own> {}
863impl<'a, T: GodotObject, Own: Ownership> Clone for TRef<'a, T, Own> {
864    #[inline]
865    fn clone(&self) -> Self {
866        TRef::new(self.obj)
867    }
868}
869
870impl<'a, T: GodotObject, Own: Ownership> Debug for TRef<'a, T, Own> {
871    #[inline]
872    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
873        write!(f, "{}({:p})", T::class_name(), self.obj)
874    }
875}
876
877impl<'a, T: GodotObject, Own: Ownership> Deref for TRef<'a, T, Own> {
878    type Target = T;
879
880    #[inline]
881    fn deref(&self) -> &Self::Target {
882        self.obj
883    }
884}
885
886impl<'a, T: GodotObject, Own: Ownership> AsRef<T> for TRef<'a, T, Own> {
887    #[inline]
888    fn as_ref(&self) -> &T {
889        self.obj
890    }
891}
892
893impl<'a, T: GodotObject, Own: Ownership> Borrow<T> for TRef<'a, T, Own> {
894    #[inline]
895    fn borrow(&self) -> &T {
896        self.obj
897    }
898}
899
900impl<'a, T: GodotObject, Own: Ownership> TRef<'a, T, Own> {
901    pub(crate) fn new(obj: &'a T) -> Self {
902        TRef {
903            obj,
904            _marker: PhantomData,
905        }
906    }
907
908    /// Returns the underlying reference without thread access.
909    #[inline]
910    #[allow(clippy::should_implement_trait)]
911    pub fn as_ref(self) -> &'a T {
912        self.obj
913    }
914
915    /// Performs a dynamic reference cast to target type, keeping the thread access info.
916    #[inline]
917    pub fn cast<U>(self) -> Option<TRef<'a, U, Own>>
918    where
919        U: GodotObject + SubClass<T>,
920    {
921        self.obj.cast().map(TRef::new)
922    }
923
924    /// Performs a static reference upcast to a supertype that is guaranteed to be valid,
925    /// keeping the thread access info.
926    ///
927    /// This is guaranteed to be a no-op at runtime.
928    #[inline(always)]
929    pub fn upcast<U>(&self) -> TRef<'a, U, Own>
930    where
931        U: GodotObject,
932        T: SubClass<U>,
933    {
934        TRef::new(self.obj.upcast())
935    }
936
937    /// Convenience method to downcast to `TInstance` where `self` is the base object.
938    #[inline]
939    pub fn cast_instance<C>(self) -> Option<TInstance<'a, C, Own>>
940    where
941        C: NativeClass<Base = T>,
942    {
943        TInstance::try_from_base(self)
944    }
945}
946
947impl<'a, Kind, T, Own> TRef<'a, T, Own>
948where
949    Kind: Memory,
950    T: GodotObject<Memory = Kind>,
951    Own: NonUniqueOwnership,
952{
953    /// Persists this reference into a persistent `Ref` with the same thread access.
954    ///
955    /// This is only available for non-`Unique` accesses.
956    #[inline]
957    pub fn claim(self) -> Ref<T, Own> {
958        unsafe { Ref::from_sys(self.obj.as_raw().sys()) }
959    }
960}
961
962impl<'a, T: GodotObject> TRef<'a, T, Shared> {
963    /// Recovers a instance ID previously returned by `Object::get_instance_id` if the object is
964    /// still alive.
965    ///
966    /// # Safety
967    ///
968    /// During the entirety of `'a`, the thread from which `try_from_instance_id` is called must
969    /// have exclusive access to the underlying object, if it is still alive.
970    #[inline]
971    pub unsafe fn try_from_instance_id(id: i64) -> Option<Self> {
972        let api = get_api();
973        let ptr = NonNull::new((api.godot_instance_from_id)(id as sys::godot_int))?;
974        let raw = RawObject::try_from_sys_ref(ptr)?;
975        Some(TRef::new(T::cast_ref(raw)))
976    }
977
978    /// Recovers a instance ID previously returned by `Object::get_instance_id` if the object is
979    /// still alive, and panics otherwise. This does **NOT** guarantee that the resulting
980    /// reference is safe to use.
981    ///
982    /// # Panics
983    ///
984    /// Panics if the given id refers to a destroyed object. For a non-panicking version, see
985    /// `try_from_instance_id`.
986    ///
987    /// # Safety
988    ///
989    /// During the entirety of `'a`, the thread from which `try_from_instance_id` is called must
990    /// have exclusive access to the underlying object, if it is still alive.
991    #[inline]
992    pub unsafe fn from_instance_id(id: i64) -> Self {
993        Self::try_from_instance_id(id).expect("instance should be alive")
994    }
995}
996
997/// Represents an explicit null reference in method arguments. This works around type inference
998/// issues with `Option`. You may create `Null`s with `Null::null` or `GodotObject::null`.
999pub struct Null<T>(PhantomData<T>);
1000
1001impl<T: GodotObject> Null<T> {
1002    /// Creates an explicit null reference that can be used as a method argument.
1003    // TODO(#997) consider something more idiomatic, like module::null::<T>(), similar to std::ptr::null()
1004    #[inline]
1005    #[allow(clippy::self_named_constructors)]
1006    pub fn null() -> Self {
1007        Null(PhantomData)
1008    }
1009}