bevy_ecs/observer/
trigger_event.rs1use crate::{
2 component::ComponentId,
3 entity::Entity,
4 event::Event,
5 world::{Command, DeferredWorld, World},
6};
7
8pub struct TriggerEvent<E, Targets: TriggerTargets = ()> {
10 pub event: E,
12
13 pub targets: Targets,
15}
16
17impl<E: Event, Targets: TriggerTargets> Command for TriggerEvent<E, Targets> {
18 fn apply(mut self, world: &mut World) {
19 let event_type = world.init_component::<E>();
20 trigger_event(world, event_type, &mut self.event, self.targets);
21 }
22}
23
24pub struct EmitDynamicTrigger<T, Targets: TriggerTargets = ()> {
26 event_type: ComponentId,
27 event_data: T,
28 targets: Targets,
29}
30
31impl<E, Targets: TriggerTargets> EmitDynamicTrigger<E, Targets> {
32 pub unsafe fn new_with_id(event_type: ComponentId, event_data: E, targets: Targets) -> Self {
36 Self {
37 event_type,
38 event_data,
39 targets,
40 }
41 }
42}
43
44impl<E: Event, Targets: TriggerTargets> Command for EmitDynamicTrigger<E, Targets> {
45 fn apply(mut self, world: &mut World) {
46 trigger_event(world, self.event_type, &mut self.event_data, self.targets);
47 }
48}
49
50#[inline]
51fn trigger_event<E, Targets: TriggerTargets>(
52 world: &mut World,
53 event_type: ComponentId,
54 event_data: &mut E,
55 targets: Targets,
56) {
57 let mut world = DeferredWorld::from(world);
58 if targets.entities().len() == 0 {
59 unsafe {
61 world.trigger_observers_with_data(
62 event_type,
63 Entity::PLACEHOLDER,
64 targets.components(),
65 event_data,
66 );
67 };
68 } else {
69 for target in targets.entities() {
70 unsafe {
72 world.trigger_observers_with_data(
73 event_type,
74 target,
75 targets.components(),
76 event_data,
77 );
78 };
79 }
80 }
81}
82
83pub trait TriggerTargets: Send + Sync + 'static {
90 fn components(&self) -> impl ExactSizeIterator<Item = ComponentId>;
92
93 fn entities(&self) -> impl ExactSizeIterator<Item = Entity>;
95}
96
97impl TriggerTargets for () {
98 fn components(&self) -> impl ExactSizeIterator<Item = ComponentId> {
99 [].into_iter()
100 }
101
102 fn entities(&self) -> impl ExactSizeIterator<Item = Entity> {
103 [].into_iter()
104 }
105}
106
107impl TriggerTargets for Entity {
108 fn components(&self) -> impl ExactSizeIterator<Item = ComponentId> {
109 [].into_iter()
110 }
111
112 fn entities(&self) -> impl ExactSizeIterator<Item = Entity> {
113 std::iter::once(*self)
114 }
115}
116
117impl TriggerTargets for Vec<Entity> {
118 fn components(&self) -> impl ExactSizeIterator<Item = ComponentId> {
119 [].into_iter()
120 }
121
122 fn entities(&self) -> impl ExactSizeIterator<Item = Entity> {
123 self.iter().copied()
124 }
125}
126
127impl<const N: usize> TriggerTargets for [Entity; N] {
128 fn components(&self) -> impl ExactSizeIterator<Item = ComponentId> {
129 [].into_iter()
130 }
131
132 fn entities(&self) -> impl ExactSizeIterator<Item = Entity> {
133 self.iter().copied()
134 }
135}
136
137impl TriggerTargets for ComponentId {
138 fn components(&self) -> impl ExactSizeIterator<Item = ComponentId> {
139 std::iter::once(*self)
140 }
141
142 fn entities(&self) -> impl ExactSizeIterator<Item = Entity> {
143 [].into_iter()
144 }
145}
146
147impl TriggerTargets for Vec<ComponentId> {
148 fn components(&self) -> impl ExactSizeIterator<Item = ComponentId> {
149 self.iter().copied()
150 }
151
152 fn entities(&self) -> impl ExactSizeIterator<Item = Entity> {
153 [].into_iter()
154 }
155}
156
157impl<const N: usize> TriggerTargets for [ComponentId; N] {
158 fn components(&self) -> impl ExactSizeIterator<Item = ComponentId> {
159 self.iter().copied()
160 }
161
162 fn entities(&self) -> impl ExactSizeIterator<Item = Entity> {
163 [].into_iter()
164 }
165}