macro_rules! gen_chain_struct {
(
name: $name:ident [$wrapper_name:ident],
query: $query_name:ident [$query_wrapper_name:ident],
vks: $vks_ty:ident,
input: $is_input:ident,
output: $is_output:ident,
$(
$field_name:ident: $field_ty:ident {
mod: $field_mod:ident,
fn_add: $field_fn_add:ident,
fn_has: $field_fn_has:ident,
fn_get: $field_fn_get:ident,
wrapper: $field_wrapper_ty:ident,
vks: $field_vks_ty:ident,
stype: $field_stype:pat,
}
)*
) => {
#[derive(Debug, Clone, Default, PartialEq)]
pub struct $name {
$( $field_name: Option<::$field_mod::$field_ty>, )*
guard: (),
}
impl $name {
#[inline]
pub fn new() -> Self {
Default::default()
}
$(
#[inline]
pub fn $field_fn_add(&mut self, $field_name: ::$field_mod::$field_ty) -> &mut Self {
self.$field_name = Some($field_name);
self
}
#[inline]
pub fn $field_fn_has(&self) -> bool {
self.$field_name.is_some()
}
#[inline]
pub fn $field_fn_get(&self) -> Option<&::$field_mod::$field_ty> {
self.$field_name.as_ref()
}
)*
}
gen_chain_struct! {
chain_from_pnext
name: $name [$wrapper_name],
query: $query_name [$query_wrapper_name],
vks: $vks_ty,
input: $is_input,
output: $is_output,
$(
$field_name: $field_ty {
mod: $field_mod,
fn_add: $field_fn_add,
fn_has: $field_fn_has,
fn_get: $field_fn_get,
wrapper: $field_wrapper_ty,
vks: $field_vks_ty,
stype: $field_stype,
}
)*
}
gen_chain_struct! {
chain_wrapper
name: $name [$wrapper_name],
query: $query_name [$query_wrapper_name],
vks: $vks_ty,
input: $is_input,
output: $is_output,
$(
$field_name: $field_ty {
mod: $field_mod,
fn_add: $field_fn_add,
fn_has: $field_fn_has,
fn_get: $field_fn_get,
wrapper: $field_wrapper_ty,
vks: $field_vks_ty,
stype: $field_stype,
}
)*
}
gen_chain_struct! {
query
name: $name [$wrapper_name],
query: $query_name [$query_wrapper_name],
vks: $vks_ty,
input: $is_input,
output: $is_output,
$(
$field_name: $field_ty {
mod: $field_mod,
fn_add: $field_fn_add,
fn_has: $field_fn_has,
fn_get: $field_fn_get,
wrapper: $field_wrapper_ty,
vks: $field_vks_ty,
stype: $field_stype,
}
)*
}
};
(
chain_from_pnext
name: $name:ident [$wrapper_name:ident],
query: $query_name:ident [$query_wrapper_name:ident],
vks: $vks_ty:ident,
input: $is_input:ident,
output: true,
$(
$field_name:ident: $field_ty:ident {
mod: $field_mod:ident,
fn_add: $field_fn_add:ident,
fn_has: $field_fn_has:ident,
fn_get: $field_fn_get:ident,
wrapper: $field_wrapper_ty:ident,
vks: $field_vks_ty:ident,
stype: $field_stype:pat,
}
)*
) => {
impl $name {
#[allow(unused_mut)]
pub(crate) unsafe fn from_pnext(mut pnext: *mut ::libc::c_void) -> Self {
let mut res = $name::new();
#[allow(non_snake_case)]
#[repr(C)]
pub struct VkStructure {
pub sType: vks::VkStructureType,
pub pNext: *mut ::libc::c_void,
}
while !pnext.is_null() {
let tmp = &*(pnext as *const VkStructure);
match tmp.sType {
$( $field_stype => res.$field_name = Some(::$field_mod::$field_ty::from_vks(&*(pnext as *const vks::$field_vks_ty), false)), )*
_ => { }
}
pnext = tmp.pNext;
}
res
}
#[inline]
pub(crate) unsafe fn from_optional_pnext(pnext: *mut ::libc::c_void, with_chain: bool) -> Option<Self> {
if with_chain && !pnext.is_null() {
Some($name::from_pnext(pnext))
}
else {
None
}
}
}
};
(
chain_from_pnext
name: $name:ident [$wrapper_name:ident],
query: $query_name:ident [$query_wrapper_name:ident],
vks: $vks_ty:ident,
input: $is_input:ident,
output: false,
$(
$field_name:ident: $field_ty:ident {
mod: $field_mod:ident,
fn_add: $field_fn_add:ident,
fn_has: $field_fn_has:ident,
fn_get: $field_fn_get:ident,
wrapper: $field_wrapper_ty:ident,
vks: $field_vks_ty:ident,
stype: $field_stype:pat,
}
)*
) => { };
(
chain_wrapper
name: $name:ident [$wrapper_name:ident],
query: $query_name:ident [$query_wrapper_name:ident],
vks: $vks_ty:ident,
input: true,
output: $is_output:ident,
$(
$field_name:ident: $field_ty:ident {
mod: $field_mod:ident,
fn_add: $field_fn_add:ident,
fn_has: $field_fn_has:ident,
fn_get: $field_fn_get:ident,
wrapper: $field_wrapper_ty:ident,
vks: $field_vks_ty:ident,
stype: $field_stype:pat,
}
)*
) => {
#[derive(Debug)]
pub(crate) struct $wrapper_name {
pub pnext: *mut ::libc::c_void,
$( $field_name: Option<Box<::$field_mod::$field_wrapper_ty>>, )*
}
impl $wrapper_name {
#[allow(unused_mut)]
#[allow(unused_variables)]
pub fn new(from: &$name) -> Self {
let mut pnext_first: *mut ::libc::c_void = ::std::ptr::null_mut();
let mut pnext: *mut *mut ::libc::c_void = &mut pnext_first;
$(
let $field_name = from.$field_name.as_ref().map(|$field_name| {
let mut $field_name: Box<_> = Box::new(::$field_mod::$field_wrapper_ty::new($field_name, false));
unsafe {
*pnext = &$field_name.vks_struct as *const _ as *mut ::libc::c_void;
pnext = &mut ($field_name.vks_struct.pNext as *mut _);
}
$field_name
});
)*
$wrapper_name {
pnext: pnext_first,
$( $field_name: $field_name, )*
}
}
#[inline]
pub fn new_optional(chain: &Option<$name>, with_chain: bool) -> (*mut ::libc::c_void, Option<Self>) {
match *chain {
Some(ref chain) if with_chain => {
let chain = Self::new(chain);
(chain.pnext, Some(chain))
}
_ => (::std::ptr::null_mut(), None),
}
}
}
};
(
chain_wrapper
name: $name:ident [$wrapper_name:ident],
query: $query_name:ident [$query_wrapper_name:ident],
vks: $vks_ty:ident,
input: false,
output: $is_output:ident,
$(
$field_name:ident: $field_ty:ident {
mod: $field_mod:ident,
fn_add: $field_fn_add:ident,
fn_has: $field_fn_has:ident,
fn_get: $field_fn_get:ident,
wrapper: $field_wrapper_ty:ident,
vks: $field_vks_ty:ident,
stype: $field_stype:pat,
}
)*
) => { };
(
query
name: $name:ident [$wrapper_name:ident],
query: $query_name:ident [$query_wrapper_name:ident],
vks: $vks_ty:ident,
input: $is_input:ident,
output: true,
$(
$field_name:ident: $field_ty:ident {
mod: $field_mod:ident,
fn_add: $field_fn_add:ident,
fn_has: $field_fn_has:ident,
fn_get: $field_fn_get:ident,
wrapper: $field_wrapper_ty:ident,
vks: $field_vks_ty:ident,
stype: $field_stype:pat,
}
)*
) => {
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Default)]
pub struct $query_name {
$( $field_name: bool, )*
guard: (),
}
impl $query_name {
#[inline]
pub fn new() -> Self {
Default::default()
}
$(
#[inline]
pub fn $field_fn_add(&mut self) -> &mut Self {
self.$field_name = true;
self
}
)*
}
#[derive(Debug, Default)]
pub(crate) struct $query_wrapper_name {
pub vks_struct: vks::$vks_ty,
$( $field_name: Option<Box<vks::$field_vks_ty>>, )*
}
impl $query_wrapper_name {
#[allow(unused_mut)]
#[allow(unused_variables)]
pub fn new(query: &$query_name) -> Self {
let mut vks_struct: vks::$vks_ty = Default::default();
let mut pnext: *mut *mut ::libc::c_void = &mut (vks_struct.pNext as *mut _);
$(
let $field_name = if query.$field_name {
let mut $field_name: Box<vks::$field_vks_ty> = Default::default();
unsafe {
let $field_name: &mut vks::$field_vks_ty = &mut $field_name;
*pnext = $field_name as *mut _ as *mut ::libc::c_void;
}
pnext = &mut ($field_name.pNext as *mut _);
Some($field_name)
}
else {
None
};
)*
$query_wrapper_name {
vks_struct: vks_struct,
$( $field_name: $field_name, )*
}
}
#[inline]
pub fn new_optional(query: Option<&$query_name>) -> Self {
match query {
Some(query) => $query_wrapper_name::new(query),
None => Default::default(),
}
}
}
};
(
query
name: $name:ident [$wrapper_name:ident],
query: $query_name:ident [$query_wrapper_name:ident],
vks: $vks_ty:ident,
input: $is_input:ident,
output: false,
$(
$field_name:ident: $field_ty:ident {
mod: $field_mod:ident,
fn_add: $field_fn_add:ident,
fn_has: $field_fn_has:ident,
fn_get: $field_fn_get:ident,
wrapper: $field_wrapper_ty:ident,
vks: $field_vks_ty:ident,
stype: $field_stype:pat,
}
)*
) => { };
}