Backend: add AtomicBool to stop input thread

This commit is contained in:
Alexandre Bury 2018-05-20 10:55:13 -07:00
parent 0b6e5b6ad4
commit c8d39910ab
7 changed files with 27 additions and 14 deletions

View File

@ -305,9 +305,6 @@ impl backend::Backend for Backend {
terminal::print_xy(pos.x as i32, pos.y as i32, text);
}
fn start_input_thread(&mut self, _event_sink: chan::Sender<Event>) {
}
fn prepare_input(&mut self, event_sink: &chan::Sender<Event>, timeout: Duration) {
// Wait for up to `timeout_ms`.
let start = Instant::now();

View File

@ -15,6 +15,8 @@ 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;
@ -262,13 +264,13 @@ impl backend::Backend for Backend {
ncurses::has_colors()
}
fn start_input_thread(&mut self, event_sink: chan::Sender<Event>) {
fn start_input_thread(&mut self, event_sink: chan::Sender<Event>, running: Arc<AtomicBool>) {
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
loop {
while running.load(Ordering::Relaxed) {
parser.parse_next();
}
});

View File

@ -12,6 +12,7 @@ use vec::Vec2;
use std::sync::Arc;
use chan;
use std::thread;
use std::sync::atomic::{AtomicBool, Ordering};
pub struct Backend {
// Used
@ -419,11 +420,11 @@ 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>) {
fn start_input_thread(&mut self, event_sink: chan::Sender<Event>, running: Arc<AtomicBool>) {
let mut input_parser = InputParser::new(event_sink, Arc::clone(&self.window));
thread::spawn(move || {
loop {
while running.load(Ordering::Relaxed) {
input_parser.parse_next();
}
});

View File

@ -32,9 +32,6 @@ impl backend::Backend for Backend {
(1, 1).into()
}
fn start_input_thread(&mut self, _event_sink: chan::Sender<event::Event>) {
}
fn prepare_input(&mut self, event_sink: &chan::Sender<event::Event>, _timeout: Duration) {
event_sink.send(event::Event::Exit)
}

View File

@ -15,6 +15,8 @@ use chan::Sender;
use vec::Vec2;
use std::time::Duration;
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
pub mod dummy;
@ -32,7 +34,11 @@ 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>);
fn start_input_thread(&mut self, event_sink: Sender<event::Event>, running: Arc<AtomicBool>) {
// Dummy implementation for some backends.
let _ = event_sink;
let _ = running;
}
/// Prepares the backend to collect input.
///

View File

@ -24,6 +24,8 @@ 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>>>,
@ -265,10 +267,10 @@ impl backend::Backend for Backend {
);
}
fn start_input_thread(&mut self, event_sink: chan::Sender<Event>) {
fn start_input_thread(&mut self, event_sink: chan::Sender<Event>, running: Arc<AtomicBool>) {
let mut parser = InputParser::new(event_sink);
thread::spawn(move || {
loop {
while running.load(Ordering::Relaxed) {
parser.parse_next();
}
});

View File

@ -7,6 +7,8 @@ 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};
@ -42,6 +44,8 @@ pub struct Cursive {
event_source: chan::Receiver<Event>,
event_sink: chan::Sender<Event>,
input_running: Arc<AtomicBool>,
}
/// Describes one of the possible interruptions we should handle.
@ -124,7 +128,9 @@ impl Cursive {
let (cb_sink, cb_source) = chan::async();
let (event_sink, event_source) = chan::async();
backend.start_input_thread(event_sink.clone());
let input_running = Arc::new(AtomicBool::new(true));
backend.start_input_thread(event_sink.clone(), input_running.clone());
Cursive {
fps: 0,
@ -139,6 +145,7 @@ impl Cursive {
cb_sink,
event_source,
event_sink,
input_running,
backend: backend,
}
}
@ -768,6 +775,7 @@ impl Cursive {
impl Drop for Cursive {
fn drop(&mut self) {
self.input_running.store(false, Ordering::Relaxed);
self.backend.finish();
}
}