You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

76 lines
2.0 KiB

//! Strongly typed safe opaque pointers to GHOST handles.
//!
//! We define opaque ZST structures for each handle type, these then implement the [`GhostHandle`] trait, which allows them to be used for type arguments to [`Handle<T>`](Handle).
use super::*;
pub use types::{Handle,GhostHandle};
pub(crate) trait AsHandle<T: GhostHandle>
{
fn as_handle(&mut self) -> &mut Handle<T>;
#[inline] fn as_raw(&mut self) -> *mut Handle<T>
{
self.as_handle() as *mut Handle<T>
}
}
impl<T: GhostHandle> AsHandle<T> for Handle<T> //this is kinda silly, but its internal and we'll know to never use this
{
#[inline] fn as_handle(&mut self) -> &mut Handle<T>
{
self
}
}
impl<T: GhostHandle> AsHandle<T> for *mut Handle<T>
{
fn as_handle(&mut self) -> &mut Handle<T>
{
unsafe{&mut* *self}
}
#[inline] fn as_raw(&mut self) -> *mut Handle<T>
{
*self
}
}
impl<'a, T: GhostHandle, U> AsHandle<T> for &'a mut U
where U: AsHandle<T>
{
fn as_handle(&mut self) -> &mut Handle<T>
{
(*self).as_handle()
}
#[inline] fn as_raw(&mut self) -> *mut Handle<T>
{
(*self).as_raw()
}
}
#[cfg(not(nightly))] enum HandleInner{}
macro_rules! handle {
($name:ident, $inner_name:ident) => {
#[cfg(nightly)] pub struct $inner_name(!);
#[cfg(not(nightly))] pub struct $inner_name(HandleInner);
impl private::Sealed for $inner_name{}
impl GhostHandle for $inner_name{}
pub type $name = *mut Handle<$inner_name>;
};
}
handle!(GHOST_SystemHandle, System);
handle!(GHOST_TimerTaskHandle, TimerTask);
handle!(GHOST_WindowHandle, Window);
handle!(GHOST_EventHandle, Event);
handle!(GHOST_RectangleHandle, Rectangle);
handle!(GHOST_EventConsumerHandle, EventConsumer);
handle!(GHOST_ContextHandle, Context);
handle!(GHOST_XrContextHandle, XrContextHandle);
// This is very unsafe.
/*#[inline] pub(crate) unsafe fn coerce<'a, T>(from: *mut Handle<T>) -> &'a mut Handle<T>
where T: GhostHandle
{
std::mem::transmute::<*mut _, &'a mut _>(from) //this is needed because we can't safely dereference `Handle<T>`.
}*/