use VK_NULL_HANDLE; use std::{borrow, cmp, fmt, ops}; #[repr(C)] pub struct Handle(*mut T); impl Handle { pub fn new(value: T) -> Self { let ptr = Box::into_raw(Box::new(value)); Handle(ptr) } pub fn null() -> Self { Handle(VK_NULL_HANDLE as *mut _) } pub fn unbox(self) -> Option { if self.0 == VK_NULL_HANDLE as *mut T { None } else { Some(*unsafe { Box::from_raw(self.0) }) } } pub fn as_ref(&self) -> Option<&T> { if self.0 == VK_NULL_HANDLE as *mut T { None } else { Some(unsafe { &*self.0 }) } } } impl Clone for Handle { fn clone(&self) -> Self { Handle(self.0) } } impl Copy for Handle {} impl ops::Deref for Handle { type Target = T; fn deref(&self) -> &T { unsafe { &*self.0 } } } impl ops::DerefMut for Handle { fn deref_mut(&mut self) -> &mut T { unsafe { &mut *self.0 } } } impl borrow::Borrow for Handle { fn borrow(&self) -> &T { unsafe { &*self.0 } } } impl cmp::PartialEq for Handle { fn eq(&self, other: &Self) -> bool { self.0.eq(&other.0) } } impl fmt::Debug for Handle { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "Handle({:p})", self.0) } } #[cfg(feature = "dispatch")] pub use self::dispatch::DispatchHandle; #[cfg(not(feature = "dispatch"))] pub type DispatchHandle = Handle; #[cfg(feature = "dispatch")] mod dispatch { use VK_NULL_HANDLE; use std::{borrow, cmp, fmt, ops}; const ICD_LOADER_MAGIC: u64 = 0x01CDC0DE; #[repr(C)] pub struct DispatchHandle(*mut (u64, T)); impl DispatchHandle { pub fn new(value: T) -> Self { let ptr = Box::into_raw(Box::new((ICD_LOADER_MAGIC, value))); DispatchHandle(ptr) } pub fn null() -> Self { DispatchHandle(VK_NULL_HANDLE as *mut _) } pub fn unbox(self) -> Option { if self.0 == VK_NULL_HANDLE as *mut (u64, T) { None } else { Some(unsafe { Box::from_raw(self.0) }.1) } } pub fn as_ref(&self) -> Option<&T> { if self.0 == VK_NULL_HANDLE as *mut (u64, T) { None } else { Some(unsafe { &(*self.0).1 }) } } } impl Clone for DispatchHandle { fn clone(&self) -> Self { DispatchHandle(self.0) } } impl Copy for DispatchHandle {} impl ops::Deref for DispatchHandle { type Target = T; fn deref(&self) -> &T { unsafe { &(*self.0).1 } } } impl ops::DerefMut for DispatchHandle { fn deref_mut(&mut self) -> &mut T { unsafe { &mut (*self.0).1 } } } impl borrow::Borrow for DispatchHandle { fn borrow(&self) -> &T { unsafe { &(*self.0).1 } } } impl cmp::PartialEq for DispatchHandle { fn eq(&self, other: &Self) -> bool { self.0.eq(&other.0) } } impl fmt::Debug for DispatchHandle { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "DispatchHandle({:p})", self.0) } } }