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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use std::marker::PhantomData;
use derivative::Derivative;
use amethyst_core::{
ecs::prelude::{Component, Read, ReadStorage, System, SystemData, World, Write},
shrev::{Event, EventChannel, ReaderId},
SystemDesc,
};
use crate::event::TargetedEvent;
#[cfg(feature = "profiler")]
use thread_profiler::profile_scope;
pub trait EventReceiver<T> {
fn receive_one(&mut self, value: &T);
fn receive(&mut self, values: &[T]);
}
impl<T> EventReceiver<T> for EventChannel<T>
where
T: Clone + Event,
{
fn receive_one(&mut self, value: &T) {
self.single_write(value.clone());
}
fn receive(&mut self, values: &[T]) {
self.iter_write(values.iter().cloned());
}
}
pub trait EventRetrigger: Component {
type In: Clone + Send + Sync + TargetedEvent;
type Out: Clone + Send + Sync;
fn apply<R>(&self, event: &Self::In, out: &mut R)
where
R: EventReceiver<Self::Out>;
}
#[derive(Derivative, Debug)]
#[derivative(Default(bound = ""))]
pub struct EventRetriggerSystemDesc<T> {
marker: PhantomData<T>,
}
impl<'a, 'b, T> SystemDesc<'a, 'b, EventRetriggerSystem<T>> for EventRetriggerSystemDesc<T>
where
T: EventRetrigger,
{
fn build(self, world: &mut World) -> EventRetriggerSystem<T> {
<EventRetriggerSystem<T> as System<'_>>::SystemData::setup(world);
let event_reader = world.fetch_mut::<EventChannel<T::In>>().register_reader();
EventRetriggerSystem::new(event_reader)
}
}
#[derive(Debug)]
pub struct EventRetriggerSystem<T: EventRetrigger> {
event_reader: ReaderId<T::In>,
}
impl<T> EventRetriggerSystem<T>
where
T: EventRetrigger,
{
pub fn new(event_reader: ReaderId<T::In>) -> Self {
Self { event_reader }
}
}
impl<'s, T> System<'s> for EventRetriggerSystem<T>
where
T: EventRetrigger,
{
type SystemData = (
Read<'s, EventChannel<T::In>>,
Write<'s, EventChannel<T::Out>>,
ReadStorage<'s, T>,
);
fn run(&mut self, (in_channel, mut out_channel, retrigger): Self::SystemData) {
#[cfg(feature = "profiler")]
profile_scope!("event_retrigger_system");
let event_reader = &mut self.event_reader;
for event in in_channel.read(event_reader) {
if let Some(entity_retrigger) = retrigger.get(event.get_target()) {
entity_retrigger.apply(&event, &mut *out_channel);
}
}
}
}