Better ncurses synchronization

Prevent any concurrent access to ncurses in event-driven steps.
This commit is contained in:
Alexandre Bury 2018-06-23 18:41:14 -07:00
parent e3887847fd
commit fda4bae8d6

View File

@ -47,6 +47,7 @@ pub struct Cursive {
// Sends true or false after each event. // Sends true or false after each event.
stop_sink: chan::Sender<bool>, stop_sink: chan::Sender<bool>,
received_event: bool,
} }
/// Describes one of the possible interruptions we should handle. /// Describes one of the possible interruptions we should handle.
@ -152,6 +153,7 @@ impl Cursive {
event_sink, event_sink,
backend, backend,
stop_sink, stop_sink,
received_event: false,
} }
} }
@ -708,17 +710,36 @@ impl Cursive {
/// ///
/// [`run(&mut self)`]: #method.run /// [`run(&mut self)`]: #method.run
pub fn step(&mut self) { pub fn step(&mut self) {
let step_start = ::std::time::Instant::now();
// Do we need to redraw everytime? // Do we need to redraw everytime?
// Probably, actually. // Probably, actually.
// TODO: Do we need to re-layout everytime? // TODO: Do we need to re-layout everytime?
self.layout(); self.layout();
eprintln!(
"After layout: {:?}",
::std::time::Instant::now() - step_start
);
// TODO: Do we need to redraw every view every time? // TODO: Do we need to redraw every view every time?
// (Is this getting repetitive? :p) // (Is this getting repetitive? :p)
self.draw(); self.draw();
eprintln!(
"After draw: {:?}",
::std::time::Instant::now() - step_start
);
self.backend.refresh(); self.backend.refresh();
eprintln!(
"After refresh: {:?}",
::std::time::Instant::now() - step_start
);
// Wait for next event. // Wait for next event.
if self.received_event {
// Now tell the backend whether he sould keep receiving.
self.stop_sink.send(!self.running);
self.received_event = false;
}
match self.poll() { match self.poll() {
Interruption::Event(event) => { Interruption::Event(event) => {
// eprintln!("{:?}, {:?}", event, self.screen_size()); // eprintln!("{:?}, {:?}", event, self.screen_size());
@ -765,14 +786,17 @@ impl Cursive {
} }
// Ok, we processed the event. // Ok, we processed the event.
// Now tell the backend whether he sould keep receiving. self.received_event = true;
self.stop_sink.send(!self.running);
} }
Interruption::Callback(cb) => { Interruption::Callback(cb) => {
cb.call_box(self); cb.call_box(self);
} }
Interruption::Timeout => {} Interruption::Timeout => {}
} }
eprintln!(
"After event: {:?}",
::std::time::Instant::now() - step_start
);
} }
/// Stops the event loop. /// Stops the event loop.