use std::any::TypeId;
use std::collections::hash_map::DefaultHasher;
use std::{fmt, hash};
use crate::util::DbgTypeId;
use crate::Archetype;
mod sealed {
pub trait Sealed {}
}
pub trait Partition: sealed::Sealed + Send + Sync + 'static {
fn describe(&self, f: &mut fmt::Formatter) -> fmt::Result;
fn compute_hash(&self) -> u64;
fn equals(&self, other: &dyn Partition) -> bool;
fn as_any(&self) -> &dyn std::any::Any;
}
impl<T: fmt::Debug + Eq + hash::Hash + 'static> sealed::Sealed for T {}
impl<T: fmt::Debug + Eq + hash::Hash + Send + Sync + 'static> Partition for T {
fn describe(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self) }
fn compute_hash(&self) -> u64 {
use hash::Hasher;
let mut hasher = DefaultHasher::new();
hash::Hash::hash(&TypeId::of::<Self>(), &mut hasher);
hash::Hash::hash(self, &mut hasher);
hasher.finish()
}
fn equals(&self, other: &dyn Partition) -> bool {
match other.as_any().downcast_ref::<Self>() {
Some(other) => self == other,
None => false,
}
}
fn as_any(&self) -> &dyn std::any::Any { self }
}
pub struct Wrapper(
pub Box<dyn Partition>,
);
impl fmt::Debug for Wrapper {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.describe(f) }
}
impl PartialEq for Wrapper {
fn eq(&self, other: &Self) -> bool { (*self.0).equals(&*other.0) }
}
impl Eq for Wrapper {}
impl hash::Hash for Wrapper {
fn hash<H: hash::Hasher>(&self, state: &mut H) { self.0.compute_hash().hash(state); }
}
#[derive(PartialEq, Eq, Hash)]
pub struct EntityCreationPartition {
pub(crate) ty: DbgTypeId,
}
impl fmt::Debug for EntityCreationPartition {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "EntityCreationPartition<{}>", self.ty)
}
}
impl EntityCreationPartition {
pub fn new<A: Archetype>() -> Self { Self { ty: DbgTypeId::of::<A>() } }
}
#[cfg(test)]
crate::assert_partition!(EntityCreationPartition);