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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use bevy_ecs::prelude::{IntoSystem, ResMut};
use std::iter::{FilterMap, Map};

use crate::prelude::CoreStage;

pub trait Event: Send + Sync {}

impl<T: Send + Sync> Event for T {}

pub trait EventStorage {
    fn clear(&mut self);
}

pub struct EventStorageVec<T: Event> {
    data: Vec<T>,
}

impl<T> EventStorage for EventStorageVec<T>
where
    T: Event,
{
    fn clear(&mut self) {
        self.data.clear()
    }
}

pub struct Events<T: Event> {
    current: Vec<T>,
    last: Vec<T>,
}

impl<T: 'static + Event> crate::ecs::Bundle for Events<T> {
    fn init(self, instance: &mut crate::Instance) {
        instance.add_resource(self);
        instance.add_system_at_stage(CoreStage::PreUpdate, Events::<T>::update_system.system());
    }
}

impl<T: Event> Default for Events<T> {
    fn default() -> Self {
        Self {
            current: Vec::new(),
            last: Vec::new(),
        }
    }
}

impl<T: 'static + Event> Events<T> {
    pub fn new() -> Self {
        Self {
            current: Vec::new(),
            last: Vec::new(),
        }
    }

    pub fn update(&mut self) {
        std::mem::swap(&mut self.current, &mut self.last);
        self.current.clear();
    }

    pub fn map<B, F>(&self, f: F) -> Map<std::slice::Iter<T>, F>
    where
        Self: Sized,
        F: FnMut(&T) -> B,
    {
        self.last.iter().map(f)
    }

    pub fn filter_map<B, F>(&self, f: F) -> FilterMap<std::slice::Iter<T>, F>
    where
        Self: Sized,
        F: FnMut(&T) -> Option<B>,
    {
        self.last.iter().filter_map(f)
    }

    pub fn iter(&self) -> std::slice::Iter<T> {
        self.last.iter()
    }

    pub fn contains<F>(&self, x: &T) -> bool
    where
        T: PartialEq,
    {
        self.last.contains(x)
    }

    pub fn push(&mut self, event: T) {
        self.current.push(event);
    }

    pub fn update_system(mut events: ResMut<Events<T>>) {
        events.update();
    }
}