diff options
-rw-r--r-- | src/bin/ttyplay/display.rs | 8 | ||||
-rw-r--r-- | src/bin/ttyplay/event.rs | 4 | ||||
-rw-r--r-- | src/bin/ttyplay/input.rs | 14 | ||||
-rw-r--r-- | src/bin/ttyplay/main.rs | 58 |
4 files changed, 72 insertions, 12 deletions
diff --git a/src/bin/ttyplay/display.rs b/src/bin/ttyplay/display.rs index c06e849..486cb0b 100644 --- a/src/bin/ttyplay/display.rs +++ b/src/bin/ttyplay/display.rs @@ -21,10 +21,18 @@ impl Display { self.current_frame = idx; } + pub fn get_current_frame(&self) -> usize { + self.current_frame + } + pub fn total_frames(&mut self, n: usize) { self.total_frames = n; } + pub fn get_total_frames(&self) -> usize { + self.total_frames + } + pub fn done_loading(&mut self) { self.done_loading = true; } diff --git a/src/bin/ttyplay/event.rs b/src/bin/ttyplay/event.rs index 1c653c9..677f488 100644 --- a/src/bin/ttyplay/event.rs +++ b/src/bin/ttyplay/event.rs @@ -4,5 +4,9 @@ pub enum Event { FrameLoaded(Option<usize>), Pause, Paused(bool), + FirstFrame, + LastFrame, + NextFrame, + PreviousFrame, Quit, } diff --git a/src/bin/ttyplay/input.rs b/src/bin/ttyplay/input.rs index 7221f63..218a21b 100644 --- a/src/bin/ttyplay/input.rs +++ b/src/bin/ttyplay/input.rs @@ -3,8 +3,20 @@ pub async fn handle_input( event_w: async_std::channel::Sender<crate::event::Event>, ) -> anyhow::Result<()> { match key { + textmode::Key::Char('g' | '0' | ')') => { + event_w.send(crate::event::Event::FirstFrame).await?; + } + textmode::Key::Char('G' | '$') => { + event_w.send(crate::event::Event::LastFrame).await?; + } + textmode::Key::Char('l' | 'n') => { + event_w.send(crate::event::Event::NextFrame).await?; + } + textmode::Key::Char('h' | 'p') => { + event_w.send(crate::event::Event::PreviousFrame).await?; + } textmode::Key::Char('q') => { - event_w.send(crate::event::Event::Quit).await? + event_w.send(crate::event::Event::Quit).await?; } textmode::Key::Char(' ') => { event_w.send(crate::event::Event::Pause).await?; diff --git a/src/bin/ttyplay/main.rs b/src/bin/ttyplay/main.rs index 10e3d3e..63a2658 100644 --- a/src/bin/ttyplay/main.rs +++ b/src/bin/ttyplay/main.rs @@ -14,6 +14,7 @@ struct Opt { enum TimerAction { Pause, + GotoFrame(usize), Quit, } @@ -59,6 +60,7 @@ fn spawn_timer_task( let mut idx = 0; let mut start_time = std::time::Instant::now(); let mut paused_time = None; + let mut force_update_time = false; loop { enum Res { Wait(Option<vt100::Screen>), @@ -67,14 +69,20 @@ fn spawn_timer_task( ), } let wait = async { - if paused_time.is_some() { - std::future::pending().await - } else { - let wait_read = - frames.lock_arc().await.wait_for_frame(idx); - if wait_read.await { - let frame = - frames.lock_arc().await.get(idx).unwrap().clone(); + let wait_read = frames.lock_arc().await.wait_for_frame(idx); + if wait_read.await { + let frame = + frames.lock_arc().await.get(idx).unwrap().clone(); + if force_update_time { + let now = std::time::Instant::now(); + start_time = now - frame.delay(); + if paused_time.take().is_some() { + paused_time = Some(now) + } + force_update_time = false; + } else if paused_time.is_some() { + std::future::pending::<()>().await; + } else { async_std::task::sleep( (start_time + frame.delay()) .saturating_duration_since( @@ -82,10 +90,10 @@ fn spawn_timer_task( ), ) .await; - Res::Wait(Some(frame.into_screen())) - } else { - Res::Wait(None) } + Res::Wait(Some(frame.into_screen())) + } else { + Res::Wait(None) } }; let action = async { Res::TimerAction(timer_r.recv().await) }; @@ -113,6 +121,10 @@ fn spawn_timer_task( .await .unwrap(); } + TimerAction::GotoFrame(new_idx) => { + idx = new_idx; + force_update_time = true; + } TimerAction::Quit => break, }, Res::TimerAction(Err(e)) => panic!("{}", e), @@ -179,6 +191,30 @@ async fn async_main(opt: Opt) -> anyhow::Result<()> { display.paused(paused); display.render(¤t_screen, &mut output).await?; } + event::Event::FirstFrame => { + timer_w.send(TimerAction::GotoFrame(0)).await?; + } + event::Event::LastFrame => { + timer_w + .send(TimerAction::GotoFrame( + display.get_total_frames() - 1, + )) + .await?; + } + event::Event::NextFrame => { + timer_w + .send(TimerAction::GotoFrame( + display.get_current_frame() + 1, + )) + .await?; + } + event::Event::PreviousFrame => { + timer_w + .send(TimerAction::GotoFrame( + display.get_current_frame() - 1, + )) + .await?; + } event::Event::Quit => { timer_w.send(TimerAction::Quit).await?; break; |