This commit is contained in:
parent
df820fa7d8
commit
8f915d1020
142
src/render.rs
142
src/render.rs
@ -1,16 +1,16 @@
|
|||||||
use ws281x_rpi::Ws2812Rpi;
|
use ws281x_rpi::Ws2812Rpi;
|
||||||
|
|
||||||
use crate::{DBPool, animations::Animation};
|
use crate::{animations::Animation, DBPool};
|
||||||
|
|
||||||
|
use smart_leds::{SmartLedsWrite, RGB, RGB8};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use smart_leds::{RGB8, SmartLedsWrite, RGB};
|
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct LocalLedConfiguration {
|
struct LocalLedConfiguration {
|
||||||
tag: Option<String>,
|
tag: Option<String>,
|
||||||
start: usize,
|
start: usize,
|
||||||
end: usize
|
end: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -24,7 +24,7 @@ pub struct LigthSetting {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct KeyFrame {
|
pub struct KeyFrame {
|
||||||
duration: u128,
|
duration: u128,
|
||||||
settings: Vec<LigthSetting>
|
settings: Vec<LigthSetting>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -60,11 +60,15 @@ struct GetRender {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn try_into_usize(input: Option<u32>) -> Option<usize> {
|
fn try_into_usize(input: Option<u32>) -> Option<usize> {
|
||||||
if input.is_none() {return None;}
|
if input.is_none() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
let t: Result<usize, _> = input.unwrap().try_into();
|
let t: Result<usize, _> = input.unwrap().try_into();
|
||||||
|
|
||||||
if t.is_err() {return None;}
|
if t.is_err() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
return t.ok();
|
return t.ok();
|
||||||
}
|
}
|
||||||
@ -100,25 +104,31 @@ impl Render {
|
|||||||
let stmt = conn.prepare("SELECT ledcount, tags from configuration;");
|
let stmt = conn.prepare("SELECT ledcount, tags from configuration;");
|
||||||
|
|
||||||
if stmt.is_err() || stmt.as_ref().ok().is_none() {
|
if stmt.is_err() || stmt.as_ref().ok().is_none() {
|
||||||
Err(format!("Something went wrong while reading the database {:?}", stmt.as_ref().err()))?;
|
Err(format!(
|
||||||
|
"Something went wrong while reading the database {:?}",
|
||||||
|
stmt.as_ref().err()
|
||||||
|
))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut stmt = stmt?;
|
let mut stmt = stmt?;
|
||||||
|
|
||||||
struct Data {
|
struct Data {
|
||||||
ledcount: u32,
|
ledcount: u32,
|
||||||
tag: String
|
tag: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
let version_iter = stmt.query_map([], |row| {
|
let version_iter = stmt.query_map([], |row| {
|
||||||
Ok(Data {
|
Ok(Data {
|
||||||
ledcount: row.get(0)?,
|
ledcount: row.get(0)?,
|
||||||
tag: row.get(1)?
|
tag: row.get(1)?,
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
if version_iter.is_err() || version_iter.as_ref().ok().is_none() {
|
if version_iter.is_err() || version_iter.as_ref().ok().is_none() {
|
||||||
Err(format!("Something went wrong while reading the database {:?}", version_iter.as_ref().err()))?;
|
Err(format!(
|
||||||
|
"Something went wrong while reading the database {:?}",
|
||||||
|
version_iter.as_ref().err()
|
||||||
|
))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let version_iter = version_iter.ok().unwrap();
|
let version_iter = version_iter.ok().unwrap();
|
||||||
@ -128,10 +138,13 @@ impl Render {
|
|||||||
let mut local_led_config = Vec::new();
|
let mut local_led_config = Vec::new();
|
||||||
|
|
||||||
for data in version_iter {
|
for data in version_iter {
|
||||||
|
|
||||||
let data = data?;
|
let data = data?;
|
||||||
|
|
||||||
let tag = if data.tag.is_empty() { None } else { Some(data.tag) };
|
let tag = if data.tag.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(data.tag)
|
||||||
|
};
|
||||||
|
|
||||||
let start = current_pos;
|
let start = current_pos;
|
||||||
let end = current_pos + data.ledcount;
|
let end = current_pos + data.ledcount;
|
||||||
@ -148,15 +161,14 @@ impl Render {
|
|||||||
let start = start.ok().unwrap();
|
let start = start.ok().unwrap();
|
||||||
let end = end.ok().unwrap();
|
let end = end.ok().unwrap();
|
||||||
|
|
||||||
local_led_config.push(LocalLedConfiguration {
|
local_led_config.push(LocalLedConfiguration { tag, start, end });
|
||||||
tag,
|
|
||||||
start,
|
|
||||||
end
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.num_leds = current_pos;
|
self.num_leds = current_pos;
|
||||||
println!("Loaded: {} leds, with config: {:?}", self.num_leds, local_led_config);
|
println!(
|
||||||
|
"Loaded: {} leds, with config: {:?}",
|
||||||
|
self.num_leds, local_led_config
|
||||||
|
);
|
||||||
self.local_led_config = local_led_config;
|
self.local_led_config = local_led_config;
|
||||||
|
|
||||||
self.ws = Some(Ws2812Rpi::new(current_pos as i32, PIN).unwrap());
|
self.ws = Some(Ws2812Rpi::new(current_pos as i32, PIN).unwrap());
|
||||||
@ -165,7 +177,6 @@ impl Render {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_animation(&mut self, animation: Animation) {
|
pub fn add_animation(&mut self, animation: Animation) {
|
||||||
|
|
||||||
println!("Added animation");
|
println!("Added animation");
|
||||||
|
|
||||||
let mut key_frames = Vec::new();
|
let mut key_frames = Vec::new();
|
||||||
@ -182,7 +193,10 @@ impl Render {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
key_frames.push(KeyFrame { duration: (frame.get_duration() as u128) * (1000 as u128), settings: light_settings })
|
key_frames.push(KeyFrame {
|
||||||
|
duration: (frame.get_duration() as u128) * (1000 as u128),
|
||||||
|
settings: light_settings,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let new_animation = RenderAnimation {
|
let new_animation = RenderAnimation {
|
||||||
@ -196,7 +210,8 @@ impl Render {
|
|||||||
|
|
||||||
self.animations.push(new_animation);
|
self.animations.push(new_animation);
|
||||||
|
|
||||||
self.animations.sort_by(|a,b| a.priority.partial_cmp(&b.priority).unwrap())
|
self.animations
|
||||||
|
.sort_by(|a, b| a.priority.partial_cmp(&b.priority).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn blank(&mut self) {
|
pub fn blank(&mut self) {
|
||||||
@ -204,17 +219,18 @@ impl Render {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_animation(&mut self, animation_name: String) {
|
pub fn remove_animation(&mut self, animation_name: String) {
|
||||||
self.animations = self.animations.clone().into_iter().filter(|ani| !ani.name.eq(&animation_name)).collect::<Vec<RenderAnimation>>();
|
self.animations = self
|
||||||
|
.animations
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.filter(|ani| !ani.name.eq(&animation_name))
|
||||||
|
.collect::<Vec<RenderAnimation>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn proccess_settings(&mut self, data: &mut Vec<RGB<f64>>, settings: &Vec<LigthSetting>) {
|
pub fn proccess_settings(&mut self, data: &mut Vec<RGB<f64>>, settings: &Vec<LigthSetting>) {
|
||||||
fn load_led_into_light(data: &mut Vec<RGB<f64>>, color: RGB8, start: usize, end: usize) {
|
fn load_led_into_light(data: &mut Vec<RGB<f64>>, color: RGB8, start: usize, end: usize) {
|
||||||
for i in start..=end {
|
for i in start..=end {
|
||||||
data[i] = RGB::new(
|
data[i] = RGB::new(color.r as f64, color.g as f64, color.b as f64);
|
||||||
color.r as f64,
|
|
||||||
color.g as f64,
|
|
||||||
color.b as f64
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,16 +247,23 @@ impl Render {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if setting.start.is_some() && setting.end.is_some() {
|
if setting.start.is_some() && setting.end.is_some() {
|
||||||
load_led_into_light(data, setting.color, setting.start.unwrap(), setting.end.unwrap());
|
load_led_into_light(
|
||||||
|
data,
|
||||||
|
setting.color,
|
||||||
|
setting.start.unwrap(),
|
||||||
|
setting.end.unwrap(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_render(&mut self) -> GetRender {
|
fn get_render(&mut self) -> GetRender {
|
||||||
|
|
||||||
let mut data: Vec<RGB<f64>> = vec![RGB::default(); self.num_leds.try_into().unwrap()];
|
let mut data: Vec<RGB<f64>> = vec![RGB::default(); self.num_leds.try_into().unwrap()];
|
||||||
|
|
||||||
let time = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards").as_millis();
|
let time = SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.expect("Time went backwards")
|
||||||
|
.as_millis();
|
||||||
|
|
||||||
if self.last_render == 0 {
|
if self.last_render == 0 {
|
||||||
self.last_render = time;
|
self.last_render = time;
|
||||||
@ -252,7 +275,11 @@ impl Render {
|
|||||||
|
|
||||||
let mut to_clean: Vec<String> = Vec::new();
|
let mut to_clean: Vec<String> = Vec::new();
|
||||||
|
|
||||||
let animations = self.animations.clone().iter_mut().map(|animation| {
|
let animations = self
|
||||||
|
.animations
|
||||||
|
.clone()
|
||||||
|
.iter_mut()
|
||||||
|
.map(|animation| {
|
||||||
let mut animation = animation.to_owned();
|
let mut animation = animation.to_owned();
|
||||||
|
|
||||||
let mut start_time = animation.start_time;
|
let mut start_time = animation.start_time;
|
||||||
@ -288,22 +315,22 @@ impl Render {
|
|||||||
self.proccess_settings(&mut data, &animation.key_frames[cf].settings);
|
self.proccess_settings(&mut data, &animation.key_frames[cf].settings);
|
||||||
|
|
||||||
return animation;
|
return animation;
|
||||||
}).collect();
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
self.animations = animations;
|
self.animations = animations;
|
||||||
|
|
||||||
to_clean.iter().for_each(|i| self.remove_animation(i.to_string()));
|
to_clean
|
||||||
|
.iter()
|
||||||
|
.for_each(|i| self.remove_animation(i.to_string()));
|
||||||
|
|
||||||
return GetRender {
|
return GetRender { data, delta, time };
|
||||||
data,
|
|
||||||
delta,
|
|
||||||
time
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&mut self) {
|
pub fn render(&mut self) {
|
||||||
|
if self.ws.is_none() {
|
||||||
if self.ws.is_none() { return; }
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let get_render = self.get_render();
|
let get_render = self.get_render();
|
||||||
|
|
||||||
@ -312,20 +339,22 @@ impl Render {
|
|||||||
let time = get_render.time;
|
let time = get_render.time;
|
||||||
|
|
||||||
if self.last.is_empty() || !self.last.clone().iter().eq(data.clone().iter()) {
|
if self.last.is_empty() || !self.last.clone().iter().eq(data.clone().iter()) {
|
||||||
|
|
||||||
if self.last.len() == 0 {
|
if self.last.len() == 0 {
|
||||||
self.last = data.clone();
|
self.last = data.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
if time - self.last_update == 0 {
|
if time - self.last_update < 100 {
|
||||||
println!("To Fast! Skiping");
|
println!("To Fast! Skiping");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.last_update = time;
|
self.last_update = time;
|
||||||
|
|
||||||
|
let lerp_data: Vec<RGB<f64>> = data
|
||||||
let lerp_data: Vec<RGB<f64>> = data.iter().zip(&self.last).map(|(d, l)| l.lerp(d, delta as f64)).collect();
|
.iter()
|
||||||
|
.zip(&self.last)
|
||||||
|
.map(|(d, l)| l.lerp(d, delta as f64))
|
||||||
|
.collect();
|
||||||
|
|
||||||
//println!("d:{:?}\n l:{:?}", data[25], lerp_data[25]);
|
//println!("d:{:?}\n l:{:?}", data[25], lerp_data[25]);
|
||||||
|
|
||||||
@ -339,17 +368,16 @@ impl Render {
|
|||||||
|
|
||||||
self.last = lerp_data;
|
self.last = lerp_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn im_render(&mut self) {
|
pub fn im_render(&mut self) {
|
||||||
|
if self.ws.is_none() {
|
||||||
if self.ws.is_none() { return; }
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let data = self.get_render().data;
|
let data = self.get_render().data;
|
||||||
|
|
||||||
if self.last.is_empty() || !self.last.clone().iter().eq(data.clone().iter()) {
|
if self.last.is_empty() || !self.last.clone().iter().eq(data.clone().iter()) {
|
||||||
|
|
||||||
if self.last.len() == 0 {
|
if self.last.len() == 0 {
|
||||||
self.last = data.clone();
|
self.last = data.clone();
|
||||||
}
|
}
|
||||||
@ -364,18 +392,14 @@ impl Render {
|
|||||||
|
|
||||||
self.last = data;
|
self.last = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rgbs_f64_to_u8(data: &Vec<RGB<f64>>) -> Vec<RGB<u8>> {
|
pub fn rgbs_f64_to_u8(data: &Vec<RGB<f64>>) -> Vec<RGB<u8>> {
|
||||||
data.clone().iter().map(|a| {
|
data.clone()
|
||||||
RGB::new(
|
.iter()
|
||||||
a.r as u8,
|
.map(|a| RGB::new(a.r as u8, a.g as u8, a.b as u8))
|
||||||
a.g as u8,
|
.collect()
|
||||||
a.b as u8
|
|
||||||
)
|
|
||||||
}).collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Lerp {
|
pub trait Lerp {
|
||||||
@ -400,6 +424,10 @@ impl Lerp for f64 {
|
|||||||
|
|
||||||
impl Lerp for RGB<f64> {
|
impl Lerp for RGB<f64> {
|
||||||
fn lerp(self, other: &Self, diff: f64) -> Self {
|
fn lerp(self, other: &Self, diff: f64) -> Self {
|
||||||
RGB::new(self.r.lerp(&other.r, diff), self.g.lerp(&other.g, diff), self.b.lerp(&other.b, diff))
|
RGB::new(
|
||||||
|
self.r.lerp(&other.r, diff),
|
||||||
|
self.g.lerp(&other.g, diff),
|
||||||
|
self.b.lerp(&other.b, diff),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user