mod.rs 2.02 KB
Newer Older
Constantin Berhard's avatar
Constantin Berhard committed
1 2
struct SphinxHead;

Ralf's avatar
Ralf committed
3 4 5 6 7 8 9
mod environment;
mod event_handler;

use std::time::Duration;

use self::environment::*;
use self::event_handler::*;
Ralf's avatar
Ralf committed
10 11
use actors::Actor;
use input::Event;
Ralf's avatar
Ralf committed
12
use util::{Wakeable, Thread};
Constantin Berhard's avatar
Constantin Berhard committed
13

Constantin Berhard's avatar
Constantin Berhard committed
14 15 16 17 18 19

enum LockAction {
    PressLock,
    PressUnlock,
    Release,
}
Constantin Berhard's avatar
Constantin Berhard committed
20 21

struct Actors {
Constantin Berhard's avatar
Constantin Berhard committed
22 23
    green_led: Box<Actor<bool> + Send>,
    lock_actor: Box<Actor<LockAction> + Send>,
Constantin Berhard's avatar
Constantin Berhard committed
24 25
}

Ralf's avatar
Ralf committed
26
struct State {
Ralf's avatar
Ralf committed
27
    run: Box<FnOnce(Actors, &mut Environment) -> (Actors, Option<State>) + 'static>,
Constantin Berhard's avatar
Constantin Berhard committed
28 29
}

Constantin Berhard's avatar
rustfmt  
Constantin Berhard committed
30
fn user_command_reject_handler(ev: Event) {}
Ralf's avatar
Ralf committed
31

Constantin Berhard's avatar
Constantin Berhard committed
32 33
impl State {
    fn new<F>(f: F) -> State
Constantin Berhard's avatar
rustfmt  
Constantin Berhard committed
34 35
        where F: FnOnce(Actors, &mut Environment) -> (Actors, Option<State>) + 'static
    {
Constantin Berhard's avatar
Constantin Berhard committed
36 37
        State { run: Box::new(f) }
    }
Constantin Berhard's avatar
rustfmt  
Constantin Berhard committed
38

Constantin Berhard's avatar
Constantin Berhard committed
39
    fn new_locking() -> Self {
Ralf's avatar
Ralf committed
40
        Self::new(|mut actors, env| {
Constantin Berhard's avatar
Constantin Berhard committed
41 42 43
            // TODO: abort if already locked
            let mut lock_actor = actors.lock_actor; // move out
            for i in 0..3 {
Constantin Berhard's avatar
Constantin Berhard committed
44
                let locker = Wakeable::new(move |t| {
Constantin Berhard's avatar
Constantin Berhard committed
45 46 47 48 49
                    lock_actor.act(LockAction::PressLock);
                    t.sleep(Duration::from_millis(100));
                    lock_actor.act(LockAction::Release);
                    lock_actor
                });
Constantin Berhard's avatar
rustfmt  
Constantin Berhard committed
50 51
                let r = env.handle_events(Duration::from_secs(1),
                                          vec![
Ralf's avatar
Ralf committed
52 53 54
                    EventHandler::new_safe(user_command_reject_handler),
                    EventHandler::new(|ev| {
                        match ev {
Ralf's avatar
Ralf committed
55 56
                            Event::DoorLocked(true) => HandlerResult::QuitLoop,
                            _ => HandlerResult::Continue,
Constantin Berhard's avatar
Constantin Berhard committed
57
                        }
Ralf's avatar
Ralf committed
58 59
                    }),
                ]);
Constantin Berhard's avatar
Constantin Berhard committed
60 61
                // take back lock_actor to feel complete again
                lock_actor = locker.terminate();
Ralf's avatar
Ralf committed
62 63
                if r != EventsResult::Timeout {
                    assert!(r == EventsResult::ShuttingDown || env.door_locked());
Constantin Berhard's avatar
Constantin Berhard committed
64 65 66 67
                    break;
                }
            }
            actors.lock_actor = lock_actor; // move back
Ralf's avatar
Ralf committed
68
            (actors, None)
Constantin Berhard's avatar
Constantin Berhard committed
69 70
        })
    }
Constantin Berhard's avatar
Constantin Berhard committed
71
}