PoC in Rust Dumping state and config

This commit is contained in:
Martin Quarda 2025-05-09 20:08:41 +02:00
parent fa64b35e18
commit 8c796b1590
2 changed files with 38 additions and 16 deletions

View File

@ -7,7 +7,8 @@ edition = "2024"
env_logger = "0.11.8" env_logger = "0.11.8"
futures-lite = "2.6.0" futures-lite = "2.6.0"
iced = {"git"= "https://github.com/iced-rs/iced.git", "features"=["tokio", "auto-detect-theme", "fira-sans", "tiny-skia", "wgpu", "sipper"]} iced = {"git"= "https://github.com/iced-rs/iced.git", "features"=["tokio", "auto-detect-theme", "fira-sans", "tiny-skia", "wgpu", "sipper"]}
lazy_static = "1.5.0"
nusb = "0.1.13" nusb = "0.1.13"
serde = {version = "1.0.219", features=["derive"]} serde = {version = "1.0.219", features=["derive"]}
serde_json = "1.0.140" serde_json = "1.0.140"
tokio = {version = "1.45.0", features=["time"]} tokio = {version = "1.45.0", features=["time", "fs", "io-util", "macros"]}

View File

@ -1,16 +1,18 @@
use iced::time::{self, Duration, Instant, milliseconds}; use iced::time::{self, Duration, Instant, milliseconds, seconds};
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt::{Formatter, Error}; use std::fmt::{Formatter, Error as fmtError};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use iced::widget::{center, column, row, text}; use iced::widget::{center, column, row, text};
use iced::{Element, Subscription, Theme, Center}; use iced::{Element, Subscription, Theme, Center, Task};
use tokio::fs::File;
use tokio::io::AsyncWriteExt;
mod card_reader; mod card_reader;
mod approx_time; mod approx_time;
mod config;
use config::CONFIG;
static DURATION: u64 = 60;
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
struct RacerTime{ struct RacerTime{
#[serde(with = "approx_time")] #[serde(with = "approx_time")]
@ -36,33 +38,49 @@ impl Default for State {
} }
} }
async fn dump_state(json: String) -> Result<(), tokio::io::Error> {
let mut file = File::create("state.json").await?;
file.write_all(json.as_bytes()).await?;
Ok(())
}
impl State{ impl State{
fn update(&mut self, message: Message){ fn update(&mut self, message: Message) -> Task<Message>{
match message { match message {
Message::RacerAdded(racer) => { Message::RacerAdded(racer) => {
self.db.insert(racer.card_id, racer); self.db.insert(racer.card_id, racer);
Task::none()
}, },
Message::Tick(time) => { Message::Tick(time) => {
if let Some(racer_time) = self.racers.iter().next() { if let Some(racer_time) = self.racers.iter().next() {
if time - racer_time.time > Duration::new(DURATION + 10, 0){ if time - racer_time.time > Duration::new(CONFIG.DURATION + 10, 0){
self.racers.remove(0); self.racers.remove(0);
} }
} }
self.time = time; self.time = time;
Task::none()
}, },
Message::DumpState(_) => {
let json = serde_json::to_string(self).unwrap();
Task::perform(dump_state(json), |_| Message::Nothing)
},
Message::Nothing => Task::none(),
Message::CardReader(card_reader::Event::ReadedCardId(card_id)) => { Message::CardReader(card_reader::Event::ReadedCardId(card_id)) => {
if let Some(racer) = self.db.get(&card_id){ if let Some(racer) = self.db.get(&card_id){
self.racers.push(RacerTime{time: Instant::now(), racer: racer.clone()}) self.racers.push(RacerTime{time: Instant::now(), racer: racer.clone()})
}else{ }else{
println!("Racer {} not found in db!", card_id) println!("Racer {} not found in db!", card_id)
} };
Task::none()
}, },
Message::CardReader(card_reader::Event::Connected) => { Message::CardReader(card_reader::Event::Connected) => {
println!("Card Reader Connected!") println!("Card Reader Connected!");
} Task::none()
},
Message::CardReader(card_reader::Event::Disconnected) => { Message::CardReader(card_reader::Event::Disconnected) => {
println!("Card Reader Disconnected!") println!("Card Reader Disconnected!");
} Task::none()
},
} }
} }
fn view(&self) -> Element<Message> { fn view(&self) -> Element<Message> {
@ -76,7 +94,7 @@ impl State{
let time = self.time - racer_time.time; let time = self.time - racer_time.time;
let duration = Duration::new(DURATION, 0); let duration = Duration::new(CONFIG.DURATION, 0);
let (duration, negative) = if duration < time { let (duration, negative) = if duration < time {
(time - duration, true) (time - duration, true)
} else { } else {
@ -104,7 +122,8 @@ impl State{
fn subscription(&self) -> Subscription<Message> { fn subscription(&self) -> Subscription<Message> {
Subscription::batch(vec![ Subscription::batch(vec![
time::every(milliseconds(10)).map(Message::Tick), time::every(milliseconds(10)).map(Message::Tick),
Subscription::run(card_reader::connect).map(Message::CardReader) time::every(seconds(CONFIG.SAVING_INTERVAL)).map(Message::DumpState),
Subscription::run(card_reader::connect).map(Message::CardReader),
]) ])
} }
fn theme(&self) -> Theme { fn theme(&self) -> Theme {
@ -122,11 +141,13 @@ enum Message{
CardReader(card_reader::Event), CardReader(card_reader::Event),
RacerAdded(Racer), RacerAdded(Racer),
Tick(Instant), Tick(Instant),
DumpState(Instant),
Nothing,
} }
impl std::fmt::Debug for Message { impl std::fmt::Debug for Message {
// Required method // Required method
fn fmt(&self, _f: &mut Formatter<'_>) -> Result<(), Error>{ fn fmt(&self, _f: &mut Formatter<'_>) -> Result<(), fmtError>{
todo!() todo!()
} }
} }