mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-08 18:30:40 +00:00
Do not consume input before exit
This commit is contained in:
parent
70cddae454
commit
3f5b37951b
@ -15,8 +15,6 @@ use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::{Write};
|
||||
use std::thread;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use libc;
|
||||
use chan;
|
||||
@ -267,15 +265,19 @@ impl backend::Backend for Backend {
|
||||
ncurses::has_colors()
|
||||
}
|
||||
|
||||
fn start_input_thread(&mut self, event_sink: chan::Sender<Event>, running: Arc<AtomicBool>) {
|
||||
fn start_input_thread(&mut self, event_sink: chan::Sender<Event>, stops: chan::Receiver<bool>) {
|
||||
let mut parser = InputParser::new(event_sink);
|
||||
|
||||
// Start an input thread
|
||||
thread::spawn(move || {
|
||||
// TODO: use an atomic boolean to stop the thread on finish
|
||||
while running.load(Ordering::Relaxed) {
|
||||
loop {
|
||||
// This sends events to the event sender.
|
||||
parser.parse_next();
|
||||
|
||||
if stops.recv() != Some(false) {
|
||||
// If the channel was closed or if `true` was sent, abort.
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ use vec::Vec2;
|
||||
use std::sync::Arc;
|
||||
use chan;
|
||||
use std::thread;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
pub struct Backend {
|
||||
// Used
|
||||
@ -420,12 +419,17 @@ impl backend::Backend for Backend {
|
||||
self.window.mvaddstr(pos.y as i32, pos.x as i32, text);
|
||||
}
|
||||
|
||||
fn start_input_thread(&mut self, event_sink: chan::Sender<Event>, running: Arc<AtomicBool>) {
|
||||
fn start_input_thread(&mut self, event_sink: chan::Sender<Event>, stops: chan::Receiver<bool>) {
|
||||
let mut input_parser = InputParser::new(event_sink, Arc::clone(&self.window));
|
||||
|
||||
thread::spawn(move || {
|
||||
while running.load(Ordering::Relaxed) {
|
||||
loop {
|
||||
input_parser.parse_next();
|
||||
|
||||
if stops.recv() != Some(false) {
|
||||
// If the channel was closed or if `true` was sent, abort.
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -10,13 +10,11 @@
|
||||
use event;
|
||||
use theme;
|
||||
|
||||
use chan::Sender;
|
||||
use chan::{Receiver, Sender};
|
||||
|
||||
use vec::Vec2;
|
||||
|
||||
use std::time::Duration;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
|
||||
pub mod dummy;
|
||||
|
||||
@ -34,7 +32,7 @@ pub trait Backend {
|
||||
fn finish(&mut self);
|
||||
|
||||
/// Starts a thread to collect input and send it to the given channel.
|
||||
fn start_input_thread(&mut self, event_sink: Sender<event::Event>, running: Arc<AtomicBool>) {
|
||||
fn start_input_thread(&mut self, event_sink: Sender<event::Event>, running: Receiver<bool>) {
|
||||
// Dummy implementation for some backends.
|
||||
let _ = event_sink;
|
||||
let _ = running;
|
||||
|
@ -24,8 +24,6 @@ use std::io::{Stdout, Write};
|
||||
use std::thread;
|
||||
use theme;
|
||||
use vec::Vec2;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
pub struct Backend {
|
||||
terminal: AlternateScreen<MouseTerminal<RawTerminal<Stdout>>>,
|
||||
@ -267,11 +265,17 @@ impl backend::Backend for Backend {
|
||||
);
|
||||
}
|
||||
|
||||
fn start_input_thread(&mut self, event_sink: chan::Sender<Event>, running: Arc<AtomicBool>) {
|
||||
fn start_input_thread(&mut self, event_sink: chan::Sender<Event>, stops: chan::Receiver<bool>) {
|
||||
let mut parser = InputParser::new(event_sink);
|
||||
thread::spawn(move || {
|
||||
while running.load(Ordering::Relaxed) {
|
||||
loop {
|
||||
// This sends events to the event sender.
|
||||
parser.parse_next();
|
||||
|
||||
if stops.recv() != Some(false) {
|
||||
// If the channel was closed or if `true` was sent, abort.
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -7,8 +7,6 @@ use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
use std::time::Duration;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use theme;
|
||||
use vec::Vec2;
|
||||
use view::{self, Finder, IntoBoxedView, Position, View};
|
||||
@ -45,7 +43,8 @@ pub struct Cursive {
|
||||
event_source: chan::Receiver<Event>,
|
||||
event_sink: chan::Sender<Event>,
|
||||
|
||||
input_running: Arc<AtomicBool>,
|
||||
// Sends true or false after each event.
|
||||
stop_sink: chan::Sender<bool>,
|
||||
}
|
||||
|
||||
/// Describes one of the possible interruptions we should handle.
|
||||
@ -128,9 +127,9 @@ impl Cursive {
|
||||
let (cb_sink, cb_source) = chan::async();
|
||||
let (event_sink, event_source) = chan::async();
|
||||
|
||||
let input_running = Arc::new(AtomicBool::new(true));
|
||||
let (stop_sink, stop_source) = chan::async();
|
||||
|
||||
backend.start_input_thread(event_sink.clone(), input_running.clone());
|
||||
backend.start_input_thread(event_sink.clone(), stop_source);
|
||||
|
||||
Cursive {
|
||||
fps: 0,
|
||||
@ -145,8 +144,8 @@ impl Cursive {
|
||||
cb_sink,
|
||||
event_source,
|
||||
event_sink,
|
||||
input_running,
|
||||
backend: backend,
|
||||
backend,
|
||||
stop_sink,
|
||||
}
|
||||
}
|
||||
|
||||
@ -758,6 +757,10 @@ impl Cursive {
|
||||
EventResult::Consumed(Some(cb)) => cb(self),
|
||||
}
|
||||
}
|
||||
|
||||
// Ok, we processed the event.
|
||||
// Now tell the backend whether he sould keep receiving.
|
||||
self.stop_sink.send(!self.running);
|
||||
},
|
||||
Interruption::Callback(cb) => {
|
||||
cb.call_box(self);
|
||||
@ -775,7 +778,6 @@ impl Cursive {
|
||||
|
||||
impl Drop for Cursive {
|
||||
fn drop(&mut self) {
|
||||
self.input_running.store(false, Ordering::Relaxed);
|
||||
self.backend.finish();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user