use std::borrow::Borrow;
use std::ffi::CString;
use std::fmt::{self, Debug};
use std::hash::{Hash, Hasher};
use std::marker::PhantomData;
use std::ops::Deref;
use std::ptr::NonNull;
use crate::private::{get_api, ManuallyManagedClassPlaceholder, ReferenceCountedClassPlaceholder};
use crate::ref_kind::{ManuallyManaged, RefCounted, RefKind};
use crate::sys;
use crate::thread_access::{
LocalThreadAccess, NonUniqueThreadAccess, Shared, ThreadAccess, ThreadLocal, Unique,
};
#[cfg(feature = "nativescript")]
use crate::nativescript::{Instance, NativeClass, RefInstance};
mod raw;
pub use self::raw::RawObject;
pub unsafe trait GodotObject: Sized + crate::private::godot_object::Sealed {
type RefKind: RefKind;
fn class_name() -> &'static str;
#[inline]
fn null() -> Null<Self> {
Null::null()
}
#[inline]
fn new() -> Ref<Self, Unique>
where
Self: Instanciable,
{
Ref::new()
}
#[inline]
fn cast<T>(&self) -> Option<&T>
where
T: GodotObject + SubClass<Self>,
{
self.as_raw().cast().map(T::cast_ref)
}
#[inline(always)]
fn upcast<T>(&self) -> &T
where
T: GodotObject,
Self: SubClass<T>,
{
unsafe { T::cast_ref(self.as_raw().cast_unchecked()) }
}
#[doc(hidden)]
#[inline]
fn cast_ref(raw: &RawObject<Self>) -> &Self {
unsafe { &*(raw as *const _ as *const _) }
}
#[doc(hidden)]
#[inline]
fn as_raw(&self) -> &RawObject<Self> {
unsafe { &*(self as *const _ as *const _) }
}
#[doc(hidden)]
#[inline]
fn as_ptr(&self) -> *mut sys::godot_object {
self.as_raw().sys().as_ptr()
}
#[inline]
unsafe fn assume_shared(&self) -> Ref<Self, Shared>
where
Self: Sized,
{
Ref::from_sys(self.as_raw().sys())
}
#[inline]
unsafe fn assume_thread_local(&self) -> Ref<Self, ThreadLocal>
where
Self: Sized + GodotObject<RefKind = RefCounted>,
{
Ref::from_sys(self.as_raw().sys())
}
#[inline]
unsafe fn assume_unique(&self) -> Ref<Self, Unique>
where
Self: Sized,
{
Ref::from_sys(self.as_raw().sys())
}
#[inline]
unsafe fn try_from_instance_id<'a>(id: i64) -> Option<TRef<'a, Self, Shared>> {
TRef::try_from_instance_id(id)
}
#[inline]
unsafe fn from_instance_id<'a>(id: i64) -> TRef<'a, Self, Shared> {
TRef::from_instance_id(id)
}
}
pub unsafe trait SubClass<A: GodotObject>: GodotObject {}
unsafe impl<T: GodotObject> SubClass<T> for T {}
pub trait Instanciable: GodotObject {
fn construct() -> Ref<Self, Unique>;
}
pub trait QueueFree: GodotObject {
#[doc(hidden)]
unsafe fn godot_queue_free(sys: *mut sys::godot_object);
}
pub struct Ref<T: GodotObject, Access: ThreadAccess = Shared> {
ptr: <T::RefKind as RefKindSpec>::PtrWrapper,
_marker: PhantomData<(*const T, Access)>,
}
unsafe impl<T: GodotObject, Access: ThreadAccess + Send> Send for Ref<T, Access> {}
unsafe impl<T: GodotObject, Access: ThreadAccess + Sync> Sync for Ref<T, Access> {}
impl<T: GodotObject, Access: ThreadAccess> private::Sealed for Ref<T, Access> {}
impl<T, Access> Copy for Ref<T, Access>
where
T: GodotObject<RefKind = ManuallyManaged>,
Access: NonUniqueThreadAccess,
{
}
impl<T, Access> Clone for Ref<T, Access>
where
T: GodotObject,
Access: NonUniqueThreadAccess,
{
#[inline]
fn clone(&self) -> Self {
unsafe { Ref::from_sys(self.ptr.as_non_null()) }
}
}
impl<T: GodotObject + Instanciable> Ref<T, Unique> {
#[inline]
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
T::construct()
}
}
impl<T: GodotObject> Ref<T, Unique> {
#[inline]
pub fn by_class_name(class_name: &str) -> Option<Self> {
unsafe {
let class_name = CString::new(class_name).ok()?;
let ctor = (get_api().godot_get_class_constructor)(class_name.as_ptr())?;
let ptr = NonNull::new(ctor() as *mut sys::godot_object)?;
<T::RefKind as RefKindSpec>::impl_from_maybe_ref_counted(ptr)
}
}
}
impl<T: GodotObject, Access: ThreadAccess> Ref<T, Access>
where
RefImplBound: SafeDeref<T::RefKind, Access>,
{
#[inline]
pub fn as_ref(&self) -> TRef<'_, T, Access> {
RefImplBound::impl_as_ref(self)
}
}
impl<T: GodotObject, Access: ThreadAccess> Deref for Ref<T, Access>
where
RefImplBound: SafeDeref<T::RefKind, Access>,
{
type Target = T;
#[inline]
fn deref(&self) -> &Self::Target {
RefImplBound::impl_as_ref(self).obj
}
}
impl<T: GodotObject, Access: ThreadAccess> Borrow<T> for Ref<T, Access>
where
RefImplBound: SafeDeref<T::RefKind, Access>,
{
#[inline]
fn borrow(&self) -> &T {
RefImplBound::impl_as_ref(self).obj
}
}
impl<T: GodotObject, Access: ThreadAccess> Ref<T, Access>
where
RefImplBound: SafeAsRaw<T::RefKind, Access>,
{
#[inline]
#[doc(hidden)]
pub fn as_raw(&self) -> &RawObject<T> {
unsafe { self.as_raw_unchecked() }
}
#[inline]
pub fn cast<U>(self) -> Option<Ref<U, Access>>
where
U: GodotObject<RefKind = T::RefKind> + SubClass<T>,
{
self.try_cast().ok()
}
#[inline]
pub fn upcast<U>(self) -> Ref<U, Access>
where
U: GodotObject<RefKind = T::RefKind>,
T: SubClass<U>,
{
unsafe { self.cast_unchecked() }
}
#[inline]
pub fn try_cast<U>(self) -> Result<Ref<U, Access>, Self>
where
U: GodotObject<RefKind = T::RefKind> + SubClass<T>,
{
if self.as_raw().is_class::<U>() {
Ok(unsafe { self.cast_unchecked() })
} else {
Err(self)
}
}
unsafe fn cast_unchecked<U>(self) -> Ref<U, Access>
where
U: GodotObject<RefKind = T::RefKind>,
{
let ret = Ref::move_from_sys(self.ptr.as_non_null());
std::mem::forget(self);
ret
}
#[inline]
#[cfg(feature = "nativescript")]
pub fn cast_instance<C>(self) -> Option<Instance<C, Access>>
where
C: NativeClass<Base = T>,
{
self.try_cast_instance().ok()
}
#[inline]
#[cfg(feature = "nativescript")]
pub fn try_cast_instance<C>(self) -> Result<Instance<C, Access>, Self>
where
C: NativeClass<Base = T>,
{
Instance::try_from_base(self)
}
}
impl<T: GodotObject> Ref<T, Shared> {
#[inline(always)]
pub unsafe fn assume_safe<'a, 'r>(&'r self) -> TRef<'a, T, Shared>
where
AssumeSafeLifetime<'a, 'r>: LifetimeConstraint<T::RefKind>,
{
T::RefKind::impl_assume_safe(self)
}
#[inline(always)]
pub unsafe fn assume_unique(self) -> Ref<T, Unique> {
T::RefKind::impl_assume_unique(self)
}
}
impl<T: GodotObject<RefKind = ManuallyManaged>> Ref<T, Shared> {
#[inline]
#[allow(clippy::trivially_copy_pass_by_ref)]
pub unsafe fn is_instance_sane(&self) -> bool {
let api = get_api();
if !(api.godot_is_instance_valid)(self.as_ptr()) {
return false;
}
self.as_raw_unchecked().is_class::<T>()
}
#[inline]
#[allow(clippy::trivially_copy_pass_by_ref)]
pub unsafe fn assume_safe_if_sane<'a>(&self) -> Option<TRef<'a, T, Shared>> {
if self.is_instance_sane() {
Some(self.assume_safe_unchecked())
} else {
None
}
}
#[inline]
pub unsafe fn assume_unique_if_sane(self) -> Option<Ref<T, Unique>> {
if self.is_instance_sane() {
Some(self.cast_access())
} else {
None
}
}
}
impl<T: GodotObject<RefKind = RefCounted>> Ref<T, Shared> {
#[inline(always)]
pub unsafe fn assume_thread_local(self) -> Ref<T, ThreadLocal> {
self.cast_access()
}
}
impl<T: GodotObject<RefKind = RefCounted>> Ref<T, Unique> {
#[inline(always)]
pub fn into_thread_local(self) -> Ref<T, ThreadLocal> {
unsafe { self.cast_access() }
}
}
impl<T: GodotObject> Ref<T, Unique> {
#[inline(always)]
pub fn into_shared(self) -> Ref<T, Shared> {
unsafe { self.cast_access() }
}
}
impl<T: GodotObject<RefKind = ManuallyManaged>> Ref<T, Unique> {
#[inline]
pub fn free(self) {
unsafe {
self.as_raw().free();
}
}
}
impl<T: GodotObject<RefKind = ManuallyManaged> + QueueFree> Ref<T, Unique> {
#[inline]
pub fn queue_free(self) {
unsafe { T::godot_queue_free(self.as_ptr()) }
}
}
impl<T: GodotObject, Access: ThreadAccess> Eq for Ref<T, Access> {}
impl<T, Access, RhsAccess> PartialEq<Ref<T, RhsAccess>> for Ref<T, Access>
where
T: GodotObject,
Access: ThreadAccess,
RhsAccess: ThreadAccess,
{
#[inline]
fn eq(&self, other: &Ref<T, RhsAccess>) -> bool {
self.ptr.as_non_null() == other.ptr.as_non_null()
}
}
impl<T: GodotObject, Access: ThreadAccess> Ord for Ref<T, Access> {
#[inline]
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.ptr.as_non_null().cmp(&other.ptr.as_non_null())
}
}
impl<T: GodotObject, Access: ThreadAccess> PartialOrd for Ref<T, Access> {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.ptr.as_non_null().partial_cmp(&other.ptr.as_non_null())
}
}
impl<T: GodotObject, Access: ThreadAccess> Hash for Ref<T, Access> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_usize(self.ptr.as_ptr() as usize)
}
}
impl<T: GodotObject, Access: ThreadAccess> Debug for Ref<T, Access> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}({:p})", T::class_name(), self.ptr.as_ptr())
}
}
impl<T: GodotObject, Access: ThreadAccess> Ref<T, Access> {
#[doc(hidden)]
#[inline]
pub fn sys(&self) -> *mut sys::godot_object {
self.ptr.as_ptr()
}
#[doc(hidden)]
#[inline]
pub fn as_ptr(&self) -> *mut sys::godot_object {
self.ptr.as_ptr()
}
#[doc(hidden)]
#[inline]
pub unsafe fn as_raw_unchecked<'a>(&self) -> &'a RawObject<T> {
RawObject::from_sys_ref_unchecked(self.ptr.as_non_null())
}
#[doc(hidden)]
#[inline]
pub unsafe fn move_from_sys(obj: NonNull<sys::godot_object>) -> Self {
Ref {
ptr: <T::RefKind as RefKindSpec>::PtrWrapper::new(obj),
_marker: PhantomData,
}
}
#[doc(hidden)]
#[inline]
pub unsafe fn from_sys(obj: NonNull<sys::godot_object>) -> Self {
let ret = Self::move_from_sys(obj);
<T::RefKind as RefKindSpec>::maybe_add_ref(ret.as_raw_unchecked());
ret
}
#[doc(hidden)]
#[inline]
pub unsafe fn init_from_sys(obj: NonNull<sys::godot_object>) -> Self {
let ret = Self::move_from_sys(obj);
<T::RefKind as RefKindSpec>::maybe_init_ref(ret.as_raw_unchecked());
ret
}
unsafe fn cast_access<TargetAccess: ThreadAccess>(self) -> Ref<T, TargetAccess> {
let ret = Ref::move_from_sys(self.ptr.as_non_null());
std::mem::forget(self);
ret
}
#[doc(hidden)]
#[inline(always)]
pub unsafe fn assume_safe_unchecked<'a>(&self) -> TRef<'a, T, Access> {
TRef::new(T::cast_ref(self.as_raw_unchecked()))
}
}
pub struct TRef<'a, T: GodotObject, Access: ThreadAccess = Shared> {
obj: &'a T,
_marker: PhantomData<Access>,
}
impl<'a, T: GodotObject, Access: ThreadAccess> Copy for TRef<'a, T, Access> {}
impl<'a, T: GodotObject, Access: ThreadAccess> Clone for TRef<'a, T, Access> {
#[inline]
fn clone(&self) -> Self {
TRef::new(self.obj)
}
}
impl<'a, T: GodotObject, Access: ThreadAccess> Debug for TRef<'a, T, Access> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}({:p})", T::class_name(), self.obj)
}
}
impl<'a, T: GodotObject, Access: ThreadAccess> Deref for TRef<'a, T, Access> {
type Target = T;
#[inline]
fn deref(&self) -> &Self::Target {
self.obj
}
}
impl<'a, T: GodotObject, Access: ThreadAccess> AsRef<T> for TRef<'a, T, Access> {
#[inline]
fn as_ref(&self) -> &T {
self.obj
}
}
impl<'a, T: GodotObject, Access: ThreadAccess> Borrow<T> for TRef<'a, T, Access> {
#[inline]
fn borrow(&self) -> &T {
self.obj
}
}
impl<'a, T: GodotObject, Access: ThreadAccess> TRef<'a, T, Access> {
pub(crate) fn new(obj: &'a T) -> Self {
TRef {
obj,
_marker: PhantomData,
}
}
#[inline]
#[allow(clippy::should_implement_trait)]
pub fn as_ref(self) -> &'a T {
self.obj
}
#[inline]
pub fn cast<U>(self) -> Option<TRef<'a, U, Access>>
where
U: GodotObject + SubClass<T>,
{
self.obj.cast().map(TRef::new)
}
#[inline(always)]
pub fn upcast<U>(&self) -> TRef<'a, U, Access>
where
U: GodotObject,
T: SubClass<U>,
{
TRef::new(self.obj.upcast())
}
#[inline]
#[cfg(feature = "nativescript")]
pub fn cast_instance<C>(self) -> Option<RefInstance<'a, C, Access>>
where
C: NativeClass<Base = T>,
{
RefInstance::try_from_base(self)
}
}
impl<'a, Kind, T, Access> TRef<'a, T, Access>
where
Kind: RefKind,
T: GodotObject<RefKind = Kind>,
Access: NonUniqueThreadAccess,
{
#[inline]
pub fn claim(self) -> Ref<T, Access> {
unsafe { Ref::from_sys(self.obj.as_raw().sys()) }
}
}
impl<'a, T: GodotObject> TRef<'a, T, Shared> {
#[inline]
pub unsafe fn try_from_instance_id(id: i64) -> Option<Self> {
let api = get_api();
let ptr = NonNull::new((api.godot_instance_from_id)(id as sys::godot_int))?;
let raw = RawObject::try_from_sys_ref(ptr)?;
Some(TRef::new(T::cast_ref(raw)))
}
#[inline]
pub unsafe fn from_instance_id(id: i64) -> Self {
Self::try_from_instance_id(id).expect("instance should be alive")
}
}
pub trait AsArg<T>: private::Sealed {
#[doc(hidden)]
fn as_arg_ptr(&self) -> *mut sys::godot_object;
#[doc(hidden)]
#[inline]
unsafe fn to_arg_variant(&self) -> crate::core_types::Variant {
crate::core_types::Variant::from_object_ptr(self.as_arg_ptr())
}
}
pub trait AsVariant: AsArg<<Self as AsVariant>::Target> {
type Target;
}
pub struct Null<T>(PhantomData<T>);
impl<T: GodotObject> Null<T> {
#[inline]
pub fn null() -> Self {
Null(PhantomData)
}
}
impl<'a, T> private::Sealed for Null<T> {}
impl<'a, T: GodotObject> AsArg<T> for Null<T> {
#[inline]
fn as_arg_ptr(&self) -> *mut sys::godot_object {
std::ptr::null_mut()
}
}
impl<'a, T: GodotObject> AsVariant for Null<T> {
type Target = T;
}
impl<'a, T: GodotObject> private::Sealed for TRef<'a, T, Shared> {}
impl<'a, T, U> AsArg<U> for TRef<'a, T, Shared>
where
T: GodotObject + SubClass<U>,
U: GodotObject,
{
#[inline]
fn as_arg_ptr(&self) -> *mut sys::godot_object {
self.as_ptr()
}
}
impl<'a, T: GodotObject> AsVariant for TRef<'a, T, Shared> {
type Target = T;
}
impl<T, U> AsArg<U> for Ref<T, Shared>
where
T: GodotObject + SubClass<U>,
U: GodotObject,
{
#[inline]
fn as_arg_ptr(&self) -> *mut sys::godot_object {
self.as_ptr()
}
}
impl<T: GodotObject> AsVariant for Ref<T, Shared> {
type Target = T;
}
impl<T, U> AsArg<U> for Ref<T, Unique>
where
T: GodotObject + SubClass<U>,
U: GodotObject,
{
#[inline]
fn as_arg_ptr(&self) -> *mut sys::godot_object {
self.as_ptr()
}
}
impl<T: GodotObject> AsVariant for Ref<T, Unique> {
type Target = T;
}
impl<'a, T: GodotObject> private::Sealed for &'a Ref<T, Shared> {}
impl<'a, T, U> AsArg<U> for &'a Ref<T, Shared>
where
T: GodotObject + SubClass<U>,
U: GodotObject,
{
#[inline]
fn as_arg_ptr(&self) -> *mut sys::godot_object {
self.as_ptr()
}
}
impl<'a, T: GodotObject> AsVariant for &'a Ref<T, Shared> {
type Target = T;
}
pub unsafe trait SafeDeref<Kind: RefKind, Access: ThreadAccess> {
#[doc(hidden)]
fn impl_as_ref<T: GodotObject<RefKind = Kind>>(this: &Ref<T, Access>) -> TRef<'_, T, Access>;
}
pub unsafe trait SafeAsRaw<Kind: RefKind, Access: ThreadAccess> {
#[doc(hidden)]
fn impl_as_raw<T: GodotObject<RefKind = Kind>>(this: &Ref<T, Access>) -> &RawObject<T>;
}
pub struct RefImplBound {
_private: (),
}
unsafe impl SafeDeref<ManuallyManaged, Unique> for RefImplBound {
#[inline]
fn impl_as_ref<T: GodotObject<RefKind = ManuallyManaged>>(
this: &Ref<T, Unique>,
) -> TRef<'_, T, Unique> {
unsafe { this.assume_safe_unchecked() }
}
}
unsafe impl<Access: LocalThreadAccess> SafeDeref<RefCounted, Access> for RefImplBound {
#[inline]
fn impl_as_ref<T: GodotObject<RefKind = RefCounted>>(
this: &Ref<T, Access>,
) -> TRef<'_, T, Access> {
unsafe { this.assume_safe_unchecked() }
}
}
unsafe impl SafeAsRaw<ManuallyManaged, Unique> for RefImplBound {
#[inline]
fn impl_as_raw<T: GodotObject<RefKind = ManuallyManaged>>(
this: &Ref<T, Unique>,
) -> &RawObject<T> {
unsafe { this.as_raw_unchecked() }
}
}
unsafe impl<Access: ThreadAccess> SafeAsRaw<RefCounted, Access> for RefImplBound {
#[inline]
fn impl_as_raw<T: GodotObject<RefKind = RefCounted>>(this: &Ref<T, Access>) -> &RawObject<T> {
unsafe { this.as_raw_unchecked() }
}
}
pub trait RefKindSpec: Sized {
#[doc(hidden)]
type PtrWrapper: PtrWrapper;
#[doc(hidden)]
unsafe fn impl_from_maybe_ref_counted<T: GodotObject<RefKind = Self>>(
ptr: NonNull<sys::godot_object>,
) -> Option<Ref<T, Unique>>;
#[doc(hidden)]
unsafe fn impl_assume_safe<'a, T: GodotObject<RefKind = Self>>(
this: &Ref<T, Shared>,
) -> TRef<'a, T, Shared>
where
Self: RefKind;
#[doc(hidden)]
unsafe fn impl_assume_unique<T: GodotObject<RefKind = Self>>(
this: Ref<T, Shared>,
) -> Ref<T, Unique>
where
Self: RefKind;
#[doc(hidden)]
unsafe fn maybe_add_ref<T: GodotObject<RefKind = Self>>(raw: &RawObject<T>)
where
Self: RefKind;
#[doc(hidden)]
unsafe fn maybe_init_ref<T: GodotObject<RefKind = Self>>(raw: &RawObject<T>)
where
Self: RefKind;
}
impl RefKindSpec for ManuallyManaged {
type PtrWrapper = Forget;
#[inline(always)]
unsafe fn impl_from_maybe_ref_counted<T: GodotObject<RefKind = Self>>(
ptr: NonNull<sys::godot_object>,
) -> Option<Ref<T, Unique>> {
if RawObject::<ReferenceCountedClassPlaceholder>::try_from_sys_ref(ptr).is_some() {
drop(Ref::<ReferenceCountedClassPlaceholder, Unique>::init_from_sys(ptr));
None
} else {
let obj = Ref::<ManuallyManagedClassPlaceholder, Unique>::init_from_sys(ptr);
if obj.as_raw().is_class::<T>() {
Some(obj.cast_unchecked())
} else {
obj.free();
None
}
}
}
#[inline(always)]
unsafe fn impl_assume_safe<'a, T: GodotObject<RefKind = Self>>(
this: &Ref<T, Shared>,
) -> TRef<'a, T, Shared> {
debug_assert!(
this.is_instance_sane(),
"assume_safe called on an invalid pointer"
);
this.assume_safe_unchecked()
}
#[inline(always)]
unsafe fn impl_assume_unique<T: GodotObject<RefKind = Self>>(
this: Ref<T, Shared>,
) -> Ref<T, Unique> {
debug_assert!(
this.is_instance_sane(),
"assume_unique called on an invalid pointer"
);
this.cast_access()
}
#[inline]
unsafe fn maybe_add_ref<T: GodotObject<RefKind = Self>>(_raw: &RawObject<T>) {}
#[inline]
unsafe fn maybe_init_ref<T: GodotObject<RefKind = Self>>(_raw: &RawObject<T>) {}
}
impl RefKindSpec for RefCounted {
type PtrWrapper = UnRef;
#[inline(always)]
unsafe fn impl_from_maybe_ref_counted<T: GodotObject<RefKind = Self>>(
ptr: NonNull<sys::godot_object>,
) -> Option<Ref<T, Unique>> {
if RawObject::<ReferenceCountedClassPlaceholder>::try_from_sys_ref(ptr).is_some() {
let obj = Ref::<ReferenceCountedClassPlaceholder, Unique>::init_from_sys(ptr);
if obj.as_raw().is_class::<T>() {
Some(obj.cast_unchecked())
} else {
None
}
} else {
RawObject::<ManuallyManagedClassPlaceholder>::from_sys_ref_unchecked(ptr).free();
None
}
}
#[inline(always)]
unsafe fn impl_assume_safe<'a, T: GodotObject<RefKind = Self>>(
this: &Ref<T, Shared>,
) -> TRef<'a, T, Shared> {
this.assume_safe_unchecked()
}
#[inline(always)]
unsafe fn impl_assume_unique<T: GodotObject<RefKind = Self>>(
this: Ref<T, Shared>,
) -> Ref<T, Unique> {
this.cast_access()
}
#[inline]
unsafe fn maybe_add_ref<T: GodotObject<RefKind = Self>>(raw: &RawObject<T>) {
raw.add_ref();
}
#[inline]
unsafe fn maybe_init_ref<T: GodotObject<RefKind = Self>>(raw: &RawObject<T>) {
raw.init_ref_count();
}
}
pub trait PtrWrapper {
fn new(ptr: NonNull<sys::godot_object>) -> Self;
fn as_non_null(&self) -> NonNull<sys::godot_object>;
#[inline]
fn as_ptr(&self) -> *mut sys::godot_object {
self.as_non_null().as_ptr()
}
}
#[derive(Copy, Clone)]
pub struct Forget(NonNull<sys::godot_object>);
impl PtrWrapper for Forget {
#[inline]
fn new(ptr: NonNull<sys::godot_object>) -> Self {
Forget(ptr)
}
#[inline]
fn as_non_null(&self) -> NonNull<sys::godot_object> {
self.0
}
}
pub struct UnRef(NonNull<sys::godot_object>);
impl PtrWrapper for UnRef {
#[inline]
fn new(ptr: NonNull<sys::godot_object>) -> Self {
UnRef(ptr)
}
#[inline]
fn as_non_null(&self) -> NonNull<sys::godot_object> {
self.0
}
}
impl Drop for UnRef {
#[inline]
fn drop(&mut self) {
unsafe {
let raw = RawObject::<ReferenceCountedClassPlaceholder>::from_sys_ref_unchecked(self.0);
raw.unref_and_free_if_last();
}
}
}
pub trait LifetimeConstraint<Kind: RefKind> {}
#[doc(hidden)]
pub struct AssumeSafeLifetime<'a, 'r> {
_marker: PhantomData<(&'a (), &'r ())>,
}
impl<'a, 'r> LifetimeConstraint<ManuallyManaged> for AssumeSafeLifetime<'a, 'r> {}
impl<'a, 'r: 'a> LifetimeConstraint<RefCounted> for AssumeSafeLifetime<'a, 'r> {}
mod private {
pub trait Sealed {}
}