#![deny(missing_docs)]
pub enum ChangeAction {
None,
Pass,
Remove,
Clear,
}
pub struct Change<S, E> {
add: Vec<Box<dyn Layer<S, E>>>,
action: ChangeAction,
}
impl<S, E> Change<S, E> {
pub fn none() -> Self {
Self {
add: Vec::new(),
action: ChangeAction::None,
}
}
pub fn pass() -> Self {
Self {
add: Vec::new(),
action: ChangeAction::Pass,
}
}
pub fn add(add: Vec<Box<dyn Layer<S, E>>>) -> Self {
Self {
add,
action: ChangeAction::None,
}
}
pub fn remove() -> Self {
Self {
add: Vec::new(),
action: ChangeAction::Remove,
}
}
pub fn replace(add: Vec<Box<dyn Layer<S, E>>>) -> Self {
Self {
add,
action: ChangeAction::Remove,
}
}
pub fn close() -> Self {
Self {
add: Vec::new(),
action: ChangeAction::Clear,
}
}
pub fn clear(add: Vec<Box<dyn Layer<S, E>>>) -> Self {
Self {
add,
action: ChangeAction::Clear,
}
}
}
pub trait Layer<S, E> {
fn passive_update(&mut self, _state: &mut S, _event: &E) {}
fn update(&mut self, _state: &mut S, _event: &E) -> Change<S, E>;
}
pub struct LayerManager<S, E>(Vec<Box<dyn Layer<S, E>>>);
impl<S, E> LayerManager<S, E> {
pub fn new(layers: Vec<Box<dyn Layer<S, E>>>) -> Self {
LayerManager::<S, E>(layers)
}
pub fn is_active(&self) -> bool {
!self.0.is_empty()
}
pub fn update(&mut self, state: &mut S, event: E) {
let count = self.0.len();
let mut i = count;
while i > 0 {
i -= 1;
let layer = &mut self.0[i];
let Change { add, action } = layer.update(state, &event);
let add_index = i + 1;
for (i, added) in add.into_iter().enumerate() {
self.0.insert(add_index + i, added);
}
use ChangeAction::*;
match action {
None => (),
Pass => continue,
Remove => {
self.0.remove(i);
}
Clear => self.0.clear(),
}
break;
}
for layer in self.0.iter_mut() {
layer.passive_update(state, &event);
}
}
}
#[cfg(test)]
mod tests {
use crate::*;
pub enum Event {
Idle,
Input,
Exit,
}
pub struct GlobalState;
pub struct MainLayer;
impl Layer<GlobalState, Event> for MainLayer {
fn update(
&mut self,
_state: &mut GlobalState,
event: &Event,
) -> Change<GlobalState, Event> {
match event {
Event::Input => Change::add(vec![Box::new(TopLayer)]),
Event::Idle => Change::none(),
Event::Exit => Change::remove(),
}
}
}
pub struct TopLayer;
impl Layer<GlobalState, Event> for TopLayer {
fn update(
&mut self,
_state: &mut GlobalState,
event: &Event,
) -> Change<GlobalState, Event> {
match event {
Event::Input => Change::pass(),
Event::Idle => Change::none(),
Event::Exit => Change::remove(),
}
}
}
#[test]
fn example() {
let mut manager = LayerManager::new(vec![Box::new(MainLayer), Box::new(TopLayer)]);
let mut state = GlobalState;
manager.update(&mut state, Event::Idle);
manager.update(&mut state, Event::Input);
manager.update(&mut state, Event::Idle);
while manager.is_active() {
manager.update(&mut state, Event::Exit);
}
}
}