Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
2759
Cargo.lock
generated
2759
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||||
|
|||||||
@@ -74,6 +74,8 @@
|
|||||||
|
|
||||||
commonNativeBuildInputs = with pkgs; [
|
commonNativeBuildInputs = with pkgs; [
|
||||||
pkg-config
|
pkg-config
|
||||||
|
cmake
|
||||||
|
python312
|
||||||
makeWrapper
|
makeWrapper
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
107
src/main.rs
107
src/main.rs
@@ -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);
|
fn draw(&mut self, gfx: &mut Graphics) {
|
||||||
|
let mut draw = gfx.create_draw();
|
||||||
|
draw.clear(Color::WHITE);
|
||||||
|
|
||||||
macroquad::shapes::draw_line(40.0, 40.0, 100.0, 200.0, 15.0, BLUE);
|
draw.line((40.0, 40.0), (100.0, 200.0))
|
||||||
macroquad::shapes::draw_rectangle(
|
.width(15.0)
|
||||||
macroquad::window::screen_width() / 2.0 - 60.0,
|
.color(Color::BLUE);
|
||||||
100.0,
|
draw.rect((220.0, 100.0), (120.0, 60.0)).color(Color::GREEN);
|
||||||
120.0,
|
|
||||||
60.0,
|
|
||||||
GREEN,
|
|
||||||
);
|
|
||||||
|
|
||||||
macroquad::text::draw_text(
|
let status_color = if self.connected.is_some() {
|
||||||
match &self.connected {
|
Color::GREEN
|
||||||
Some(name) => &name,
|
} else {
|
||||||
None => "Serial disconnected",
|
Color::GRAY
|
||||||
},
|
};
|
||||||
20.0,
|
draw.rect((14.0, 14.0), (20.0, 20.0)).color(status_color);
|
||||||
20.0,
|
|
||||||
30.0,
|
|
||||||
DARKGRAY,
|
|
||||||
);
|
|
||||||
|
|
||||||
macroquad::window::next_frame().await
|
gfx.render(&draw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn window_conf() -> macroquad::prelude::Conf {
|
fn setup(_gfx: &mut Graphics) -> SingerApp {
|
||||||
let mut conf = macroquad::prelude::Conf::default();
|
SingerApp::new()
|
||||||
conf.fullscreen = true;
|
|
||||||
conf.platform.linux_backend = LinuxBackend::WaylandWithX11Fallback;
|
|
||||||
conf
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macroquad::main(window_conf)]
|
fn update(_app: &mut notan::app::App, state: &mut SingerApp) {
|
||||||
async fn main() {
|
state.update();
|
||||||
let mut app = App::new();
|
}
|
||||||
app.run().await;
|
|
||||||
|
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()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user