Cleanup and properly parse parameters

This commit is contained in:
Austen Adler 2021-08-10 17:44:03 -04:00
parent fd231adec9
commit 2ac7947786
4 changed files with 39 additions and 35 deletions

View File

@ -61,7 +61,9 @@ fn main() -> Result<(), ProgramError> {
// I do not care if the web ui crashes // I do not care if the web ui crashes
let _web_ui_handle = thread::spawn(move || -> Result<(), io::Error> { let _web_ui_handle = thread::spawn(move || -> Result<(), io::Error> {
webui::start(h) let ret = webui::start(h);
println!("Webui dead");
ret
// TODO: Do not join -- this is just because we are running on a computer with no spi env // TODO: Do not join -- this is just because we are running on a computer with no spi env
}) })
.join()?; .join()?;

View File

@ -15,24 +15,32 @@ pub use orb::Orb;
pub use solid::Solid; pub use solid::Solid;
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
enum PatternParameters {
Collide(Rgb, Rgb, Rgb),
}
pub enum PatternParameters { pub enum PatternParameters {
Collide(Rgb, Rgb, Rgb), Collide(Rgb, Rgb, Rgb),
Fade(Rgb), Fade((Rgb,)),
MovingPixel(Rgb), MovingPixel((Rgb,)),
MovingRainbow(u8, bool), MovingRainbow(u8, bool),
Orb(Rgb, u8, u8), Orb(Rgb, u8, u8),
Solid(Rgb), Solid((Rgb,)),
} }
pub trait Pattern: std::fmt::Debug { impl PatternParameters {
pub fn to_pattern(&self) -> Box<dyn Pattern + Send + Sync> {
match self {
PatternParameters::Collide(l, r, c) => Box::new(Collide::new(*l, *r, *c)),
PatternParameters::Fade((c,)) => Box::new(Fade::new(*c)),
PatternParameters::MovingPixel((c,)) => Box::new(MovingPixel::new(*c)),
PatternParameters::MovingRainbow(w, f) => Box::new(MovingRainbow::new(*w, *f)),
PatternParameters::Orb(c, x, y) => Box::new(Orb::new(*c, *x, *y)),
PatternParameters::Solid((c,)) => Box::new(Solid::new(*c)),
}
}
}
pub trait Pattern: std::fmt::Debug + Send + Sync {
fn init(&mut self, num_lights: u16) -> Result<(), ()>; fn init(&mut self, num_lights: u16) -> Result<(), ()>;
fn step(&mut self) -> Result<bool, ()>; fn step(&mut self) -> Result<bool, ()>;
fn get_strip(&self) -> &[Rgb]; fn get_strip(&self) -> &[Rgb];
// fn get_strip_mut(&mut self) -> &[Rgb];
} }
// #[cfg(test)] // #[cfg(test)]

View File

@ -26,7 +26,7 @@ impl Pattern for MovingPixel {
let len = self.num_lights; let len = self.num_lights;
self.lights_buf.swap( self.lights_buf.swap(
self.step.rem_euclid(len).into(), self.step.rem_euclid(len).into(),
self.step.saturating_add(1).saturating_mul(3).into(), self.step.saturating_add(1).rem_euclid(len).into(),
); );
self.step = self.step.wrapping_add(1); self.step = self.step.wrapping_add(1);
Ok(true) Ok(true)

View File

@ -1,21 +1,25 @@
use crate::color::Rgb; use crate::color::Rgb;
use crate::pattern; use crate::pattern;
use crate::strip; use crate::strip;
use actix_web::web::Form; use actix_web::web::{Form, JsonConfig};
use actix_web::{get, post, web, App, HttpRequest, HttpServer, Responder, Result}; use actix_web::{get, post, web, App, HttpRequest, HttpServer, Responder, Result};
// use actix_web::error::InternalError; // use actix_web::error::InternalError;
use actix_web_static_files;
use pattern::{Pattern, PatternParameters};
use rust_embed::RustEmbed; use rust_embed::RustEmbed;
use serde::Deserialize; use serde::Deserialize;
use std::io; use std::io;
use std::str::FromStr; use std::str::FromStr;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
include!(concat!(env!("OUT_DIR"), "/generated.rs"));
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
// TODO: Pre-compute binary somehow? So do not have to unwrap // TODO: Pre-compute binary somehow? So do not have to unwrap
#[derive(RustEmbed)] // #[derive(RustEmbed)]
#[folder = "html/"] // #[folder = "html/"]
struct Asset; // struct Asset;
struct AppState { struct AppState {
strip_tx: Arc<Mutex<Sender<strip::Message>>>, strip_tx: Arc<Mutex<Sender<strip::Message>>>,
@ -32,20 +36,14 @@ async fn set_color(
data: web::Data<AppState>, data: web::Data<AppState>,
params: web::Json<PatternParameters>, params: web::Json<PatternParameters>,
) -> Result<impl Responder> { ) -> Result<impl Responder> {
println!("{:?}", params); println!("Got params: {:?}", params);
let pattern = match params.0 {
PatternParameters::Collide(l, r, c) => pattern::Collide::new(l, r, c),
};
data.strip_tx data.strip_tx
.lock() .lock()
.or(Err(io::Error::new( .or(Err(io::Error::new(
io::ErrorKind::Other, io::ErrorKind::Other,
"Failed to get a lock", "Failed to get a lock",
)))? )))?
.send(strip::Message::ChangePattern(Box::new( .send(strip::Message::ChangePattern(params.0.to_pattern()))
// pattern::Solid::new(Rgb::from_str(&params.color).or(Err(io::Error::new(io::ErrorKind::Other, "Failed to parse")))?),
pattern,
)))
.or(Err(io::Error::new( .or(Err(io::Error::new(
io::ErrorKind::Other, io::ErrorKind::Other,
"Failed to send to channel", "Failed to send to channel",
@ -53,27 +51,23 @@ async fn set_color(
Ok(format!("{:?}", params)) Ok(format!("{:?}", params))
} }
#[get("/")]
async fn index(_data: web::Data<AppState>, _req: HttpRequest) -> impl Responder {
// TODO: This is probably the ugliest possible way to do it. Make this better
String::from_utf8((&Asset::get("index.html").unwrap().data).to_vec()).unwrap()
}
#[actix_web::main] #[actix_web::main]
pub async fn start(tx: Sender<strip::Message>) -> std::io::Result<()> { pub async fn start(tx: Sender<strip::Message>) -> std::io::Result<()> {
println!("Starting webui"); println!("Starting webui");
HttpServer::new(move || { HttpServer::new(move || {
let generated = generate();
App::new() App::new()
.data(AppState { .data(AppState {
strip_tx: Arc::new(Mutex::new(tx.clone())), strip_tx: Arc::new(Mutex::new(tx.clone())),
}) })
.service(index) .service(
.service(set_color) web::scope("/api")
// App::new() // .app_data(JsonConfig::default())
// .route("/", web::get().to(greet)) .service(set_color),
// .route("/{name}", web::get().to(greet)) )
.service(actix_web_static_files::ResourceFiles::new("/", generated))
}) })
.bind(("127.0.0.1", 8080))? .bind(("0.0.0.0", 8080))?
.run() .run()
.await .await
} }