first sim pass

This commit is contained in:
Daniel Bulant 2026-05-12 21:22:36 +02:00
parent 8638b90cbe
commit 18cdc54781
No known key found for this signature in database
8 changed files with 594 additions and 31 deletions

View file

@ -1,17 +1,2 @@
[build]
target = "xtensa-esp32-none-elf"
[target.xtensa-esp32-none-elf]
runner = "espflash flash --monitor"
rustflags = [
"-C",
"link-arg=-Wl,-Tlinkall.x",
"-C",
"link-arg=-nostartfiles",
]
[unstable]
build-std = ["core", "alloc", "compiler_builtins"]
[env]
DEFMT_LOG = "debug"

370
Cargo.lock generated
View file

@ -49,6 +49,56 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c583acf993cf4245c4acb0a2cc2ab1f9cc097de73411bb6d3647ff6af2b1013d"
[[package]]
name = "anstream"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
[[package]]
name = "anstyle-parse"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys 0.61.2",
]
[[package]]
name = "arrayvec"
version = "0.7.6"
@ -215,6 +265,12 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
[[package]]
name = "cc"
version = "1.2.62"
@ -242,6 +298,46 @@ dependencies = [
"pure-rust-locales",
]
[[package]]
name = "clap"
version = "4.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "clap_lex"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
[[package]]
name = "codespan-reporting"
version = "0.11.1"
@ -252,6 +348,12 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "colorchoice"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
[[package]]
name = "const-default"
version = "1.0.0"
@ -324,6 +426,31 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
[[package]]
name = "crossterm"
version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
dependencies = [
"bitflags 2.11.1",
"crossterm_winapi",
"mio",
"parking_lot",
"rustix",
"signal-hook",
"signal-hook-mio",
"winapi",
]
[[package]]
name = "crossterm_winapi"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
dependencies = [
"winapi",
]
[[package]]
name = "crunchy"
version = "0.2.4"
@ -1047,6 +1174,16 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "errno"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys 0.61.2",
]
[[package]]
name = "esp-alloc"
version = "0.10.0"
@ -1680,6 +1817,12 @@ dependencies = [
"syn 2.0.117",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
[[package]]
name = "itertools"
version = "0.14.0"
@ -1778,6 +1921,12 @@ version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b23ac50abb8261cb38c6e2a7192d3302e0836dac1628f6a93b82b4fad185897"
[[package]]
name = "linux-raw-sys"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "litrs"
version = "1.0.0"
@ -1833,6 +1982,18 @@ version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]]
name = "mio"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
dependencies = [
"libc",
"log",
"wasi",
"windows-sys 0.61.2",
]
[[package]]
name = "nb"
version = "0.1.3"
@ -1860,7 +2021,7 @@ version = "0.50.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
dependencies = [
"windows-sys",
"windows-sys 0.61.2",
]
[[package]]
@ -1910,6 +2071,12 @@ version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
name = "once_cell_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
[[package]]
name = "owned_str"
version = "0.1.2"
@ -2337,6 +2504,19 @@ dependencies = [
"semver",
]
[[package]]
name = "rustix"
version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
dependencies = [
"bitflags 2.11.1",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.59.0",
]
[[package]]
name = "rustversion"
version = "1.0.22"
@ -2510,6 +2690,47 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "signal-hook"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2"
dependencies = [
"libc",
"signal-hook-registry",
]
[[package]]
name = "signal-hook-mio"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc"
dependencies = [
"libc",
"mio",
"signal-hook",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
dependencies = [
"errno",
"libc",
]
[[package]]
name = "simulator"
version = "0.1.0"
dependencies = [
"clap",
"crossterm",
"device-state",
"tokio",
]
[[package]]
name = "siphasher"
version = "1.0.3"
@ -2554,6 +2775,16 @@ dependencies = [
"managed",
]
[[package]]
name = "socket2"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
dependencies = [
"libc",
"windows-sys 0.61.2",
]
[[package]]
name = "somni-expr"
version = "0.2.0"
@ -2674,7 +2905,7 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8c27177b12a6399ffc08b98f76f7c9a1f4fe9fc967c784c5a071fa8d93cf7e1"
dependencies = [
"windows-sys",
"windows-sys 0.61.2",
]
[[package]]
@ -2715,6 +2946,32 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "tokio"
version = "1.52.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
dependencies = [
"bytes",
"libc",
"mio",
"pin-project-lite",
"socket2",
"tokio-macros",
"windows-sys 0.61.2",
]
[[package]]
name = "tokio-macros"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "toml_datetime"
version = "1.1.1+spec-1.1.0"
@ -2933,6 +3190,12 @@ dependencies = [
"usbd-hid-descriptors",
]
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "valuable"
version = "0.1.1"
@ -2976,15 +3239,43 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
"windows-sys",
"windows-sys 0.61.2",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-link"
version = "0.2.1"
@ -3000,6 +3291,15 @@ dependencies = [
"windows-link",
]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.61.2"
@ -3009,6 +3309,70 @@ dependencies = [
"windows-link",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "1.0.2"

View file

@ -1,8 +1,11 @@
cargo-features = ["per-package-target"]
[workspace]
members = [
"device-state",
"esp32",
"pico",
"simulator",
]
resolver = "2"

17
esp32/.cargo/config.toml Normal file
View file

@ -0,0 +1,17 @@
[build]
target = "xtensa-esp32-none-elf"
[target.xtensa-esp32-none-elf]
runner = "espflash flash --monitor"
rustflags = [
"-C",
"link-arg=-Wl,-Tlinkall.x",
"-C",
"link-arg=-nostartfiles",
]
[unstable]
build-std = ["core", "alloc", "compiler_builtins"]
[env]
DEFMT_LOG = "debug"

View file

@ -1,7 +1,9 @@
cargo-features = ["per-package-target"]
[package]
name = "esp32"
version = "0.1.0"
edition = "2024"
default-target = "xtensa-esp32-none-elf"
[dependencies]
[dependencies.device-state]

View file

@ -3,6 +3,7 @@
extern crate alloc;
use device_state::DeviceState;
use embassy_executor::Spawner;
use embassy_futures::select::{Either, select};
use embassy_net::tcp::{TcpReader, TcpWriter};
@ -17,7 +18,6 @@ use esp_hal::{
timer::timg::TimerGroup,
};
use esp_println::println;
use device_state::{DeviceState, ViewState};
mod buffer;
mod input;
@ -26,8 +26,6 @@ mod screen;
pub use input::ANGLE;
use crate::screen::overwrite_lcd;
const WIFI_NETWORK: &str = "flamme";
const WIFI_PASSWORD: &str = "12345678";
const TARGET_IP: &str = "84.238.32.253";
@ -135,18 +133,8 @@ pub async fn main_loop() {
let mut state = STATE.lock().await;
state.tick();
let lines = state.render_lines();
let view = state.view_state();
drop(state);
match view {
ViewState::Loading => continue,
ViewState::Results => {
overwrite_lcd("Results", "").await;
continue;
}
ViewState::Question => {}
}
let Some((title_line, second_line)) = lines else {
continue;
};

12
simulator/Cargo.toml Normal file
View file

@ -0,0 +1,12 @@
cargo-features = ["per-package-target"]
[package]
name = "simulator"
version = "0.1.0"
edition = "2024"
default-target = "x86_64-unknown-linux-gnu"
[dependencies]
clap = { version = "4.5.45", features = ["derive"] }
crossterm = "0.28.1"
device-state = { path = "../device-state" }
tokio = { version = "1.47.0", features = ["macros", "rt-multi-thread", "net", "sync", "time", "io-util"] }

192
simulator/src/main.rs Normal file
View file

@ -0,0 +1,192 @@
use std::io::{self, Write as _};
use std::net::SocketAddr;
use std::sync::{Arc, Mutex};
use std::thread;
use clap::Parser;
use crossterm::event::{Event, KeyCode, KeyEventKind};
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
use crossterm::event;
use device_state::{DeviceState, WriteType, apply_wheel_delta};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpStream;
use tokio::sync::mpsc;
use tokio::time::{Duration, interval};
const DEVICE_ID: &str = "esp32-1";
const DEFAULT_HOST: &str = "84.238.32.253";
const DEFAULT_PORT: u16 = 7070;
const WHEEL_PRECISION: i32 = 32;
const WHEEL_STEP: i32 = 1;
#[derive(Parser, Debug)]
#[command(author, version, about)]
struct Args {
#[arg(long, default_value = DEFAULT_HOST)]
host: String,
#[arg(long, default_value_t = DEFAULT_PORT)]
port: u16,
}
enum InputEvent {
Button(u8),
WheelDelta(i32),
Quit,
}
#[tokio::main]
async fn main() -> io::Result<()> {
let args = Args::parse();
let addr: SocketAddr = format!("{}:{}", args.host, args.port).parse().unwrap();
let state = Arc::new(Mutex::new(DeviceState::new()));
let (input_tx, mut input_rx) = mpsc::channel::<InputEvent>(64);
spawn_input_thread(input_tx.clone());
tokio::spawn(ui_task(state.clone()));
let mut buf = [0u8; 1024];
loop {
let stream = match TcpStream::connect(addr).await {
Ok(stream) => stream,
Err(err) => {
eprintln!("connect error: {err}");
tokio::time::sleep(Duration::from_secs(1)).await;
continue;
}
};
let (mut read, mut write) = stream.into_split();
let device_id = device_state::serialize_write(&WriteType::DeviceId(DEVICE_ID)).unwrap();
if write.write_all(device_id.as_bytes()).await.is_err() {
tokio::time::sleep(Duration::from_secs(1)).await;
continue;
}
loop {
tokio::select! {
maybe_event = input_rx.recv() => {
match maybe_event {
Some(InputEvent::Quit) | None => {
let _ = disable_raw_mode();
return Ok(());
}
Some(InputEvent::Button(id)) => {
let value = state.lock().unwrap().response_value(id);
let data = WriteType::QuizResponse(value);
let buffer = device_state::serialize_write(&data).unwrap();
if write.write_all(buffer.as_bytes()).await.is_err() {
break;
}
}
Some(InputEvent::WheelDelta(diff)) => {
let mut state = state.lock().unwrap();
let wheel = state.wheel();
if wheel.max != wheel.min {
let mut value = wheel.value;
let mut accumulated = wheel.accumulated;
apply_wheel_delta(
&mut value,
wheel.min,
wheel.max,
&mut accumulated,
diff,
WHEEL_PRECISION,
);
let wheel = state.wheel_mut();
wheel.value = value;
wheel.accumulated = accumulated;
}
}
}
}
read_res = read.read(&mut buf) => {
let len = match read_res {
Ok(0) => break,
Ok(len) => len,
Err(_) => break,
};
let Ok(text) = core::str::from_utf8(&buf[..len]) else {
continue;
};
if let Some(last) = text.lines().last() {
let Ok(data) = device_state::parse_proxy_output(last) else {
continue;
};
let mut state = state.lock().unwrap();
state.apply_proxy_output(data);
}
}
}
}
tokio::time::sleep(Duration::from_millis(500)).await;
}
}
fn spawn_input_thread(tx: mpsc::Sender<InputEvent>) {
let _ = thread::Builder::new()
.name("sim-input".to_string())
.spawn(move || input_thread(tx));
}
fn input_thread(tx: mpsc::Sender<InputEvent>) {
let _ = enable_raw_mode();
let mut stdout = io::stdout();
let _ = crossterm::execute!(stdout, crossterm::cursor::MoveTo(0, 0));
loop {
if let Ok(Event::Key(key)) = event::read() {
if key.kind == KeyEventKind::Release {
continue;
}
let event = match key.code {
KeyCode::Char('1') => Some(InputEvent::Button(1)),
KeyCode::Char('2') => Some(InputEvent::Button(2)),
KeyCode::Char('3') => Some(InputEvent::Button(3)),
KeyCode::Char('4') => Some(InputEvent::Button(4)),
KeyCode::Left => Some(InputEvent::WheelDelta(-WHEEL_STEP)),
KeyCode::Right => Some(InputEvent::WheelDelta(WHEEL_STEP)),
KeyCode::Char('a') => Some(InputEvent::WheelDelta(-WHEEL_STEP)),
KeyCode::Char('d') => Some(InputEvent::WheelDelta(WHEEL_STEP)),
KeyCode::Char('q') => Some(InputEvent::Quit),
_ => None,
};
if let Some(event) = event {
let quit = matches!(event, InputEvent::Quit);
if tx.blocking_send(event).is_err() {
break;
}
if quit {
break;
}
}
}
}
let _ = disable_raw_mode();
}
async fn ui_task(state: Arc<Mutex<DeviceState>>) {
let mut ticker = interval(Duration::from_millis(50));
loop {
ticker.tick().await;
let (line1, line2) = {
let mut state = state.lock().unwrap();
state.tick();
match state.render_lines() {
Some((line1, line2)) => (line1, line2),
None => continue,
}
};
let mut stdout = io::stdout();
let _ = crossterm::execute!(stdout, crossterm::cursor::MoveTo(0, 0));
let _ = writeln!(stdout, "{:<16}", line1.as_str());
let _ = writeln!(stdout, "{:<16}", line2.as_str());
let _ = writeln!(stdout, "[1-4]=buttons <-/->=wheel a/d q=quit");
let _ = stdout.flush();
}
}