Move to notam from macroquad
Some checks failed
Build project / Build (push) Failing after 2m5s

Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
2026-03-28 15:32:11 +02:00
parent 5656d3d424
commit 54538dcd2a
4 changed files with 2722 additions and 152 deletions

2759
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,6 +5,6 @@ edition = "2024"
[dependencies] [dependencies]
anyhow = "1.0.102" anyhow = "1.0.102"
macroquad = { version = "0.4.14", features = ["log-rs"] } notan = "0.14.0"
midly = "0.5.3" midly = "0.5.3"
serialport = "4.9.0" serialport = "4.9.0"

View File

@@ -74,6 +74,8 @@
commonNativeBuildInputs = with pkgs; [ commonNativeBuildInputs = with pkgs; [
pkg-config pkg-config
cmake
python312
makeWrapper makeWrapper
]; ];

View File

@@ -4,15 +4,9 @@ use std::{
time::Duration, time::Duration,
}; };
use anyhow::{Result, anyhow}; use anyhow::{anyhow, Result};
use macroquad::{
color::*,
miniquad::{
conf::LinuxBackend,
error, info,
},
};
use midly::Smf; use midly::Smf;
use notan::{draw::*, prelude::*};
use serialport::SerialPortType; use serialport::SerialPortType;
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
@@ -170,14 +164,15 @@ pub enum SerialStatus {
SerialDisconnected, SerialDisconnected,
} }
struct App { #[derive(AppState)]
struct SingerApp {
song_state: Option<AppSongState>, song_state: Option<AppSongState>,
tx: Sender<SerialCommand>, tx: Sender<SerialCommand>,
rx: Receiver<SerialStatus>, rx: Receiver<SerialStatus>,
connected: Option<String>, connected: Option<String>,
} }
impl App { impl SingerApp {
pub fn new() -> Self { pub fn new() -> Self {
let (tx_cmd, rx_cmd) = mpsc::channel(); let (tx_cmd, rx_cmd) = mpsc::channel();
let (tx_status, rx_status) = mpsc::channel(); let (tx_status, rx_status) = mpsc::channel();
@@ -198,15 +193,12 @@ impl App {
if device.is_none() { if device.is_none() {
match SerialDevice::new() { match SerialDevice::new() {
Ok(new_device) => { Ok(new_device) => {
info!("Serial device connected"); let name = new_device
let _ = tx.send(SerialStatus::SerialConnected {
name: device
.as_ref()
.unwrap()
.port .port
.name() .name()
.unwrap_or("<unknown serial port>".to_string()), .unwrap_or("<unknown serial port>".to_string());
}); println!("Serial device connected: {name}");
let _ = tx.send(SerialStatus::SerialConnected { name });
device = Some(new_device); device = Some(new_device);
} }
Err(_err) => { Err(_err) => {
@@ -222,14 +214,14 @@ impl App {
match command { match command {
SerialCommand::Instruction(ch, instr) => { SerialCommand::Instruction(ch, instr) => {
if let Err(e) = dev.execute(ch, instr) { if let Err(e) = dev.execute(ch, instr) {
error!("Disconnected: {e}"); eprintln!("Disconnected: {e}");
device = None; device = None;
let _ = tx.send(SerialStatus::SerialDisconnected); let _ = tx.send(SerialStatus::SerialDisconnected);
} }
} }
SerialCommand::Stop => { SerialCommand::Stop => {
if let Err(e) = dev.stop() { if let Err(e) = dev.stop() {
error!("Disconnected: {e}"); eprintln!("Disconnected: {e}");
device = None; device = None;
let _ = tx.send(SerialStatus::SerialDisconnected); let _ = tx.send(SerialStatus::SerialDisconnected);
} }
@@ -244,56 +236,53 @@ impl App {
}); });
} }
pub async fn run(&mut self) { fn update(&mut self) {
loop { while let Ok(status) = self.rx.try_recv() {
self.update().await; match status {
}
}
async fn update(&mut self) {
match self.rx.recv_timeout(Duration::from_millis(100)) {
Ok(status) => match status {
SerialStatus::SerialDisconnected => self.connected = None, SerialStatus::SerialDisconnected => self.connected = None,
SerialStatus::SerialConnected { name } => self.connected = Some(name), SerialStatus::SerialConnected { name } => self.connected = Some(name),
},
_ => {}
} }
macroquad::window::clear_background(WHITE);
macroquad::shapes::draw_line(40.0, 40.0, 100.0, 200.0, 15.0, BLUE);
macroquad::shapes::draw_rectangle(
macroquad::window::screen_width() / 2.0 - 60.0,
100.0,
120.0,
60.0,
GREEN,
);
macroquad::text::draw_text(
match &self.connected {
Some(name) => &name,
None => "Serial disconnected",
},
20.0,
20.0,
30.0,
DARKGRAY,
);
macroquad::window::next_frame().await
} }
} }
fn window_conf() -> macroquad::prelude::Conf { fn draw(&mut self, gfx: &mut Graphics) {
let mut conf = macroquad::prelude::Conf::default(); let mut draw = gfx.create_draw();
conf.fullscreen = true; draw.clear(Color::WHITE);
conf.platform.linux_backend = LinuxBackend::WaylandWithX11Fallback;
conf draw.line((40.0, 40.0), (100.0, 200.0))
.width(15.0)
.color(Color::BLUE);
draw.rect((220.0, 100.0), (120.0, 60.0)).color(Color::GREEN);
let status_color = if self.connected.is_some() {
Color::GREEN
} else {
Color::GRAY
};
draw.rect((14.0, 14.0), (20.0, 20.0)).color(status_color);
gfx.render(&draw);
}
} }
#[macroquad::main(window_conf)] fn setup(_gfx: &mut Graphics) -> SingerApp {
async fn main() { SingerApp::new()
let mut app = App::new(); }
app.run().await;
fn update(_app: &mut notan::app::App, state: &mut SingerApp) {
state.update();
}
fn draw(gfx: &mut Graphics, state: &mut SingerApp) {
state.draw(gfx);
}
#[notan_main]
fn main() -> Result<(), String> {
notan::init_with(setup)
.add_config(WindowConfig::new().set_title("singer").set_fullscreen(true))
.add_config(DrawConfig)
.update(update)
.draw(draw)
.build()
} }