increased render time
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Andre Henriques 2023-04-14 19:21:09 +01:00
parent df820fa7d8
commit 8f915d1020

View File

@ -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),
)
} }
} }