aboutsummaryrefslogtreecommitdiff
path: root/src/util/event.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/event.rs')
-rw-r--r--src/util/event.rs75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/util/event.rs b/src/util/event.rs
new file mode 100644
index 0000000..33ee9ec
--- /dev/null
+++ b/src/util/event.rs
@@ -0,0 +1,75 @@
+use std::io;
+use std::sync::mpsc;
+use std::thread;
+use std::time::Duration;
+
+use termion::event::Key;
+use termion::input::TermRead;
+
+pub enum Event<I> {
+ Input(I),
+ Tick,
+}
+
+/// A small event handler that wrap termion input and tick events. Each event
+/// type is handled in its own thread and returned to a common `Receiver`
+pub struct Events {
+ rx: mpsc::Receiver<Event<Key>>,
+ input_handle: thread::JoinHandle<()>,
+ tick_handle: thread::JoinHandle<()>,
+}
+
+#[derive(Debug, Clone, Copy)]
+pub struct Config {
+ pub tick_rate: Duration,
+}
+
+impl Default for Config {
+ fn default() -> Config {
+ Config {
+ tick_rate: Duration::from_millis(250),
+ }
+ }
+}
+
+impl Events {
+ pub fn new() -> Events {
+ Events::with_config(Config::default())
+ }
+
+ pub fn with_config(config: Config) -> Events {
+ let (tx, rx) = mpsc::channel();
+ let input_handle = {
+ let tx = tx.clone();
+ thread::spawn(move || {
+ let stdin = io::stdin();
+ for evt in stdin.keys() {
+ if let Ok(key) = evt {
+ if let Err(err) = tx.send(Event::Input(key)) {
+ eprintln!("{}", err);
+ return;
+ }
+ }
+ }
+ })
+ };
+ let tick_handle = {
+ thread::spawn(move || loop {
+ if let Err(err) = tx.send(Event::Tick) {
+ eprintln!("{}", err);
+ break;
+ }
+ thread::sleep(config.tick_rate);
+ })
+ };
+ Events {
+ rx,
+ input_handle,
+ tick_handle,
+ }
+ }
+
+ pub fn next(&self) -> Result<Event<Key>, mpsc::RecvError> {
+ self.rx.recv()
+ }
+}