mirror of
https://github.com/sayanarijit/xplr
synced 2024-11-04 18:00:14 +00:00
Optimize the main thread
This commit is contained in:
parent
b9e9601a71
commit
097c9dd8c5
@ -1331,7 +1331,6 @@ impl App {
|
||||
pub fn refresh_selection(mut self) -> Result<Self> {
|
||||
self.selection = self
|
||||
.selection
|
||||
.clone()
|
||||
.into_iter()
|
||||
.filter(|n| PathBuf::from(&n.absolute_path).exists())
|
||||
.collect();
|
||||
|
261
src/main.rs
261
src/main.rs
@ -4,6 +4,7 @@ use anyhow::Result;
|
||||
use crossterm::execute;
|
||||
use crossterm::terminal as term;
|
||||
use handlebars::Handlebars;
|
||||
use std::collections::BinaryHeap;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::io::prelude::*;
|
||||
@ -97,160 +98,168 @@ fn main() -> Result<()> {
|
||||
event_reader::keep_reading(tx_msg_in.clone(), rx_event_reader);
|
||||
pwd_watcher::keep_watching(app.pwd(), tx_msg_in.clone(), rx_pwd_watcher)?;
|
||||
|
||||
'outer: for task in rx_msg_in {
|
||||
let last_app = app.clone();
|
||||
let mut tasks: BinaryHeap<app::Task> = Default::default();
|
||||
|
||||
let (new_app, new_result) = match app.handle_task(task) {
|
||||
Ok(a) => (a, Ok(())),
|
||||
Err(err) => (last_app.clone(), Err(err)),
|
||||
};
|
||||
|
||||
app = new_app;
|
||||
result = new_result;
|
||||
|
||||
if result.is_err() {
|
||||
break;
|
||||
'outer: while result.is_ok() {
|
||||
for task in rx_msg_in.try_iter() {
|
||||
tasks.push(task);
|
||||
}
|
||||
|
||||
while let Some(msg) = app.pop_msg_out() {
|
||||
match msg {
|
||||
app::MsgOut::PrintResultAndQuit => {
|
||||
output = Some(app.result_str());
|
||||
break 'outer;
|
||||
}
|
||||
if let Some(task) = tasks.pop() {
|
||||
let last_app = app.clone();
|
||||
|
||||
app::MsgOut::PrintAppStateAndQuit => {
|
||||
let out = serde_yaml::to_string(&app)?;
|
||||
output = Some(out);
|
||||
break 'outer;
|
||||
}
|
||||
let (new_app, new_result) = match app.handle_task(task) {
|
||||
Ok(a) => (a, Ok(())),
|
||||
Err(err) => (last_app.clone(), Err(err)),
|
||||
};
|
||||
|
||||
app::MsgOut::Debug(path) => {
|
||||
fs::write(&path, serde_yaml::to_string(&app)?)?;
|
||||
}
|
||||
app = new_app;
|
||||
result = new_result;
|
||||
|
||||
app::MsgOut::ClearScreen => {
|
||||
terminal.clear()?;
|
||||
}
|
||||
while let Some(msg) = app.pop_msg_out() {
|
||||
match msg {
|
||||
app::MsgOut::PrintResultAndQuit => {
|
||||
output = Some(app.result_str());
|
||||
break 'outer;
|
||||
}
|
||||
|
||||
app::MsgOut::Explore => {
|
||||
explorer::explore(
|
||||
app.explorer_config().clone(),
|
||||
app.pwd().clone(),
|
||||
app.focused_node().map(|n| n.relative_path.clone()),
|
||||
tx_msg_in.clone(),
|
||||
);
|
||||
}
|
||||
app::MsgOut::PrintAppStateAndQuit => {
|
||||
let out = serde_yaml::to_string(&app)?;
|
||||
output = Some(out);
|
||||
break 'outer;
|
||||
}
|
||||
|
||||
app::MsgOut::Refresh => {
|
||||
app = app.refresh_selection()?;
|
||||
if app.pwd() != last_app.pwd() {
|
||||
tx_pwd_watcher.send(app.pwd().clone())?;
|
||||
app::MsgOut::Debug(path) => {
|
||||
fs::write(&path, serde_yaml::to_string(&app)?)?;
|
||||
}
|
||||
|
||||
app::MsgOut::ClearScreen => {
|
||||
terminal.clear()?;
|
||||
}
|
||||
|
||||
app::MsgOut::Explore => {
|
||||
explorer::explore(
|
||||
app.explorer_config().clone(),
|
||||
app.pwd().clone(),
|
||||
app.focused_node().map(|n| n.relative_path.clone()),
|
||||
tx_msg_in.clone(),
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
// UI
|
||||
terminal.draw(|f| ui::draw(f, &app, &hb))?;
|
||||
}
|
||||
app::MsgOut::Refresh => {
|
||||
app = app.refresh_selection()?;
|
||||
if app.pwd() != last_app.pwd() {
|
||||
tx_pwd_watcher.send(app.pwd().clone())?;
|
||||
explorer::explore(
|
||||
app.explorer_config().clone(),
|
||||
app.pwd().clone(),
|
||||
app.focused_node().map(|n| n.relative_path.clone()),
|
||||
tx_msg_in.clone(),
|
||||
);
|
||||
};
|
||||
|
||||
app::MsgOut::Call(cmd) => {
|
||||
tx_event_reader.send(true)?;
|
||||
terminal.clear()?;
|
||||
term::disable_raw_mode()?;
|
||||
terminal.set_cursor(0, 0)?;
|
||||
terminal.show_cursor()?;
|
||||
// UI
|
||||
terminal.draw(|f| ui::draw(f, &app, &hb))?;
|
||||
}
|
||||
|
||||
let input_buffer = app.input_buffer().unwrap_or_default();
|
||||
app::MsgOut::Call(cmd) => {
|
||||
tx_event_reader.send(true)?;
|
||||
terminal.clear()?;
|
||||
term::disable_raw_mode()?;
|
||||
terminal.set_cursor(0, 0)?;
|
||||
terminal.show_cursor()?;
|
||||
|
||||
let focus_index = app
|
||||
.directory_buffer()
|
||||
.map(|d| d.focus)
|
||||
.unwrap_or_default()
|
||||
.to_string();
|
||||
let input_buffer = app.input_buffer().unwrap_or_default();
|
||||
|
||||
let pipe_msg_in = app.pipe().msg_in.clone();
|
||||
let pipe_mode_out = app.pipe().mode_out.clone();
|
||||
let pipe_focus_out = app.pipe().focus_out.clone();
|
||||
let pipe_selection_out = app.pipe().selection_out.clone();
|
||||
let pipe_result_out = app.pipe().result_out.clone();
|
||||
let pipe_directory_nodes_out = app.pipe().directory_nodes_out.clone();
|
||||
let pipe_global_help_menu_out = app.pipe().global_help_menu_out.clone();
|
||||
let pipe_logs_out = app.pipe().logs_out.clone();
|
||||
let session_path = app.session_path();
|
||||
let focus_index = app
|
||||
.directory_buffer()
|
||||
.map(|d| d.focus)
|
||||
.unwrap_or_default()
|
||||
.to_string();
|
||||
|
||||
let status = std::process::Command::new(cmd.command.clone())
|
||||
.current_dir(app.pwd())
|
||||
.env("XPLR_APP_VERSION", app.version())
|
||||
.env("XPLR_CONFIG_VERSION", &app.config().version)
|
||||
.env("XPLR_PID", &app.pid().to_string())
|
||||
.env("XPLR_INPUT_BUFFER", input_buffer)
|
||||
.env("XPLR_FOCUS_PATH", app.focused_node_str())
|
||||
.env("XPLR_FOCUS_INDEX", focus_index)
|
||||
.env("XPLR_SESSION_PATH", session_path)
|
||||
.env("XPLR_PIPE_MSG_IN", pipe_msg_in)
|
||||
.env("XPLR_PIPE_SELECTION_OUT", pipe_selection_out)
|
||||
.env("XPLR_PIPE_FOCUS_OUT", pipe_focus_out)
|
||||
.env("XPLR_PIPE_MODE_OUT", pipe_mode_out)
|
||||
.env("XPLR_PIPE_RESULT_OUT", pipe_result_out)
|
||||
.env("XPLR_PIPE_GLOBAL_HELP_MENU_OUT", pipe_global_help_menu_out)
|
||||
.env("XPLR_PIPE_DIRECTORY_NODES_OUT", pipe_directory_nodes_out)
|
||||
.env("XPLR_PIPE_LOGS_OUT", pipe_logs_out)
|
||||
.args(cmd.args.clone())
|
||||
.status()
|
||||
.map(|s| {
|
||||
if s.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("process exited with code {}", &s))
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|e| Err(e.to_string()));
|
||||
let pipe_msg_in = app.pipe().msg_in.clone();
|
||||
let pipe_mode_out = app.pipe().mode_out.clone();
|
||||
let pipe_focus_out = app.pipe().focus_out.clone();
|
||||
let pipe_selection_out = app.pipe().selection_out.clone();
|
||||
let pipe_result_out = app.pipe().result_out.clone();
|
||||
let pipe_directory_nodes_out = app.pipe().directory_nodes_out.clone();
|
||||
let pipe_global_help_menu_out = app.pipe().global_help_menu_out.clone();
|
||||
let pipe_logs_out = app.pipe().logs_out.clone();
|
||||
let session_path = app.session_path();
|
||||
|
||||
if let Err(e) = status {
|
||||
let msg = app::MsgIn::External(app::ExternalMsg::LogError(e));
|
||||
tx_msg_in.send(app::Task::new(1, msg, None))?;
|
||||
};
|
||||
let status = std::process::Command::new(cmd.command.clone())
|
||||
.current_dir(app.pwd())
|
||||
.env("XPLR_APP_VERSION", app.version())
|
||||
.env("XPLR_CONFIG_VERSION", &app.config().version)
|
||||
.env("XPLR_PID", &app.pid().to_string())
|
||||
.env("XPLR_INPUT_BUFFER", input_buffer)
|
||||
.env("XPLR_FOCUS_PATH", app.focused_node_str())
|
||||
.env("XPLR_FOCUS_INDEX", focus_index)
|
||||
.env("XPLR_SESSION_PATH", session_path)
|
||||
.env("XPLR_PIPE_MSG_IN", pipe_msg_in)
|
||||
.env("XPLR_PIPE_SELECTION_OUT", pipe_selection_out)
|
||||
.env("XPLR_PIPE_FOCUS_OUT", pipe_focus_out)
|
||||
.env("XPLR_PIPE_MODE_OUT", pipe_mode_out)
|
||||
.env("XPLR_PIPE_RESULT_OUT", pipe_result_out)
|
||||
.env("XPLR_PIPE_GLOBAL_HELP_MENU_OUT", pipe_global_help_menu_out)
|
||||
.env("XPLR_PIPE_DIRECTORY_NODES_OUT", pipe_directory_nodes_out)
|
||||
.env("XPLR_PIPE_LOGS_OUT", pipe_logs_out)
|
||||
.args(cmd.args.clone())
|
||||
.status()
|
||||
.map(|s| {
|
||||
if s.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("process exited with code {}", &s))
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|e| Err(e.to_string()));
|
||||
|
||||
terminal.hide_cursor()?;
|
||||
terminal.clear()?;
|
||||
term::enable_raw_mode()?;
|
||||
tx_event_reader.send(false)?;
|
||||
}
|
||||
if let Err(e) = status {
|
||||
let msg = app::MsgIn::External(app::ExternalMsg::LogError(e));
|
||||
tx_msg_in.send(app::Task::new(1, msg, None))?;
|
||||
};
|
||||
|
||||
terminal.hide_cursor()?;
|
||||
terminal.clear()?;
|
||||
term::enable_raw_mode()?;
|
||||
tx_event_reader.send(false)?;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if app.focused_node() != last_app.focused_node() {
|
||||
fs::write(&app.pipe().focus_out, app.focused_node_str())?;
|
||||
};
|
||||
|
||||
if app.selection() != last_app.selection() {
|
||||
fs::write(&app.pipe().selection_out, app.selection_str())?;
|
||||
};
|
||||
|
||||
if app.mode_str() != last_app.mode_str() {
|
||||
fs::write(&app.pipe().mode_out, app.mode_str())?;
|
||||
};
|
||||
|
||||
if app.directory_buffer() != last_app.directory_buffer() {
|
||||
fs::write(&app.pipe().directory_nodes_out, app.directory_nodes_str())?;
|
||||
};
|
||||
|
||||
if app.logs() != last_app.logs() {
|
||||
fs::write(&app.pipe().logs_out, app.logs_str())?;
|
||||
};
|
||||
|
||||
if app.result() != last_app.result() {
|
||||
fs::write(&app.pipe().result_out, app.result_str())?;
|
||||
};
|
||||
}
|
||||
|
||||
while let Some(task) = app.pop_task_out() {
|
||||
tx_msg_in.send(task)?;
|
||||
tasks.push(task);
|
||||
}
|
||||
|
||||
if app.focused_node() != last_app.focused_node() {
|
||||
fs::write(&app.pipe().focus_out, app.focused_node_str())?;
|
||||
};
|
||||
|
||||
if app.selection() != last_app.selection() {
|
||||
fs::write(&app.pipe().selection_out, app.selection_str())?;
|
||||
};
|
||||
|
||||
if app.mode_str() != last_app.mode_str() {
|
||||
fs::write(&app.pipe().mode_out, app.mode_str())?;
|
||||
};
|
||||
|
||||
if app.directory_buffer() != last_app.directory_buffer() {
|
||||
fs::write(&app.pipe().directory_nodes_out, app.directory_nodes_str())?;
|
||||
};
|
||||
|
||||
if app.logs() != last_app.logs() {
|
||||
fs::write(&app.pipe().logs_out, app.logs_str())?;
|
||||
};
|
||||
|
||||
if app.result() != last_app.result() {
|
||||
fs::write(&app.pipe().result_out, app.result_str())?;
|
||||
};
|
||||
if tasks.is_empty() {
|
||||
std::thread::sleep(std::time::Duration::from_millis(5));
|
||||
}
|
||||
}
|
||||
|
||||
terminal.clear()?;
|
||||
|
Loading…
Reference in New Issue
Block a user