use std::any::TypeId; use std::fmt::Debug; use std::hash::{DefaultHasher, Hash, Hasher}; use seq_macro::seq; pub mod component; pub trait Event: Debug + 'static { /// Returns the ID of this event. fn id() -> Id where Self: Sized, { Id::new::(None) } } pub mod start; /// The ID of a [`Event`]. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Id { inner: TypeId, extra: Option, } impl Id { #[must_use] pub fn new(extra: Option) -> Self where EventT: Event, Extra: Hash, { Self { inner: TypeId::of::(), extra: extra.map(|extra| { let mut hasher = DefaultHasher::new(); extra.hash(&mut hasher); hasher.finish() }), } } } pub trait Ids { type Iter<'a>: Iterator where Self: 'a; fn iter(&self) -> Self::Iter<'_>; } /// A sequence of events. pub trait Sequence { type Ids: Ids; fn ids() -> Self::Ids; } macro_rules! impl_sequence { ($c: tt) => { seq!(I in 0..=$c { impl Ids for [Id; $c + 1] { type Iter<'a> = std::slice::Iter<'a, Id>; fn iter(&self) -> Self::Iter<'_> { self.into_iter() } } impl<#(Event~I: Event,)*> Sequence for (#(Event~I,)*) { type Ids = [Id; $c + 1]; fn ids() -> Self::Ids { [#( Event~I::id(), )*] } } }); }; } seq!(C in 0..=64 { impl_sequence!(C); });