Use crossbeam for message passing
This commit is contained in:
parent
00b7620157
commit
6da63b6bed
@ -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<u8>,
|
||||
@ -24,6 +31,18 @@ impl Default for CommandResult {
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn command_event_loop(command_request_receiver: Receiver<CommandRequest>,event_sender: Sender<EventMessage>) -> 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) => {
|
||||
|
22
src/event.rs
Normal file
22
src/event.rs
Normal file
@ -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<EventMessage>) -> 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
31
src/main.rs
31
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<B: Backend>(
|
||||
terminal: &mut Terminal<B>,
|
||||
mut app: App,
|
||||
) -> io::Result<Option<(String, Vec<u8>)>> {
|
||||
) -> Result<Option<(String, Vec<u8>)>> {
|
||||
if !app.cmdline.is_empty() {
|
||||
command::run(&mut app);
|
||||
}
|
||||
@ -239,11 +241,22 @@ fn run_app<B: Backend>(
|
||||
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<B: Backend>(
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
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<B: Backend>(
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
3
src/worker.rs
Normal file
3
src/worker.rs
Normal file
@ -0,0 +1,3 @@
|
||||
struct CommandRunner {
|
||||
event_sender: Sender<>
|
||||
}
|
Loading…
Reference in New Issue
Block a user