aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2022-02-24 17:03:39 -0500
committerJesse Luehrs <doy@tozt.net>2022-02-24 17:03:39 -0500
commitaed2684db55ac04496fe1a7dc7a4a37ce02bcfc9 (patch)
tree593fc6eb81e03d315803971369b8593486bd4587
parentadd247bd7e6b617db087f529ec7729911ba1a6cd (diff)
downloadttyrec-bin-aed2684db55ac04496fe1a7dc7a4a37ce02bcfc9.tar.gz
ttyrec-bin-aed2684db55ac04496fe1a7dc7a4a37ce02bcfc9.zip
stop using tokio::select!
-rw-r--r--Cargo.lock102
-rw-r--r--Cargo.toml1
-rw-r--r--src/bin/ttyplay/timer.rs167
3 files changed, 192 insertions, 78 deletions
diff --git a/Cargo.lock b/Cargo.lock
index e5ab15a..18e6301 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -75,6 +75,95 @@ dependencies = [
]
[[package]]
+name = "futures"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
+
+[[package]]
+name = "futures-executor"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-io"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b"
+
+[[package]]
+name = "futures-macro"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "futures-sink"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
+
+[[package]]
+name = "futures-task"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a"
+
+[[package]]
+name = "futures-util"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-macro",
+ "futures-sink",
+ "futures-task",
+ "memchr",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+]
+
+[[package]]
name = "heck"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -258,6 +347,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c"
[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -334,6 +429,12 @@ dependencies = [
]
[[package]]
+name = "slab"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
+
+[[package]]
name = "smallvec"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -477,6 +578,7 @@ name = "ttyrec-bin"
version = "0.1.3"
dependencies = [
"anyhow",
+ "futures",
"libc",
"paw",
"pty-process",
diff --git a/Cargo.toml b/Cargo.toml
index 47665fc..aa1e9bc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,6 +14,7 @@ include = ["src/**/*", "LICENSE", "README.md", "CHANGELOG.md"]
[dependencies]
anyhow = "1.0.55"
+futures = "0.3.21"
libc = "0.2.119"
paw = "1.0.0"
pty-process = { version = "0.2.0", features = ["async"] }
diff --git a/src/bin/ttyplay/timer.rs b/src/bin/ttyplay/timer.rs
index 2f99786..e8dc0fa 100644
--- a/src/bin/ttyplay/timer.rs
+++ b/src/bin/ttyplay/timer.rs
@@ -1,3 +1,5 @@
+use futures::future::FutureExt as _;
+
pub fn spawn_task(
event_w: tokio::sync::mpsc::UnboundedSender<crate::event::Event>,
frames: std::sync::Arc<tokio::sync::Mutex<crate::frames::FrameData>>,
@@ -8,6 +10,11 @@ pub fn spawn_task(
speed: u32,
) -> tokio::task::JoinHandle<()> {
tokio::task::spawn(async move {
+ enum Res {
+ Frame(Option<Box<vt100::Screen>>),
+ Action(Option<crate::event::TimerAction>),
+ }
+
let mut idx = 0;
let mut start_time = std::time::Instant::now();
let mut paused_time = if pause_at_start {
@@ -62,8 +69,14 @@ pub fn spawn_task(
None
}
};
- tokio::select! {
- screen = wait => if let Some(screen) = screen {
+ let select: futures::future::SelectAll<_> = [
+ wait.map(Res::Frame).boxed(),
+ timer_r.recv().map(Res::Action).boxed(),
+ ]
+ .into_iter()
+ .collect();
+ match select.map(|(res, _, _)| res).await {
+ Res::Frame(Some(screen)) => {
event_w
.send(crate::event::Event::FrameTransition((
idx, screen,
@@ -72,105 +85,103 @@ pub fn spawn_task(
.unwrap();
idx += 1;
}
- else {
+ Res::Frame(None) => {
idx = frames.clone().lock_owned().await.count() - 1;
paused_time = Some(std::time::Instant::now());
event_w
.send(crate::event::Event::Paused(true))
// event_w is never closed, so this can never fail
.unwrap();
- },
- action = timer_r.recv() => match action {
- Some(action) => match action {
- crate::event::TimerAction::Pause => {
- let now = std::time::Instant::now();
- paused_time.take().map_or_else(|| {
+ }
+ Res::Action(Some(action)) => match action {
+ crate::event::TimerAction::Pause => {
+ let now = std::time::Instant::now();
+ paused_time.take().map_or_else(
+ || {
paused_time = Some(now);
- }, |time| {
+ },
+ |time| {
start_time += now - time;
- });
+ },
+ );
+ event_w
+ .send(crate::event::Event::Paused(
+ paused_time.is_some(),
+ ))
+ // event_w is never closed, so this can never fail
+ .unwrap();
+ }
+ crate::event::TimerAction::FirstFrame => {
+ idx = 0;
+ force_update_time = true;
+ }
+ crate::event::TimerAction::LastFrame => {
+ idx = frames.clone().lock_owned().await.count() - 1;
+ force_update_time = true;
+ }
+ // force_update_time will immediately transition to the
+ // next frame and do idx += 1 on its own
+ crate::event::TimerAction::NextFrame => {
+ force_update_time = true;
+ }
+ crate::event::TimerAction::PreviousFrame => {
+ idx = idx.saturating_sub(2);
+ force_update_time = true;
+ }
+ crate::event::TimerAction::SpeedUp => {
+ if playback_ratio > 1 {
+ playback_ratio /= 2;
+ let now = std::time::Instant::now();
+ start_time = now - (now - start_time) / 2;
event_w
- .send(crate::event::Event::Paused(
- paused_time.is_some(),
+ .send(crate::event::Event::Speed(
+ playback_ratio,
))
// event_w is never closed, so this can never
// fail
.unwrap();
}
- crate::event::TimerAction::FirstFrame => {
- idx = 0;
- force_update_time = true;
- }
- crate::event::TimerAction::LastFrame => {
- idx =
- frames.clone().lock_owned().await.count() - 1;
- force_update_time = true;
- }
- // force_update_time will immediately transition to the
- // next frame and do idx += 1 on its own
- crate::event::TimerAction::NextFrame => {
- force_update_time = true;
- }
- crate::event::TimerAction::PreviousFrame => {
- idx = idx.saturating_sub(2);
- force_update_time = true;
- }
- crate::event::TimerAction::SpeedUp => {
- if playback_ratio > 1 {
- playback_ratio /= 2;
- let now = std::time::Instant::now();
- start_time = now - (now - start_time) / 2;
- event_w
- .send(crate::event::Event::Speed(
- playback_ratio,
- ))
- // event_w is never closed, so this can
- // never fail
- .unwrap();
- }
- }
- crate::event::TimerAction::SlowDown => {
- if playback_ratio < 256 {
- playback_ratio *= 2;
- let now = std::time::Instant::now();
- start_time = now - (now - start_time) * 2;
- event_w
- .send(crate::event::Event::Speed(
- playback_ratio,
- ))
- // event_w is never closed, so this can
- // never fail
- .unwrap();
- }
- }
- crate::event::TimerAction::DefaultSpeed => {
+ }
+ crate::event::TimerAction::SlowDown => {
+ if playback_ratio < 256 {
+ playback_ratio *= 2;
let now = std::time::Instant::now();
- start_time = now
- - (((now - start_time) * 16) / playback_ratio);
- playback_ratio = 16;
+ start_time = now - (now - start_time) * 2;
event_w
- .send(
- crate::event::Event::Speed(playback_ratio)
- )
+ .send(crate::event::Event::Speed(
+ playback_ratio,
+ ))
// event_w is never closed, so this can never
// fail
.unwrap();
}
- crate::event::TimerAction::Search(s, backwards) => {
- if let Some(new_idx) =
- frames.clone()
- .lock_owned()
- .await
- .search(idx, &s, backwards)
- {
- idx = new_idx;
- force_update_time = true;
- }
+ }
+ crate::event::TimerAction::DefaultSpeed => {
+ let now = std::time::Instant::now();
+ start_time = now
+ - (((now - start_time) * 16) / playback_ratio);
+ playback_ratio = 16;
+ event_w
+ .send(crate::event::Event::Speed(playback_ratio))
+ // event_w is never closed, so this can never fail
+ .unwrap();
+ }
+ crate::event::TimerAction::Search(s, backwards) => {
+ if let Some(new_idx) = frames
+ .clone()
+ .lock_owned()
+ .await
+ .search(idx, &s, backwards)
+ {
+ idx = new_idx;
+ force_update_time = true;
}
- crate::event::TimerAction::Quit => break,
}
- None => unreachable!(),
+ crate::event::TimerAction::Quit => break,
},
+ Res::Action(None) => {
+ unreachable!()
+ }
}
}
})