Update orb
This commit is contained in:
parent
7987c1796c
commit
17b9f8ed66
@ -96,7 +96,7 @@ pub fn merge_colors(from_color: Rgb, to_color: Rgb, factor: f32) -> Rgb {
|
|||||||
|
|
||||||
/// Builds a color ramp of length `length` of the (exclusive) bounds of `from_color` to `to_color`
|
/// Builds a color ramp of length `length` of the (exclusive) bounds of `from_color` to `to_color`
|
||||||
pub fn build_ramp(from_color: Rgb, to_color: Rgb, length: usize) -> Vec<Rgb> {
|
pub fn build_ramp(from_color: Rgb, to_color: Rgb, length: usize) -> Vec<Rgb> {
|
||||||
let offset = 1.0f32 / (length as f32 + 1.0f32);
|
let offset = 1.0_f32 / (length as f32 + 1.0_f32);
|
||||||
let mut ret: Vec<Rgb> = vec![];
|
let mut ret: Vec<Rgb> = vec![];
|
||||||
for step in 1..=length {
|
for step in 1..=length {
|
||||||
ret.push(merge_colors(from_color, to_color, offset * step as f32));
|
ret.push(merge_colors(from_color, to_color, offset * step as f32));
|
||||||
|
@ -56,13 +56,16 @@ fn main() -> Result<(), ProgramError> {
|
|||||||
|
|
||||||
// I do not care if the console ui crashes
|
// I do not care if the console ui crashes
|
||||||
let (g, h) = (tx.clone(), tx.clone());
|
let (g, h) = (tx.clone(), tx.clone());
|
||||||
let _console_ui_handle =
|
let _console_ui_handle = thread::spawn(move || -> Result<(), ProgramError> {
|
||||||
thread::spawn(move || -> Result<(), ProgramError> { console_ui_loop(&g) });
|
let ret = console_ui_loop(&g);
|
||||||
|
println!("Console ui dead: {:?}", ret);
|
||||||
|
ret
|
||||||
|
});
|
||||||
|
|
||||||
// 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> {
|
||||||
let ret = webui::start(h);
|
let ret = webui::start(h);
|
||||||
println!("Webui dead");
|
println!("Webui dead: {:?}", ret);
|
||||||
ret
|
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
|
||||||
})
|
})
|
||||||
|
@ -1,46 +1,64 @@
|
|||||||
use super::Pattern;
|
use super::Pattern;
|
||||||
use crate::color::{self, Rgb};
|
use crate::color::{self, Rgb};
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Orb {
|
pub struct Orb {
|
||||||
lights_buf: Vec<Rgb>,
|
/// Buffer to manage the lights
|
||||||
|
lights_buf: VecDeque<Rgb>,
|
||||||
|
/// The color of the orb
|
||||||
color: Rgb,
|
color: Rgb,
|
||||||
|
/// The width of the center of the orb
|
||||||
center_width: u8,
|
center_width: u8,
|
||||||
|
/// The width of each side's backoff (fadeout)
|
||||||
backoff_width: u8,
|
backoff_width: u8,
|
||||||
|
/// The total width of the orb, equal to center_width + 2*backoff_width
|
||||||
total_width: u8,
|
total_width: u8,
|
||||||
|
/// True if the orb should bounce from left to right, otherwise it will wrap around
|
||||||
bounces: bool,
|
bounces: bool,
|
||||||
step: isize,
|
/// The state of the program
|
||||||
|
step: usize,
|
||||||
|
/// The maximum number of steps for a given direction. The orb will turn around after this many steps
|
||||||
|
step_max: usize,
|
||||||
|
/// Direction of the orb. This can switch if `bounces` is true
|
||||||
direction: bool,
|
direction: bool,
|
||||||
}
|
}
|
||||||
impl Orb {
|
impl Orb {
|
||||||
pub const fn new(color: Rgb, center_width: u8, backoff_width: u8) -> Self {
|
pub const fn new(color: Rgb, center_width: u8, backoff_width: u8) -> Self {
|
||||||
Self {
|
Self {
|
||||||
lights_buf: vec![],
|
lights_buf: VecDeque::new(),
|
||||||
color,
|
color,
|
||||||
center_width,
|
center_width,
|
||||||
backoff_width,
|
backoff_width,
|
||||||
total_width: center_width + backoff_width * 2,
|
total_width: center_width + backoff_width * 2,
|
||||||
bounces: false,
|
bounces: false,
|
||||||
step: 0,
|
step: 0,
|
||||||
|
step_max: 0,
|
||||||
direction: true,
|
direction: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Pattern for Orb {
|
impl Pattern for Orb {
|
||||||
fn step(&mut self) -> Result<bool, ()> {
|
fn step(&mut self) -> Result<bool, ()> {
|
||||||
if self.direction {
|
if !self.bounces {
|
||||||
|
// If we don't bounce, then just wrap and we're done
|
||||||
self.lights_buf.rotate_right(1);
|
self.lights_buf.rotate_right(1);
|
||||||
self.step += 1;
|
return Ok(true);
|
||||||
} else {
|
|
||||||
self.lights_buf.rotate_left(1);
|
|
||||||
self.step -= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if step == 0 {
|
if self.direction {
|
||||||
self.direction = true;
|
self.lights_buf.rotate_right(1);
|
||||||
} else if self.lights_buf - self.step == self.total_width {
|
self.step = self.step.saturating_add(1);
|
||||||
self.direction = false;
|
} else {
|
||||||
|
self.lights_buf.rotate_left(1);
|
||||||
|
self.step = self.step.saturating_sub(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.step == self.step_max || self.step == 0 {
|
||||||
|
self.direction = !self.direction;
|
||||||
|
// } else if self.lights_buf - self.step == self.total_width {
|
||||||
|
// self.direction = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
@ -62,6 +80,13 @@ impl Pattern for Orb {
|
|||||||
.take(num_lights.saturating_sub(self.total_width.into()).into()),
|
.take(num_lights.saturating_sub(self.total_width.into()).into()),
|
||||||
)
|
)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
self.step_max = self
|
||||||
|
.lights_buf
|
||||||
|
.len()
|
||||||
|
.checked_sub(self.total_width.into())
|
||||||
|
.unwrap_or(self.lights_buf.len());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn get_strip(&self) -> &[Rgb] {
|
fn get_strip(&self) -> &[Rgb] {
|
||||||
|
22
src/webui.rs
22
src/webui.rs
@ -1,8 +1,8 @@
|
|||||||
use crate::pattern;
|
use crate::pattern;
|
||||||
use crate::strip;
|
use crate::strip;
|
||||||
// use actix_web::web::JsonConfig;
|
use actix_web::error::{ErrorBadRequest, JsonPayloadError};
|
||||||
|
use actix_web::web::JsonConfig;
|
||||||
use actix_web::{post, web, App, HttpServer, Responder, Result};
|
use actix_web::{post, web, App, HttpServer, Responder, Result};
|
||||||
// use actix_web::error::InternalError;
|
|
||||||
use actix_web_static_files;
|
use actix_web_static_files;
|
||||||
use pattern::PatternParameters;
|
use pattern::PatternParameters;
|
||||||
use std::io;
|
use std::io;
|
||||||
@ -12,21 +12,10 @@ 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
|
|
||||||
// #[derive(RustEmbed)]
|
|
||||||
// #[folder = "html/"]
|
|
||||||
// struct Asset;
|
|
||||||
|
|
||||||
struct AppState {
|
struct AppState {
|
||||||
strip_tx: Arc<Mutex<Sender<strip::Message>>>,
|
strip_tx: Arc<Mutex<Sender<strip::Message>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[derive(Deserialize, Debug)]
|
|
||||||
// struct ColorForm {
|
|
||||||
// color: String,
|
|
||||||
// e: E
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[post("/setcolor")]
|
#[post("/setcolor")]
|
||||||
async fn set_color(
|
async fn set_color(
|
||||||
data: web::Data<AppState>,
|
data: web::Data<AppState>,
|
||||||
@ -58,7 +47,12 @@ pub async fn start(tx: Sender<strip::Message>) -> std::io::Result<()> {
|
|||||||
})
|
})
|
||||||
.service(
|
.service(
|
||||||
web::scope("/api")
|
web::scope("/api")
|
||||||
// .app_data(JsonConfig::default())
|
.app_data(
|
||||||
|
JsonConfig::default().error_handler(|err: JsonPayloadError, _req| {
|
||||||
|
println!("JSON error: {:?}", err);
|
||||||
|
err.into()
|
||||||
|
}),
|
||||||
|
)
|
||||||
.service(set_color),
|
.service(set_color),
|
||||||
)
|
)
|
||||||
.service(actix_web_static_files::ResourceFiles::new("/", generated))
|
.service(actix_web_static_files::ResourceFiles::new("/", generated))
|
||||||
|
Loading…
Reference in New Issue
Block a user