Skip to content

Commit

Permalink
generator: Implement push_next for all structures that declare a pNex…
Browse files Browse the repository at this point in the history
…t member

honor all extends (was honoring only "root" extends)

removed root_struct_names() function as it was not used anymore
the notion of root structure is not well defined in Vulkan

fixes #229
  • Loading branch information
filnet committed Jun 7, 2021
1 parent 06b4f8e commit 7dee935
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 48 deletions.
4 changes: 4 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased] - ReleaseDate

### Added

- Implement `push_next` for all structures that declare a `pNext` member

## [0.32.1] - 2021-03-29

### Added
Expand Down
68 changes: 20 additions & 48 deletions generator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1776,10 +1776,7 @@ pub fn derive_debug(
Some(q)
}

pub fn derive_setters(
_struct: &vkxml::Struct,
root_struct_names: &HashSet<String, impl BuildHasher>,
) -> Option<TokenStream> {
pub fn derive_setters(_struct: &vkxml::Struct) -> Option<TokenStream> {
if &_struct.name == "VkBaseInStructure"
|| &_struct.name == "VkBaseOutStructure"
|| &_struct.name == "VkTransformMatrixKHR"
Expand All @@ -1796,8 +1793,6 @@ pub fn derive_setters(
_ => None,
});

let has_next = members.clone().any(|field| field.param_ident() == "p_next");

let nofilter_count_members = [
"VkPipelineViewportStateCreateInfo.pViewports",
"VkPipelineViewportStateCreateInfo.pScissors",
Expand Down Expand Up @@ -1979,22 +1974,9 @@ pub fn derive_setters(

let extends_name = format_ident!("Extends{}", name);

let root_structs: Vec<Ident> = _struct
.extends
.as_ref()
.map(|extends| {
extends
.split(',')
.filter(|extend| root_struct_names.contains(*extend))
.map(|extends| format_ident!("Extends{}", name_to_tokens(extends)))
.collect()
})
.unwrap_or_else(Vec::new);

let is_root_struct = has_next && root_structs.is_empty();

// We only implement a next methods for root structs with a `pnext` field.
let next_function = if is_root_struct {
// We implement a `push_next` method for structs with a `p_next` field.
let has_next = members.clone().any(|field| field.param_ident() == "p_next");
let next_function = if has_next {
quote! {
/// Prepends the given extension struct between the root and the first pointer. This
/// method only exists on structs that can be passed to a function directly. Only
Expand Down Expand Up @@ -2024,16 +2006,26 @@ pub fn derive_setters(
quote!()
};

// Root structs come with their own trait that structs that extend
// Structs with a `p_next` member come with their own trait that structs that extend
// this struct will implement
let next_trait = if is_root_struct {
let next_trait = if has_next {
quote!(pub unsafe trait #extends_name {})
} else {
quote!()
};

// If the struct extends something we need to implement the trait.
let impl_extend_trait = root_structs.iter().map(|extends| {
// If the struct extends something we need to implement the traits.
let extends_structs: Vec<Ident> = _struct
.extends
.as_ref()
.map(|extends| {
extends
.split(',')
.map(|extends| format_ident!("Extends{}", name_to_tokens(extends)))
.collect()
})
.unwrap_or_else(Vec::new);
let impl_extend_trait = extends_structs.iter().map(|extends| {
quote! {
unsafe impl #extends for #name_builder<'_> {}
unsafe impl #extends for #name {}
Expand Down Expand Up @@ -2104,7 +2096,6 @@ pub fn manual_derives(_struct: &vkxml::Struct) -> TokenStream {
}
pub fn generate_struct(
_struct: &vkxml::Struct,
root_struct_names: &HashSet<String, impl BuildHasher>,
union_types: &HashSet<&str, impl BuildHasher>,
) -> TokenStream {
let name = name_to_tokens(&_struct.name);
Expand Down Expand Up @@ -2150,7 +2141,7 @@ pub fn generate_struct(

let debug_tokens = derive_debug(_struct, union_types);
let default_tokens = derive_default(_struct);
let setter_tokens = derive_setters(_struct, root_struct_names);
let setter_tokens = derive_setters(_struct);
let manual_derive_tokens = manual_derives(_struct);
let dbg_str = if debug_tokens.is_none() {
quote!(Debug,)
Expand Down Expand Up @@ -2248,26 +2239,9 @@ fn generate_union(union: &vkxml::Union) -> TokenStream {
}
}
}
pub fn root_struct_names(definitions: &[&vkxml::DefinitionsElement]) -> HashSet<String> {
definitions
.iter()
.filter_map(|definition| match *definition {
vkxml::DefinitionsElement::Struct(ref _struct) => {
let is_root_struct = _struct.extends.is_none();
if is_root_struct {
Some(_struct.name.clone())
} else {
None
}
}
_ => None,
})
.collect()
}
pub fn generate_definition(
definition: &vkxml::DefinitionsElement,
union_types: &HashSet<&str, impl BuildHasher>,
root_structs: &HashSet<String, impl BuildHasher>,
bitflags_cache: &mut HashSet<Ident, impl BuildHasher>,
const_values: &mut BTreeMap<Ident, ConstantTypeInfo>,
identifier_renames: &mut BTreeMap<String, Ident>,
Expand All @@ -2278,7 +2252,7 @@ pub fn generate_definition(
}
vkxml::DefinitionsElement::Typedef(ref typedef) => Some(generate_typedef(typedef)),
vkxml::DefinitionsElement::Struct(ref _struct) => {
Some(generate_struct(_struct, root_structs, union_types))
Some(generate_struct(_struct, union_types))
}
vkxml::DefinitionsElement::Bitmask(ref mask) => {
generate_bitmask(mask, bitflags_cache, const_values)
Expand Down Expand Up @@ -2731,14 +2705,12 @@ pub fn write_source_code<P: AsRef<Path>>(vk_headers_dir: &Path, src_dir: P) {

let mut identifier_renames = BTreeMap::new();

let root_names = root_struct_names(&definitions);
let definition_code: Vec<_> = definitions
.into_iter()
.filter_map(|def| {
generate_definition(
def,
&union_types,
&root_names,
&mut bitflags_cache,
&mut const_values,
&mut identifier_renames,
Expand Down

0 comments on commit 7dee935

Please sign in to comment.