use std::hash::{DefaultHasher, Hash, Hasher}; use crate::component::{ IsOptional as ComponentIsOptional, Metadata as ComponentMetadata, }; use crate::uid::Uid; /// 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 { debug_assert!( components_metadata.as_ref().len() > 0, "Cannot create a archetype ID from a empty component metadata list" ); 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" ); Self::new( components_metadata .as_ref() .iter() .filter_map(|component_metadata| { if component_metadata.is_optional == ComponentIsOptional::Yes { return None; } Some(component_metadata.id) }), ) } /// Returns the ID of a archetype with the given components. fn new(component_ids: impl IntoIterator) -> Self { let mut hasher = DefaultHasher::new(); for component_id in component_ids { component_id.hash(&mut hasher); } let hash = hasher.finish(); Self { hash } } }