appy/utils/
trigger.rs

1use crate::*;
2use std::cell::RefCell;
3use std::rc::Rc;
4
5/// A trigger is similar to an event, but more asynchronous in nature.
6///
7/// A trigger can be created in one place, and then a trigger function can
8/// be created. The trigger function can be passed to another piece of code,
9/// and that piece of code can call the function to trigger the trigger.
10///
11/// When the trigger is triggered, no handler will be called (as with an event).
12/// Instead, a state will be set, which can later be checked where the trigger
13/// was created.
14pub struct Trigger {
15    state: Rc<RefCell<bool>>,
16    trigger: Rc<dyn Fn()>,
17}
18
19impl Trigger {
20    /// Create a trigger.
21    pub fn new() -> Self {
22        let state = Rc::new(RefCell::new(false));
23        let trigger = Rc::new(with_clone!([state], move || {
24            *state.borrow_mut() = true;
25        }));
26
27        Trigger { state, trigger }
28    }
29
30    /// Get the current state of the trigger.
31    pub fn get_state(&self) -> bool {
32        *self.state.borrow()
33    }
34
35    /// Set the current state of the trigger.
36    pub fn set_state(&self, new_state: bool) {
37        *self.state.borrow_mut() = new_state;
38    }
39
40    /// Get a trigger function for this trigger.
41    ///
42    /// This trigger function can be safely passed to another part of
43    /// the program, as well as cheaply cloned.
44    pub fn create_trigger(&self) -> Rc<dyn Fn()> {
45        self.trigger.clone()
46    }
47}