From 0fff587c892ef00e1f708febd6f983e8cdd7f10f Mon Sep 17 00:00:00 2001 From: Slendi Date: Sat, 28 Mar 2026 02:32:16 +0200 Subject: [PATCH] Serial thread and tx channel, more App state work Signed-off-by: Slendi --- src/main.rs | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 84 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index bcb63ea..220d443 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,18 @@ +use std::{ + sync::{ + Arc, Mutex, + mpsc::{self, Receiver, Sender}, + }, + thread::{self, Thread}, + time::Duration, +}; + use anyhow::{Result, anyhow}; -use macroquad::color::*; +use macroquad::{ + color::*, + miniquad::{error, info}, +}; +use midly::Smf; use serialport::SerialPortType; #[derive(Clone, Copy, Debug)] @@ -133,14 +146,81 @@ impl Song { pattern_order: Vec::new(), } } + + pub fn from_midi(_smf: Smf) -> Result { + todo!("TBD"); + } } -#[derive(Default)] -struct App {} +struct AppSongState { + pub song: Song, + pub current_pattern: usize, + pub current_row: usize, + pub current_column: u8, + pub playing: bool, +} + +pub enum SerialCommand { + Instruction(u8, Instruction), + Stop, +} + +struct App { + song_state: Option, + tx: Sender, +} impl App { pub fn new() -> Self { - Self { ..App::default() } + let (tx, rx) = mpsc::channel(); + Self::spawn_serial_worker(rx); + Self { + song_state: None, + tx, + } + } + + fn spawn_serial_worker(rx: Receiver) { + thread::spawn(move || { + let mut device: Option = None; + loop { + if device.is_none() { + match SerialDevice::new() { + Ok(new_device) => { + info!("Serial device connected"); + device = Some(new_device); + } + Err(_err) => { + thread::sleep(Duration::from_secs(1)); + continue; + } + } + } + + match rx.recv_timeout(Duration::from_millis(100)) { + Ok(command) => { + if let Some(dev) = device.as_mut() { + match command { + SerialCommand::Instruction(ch, instr) => { + if let Err(e) = dev.execute(ch, instr) { + error!("Disconnected: {e}"); + device = None; + } + } + SerialCommand::Stop => { + if let Err(e) = dev.stop() { + error!("Disconnected: {e}"); + device = None; + } + } + } + } + } + Err(mpsc::RecvTimeoutError::Timeout) => {} + Err(_) => break, + } + } + }); } pub async fn run(&self) {