Don't refresh pipes on every iteration

From this commit, the app state will be written to the output pipes only
when invoking a command.

For auto refreshing pipes, we can brainstorm on `service`s concept.
pull/127/head
Arijit Basu 3 years ago committed by Arijit Basu
parent fd92d8ee01
commit 3aa349f614

@ -12,22 +12,19 @@ fn criterion_benchmark(c: &mut Criterion) {
app = app app = app
.clone() .clone()
.handle_task( .handle_task(app::Task::new(
app::Task::new( app::MsgIn::External(app::ExternalMsg::ChangeDirectory("/tmp/xplr_bench".into())),
app::MsgIn::External(app::ExternalMsg::ChangeDirectory("/tmp/xplr_bench".into())), None,
None, ))
),
&app.clone(),
)
.unwrap(); .unwrap();
c.bench_function("focus next item", |b| { c.bench_function("focus next item", |b| {
b.iter(|| { b.iter(|| {
app.clone() app.clone()
.handle_task( .handle_task(app::Task::new(
app::Task::new(app::MsgIn::External(app::ExternalMsg::FocusNext), None), app::MsgIn::External(app::ExternalMsg::FocusNext),
&app.clone(), None,
) ))
.unwrap() .unwrap()
}) })
}); });
@ -35,10 +32,10 @@ fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("focus previous item", |b| { c.bench_function("focus previous item", |b| {
b.iter(|| { b.iter(|| {
app.clone() app.clone()
.handle_task( .handle_task(app::Task::new(
app::Task::new(app::MsgIn::External(app::ExternalMsg::FocusPrevious), None), app::MsgIn::External(app::ExternalMsg::FocusPrevious),
&app.clone(), None,
) ))
.unwrap() .unwrap()
}) })
}); });
@ -46,10 +43,10 @@ fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("focus first item", |b| { c.bench_function("focus first item", |b| {
b.iter(|| { b.iter(|| {
app.clone() app.clone()
.handle_task( .handle_task(app::Task::new(
app::Task::new(app::MsgIn::External(app::ExternalMsg::FocusFirst), None), app::MsgIn::External(app::ExternalMsg::FocusFirst),
&app.clone(), None,
) ))
.unwrap() .unwrap()
}) })
}); });
@ -57,10 +54,10 @@ fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("focus last item", |b| { c.bench_function("focus last item", |b| {
b.iter(|| { b.iter(|| {
app.clone() app.clone()
.handle_task( .handle_task(app::Task::new(
app::Task::new(app::MsgIn::External(app::ExternalMsg::FocusLast), None), app::MsgIn::External(app::ExternalMsg::FocusLast),
&app.clone(), None,
) ))
.unwrap() .unwrap()
}) })
}); });
@ -68,15 +65,15 @@ fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("leave and enter directory", |b| { c.bench_function("leave and enter directory", |b| {
b.iter(|| { b.iter(|| {
app.clone() app.clone()
.handle_task( .handle_task(app::Task::new(
app::Task::new(app::MsgIn::External(app::ExternalMsg::Back), None), app::MsgIn::External(app::ExternalMsg::Back),
&app.clone(), None,
) ))
.unwrap() .unwrap()
.handle_task( .handle_task(app::Task::new(
app::Task::new(app::MsgIn::External(app::ExternalMsg::Enter), None), app::MsgIn::External(app::ExternalMsg::Enter),
&app.clone(), None,
) ))
.unwrap() .unwrap()
}) })
}); });

@ -12,7 +12,6 @@ use std::collections::VecDeque;
use std::env; use std::env;
use std::fs; use std::fs;
use std::io; use std::io;
use std::io::prelude::*;
use std::path::PathBuf; use std::path::PathBuf;
pub const TEMPLATE_TABLE_ROW: &str = "TEMPLATE_TABLE_ROW"; pub const TEMPLATE_TABLE_ROW: &str = "TEMPLATE_TABLE_ROW";
@ -25,7 +24,6 @@ pub struct Pipe {
focus_out: String, focus_out: String,
selection_out: String, selection_out: String,
result_out: String, result_out: String,
mode_out: String,
directory_nodes_out: String, directory_nodes_out: String,
global_help_menu_out: String, global_help_menu_out: String,
logs_out: String, logs_out: String,
@ -46,8 +44,6 @@ impl Pipe {
let result_out = pipesdir.join("result_out").to_string_lossy().to_string(); let result_out = pipesdir.join("result_out").to_string_lossy().to_string();
let mode_out = pipesdir.join("mode_out").to_string_lossy().to_string();
let directory_nodes_out = pipesdir let directory_nodes_out = pipesdir
.join("directory_nodes_out") .join("directory_nodes_out")
.to_string_lossy() .to_string_lossy()
@ -65,7 +61,6 @@ impl Pipe {
fs::write(&msg_in, "")?; fs::write(&msg_in, "")?;
fs::write(&focus_out, "")?; fs::write(&focus_out, "")?;
fs::write(&selection_out, "")?; fs::write(&selection_out, "")?;
fs::write(&mode_out, "")?;
fs::write(&directory_nodes_out, "")?; fs::write(&directory_nodes_out, "")?;
fs::write(&global_help_menu_out, "")?; fs::write(&global_help_menu_out, "")?;
fs::write(&result_out, "")?; fs::write(&result_out, "")?;
@ -77,7 +72,6 @@ impl Pipe {
focus_out, focus_out,
selection_out, selection_out,
result_out, result_out,
mode_out,
directory_nodes_out, directory_nodes_out,
global_help_menu_out, global_help_menu_out,
logs_out, logs_out,
@ -105,11 +99,6 @@ impl Pipe {
&self.result_out &self.result_out
} }
/// Get a reference to the pipe's mode out.
pub fn mode_out(&self) -> &String {
&self.mode_out
}
/// Get a reference to the pipe's directory nodes out. /// Get a reference to the pipe's directory nodes out.
pub fn directory_nodes_out(&self) -> &String { pub fn directory_nodes_out(&self) -> &String {
&self.directory_nodes_out &self.directory_nodes_out
@ -1542,8 +1531,8 @@ impl App {
)); ));
} }
fs::write(&app.pipe().global_help_menu_out, app.global_help_menu_str())?; app.write_pipes()?;
app.write_pipes(None) Ok(app)
} }
pub fn focused_node(&self) -> Option<&Node> { pub fn focused_node(&self) -> Option<&Node> {
@ -1561,10 +1550,10 @@ impl App {
self self
} }
pub fn handle_task(self, task: Task, last_app: &Self) -> Result<Self> { pub fn handle_task(self, task: Task) -> Result<Self> {
match task.msg { match task.msg {
MsgIn::Internal(msg) => self.handle_internal(msg), MsgIn::Internal(msg) => self.handle_internal(msg),
MsgIn::External(msg) => self.handle_external(msg, task.key, last_app), MsgIn::External(msg) => self.handle_external(msg, task.key),
} }
} }
@ -1575,7 +1564,7 @@ impl App {
} }
} }
fn handle_external(self, msg: ExternalMsg, key: Option<Key>, last_app: &Self) -> Result<Self> { fn handle_external(self, msg: ExternalMsg, key: Option<Key>) -> Result<Self> {
if self.config().general().read_only().unwrap_or_default() && !msg.is_read_only() { if self.config().general().read_only().unwrap_or_default() && !msg.is_read_only() {
self.log_error("Cannot call shell command in read-only mode.".into()) self.log_error("Cannot call shell command in read-only mode.".into())
} else { } else {
@ -1664,7 +1653,6 @@ impl App {
} }
}? }?
.refresh_selection() .refresh_selection()
.write_pipes(Some(&last_app))
} }
fn handle_key(mut self, key: Key) -> Result<Self> { fn handle_key(mut self, key: Key) -> Result<Self> {
@ -2359,10 +2347,10 @@ impl App {
&self.session_path &self.session_path
} }
fn refresh_selection(mut self) -> Self { fn refresh_selection(mut self) -> Result<Self> {
self.selection self.selection
.retain(|n| PathBuf::from(&n.absolute_path).exists()); .retain(|n| PathBuf::from(&n.absolute_path).exists());
self Ok(self)
} }
pub fn result(&self) -> Vec<&Node> { pub fn result(&self) -> Vec<&Node> {
@ -2411,6 +2399,14 @@ impl App {
&self.logs &self.logs
} }
pub fn logs_str(&self) -> String {
self.logs()
.iter()
.map(|l| format!("{}\n", l))
.collect::<Vec<String>>()
.join("")
}
pub fn global_help_menu_str(&self) -> String { pub fn global_help_menu_str(&self) -> String {
let builtin = self.config().modes().builtin().clone(); let builtin = self.config().modes().builtin().clone();
let custom = self.config().modes().custom().clone(); let custom = self.config().modes().custom().clone();
@ -2487,7 +2483,7 @@ impl App {
.join("") .join("")
} }
fn write_pipes(self, last_app: Option<&Self>) -> Result<Self> { pub fn write_pipes(&self) -> Result<()> {
// TODO optimize and test // TODO optimize and test
let focused_node_str = self.focused_node_str(); let focused_node_str = self.focused_node_str();
@ -2514,11 +2510,6 @@ impl App {
fs::write(&self.pipe().history_out, history_str)?; fs::write(&self.pipe().history_out, history_str)?;
// }; // };
let mode_str = self.mode_str();
// if last_app.map(|a| a.mode_str() != mode_str).unwrap_or(true) {
fs::write(&self.pipe().mode_out, mode_str)?;
// };
let directory_nodes_str = self.directory_nodes_str(); let directory_nodes_str = self.directory_nodes_str();
// if last_app // if last_app
// .map(|a| a.directory_nodes_str() != directory_nodes_str) // .map(|a| a.directory_nodes_str() != directory_nodes_str)
@ -2531,20 +2522,21 @@ impl App {
// .map(|a| a.logs().len() != self.logs().len()) // .map(|a| a.logs().len() != self.logs().len())
// .unwrap_or(true) // .unwrap_or(true)
// { // {
let new_logs = self // let new_logs = self
.logs() // .logs()
.iter() // .iter()
.skip(last_app.map(|a| a.logs().len()).unwrap_or(0)) // .skip(last_app.map(|a| a.logs().len()).unwrap_or(0))
.map(|l| format!("{}\n", l)) // .map(|l| format!("{}\n", l))
.collect::<Vec<String>>() // .collect::<Vec<String>>()
.join(""); // .join("");
let mut file = fs::OpenOptions::new() // let mut file = fs::OpenOptions::new()
.append(true) // .append(true)
.open(&self.pipe().logs_out)?; // .open(&self.pipe().logs_out)?;
// file.write_all(new_logs.as_bytes())?;
file.write_all(new_logs.as_bytes())?;
// }; // };
let logs_str = self.logs_str();
fs::write(&self.pipe().logs_out, logs_str)?;
let result_str = self.result_str(); let result_str = self.result_str();
// if last_app // if last_app
@ -2553,7 +2545,7 @@ impl App {
// { // {
fs::write(&self.pipe().result_out, result_str)?; fs::write(&self.pipe().result_out, result_str)?;
// }; // };
Ok(self) Ok(())
} }
/// Get a reference to the app's layout. /// Get a reference to the app's layout.

@ -48,7 +48,7 @@ fn call(app: &app::App, cmd: app::Command, silent: bool) -> io::Result<ExitStatu
.env("XPLR_PIPE_SELECTION_OUT", app.pipe().selection_out()) .env("XPLR_PIPE_SELECTION_OUT", app.pipe().selection_out())
.env("XPLR_PIPE_HISTORY_OUT", app.pipe().history_out()) .env("XPLR_PIPE_HISTORY_OUT", app.pipe().history_out())
.env("XPLR_PIPE_FOCUS_OUT", app.pipe().focus_out()) .env("XPLR_PIPE_FOCUS_OUT", app.pipe().focus_out())
.env("XPLR_PIPE_MODE_OUT", app.pipe().mode_out()) .env("XPLR_MODE", app.mode_str())
.env("XPLR_PIPE_RESULT_OUT", app.pipe().result_out()) .env("XPLR_PIPE_RESULT_OUT", app.pipe().result_out())
.env( .env(
"XPLR_PIPE_GLOBAL_HELP_MENU_OUT", "XPLR_PIPE_GLOBAL_HELP_MENU_OUT",
@ -115,7 +115,7 @@ pub fn run(mut app: app::App, focused_path: Option<String>) -> Result<Option<Str
'outer: for task in rx_msg_in { 'outer: for task in rx_msg_in {
let last_app = app.clone(); let last_app = app.clone();
let (new_app, new_result) = match app.handle_task(task, &last_app) { let (new_app, new_result) = match app.handle_task(task) {
Ok(a) => (a, Ok(None)), Ok(a) => (a, Ok(None)),
Err(err) => (last_app.clone(), Err(err)), Err(err) => (last_app.clone(), Err(err)),
}; };
@ -184,6 +184,7 @@ pub fn run(mut app: app::App, focused_path: Option<String>) -> Result<Option<Str
app::MsgOut::CallSilently(cmd) => { app::MsgOut::CallSilently(cmd) => {
tx_event_reader.send(true)?; tx_event_reader.send(true)?;
app.write_pipes()?;
let status = call(&app, cmd, false) let status = call(&app, cmd, false)
.map(|s| { .map(|s| {
if s.success() { if s.success() {
@ -210,6 +211,7 @@ pub fn run(mut app: app::App, focused_path: Option<String>) -> Result<Option<Str
term::disable_raw_mode()?; term::disable_raw_mode()?;
terminal.show_cursor()?; terminal.show_cursor()?;
app.write_pipes()?;
let status = call(&app, cmd, false) let status = call(&app, cmd, false)
.map(|s| { .map(|s| {
if s.success() { if s.success() {

Loading…
Cancel
Save