Commit 60d4e504 authored by Ralf's avatar Ralf
Browse files

make UnLocking conform with the general structure of a state

parent 0518a4ac
...@@ -10,11 +10,12 @@ use brain::{Actors, Situation}; ...@@ -10,11 +10,12 @@ use brain::{Actors, Situation};
#[derive(Debug)] #[derive(Debug)]
pub struct UnLocking { pub struct UnLocking {
locking: bool, locking: bool,
remaining_retries: u32,
} }
impl UnLocking { impl UnLocking {
pub fn new(locking: bool) -> UnLocking { pub fn new(locking: bool, remaining_retries: u32) -> UnLocking {
UnLocking { locking: locking } UnLocking { locking: locking, remaining_retries: remaining_retries }
} }
} }
...@@ -25,36 +26,44 @@ impl Situation for UnLocking { ...@@ -25,36 +26,44 @@ impl Situation for UnLocking {
-> (Actors, Option<Box<Situation>>) { -> (Actors, Option<Box<Situation>>) {
// TODO: abort if already locked // TODO: abort if already locked
let locking = self.locking; let locking = self.locking;
for _ in 0..3 { let locker = Wakeable::spawn(actors.lock, (), move |t, mut lock_actor, _| {
let locker = Wakeable::spawn(actors.lock, (), move |t, mut lock_actor, _| { lock_actor.act(if locking {
lock_actor.act(if locking { LockAction::PressLock
LockAction::PressLock } else {
} else { LockAction::PressUnlock
LockAction::PressUnlock
});
t.sleep(Duration::from_millis(100));
lock_actor.act(LockAction::Release);
lock_actor
}); });
let r = handle_events_timeout!(env, t.sleep(Duration::from_millis(100));
Duration::from_secs(1), lock_actor.act(LockAction::Release);
EventHandler::new_safe(handlers::user_command_reject_handler), lock_actor
EventHandler::new(|ev| { });
match ev { // for max. 1 second, handle whatever events we see
Event::DoorLocked(b) if b == locking => { let r = handle_events_timeout!(env,
HandlerResult::QuitLoop Duration::from_secs(1),
} EventHandler::new_safe(handlers::user_command_reject_handler),
_ => HandlerResult::Continue, EventHandler::new(|ev| {
match ev {
Event::DoorLocked(b) if b == locking => {
HandlerResult::QuitLoop
} }
})); _ => HandlerResult::Continue,
actors.lock = locker.terminate(); }
if r != EventsResult::Timeout { }));
assert!(r == EventsResult::ShuttingDown || // Either we timed out, or we succeeded in (un)locking
env.sensors().door_locked() == Some(locking)); actors.lock = locker.terminate();
break; // the retries (actors,
match r {
EventsResult::ShuttingDown => None,
EventsResult::Timeout =>
{
if self.remaining_retries > 0 {
Some(Box::new(UnLocking::new(self.locking, self.remaining_retries - 1)))
} else {
None /* FIXME: What do do when all attempts failed? */
}
} }
} EventsResult::Quit =>
(actors, None) // FIXME None /* FIXME: Which state to go in next? */
})
} }
} }
......
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