Commit e8c9ffaf authored by Ralf's avatar Ralf
Browse files

more compiling stuff

parent 45fdcba8
...@@ -19,18 +19,19 @@ struct Actors { ...@@ -19,18 +19,19 @@ struct Actors {
} }
struct State { struct State {
run: Box<FnOnce(Actors, Receiver<Event>) -> (Actors, Receiver<Event>, Option<State>) + 'static>, run: Box<FnOnce(Actors, &mut Environment) -> (Actors, Option<State>) + 'static>,
} }
#[must_use] #[must_use]
#[derive(Copy,Clone,Debug,PartialEq,Eq)]
enum EventHandlerResult { enum EventHandlerResult {
Continue, Continue,
CancelEvent,
QuitLoop, QuitLoop,
} }
#[must_use] #[must_use]
#[derive(Copy,Clone,Debug,PartialEq,Eq)]
enum EventsHandledResult { enum EventsHandledResult {
ShuttingDown, ShuttingDown,
Timeout, Timeout,
...@@ -41,24 +42,20 @@ struct Environment { ...@@ -41,24 +42,20 @@ struct Environment {
events: Receiver<Event>, events: Receiver<Event>,
} }
struct EventHandler<'a> {
run: Box<FnMut(Event) -> EventHandlerResult + 'a>
}
impl Environment { impl Environment {
fn handle_events(&mut self, d: Duration, mut handlers: Vec<EventHandler>) -> EventsHandledResult { pub fn handle_events(&mut self, d: Duration, mut handlers: Vec<EventHandler>) -> EventsHandledResult {
let timeout_chan = timeout_chan(d); let timeout_chan = timeout_chan(d);
loop { loop {
let events = &self.events; let events = self.events.clone();
chan_select! { chan_select! {
timeout_chan.recv() => return EventsHandledResult::Timeout, timeout_chan.recv() => return EventsHandledResult::Timeout,
events.recv() -> ev => { events.recv() -> ev => {
match ev { match ev {
Some(ev) => { Some(ev) => {
self.record_state(&ev);
for handler in handlers.iter_mut() { for handler in handlers.iter_mut() {
match (handler.run)(ev) { match (handler.run)(ev) {
EventHandlerResult::Continue => {}, EventHandlerResult::Continue => {},
EventHandlerResult::CancelEvent => break,
EventHandlerResult::QuitLoop => return EventsHandledResult::Quit, EventHandlerResult::QuitLoop => return EventsHandledResult::Quit,
} }
} }
...@@ -70,16 +67,54 @@ impl Environment { ...@@ -70,16 +67,54 @@ impl Environment {
} }
unreachable!() unreachable!()
} }
fn record_state(&mut self, ev: &Event) {
}
pub fn door_locked(&self) -> bool {
true
}
} }
struct EventHandler<'a> {
run: Box<FnMut(Event) -> EventHandlerResult + 'a>
}
impl<'a> EventHandler<'a> {
fn new<F>(f: F) -> Self
where F: FnMut(Event) -> EventHandlerResult + 'a
{
EventHandler { run: Box::new(f) }
}
fn new_boxed(f: Box<FnMut(Event) -> EventHandlerResult + 'a>) -> Self
{
EventHandler { run: f }
}
fn new_safe<F>(mut f: F) -> Self
where F: FnMut(Event) + 'a
{
EventHandler { run: Box::new(move |ev| { f(ev); EventHandlerResult::Continue }) }
}
fn new_safe_boxed(mut f: Box<FnMut(Event) + 'a>) -> Self
{
EventHandler { run: Box::new(move |ev| { f(ev); EventHandlerResult::Continue }) }
}
}
fn user_command_reject_handler(ev: Event) {
}
impl State { impl State {
fn new<F>(f: F) -> State fn new<F>(f: F) -> State
where F: FnOnce(Actors, Receiver<Event>) -> (Actors, Receiver<Event>, Option<State>) + 'static { where F: FnOnce(Actors, &mut Environment) -> (Actors, Option<State>) + 'static {
State { run: Box::new(f) } State { run: Box::new(f) }
} }
fn new_locking() -> Self { fn new_locking() -> Self {
Self::new(|mut actors, events| { Self::new(|mut actors, env| {
// TODO: abort if already locked // TODO: abort if already locked
let mut lock_actor = actors.lock_actor; // move out let mut lock_actor = actors.lock_actor; // move out
for i in 0..3 { for i in 0..3 {
...@@ -89,25 +124,24 @@ impl State { ...@@ -89,25 +124,24 @@ impl State {
lock_actor.act(LockAction::Release); lock_actor.act(LockAction::Release);
lock_actor lock_actor
}); });
let timeout_chan = timeout_chan(Duration::from_secs(1)); let r = env.handle_events(Duration::from_secs(1), vec![
let mut success = false; EventHandler::new_safe(user_command_reject_handler),
loop { EventHandler::new(|ev| {
chan_select! { match ev {
timeout_chan.recv() => break, Event::DoorLocked(true) => EventHandlerResult::QuitLoop,
events.recv() -> ev => match ev { _ => EventHandlerResult::Continue,
Some(Event::DoorLocked(true)) => { success = true; break; },
_ => {} // TODO handle other stuff modularly
} }
} }),
} ]);
// take back lock_actor to feel complete again // take back lock_actor to feel complete again
lock_actor = locker.terminate(); lock_actor = locker.terminate();
if success { if r != EventsHandledResult::Timeout {
assert!(r == EventsHandledResult::ShuttingDown || env.door_locked());
break; break;
} }
} }
actors.lock_actor = lock_actor; // move back actors.lock_actor = lock_actor; // move back
(actors, events, None) (actors, None)
}) })
} }
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment