use crate::meta::error::ConvertError;
use crate::meta::shape::GodotShape;
use crate::meta::{FromGodot, GodotConvert, GodotType, ToGodot, sealed};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RawPtr<P: FfiRawPointer> {
ptr: P,
}
impl<P: FfiRawPointer> RawPtr<P> {
#[inline]
pub unsafe fn new(ptr: P) -> Self {
RawPtr { ptr }
}
#[inline]
pub unsafe fn null() -> Self {
let ptr = P::ptr_from_i64(0);
unsafe { RawPtr::new(ptr) }
}
#[inline]
pub fn ptr(self) -> P {
self.ptr
}
}
impl<P> GodotType for RawPtr<P>
where
P: FfiRawPointer + 'static,
{
type Ffi = i64;
type ToFfi<'f> = i64;
fn to_ffi(&self) -> Self::ToFfi<'_> {
self.ptr.to_i64()
}
fn into_ffi(self) -> Self::Ffi {
self.ptr.to_i64()
}
fn try_from_ffi(ffi: Self::Ffi) -> Result<Self, ConvertError> {
Ok(RawPtr {
ptr: P::ptr_from_i64(ffi),
})
}
}
impl<P> GodotConvert for RawPtr<P>
where
P: FfiRawPointer + 'static,
{
type Via = Self;
fn godot_shape() -> GodotShape {
GodotShape::of_builtin::<Self>()
}
}
impl<P> ToGodot for RawPtr<P>
where
P: FfiRawPointer + 'static,
{
type Pass = crate::meta::ByValue;
fn to_godot(&self) -> Self::Via {
*self
}
}
impl<P> FromGodot for RawPtr<P>
where
P: FfiRawPointer + 'static,
{
fn try_from_godot(via: Self::Via) -> Result<Self, ConvertError> {
Ok(via)
}
}
impl<P> sealed::Sealed for RawPtr<P> where P: FfiRawPointer + 'static {}
pub trait FfiRawPointer: Copy + sealed::Sealed {
#[doc(hidden)]
fn to_i64(self) -> i64;
#[doc(hidden)]
fn ptr_from_i64(addr: i64) -> Self;
}
impl<T> FfiRawPointer for *const T {
#[inline]
fn to_i64(self) -> i64 {
self as i64
}
#[inline]
fn ptr_from_i64(addr: i64) -> Self {
addr as *const T
}
}
impl<T> FfiRawPointer for *mut T {
#[inline]
fn to_i64(self) -> i64 {
self as i64
}
#[inline]
fn ptr_from_i64(addr: i64) -> Self {
addr as *mut T
}
}