summaryrefslogtreecommitdiff
path: root/ecs/src/event.rs
blob: 01d9d801b2d0aa399ba285a4be08356a33f967c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use std::any::TypeId;
use std::fmt::Debug;
use std::hash::Hash;

use seq_macro::seq;

pub trait Event: Debug + 'static
{
    fn id(&self) -> Id;
}

/// The ID of a [`Event`].
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Id
{
    inner: TypeId,
}

impl Id
{
    /// Returns the id of a [`Event`];
    pub fn of<EventT: Event>() -> Self
    {
        Self { inner: TypeId::of::<EventT>() }
    }
}

pub trait Ids
{
    type Iter<'a>: Iterator<Item = &'a Id>
    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 {
                    [#(
                        Id::of::<Event~I>(),
                    )*]
                }
            }
        });
    };
}

seq!(C in 0..=64 {
    impl_sequence!(C);
});