From 6da63b6bed47c9e040da2cbe7f6468c8ff6360cb Mon Sep 17 00:00:00 2001 From: Austen Adler Date: Sat, 17 Dec 2022 12:02:15 -0500 Subject: [PATCH] Use crossbeam for message passing --- src/command.rs | 19 +++++++++++++++++++ src/event.rs | 22 ++++++++++++++++++++++ src/main.rs | 31 +++++++++++++++++++++++++------ src/worker.rs | 3 +++ 4 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 src/event.rs create mode 100644 src/worker.rs diff --git a/src/command.rs b/src/command.rs index e0af510..ae60560 100644 --- a/src/command.rs +++ b/src/command.rs @@ -1,6 +1,9 @@ +use crate::event::EventMessage; use anyhow::bail; use anyhow::Context; use anyhow::Result; +use crossbeam::channel::Receiver; +use crossbeam::channel::Sender; use std::{ io::Write, process::{Command, Stdio}, @@ -8,6 +11,10 @@ use std::{ use crate::App; +pub struct CommandRequest { + cmdline: String, +} + pub struct CommandResult { pub status_success: bool, pub stdout: Vec, @@ -24,6 +31,18 @@ impl Default for CommandResult { } } +// pub fn command_event_loop(command_request_receiver: Receiver,event_sender: Sender) -> Result<()> { +// loop { +// match command_request_receiver.recv() { +// Ok(command_request) => event_sender.send(EventMessage::CrosstermEvent(e))?, +// Err(e) => { +// event_sender.send(EventMessage::CrosstermError(e))?; +// bail!("Crossterm read error"); +// } +// } +// } +// } + pub fn run(app: &mut App) { match run_inner(app) { Ok(c) => { diff --git a/src/event.rs b/src/event.rs new file mode 100644 index 0000000..51a50ae --- /dev/null +++ b/src/event.rs @@ -0,0 +1,22 @@ +use crate::command::CommandRequest; +use anyhow::bail; +use anyhow::Result; +use crossbeam::channel::Sender; + +pub enum EventMessage { + CommandCompleted, + CrosstermEvent(crossterm::event::Event), + CrosstermError(std::io::Error), +} + +pub fn crossterm_event_loop(event_sender: Sender) -> Result<()> { + loop { + match crossterm::event::read() { + Ok(e) => event_sender.send(EventMessage::CrosstermEvent(e))?, + Err(e) => { + event_sender.send(EventMessage::CrosstermError(e))?; + bail!("Crossterm read error"); + } + } + } +} diff --git a/src/main.rs b/src/main.rs index 43f9aa5..21b401e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ #![allow(clippy::module_name_repetitions, clippy::cast_possible_truncation)] mod command; +mod event; mod ui; use ansi4tui::bytes_to_text; use anyhow::anyhow; @@ -11,6 +12,7 @@ use anyhow::Result; use command::CommandResult; use crossterm::event::DisableBracketedPaste; use crossterm::event::EnableBracketedPaste; +use event::EventMessage; use std::str::FromStr; use std::{ io::{self, Write}, @@ -28,7 +30,7 @@ use tui::{ }; use crossterm::{ - event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode}, + event::{DisableMouseCapture, EnableMouseCapture, Event, KeyCode}, execute, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, }; @@ -230,7 +232,7 @@ fn main() -> Result<()> { fn run_app( terminal: &mut Terminal, mut app: App, -) -> io::Result)>> { +) -> Result)>> { if !app.cmdline.is_empty() { command::run(&mut app); } @@ -239,11 +241,22 @@ fn run_app( app.cmdline_position = app.cmdline.len() as u16; } + let (tx, rx) = crossbeam::channel::bounded(100); + + // Start the event thread + let crossterm_tx = tx.clone(); + std::thread::spawn(move || { + let _result = event::crossterm_event_loop(crossterm_tx); + }); + + std::mem::drop(tx); + loop { terminal.draw(|f| ui::draw(f, &app))?; - match event::read()? { - Event::Key(key) => match key.code { + match rx.recv()? { + // match event::read()? { + EventMessage::CrosstermEvent(Event::Key(key)) => match key.code { KeyCode::Esc => { // TODO: If there is any command line text, ask if the user is sure they want to quit return Ok(None); @@ -297,7 +310,7 @@ fn run_app( } _ => {} }, - Event::Paste(data) => { + EventMessage::CrosstermEvent(Event::Paste(data)) => { app.cmdline.insert_str(app.cmdline_position as usize, &data); app.cmdline_position = app.cmdline_position.saturating_add(data.len() as u16); @@ -306,7 +319,13 @@ fn run_app( } } - Event::FocusGained | Event::FocusLost | Event::Mouse(_) | Event::Resize(_, _) => {} + EventMessage::CrosstermEvent(Event::FocusGained) + | EventMessage::CrosstermEvent(Event::FocusLost) + | EventMessage::CrosstermEvent(Event::Mouse(_)) + | EventMessage::CrosstermEvent(Event::Resize(_, _)) => {} + + // TODO + _ => {} } } } diff --git a/src/worker.rs b/src/worker.rs new file mode 100644 index 0000000..e8d475d --- /dev/null +++ b/src/worker.rs @@ -0,0 +1,3 @@ +struct CommandRunner { + event_sender: Sender<> +}