Skip to content

Commit

Permalink
Emit more info on duplicate components in archetype creation
Browse files Browse the repository at this point in the history
  • Loading branch information
Veykril committed Nov 1, 2020
1 parent 42fc5ec commit e0bd1e0
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 6 deletions.
2 changes: 1 addition & 1 deletion crates/bevy_ecs/hecs/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ fn struct_fields(fields: &syn::Fields) -> (Vec<&syn::Type>, Vec<syn::Member>) {
}
}

fn member_as_idents<'a>(members: &'a [syn::Member]) -> Vec<Cow<'a, syn::Ident>> {
fn member_as_idents(members: &[syn::Member]) -> Vec<Cow<'_, syn::Ident>> {
members
.iter()
.map(|member| match member {
Expand Down
27 changes: 23 additions & 4 deletions crates/bevy_ecs/hecs/src/archetype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,32 @@ pub struct Archetype {
}

impl Archetype {
fn assert_type_info(types: &[TypeInfo]) {
types.windows(2).for_each(|x| match x[0].cmp(&x[1]) {
core::cmp::Ordering::Less => (),
#[cfg(debug_assertions)]
core::cmp::Ordering::Equal => panic!(
"attempted to allocate entity with duplicate {} components; \
each type must occur at most once!",
x[0].type_name
),
#[cfg(not(debug_assertions))]
core::cmp::Ordering::Equal => panic!(
"attempted to allocate entity with duplicate components; \
each type must occur at most once!"
),
core::cmp::Ordering::Greater => panic!("type info is unsorted"),
});
}

#[allow(missing_docs)]
pub fn new(types: Vec<TypeInfo>) -> Self {
Self::with_grow(types, 64)
}

#[allow(missing_docs)]
pub fn with_grow(types: Vec<TypeInfo>, grow_size: usize) -> Self {
debug_assert!(
types.windows(2).all(|x| x[0] < x[1]),
"type info unsorted or contains duplicates"
);
Self::assert_type_info(&types);
let mut state = HashMap::with_capacity_and_hasher(types.len(), Default::default());
for ty in &types {
state.insert(ty.id, TypeState::new());
Expand Down Expand Up @@ -484,6 +499,8 @@ pub struct TypeInfo {
id: TypeId,
layout: Layout,
drop: unsafe fn(*mut u8),
#[cfg(debug_assertions)]
type_name: &'static str,
}

impl TypeInfo {
Expand All @@ -497,6 +514,8 @@ impl TypeInfo {
id: TypeId::of::<T>(),
layout: Layout::new::<T>(),
drop: drop_ptr::<T>,
#[cfg(debug_assertions)]
type_name: core::any::type_name::<T>(),
}
}

Expand Down
31 changes: 30 additions & 1 deletion crates/bevy_ecs/hecs/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,18 @@ fn derived_bundle() {

#[test]
#[cfg(feature = "macros")]
#[should_panic(expected = "each type must occur at most once")]
#[cfg_attr(
debug_assertions,
should_panic(
expected = "attempted to allocate entity with duplicate i32 components; each type must occur at most once!"
)
)]
#[cfg_attr(
not(debug_assertions),
should_panic(
expected = "attempted to allocate entity with duplicate components; each type must occur at most once!"
)
)]
fn bad_bundle_derive() {
#[derive(Bundle)]
struct Foo {
Expand Down Expand Up @@ -361,3 +372,21 @@ fn added_tracking() {
assert!(world.query_one_mut::<&i32>(a).is_ok());
assert!(world.query_one_mut::<Added<i32>>(a).is_err());
}

#[test]
#[cfg_attr(
debug_assertions,
should_panic(
expected = "attempted to allocate entity with duplicate f32 components; each type must occur at most once!"
)
)]
#[cfg_attr(
not(debug_assertions),
should_panic(
expected = "attempted to allocate entity with duplicate components; each type must occur at most once!"
)
)]
fn duplicate_components_panic() {
let mut world = World::new();
world.reserve::<(f32, i64, f32)>(1);
}

0 comments on commit e0bd1e0

Please sign in to comment.