Skip to content

Commit

Permalink
simplify spinner and mainloop to reduce log noise (#156)
Browse files Browse the repository at this point in the history
  • Loading branch information
Stephan Dilly committed Jun 29, 2020
1 parent 51d17b2 commit b54e90a
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 47 deletions.
4 changes: 4 additions & 0 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,14 @@ impl App {
/// forward ticking to components that require it
pub fn update(&mut self) -> Result<()> {
log::trace!("update");

self.status_tab.update()?;
self.revlog.update()?;
self.stashing_tab.update()?;
self.stashlist_tab.update()?;

self.update_commands();

Ok(())
}

Expand Down Expand Up @@ -259,6 +262,7 @@ impl App {
}

///
//TODO: rename
pub const fn set_polling(&self) -> bool {
self.set_polling
}
Expand Down
80 changes: 35 additions & 45 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ use tui::{
};

static TICK_INTERVAL: Duration = Duration::from_secs(5);
static SPINNER_INTERVAL: Duration = Duration::from_millis(50);
static SPINNER_INTERVAL: Duration = Duration::from_millis(80);

///
#[derive(Clone, Copy)]
Expand Down Expand Up @@ -97,46 +97,46 @@ fn main() -> Result<()> {
let ticker = tick(TICK_INTERVAL);
let spinner_ticker = tick(SPINNER_INTERVAL);

app.update()?;
draw(&mut terminal, &app)?;

let mut spinner = Spinner::default();
let mut first_update = true;

loop {
let events: Vec<QueueEvent> = select_event(
&rx_input,
&rx_git,
&ticker,
&spinner_ticker,
)?;
let event = if first_update {
first_update = false;
QueueEvent::Tick
} else {
select_event(
&rx_input,
&rx_git,
&ticker,
&spinner_ticker,
)?
};

{
if let QueueEvent::SpinnerUpdate = event {
spinner.update();
spinner.draw(&mut terminal)?;
continue;
}

scope_time!("loop");

let mut needs_draw = true;

for e in events {
match e {
QueueEvent::InputEvent(ev) => app.event(ev)?,
QueueEvent::Tick => app.update()?,
QueueEvent::GitEvent(ev) => app.update_git(ev)?,
QueueEvent::SpinnerUpdate => {
needs_draw = false;
spinner.update()
}
}
match event {
QueueEvent::InputEvent(ev) => app.event(ev)?,
QueueEvent::Tick => app.update()?,
QueueEvent::GitEvent(ev) => app.update_git(ev)?,
QueueEvent::SpinnerUpdate => unreachable!(),
}

input.set_polling(app.set_polling());

if needs_draw {
draw(&mut terminal, &app)?;
}
draw(&mut terminal, &app)?;

spinner.draw(
&mut terminal,
spinner.set_state(
app.any_work_pending() || input.is_state_changing(),
)?;
);
spinner.draw(&mut terminal)?;

if app.is_quit() {
break;
Expand Down Expand Up @@ -184,9 +184,7 @@ fn select_event(
rx_git: &Receiver<AsyncNotification>,
rx_ticker: &Receiver<Instant>,
rx_spinner: &Receiver<Instant>,
) -> Result<Vec<QueueEvent>> {
let mut events: Vec<QueueEvent> = Vec::new();

) -> Result<QueueEvent> {
let mut sel = Select::new();

sel.recv(rx_input);
Expand All @@ -197,23 +195,15 @@ fn select_event(
let oper = sel.select();
let index = oper.index();

match index {
0 => oper
.recv(rx_input)
.map(|input| events.push(QueueEvent::InputEvent(input))),
1 => oper
.recv(rx_git)
.map(|ev| events.push(QueueEvent::GitEvent(ev))),
2 => oper
.recv(rx_ticker)
.map(|_| events.push(QueueEvent::Tick)),
3 => oper
.recv(rx_spinner)
.map(|_| events.push(QueueEvent::SpinnerUpdate)),
let ev = match index {
0 => oper.recv(rx_input).map(QueueEvent::InputEvent),
1 => oper.recv(rx_git).map(QueueEvent::GitEvent),
2 => oper.recv(rx_ticker).map(|_| QueueEvent::Tick),
3 => oper.recv(rx_spinner).map(|_| QueueEvent::SpinnerUpdate),
_ => return Err(anyhow!("unknown select source")),
}?;

Ok(events)
Ok(ev)
}

fn start_terminal<W: Write>(
Expand Down
13 changes: 11 additions & 2 deletions src/spinner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ static SPINNER_CHARS: &[char] = &['|', '/', '-', '\\'];
#[derive(Default)]
pub struct Spinner {
idx: usize,
pending: bool,
}

impl Spinner {
Expand All @@ -16,16 +17,24 @@ impl Spinner {
self.idx %= SPINNER_CHARS.len();
}

///
pub fn set_state(&mut self, pending: bool) {
self.pending = pending;
}

/// draws or removes spinner char depending on `pending` state
pub fn draw<B: Backend>(
&self,
terminal: &mut Terminal<B>,
pending: bool,
) -> io::Result<()> {
let idx = self.idx;

let c: Cell = Cell::default()
.set_char(if pending { SPINNER_CHARS[idx] } else { ' ' })
.set_char(if self.pending {
SPINNER_CHARS[idx]
} else {
' '
})
.clone();
terminal
.backend_mut()
Expand Down

0 comments on commit b54e90a

Please sign in to comment.