use super::*;
use core::ffi::{CStr, c_char, c_void};
use core::hash::Hash;
pub trait Vk<'a> {
type Target;
fn vk(self) -> Self::Target;
}
pub trait Sys<'a> {
type Target;
fn sys(self) -> Self::Target;
}
pub trait Chainable: Sized + StructType {
fn p_next(&self) -> &*const c_void;
fn p_next_mut(&mut self) -> &mut *mut c_void;
unsafe fn push_next<E: Extend<Self>>(&mut self, ex: &mut E) -> &mut Self {
core::mem::replace(ex.p_next_mut(), *self.p_next_mut());
*self.p_next_mut() = (ex as *mut E).cast();
self
}
unsafe fn with_next<E: Extend<Self>>(mut self, ex: &mut E) -> Self {
core::mem::replace(ex.p_next_mut(), *self.p_next_mut());
*self.p_next_mut() = (ex as *mut E).cast();
self
}
unsafe fn next(&'_ self) -> Option<&'_ vk::BaseInStructure<'_>> {
let p_next = *self.p_next();
if p_next.is_null() {
None
} else {
Some(unsafe { &*(p_next.cast::<vk::BaseInStructure>()) })
}
}
unsafe fn next_mut(&'_ mut self) -> Option<&'_ mut vk::BaseOutStructure<'_>> {
let p_next = *self.p_next_mut();
if p_next.is_null() {
None
} else {
Some(unsafe { &mut *(p_next.cast::<vk::BaseOutStructure>()) })
}
}
unsafe fn upcast(&'_ self) -> &'_ vk::BaseInStructure<'_> {
unsafe { core::mem::transmute(self) }
}
unsafe fn upcast_mut(&'_ mut self) -> &'_ mut vk::BaseOutStructure<'_> {
unsafe { core::mem::transmute(self) }
}
}
pub trait Extend<T: Chainable>: Chainable {}
impl<'a> vk::BaseInStructure<'a> {
pub unsafe fn downcast<T: Chainable>(&self) -> Option<&T> {
if self.s_type == T::TYPE {
Some(unsafe { core::mem::transmute(self) })
} else {
None
}
}
pub unsafe fn downcast_mut<T: Chainable>(&mut self) -> Option<&mut T> {
if self.s_type == T::TYPE {
Some(unsafe { core::mem::transmute(self) })
} else {
None
}
}
}
impl<'a> vk::BaseOutStructure<'a> {
pub unsafe fn downcast<T: Chainable>(&self) -> Option<&T> {
if self.s_type == T::TYPE {
Some(unsafe { core::mem::transmute(self) })
} else {
None
}
}
pub unsafe fn downcast_mut<T: Chainable>(&mut self) -> Option<&mut T> {
if self.s_type == T::TYPE {
Some(unsafe { core::mem::transmute(self) })
} else {
None
}
}
}
pub trait RawHandle:
ObjectType + Copy + Eq + Ord + Hash + core::fmt::Debug + core::fmt::Pointer
{
}
pub trait RawRootHandle: RawHandle {}
pub trait RawSubHandle: RawHandle {
type Parent: RawHandle;
}
pub trait StructType {
const TYPE: vk::StructureType;
}
pub trait ObjectType {
const TYPE: vk::ObjectType;
}
pub trait ProcAddrLoader {
unsafe fn load(&mut self, name: &CStr) -> Option<ProcAddr>;
}
impl<F: FnMut(&CStr) -> Option<ProcAddr>> ProcAddrLoader for F {
unsafe fn load(&mut self, name: &CStr) -> Option<ProcAddr> {
self(name)
}
}
pub trait Abi<T> {
fn abi(self) -> T;
}
impl<T> Abi<T> for T {
fn abi(self) -> T {
self
}
}
impl<T> Abi<*const T> for &T {
fn abi(self) -> *const T {
self
}
}
impl<T> Abi<*mut T> for &mut T {
fn abi(self) -> *mut T {
self
}
}
impl<T> Abi<*const T> for &[T] {
fn abi(self) -> *const T {
self.as_ptr()
}
}
impl<T> Abi<*mut T> for &mut [T] {
fn abi(self) -> *mut T {
self.as_mut_ptr()
}
}
impl<T> Abi<*const T> for Option<&T> {
fn abi(self) -> *const T {
self.map(|a| a as *const T).unwrap_or_default()
}
}
impl<T> Abi<*mut T> for Option<&mut T> {
fn abi(self) -> *mut T {
self.map(|a| a as *mut T).unwrap_or_default()
}
}
impl<T> Abi<*const T> for Option<&[T]> {
fn abi(self) -> *const T {
self.map(|a| a.as_ptr()).unwrap_or_default()
}
}
impl<T> Abi<*mut T> for Option<&mut [T]> {
fn abi(self) -> *mut T {
self.map(|a| a.as_mut_ptr()).unwrap_or_default()
}
}
impl Abi<vk::Bool> for bool {
fn abi(self) -> vk::Bool {
self.into()
}
}
impl Abi<sys::VkBool32> for bool {
fn abi(self) -> sys::VkBool32 {
if self { sys::VK_TRUE } else { sys::VK_FALSE }
}
}
impl<'a> Abi<*const c_char> for &'a CStr {
fn abi(self) -> *const c_char {
self.as_ptr()
}
}
impl<'a> Abi<*const c_char> for Option<&'a CStr> {
fn abi(self) -> *const c_char {
self.map(|a| a.as_ptr()).unwrap_or_default()
}
}
impl Abi<[u8; sys::VK_UUID_SIZE as usize]> for Uuid {
fn abi(self) -> [u8; sys::VK_UUID_SIZE as usize] {
unsafe { core::mem::transmute(self) }
}
}