Layer system

This is a simple system for managing programs with multiple different parts. It's inspired by State in Amethyst, but aims to be simpler, more flexible and more general.

Example Usage

```rust enum Event { Fixed, // generated at fixed times Click(u16, u16), // generated by click Quit, // genreated by try to close window }

use self::Event::*;

struct State; // a global state

type LayerManager<'m> = layer_system::LayerManager<'m, State, Event>; // the layer manager

use layer_system::{Layer, Change}; // other imports from layer System

struct World; // layer for the game world

impl Layer for World { fn passive_update(&mut self, state: &mut State, event: &Event) { match event { Fixed => { /* render here */ } _ => (), } }

fn update(&mut self, state: &mut State, event: &Event) -> Change<State, Event> {
    match event {
        Fixed => { /* world physics update */ }
        _ => ()
    }
    Change::Stay
}

}

struct Interface;

enum ClickEvent { Action, Pause, Exit, Nothing, }

impl Interface { fn click(&self, x: u16, y: u16) -> ClickEvent { use self::ClickEvent::*; if y < 16 { if x < 64 { Action } else if x < 128 { Pause } else if x < 192 { Exit } else { Nothing } } else { Nothing } } }

impl Layer for Interface { fn passive_update(&mut self, state: &mut State, event: &Event) { match event { Fixed => { /* render here */ } _ => (), } }

fn update(&mut self, state: &mut State, event: &Event) -> Change<State, Event> {
    match event {
        Click(x, y) => match self.click(*x, *y) {
            // execute some action when clicking "Action"
            ClickEvent::Action => {
                /* execute action */
                Change::Stay
            },
            // pause when clicking "Pause"
            ClickEvent::Pause => Change::Add(Box::new(Pause)),
            // remove all layers when clicking "Exit"
            ClickEvent::Exit => Change::Close,
            // nothing was clicked, so in case the world supports a click event, just defer it
            ClickEvent::Nothing => Change::Defer,
        }
        // when trying to quit the game, pause it first
        Quit => Change::Add(Box::new(Pause)),
        // Defer all other events, so World will handle everything else
        _ => Change::Defer,
    }
}

}

struct Pause;

impl Layer for Pause { fn passive_update(&mut self, state: &mut State, event: &Event) { match event { Fixed => { /* render here */ } _ => (), } }

fn update(&mut self, state: &mut State, event: &Event) -> Change<State, Event> {
    match event {
        // do not defer `Fixed`, so world physics won't be updated anymore
        Fixed => Change::Stay,
        // end pause by clicking somewhere
        Click(_, _) => Change::Remove,
        // when trying to quit the game again, quit it
        Quit => Change::Close,
    }
}

}

fn main() { let mut manager = LayerManager::new(); manager.add(World); // add World manager.add(Interface); // add Interface above world

let mut state = State;

while manager.is_active() {
    manager.update(&mut state, Fixed);
    /* handle other events in events loop */
    /* wait for a fixed time */
}

} ```