event_trigger_action_system/
triggers.rs1use crate::TriggerCondition;
2use crate::conditions::{CompiledTriggerCondition, TriggerConditionUpdate};
3use btreemultimap_value_ord::BTreeMultiMap;
4use conditional_serde::ConditionalSerde;
5#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize};
7use std::cmp::Ordering;
8use std::collections::{BTreeMap, VecDeque};
9use std::fmt::Debug;
10
11mod std_lib_implementations;
12
13#[derive(Debug, Clone)]
15pub struct Triggers<Event, Action> {
16 triggers: Vec<Trigger<Event, Action>>,
17}
18
19#[derive(Debug, Clone)]
24#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
25pub struct CompiledTriggers<Event: TriggerEvent> {
26 trigger_system: TriggerSystem<Event>,
27 action_queue: VecDeque<Event::Action>,
28}
29
30#[derive(Debug, Clone)]
31#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
32struct TriggerSystem<Event: TriggerEvent> {
33 triggers: Vec<CompiledTrigger<Event>>,
34 subscriptions: BTreeMultiMap<Event::Identifier, usize>,
35}
36
37#[derive(Debug, Clone)]
39pub struct Trigger<Event, Action> {
40 pub id_str: String,
42 pub condition: TriggerCondition<Event>,
44 pub actions: Vec<Action>,
46}
47
48#[derive(Debug, Clone)]
50#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
51pub struct CompiledTrigger<Event: TriggerEvent> {
52 pub id_str: String,
54 condition: CompiledTriggerCondition<Event>,
55 actions: Option<Vec<Event::Action>>,
56}
57
58#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash, Ord, PartialOrd)]
62#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
63pub struct TriggerHandle(usize);
64
65pub trait TriggerAction: Debug + Clone {}
67
68pub trait TriggerIdentifier: Debug + Ord + Clone {}
72
73pub trait TriggerEvent: From<Self::Action> + PartialOrd {
75 type Action: TriggerAction + ConditionalSerde;
77
78 type Identifier: TriggerIdentifier + ConditionalSerde;
82
83 fn identifier(&self) -> Self::Identifier;
85
86 fn partial_cmp_progress(&self, other: &Self, target_ordering: Ordering) -> Option<f64>;
89}
90
91impl<Event, Action> Triggers<Event, Action> {
92 pub fn new(triggers: Vec<Trigger<Event, Action>>) -> Self {
94 Self { triggers }
95 }
96
97 pub fn compile<
101 EventCompiler: Fn(Event) -> CompiledEvent,
102 CompiledEvent: TriggerEvent,
103 ActionCompiler: Fn(Action) -> CompiledEvent::Action,
104 >(
105 self,
106 event_compiler: &EventCompiler,
107 action_compiler: &ActionCompiler,
108 ) -> CompiledTriggers<CompiledEvent> {
109 CompiledTriggers::new(
110 self.triggers
111 .into_iter()
112 .map(|trigger| trigger.compile(event_compiler, action_compiler))
113 .collect(),
114 )
115 }
116}
117
118impl<Event: TriggerEvent> CompiledTriggers<Event> {
119 pub(crate) fn new(mut triggers: Vec<CompiledTrigger<Event>>) -> Self {
120 let mut initial_actions = Vec::new();
121 let subscriptions = triggers
122 .iter_mut()
123 .enumerate()
124 .flat_map(|(id, trigger)| {
125 let subscriptions = trigger.subscriptions();
126 if trigger.completed() {
127 initial_actions.append(&mut trigger.consume_actions());
128 }
129 subscriptions
130 .into_iter()
131 .map(move |identifier| (identifier, id))
132 })
133 .collect();
134 let mut trigger_system = TriggerSystem {
135 triggers,
136 subscriptions,
137 };
138
139 let mut i = 0;
140 while i < initial_actions.len() {
141 initial_actions.append(
142 &mut trigger_system.execute_event(&Event::from(initial_actions[i].clone())),
143 );
144 i += 1;
145 }
146
147 Self {
148 trigger_system,
149 action_queue: initial_actions.into_iter().collect(),
150 }
151 }
152
153 pub fn execute_event(&mut self, event: &Event) {
158 self.action_queue
159 .extend(self.trigger_system.execute_event(event));
160 }
161
162 pub fn execute_events<'events>(&mut self, events: impl IntoIterator<Item = &'events Event>)
167 where
168 Event: 'events,
169 {
170 events
171 .into_iter()
172 .for_each(|event| self.execute_event(event));
173 }
174
175 pub fn execute_owned_events(&mut self, events: impl IntoIterator<Item = Event>) {
182 events
183 .into_iter()
184 .for_each(|event| self.execute_event(&event));
185 }
186
187 pub fn consume_action(&mut self) -> Option<Event::Action> {
189 self.action_queue.pop_front()
190 }
191
192 pub fn consume_all_actions(&mut self) -> impl '_ + Iterator<Item = Event::Action> {
196 self.action_queue.drain(0..self.action_queue.len())
197 }
198
199 pub fn progress(&self, handle: TriggerHandle) -> Option<(f64, f64)> {
203 self.trigger_system
204 .triggers
205 .get(handle.0)
206 .map(|trigger| trigger.progress())
207 }
208}
209
210impl<Event: TriggerEvent> TriggerSystem<Event> {
211 fn execute_event(&mut self, event: &Event) -> Vec<Event::Action> {
212 let mut all_actions = Vec::new();
213 let identifier = event.identifier();
214 let trigger_indices: Vec<_> = self
215 .subscriptions
216 .get(&identifier)
217 .unwrap_or(&BTreeMap::new())
218 .keys()
219 .copied()
220 .collect();
221 for trigger_index in trigger_indices {
222 let trigger = &mut self.triggers[trigger_index];
223 let (mut actions, trigger_condition_updates) = trigger.execute_event(event);
224 all_actions.append(&mut actions);
225
226 for trigger_condition_update in trigger_condition_updates {
227 match trigger_condition_update {
228 TriggerConditionUpdate::Subscribe(identifier) => {
229 self.subscriptions.insert(identifier.clone(), trigger_index);
230 }
231 TriggerConditionUpdate::Unsubscribe(identifier) => {
232 self.subscriptions
233 .remove_key_value(&identifier, &trigger_index);
234 }
235 }
236 }
237 }
238
239 let mut i = 0;
240 while i < all_actions.len() {
241 all_actions.append(&mut self.execute_event(&Event::from(all_actions[i].clone())));
242 i += 1;
243 }
244
245 all_actions
246 }
247}
248
249impl<Event, Action> Trigger<Event, Action> {
250 pub fn new(id_str: String, condition: TriggerCondition<Event>, actions: Vec<Action>) -> Self {
252 Self {
253 id_str,
254 condition,
255 actions,
256 }
257 }
258
259 pub fn compile<
263 EventCompiler: Fn(Event) -> CompiledEvent,
264 CompiledEvent: TriggerEvent,
265 ActionCompiler: Fn(Action) -> CompiledEvent::Action,
266 >(
267 self,
268 event_compiler: &EventCompiler,
269 action_compiler: &ActionCompiler,
270 ) -> CompiledTrigger<CompiledEvent> {
271 CompiledTrigger::new(
272 self.id_str,
273 self.condition.compile(event_compiler),
274 self.actions.into_iter().map(action_compiler).collect(),
275 )
276 }
277}
278
279impl<Event: TriggerEvent> CompiledTrigger<Event> {
280 pub(crate) fn new(
281 id_str: String,
282 condition: CompiledTriggerCondition<Event>,
283 actions: Vec<Event::Action>,
284 ) -> Self {
285 Self {
286 id_str,
287 condition,
288 actions: Some(actions),
289 }
290 }
291
292 pub(crate) fn subscriptions(&self) -> Vec<Event::Identifier> {
293 self.condition.subscriptions()
294 }
295
296 pub(crate) fn execute_event(
297 &mut self,
298 event: &Event,
299 ) -> (
300 Vec<Event::Action>,
301 Vec<TriggerConditionUpdate<Event::Identifier>>,
302 ) {
303 let (trigger_condition_updates, result, _) = self.condition.execute_event(event);
304 if result {
305 (self.actions.take().unwrap(), trigger_condition_updates)
306 } else {
307 (Default::default(), trigger_condition_updates)
308 }
309 }
310
311 pub(crate) fn progress(&self) -> (f64, f64) {
312 (
313 self.condition.current_progress(),
314 self.condition.required_progress(),
315 )
316 }
317
318 #[allow(dead_code)]
320 pub(crate) fn condition(&self) -> &CompiledTriggerCondition<Event> {
321 &self.condition
322 }
323
324 #[allow(dead_code)]
326 pub(crate) fn actions(&self) -> &[Event::Action] {
327 self.actions.as_deref().unwrap_or(&[])
328 }
329
330 pub(crate) fn completed(&self) -> bool {
331 self.condition.completed()
332 }
333
334 fn consume_actions(&mut self) -> Vec<Event::Action> {
335 self.actions.take().unwrap()
336 }
337}
338
339impl From<usize> for TriggerHandle {
340 fn from(value: usize) -> Self {
341 Self(value)
342 }
343}