use std::hash::{DefaultHasher, Hash, Hasher}; use crate::component::{ IsOptional as ComponentIsOptional, Metadata as ComponentMetadata, }; /// Archetype ID. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Id { hash: u64, } impl Id { pub fn from_components_metadata( components_metadata: &impl AsRef<[ComponentMetadata]>, ) -> Self { if components_metadata.as_ref().len() == 0 { return Self { hash: 0 }; } debug_assert!( components_metadata .as_ref() .is_sorted_by_key(|comp_metadata| comp_metadata.id), "Cannot create archetype ID from a unsorted component metadata list" ); let component_ids = components_metadata .as_ref() .iter() .filter_map(|component_metadata| { if component_metadata.is_optional == ComponentIsOptional::Yes { return None; } Some(component_metadata.id) }); let mut hasher = DefaultHasher::new(); for component_id in component_ids { component_id.hash(&mut hasher); } let hash = hasher.finish(); assert_ne!( hash, 0, "Archetype ID 0 is reserved for a archetype with zero components" ); Self { hash } } }