Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Hacksaar
rinx
Commits
55e21f18
Commit
55e21f18
authored
Mar 06, 2016
by
Ralf
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
change environment around to no longer use select
parent
2c222eda
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
76 additions
and
58 deletions
+76
-58
src/brain/environment.rs
src/brain/environment.rs
+75
-45
src/brain/states.rs
src/brain/states.rs
+1
-1
src/util/mod.rs
src/util/mod.rs
+0
-12
No files found.
src/brain/environment.rs
View file @
55e21f18
use
std
::
time
::
Duration
;
use
chan
::
Receiver
;
use
std
::
thread
;
use
std
::
sync
::
mpsc
::{
channel
,
Sender
,
Receiver
};
use
util
::
timeout_chan
;
use
input
::
Event
;
#[must_use]
...
...
@@ -64,9 +64,24 @@ pub enum EventsResult {
Quit
,
}
enum
EventOrTimer
{
Ev
(
Event
),
Timeout
(
u32
),
}
pub
struct
SensorStates
{
door_locked
:
Option
<
bool
>
,
}
pub
struct
Environment
{
events
:
Receiver
<
Event
>
,
door_locked
:
bool
,
events
:
Receiver
<
EventOrTimer
>
,
sender
:
Sender
<
EventOrTimer
>
,
sensors
:
SensorStates
,
cur_id
:
u32
,
// current ID used for timeout events
}
pub
struct
EventSender
{
sender
:
Sender
<
EventOrTimer
>
,
}
macro_rules!
handle_events
{
...
...
@@ -82,64 +97,79 @@ macro_rules! handle_events_timeout {
}
impl
Environment
{
pub
fn
handle_events
(
&
mut
self
,
mut
handlers
:
Vec
<
EventHandler
>
)
->
EventsResult
{
for
ev
in
self
.events
.clone
()
{
match
self
.handle_event
(
&
mut
handlers
,
ev
)
{
Some
(
result
)
=>
return
result
,
_
=>
{}
}
}
return
EventsResult
::
ShuttingDown
;
pub
fn
new
()
->
(
Environment
,
EventSender
)
{
let
(
tx
,
rx
)
=
channel
();
(
Environment
{
events
:
rx
,
sender
:
tx
.clone
(),
sensors
:
SensorStates
::
new
(),
cur_id
:
0
},
EventSender
{
sender
:
tx
}
)
}
pub
fn
handle_events
(
&
mut
self
,
handlers
:
Vec
<
EventHandler
>
)
->
EventsResult
{
self
.cur_id
=
u32
::
wrapping_add
(
self
.cur_id
,
1
);
// make sure we ignore old timeouts
self
.handle_events_cur_id
(
handlers
)
}
pub
fn
handle_events_timeout
(
&
mut
self
,
d
:
Duration
,
mut
handlers
:
Vec
<
EventHandler
>
)
->
EventsResult
{
let
timeout_chan
=
timeout_chan
(
d
);
let
events
=
self
.events
.clone
();
loop
{
chan_select!
{
timeout_chan
.recv
()
=>
return
EventsResult
::
Timeout
,
events
.recv
()
->
ev
=>
{
match
ev
{
None
=>
return
EventsResult
::
ShuttingDown
,
Some
(
ev
)
=>
{
match
self
.handle_event
(
&
mut
handlers
,
ev
)
{
Some
(
result
)
=>
return
result
,
_
=>
{},
}
handlers
:
Vec
<
EventHandler
>
)
->
EventsResult
{
let
sender
=
self
.sender
.clone
();
// make sure we ignore old timeouts
let
id
=
{
self
.cur_id
=
u32
::
wrapping_add
(
self
.cur_id
,
1
);
self
.cur_id
};
// spawn a thread that sends a timeout event with this id in [d] time
thread
::
spawn
(
move
||
{
thread
::
sleep
(
d
);
// if sending fails, we just ignore that -- it means the timeout is not necessary any more
let
_
=
sender
.send
(
EventOrTimer
::
Timeout
(
id
));
});
// now we are ready to listen for events
self
.handle_events_cur_id
(
handlers
)
}
fn
handle_events_cur_id
(
&
mut
self
,
mut
handlers
:
Vec
<
EventHandler
>
)
->
EventsResult
{
for
ev
in
self
.events
.iter
()
{
match
ev
{
EventOrTimer
::
Timeout
(
id
)
=>
{
if
id
==
self
.cur_id
{
return
EventsResult
::
Timeout
;
}
// old timeout event, ignore
},
EventOrTimer
::
Ev
(
ev
)
=>
{
// a regular event
self
.sensors
.record_state
(
&
ev
);
// forward to all handlers
for
handler
in
handlers
.iter_mut
()
{
match
handler
.run
(
ev
)
{
HandlerResult
::
Continue
=>
{}
HandlerResult
::
QuitLoop
=>
return
EventsResult
::
Quit
,
}
}
}
}
}
return
EventsResult
::
ShuttingDown
;
}
pub
fn
sensors
(
&
self
)
->
&
SensorStates
{
&
self
.sensors
}
}
impl
SensorStates
{
fn
new
()
->
SensorStates
{
SensorStates
{
door_locked
:
None
}
}
fn
handle_event
(
&
mut
self
,
handlers
:
&
mut
Vec
<
EventHandler
>
,
ev
:
Event
)
->
Option
<
EventsResult
>
{
self
.record_state
(
&
ev
);
for
handler
in
handlers
.iter_mut
()
{
match
handler
.run
(
ev
)
{
HandlerResult
::
Continue
=>
{}
HandlerResult
::
QuitLoop
=>
return
Some
(
EventsResult
::
Quit
),
}
}
return
None
;
pub
fn
door_locked
(
&
self
)
->
Option
<
bool
>
{
self
.door_locked
}
fn
record_state
(
&
mut
self
,
ev
:
&
Event
)
{
match
ev
{
&
Event
::
DoorLocked
(
b
)
=>
self
.door_locked
=
b
,
&
Event
::
DoorLocked
(
b
)
=>
self
.door_locked
=
Some
(
b
)
,
_
=>
{}
}
}
pub
fn
door_locked
(
&
self
)
->
bool
{
true
}
}
src/brain/states.rs
View file @
55e21f18
...
...
@@ -46,7 +46,7 @@ impl State for UnLockingState {
}));
actors
.lock
=
locker
.terminate
();
if
r
!=
EventsResult
::
Timeout
{
assert
!
(
r
==
EventsResult
::
ShuttingDown
||
env
.door_locked
()
==
locking
);
assert
!
(
r
==
EventsResult
::
ShuttingDown
||
env
.
sensors
()
.
door_locked
()
==
Some
(
locking
)
)
;
break
;
// the retries
}
}
...
...
src/util/mod.rs
View file @
55e21f18
use
std
::
time
::
Duration
;
use
std
::
thread
;
use
chan
;
pub
mod
wakeable
;
pub
fn
timeout_chan
(
d
:
Duration
)
->
chan
::
Receiver
<
()
>
{
let
(
s
,
r
)
=
chan
::
sync
(
0
);
thread
::
spawn
(
move
||
{
thread
::
sleep
(
d
);
drop
(
s
);
});
r
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment