layer_system/
lib.rs

1#![deny(missing_docs)]
2/*!
3See [README.md]
4**/
5
6/// A special action for the layer.
7pub enum ChangeAction {
8    /// No special action to the layer.
9    None,
10    /// Pass the event to the next layer.
11    Pass,
12    /// Remove the current layer.
13    Remove,
14    /// Remove all layers.
15    Clear,
16}
17
18/// The action, that will be done after handling an event by a layer.
19pub struct Change<S, E> {
20    /// Add new layers on top of the current layer.
21    add: Vec<Box<dyn Layer<S, E>>>,
22    /// Special actions.
23    action: ChangeAction,
24}
25
26impl<S, E> Change<S, E> {
27    /// A simple change doing nothing.
28    pub fn none() -> Self {
29        Self {
30            add: Vec::new(),
31            action: ChangeAction::None,
32        }
33    }
34
35    /// A change passing the event to the next layer.
36    pub fn pass() -> Self {
37        Self {
38            add: Vec::new(),
39            action: ChangeAction::Pass,
40        }
41    }
42
43    /// A change just adding new layers.
44    pub fn add(add: Vec<Box<dyn Layer<S, E>>>) -> Self {
45        Self {
46            add,
47            action: ChangeAction::None,
48        }
49    }
50
51    /// A simple change removing the current layer.
52    pub fn remove() -> Self {
53        Self {
54            add: Vec::new(),
55            action: ChangeAction::Remove,
56        }
57    }
58
59    /// A change replacing the current layer with new layers.
60    pub fn replace(add: Vec<Box<dyn Layer<S, E>>>) -> Self {
61        Self {
62            add,
63            action: ChangeAction::Remove,
64        }
65    }
66
67    /// A change removing all layers.
68    pub fn close() -> Self {
69        Self {
70            add: Vec::new(),
71            action: ChangeAction::Clear,
72        }
73    }
74
75    /// A change replacing all layers with a new stack of layers.
76    pub fn clear(add: Vec<Box<dyn Layer<S, E>>>) -> Self {
77        Self {
78            add,
79            action: ChangeAction::Clear,
80        }
81    }
82}
83
84/// A trait, every layer has to implement, in order to be used by the layer manager;
85pub trait Layer<S, E> {
86    /// Executed for all layers from bottom to top. Most useful for rendering.
87    fn passive_update(&mut self, _state: &mut S, _event: &E) {}
88
89    /// Executed for top layer and optionally for more layers. Most useful for click events.
90    fn update(&mut self, _state: &mut S, _event: &E) -> Change<S, E>;
91}
92
93/// The layer manager deals with the layers you create.
94pub struct LayerManager<S, E>(Vec<Box<dyn Layer<S, E>>>);
95
96impl<S, E> LayerManager<S, E> {
97    /// Create a new layer manager containing specified initial layers.
98    pub fn new(layers: Vec<Box<dyn Layer<S, E>>>) -> Self {
99        LayerManager::<S, E>(layers)
100    }
101
102    /// Checks if the layer manger is still active. When not active, the program should terminate or new layers should be added before calling `update` again.
103    pub fn is_active(&self) -> bool {
104        !self.0.is_empty()
105    }
106
107    /// Everytime the program recieves or generates an event, which should be handled by a layer, this method has to be called.
108    pub fn update(&mut self, state: &mut S, event: E) {
109        let count = self.0.len();
110        let mut i = count;
111        while i > 0 {
112            i -= 1;
113            let layer = &mut self.0[i];
114            let Change { add, action } = layer.update(state, &event);
115            let add_index = i + 1;
116            for (i, added) in add.into_iter().enumerate() {
117                self.0.insert(add_index + i, added);
118            }
119            use ChangeAction::*;
120            match action {
121                None => (),
122                Pass => continue,
123                Remove => {
124                    self.0.remove(i);
125                }
126                Clear => self.0.clear(),
127            }
128            break;
129        }
130
131        for layer in self.0.iter_mut() {
132            layer.passive_update(state, &event);
133        }
134    }
135}
136
137#[cfg(test)]
138mod tests {
139    use crate::*;
140
141    pub enum Event {
142        Idle,
143        Input,
144        Exit,
145    }
146
147    pub struct GlobalState;
148
149    pub struct MainLayer;
150
151    impl Layer<GlobalState, Event> for MainLayer {
152        fn update(
153            &mut self,
154            _state: &mut GlobalState,
155            event: &Event,
156        ) -> Change<GlobalState, Event> {
157            match event {
158                Event::Input => Change::add(vec![Box::new(TopLayer)]),
159                Event::Idle => Change::none(),
160                Event::Exit => Change::remove(),
161            }
162        }
163    }
164
165    pub struct TopLayer;
166
167    impl Layer<GlobalState, Event> for TopLayer {
168        fn update(
169            &mut self,
170            _state: &mut GlobalState,
171            event: &Event,
172        ) -> Change<GlobalState, Event> {
173            match event {
174                Event::Input => Change::pass(),
175                Event::Idle => Change::none(),
176                Event::Exit => Change::remove(),
177            }
178        }
179    }
180
181    #[test]
182    fn example() {
183        let mut manager = LayerManager::new(vec![Box::new(MainLayer), Box::new(TopLayer)]);
184        let mut state = GlobalState;
185
186        manager.update(&mut state, Event::Idle);
187        manager.update(&mut state, Event::Input);
188        manager.update(&mut state, Event::Idle);
189
190        while manager.is_active() {
191            manager.update(&mut state, Event::Exit);
192        }
193    }
194}