From 1e3a92000a05d8986634b6eca017852162170d24 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Sat, 3 Aug 2024 22:50:04 +0200 Subject: [PATCH] move controller to separate module --- src/controller.rs | 92 ++++++++++++++++++++ src/fixture.rs | 2 +- src/inputs.rs | 23 +++++ src/main.rs | 123 +++++---------------------- src/patterns/alternate.rs | 20 +++-- src/patterns/arctic_rain.rs | 18 ++-- src/patterns/breathing.rs | 26 ++++-- src/patterns/pastel_fade.rs | 16 ++-- src/patterns/strobe.rs | 15 ++-- src/patterns/uboot_prüfstand_fade.rs | 19 +++-- src/patterns/wave_fade.rs | 16 ++-- src/patterns/wheel.rs | 21 +++-- src/scene_library.rs | 82 +++++++++--------- src/setup.rs | 18 ++-- src/view.rs | 6 +- 15 files changed, 293 insertions(+), 204 deletions(-) create mode 100644 src/controller.rs diff --git a/src/controller.rs b/src/controller.rs new file mode 100644 index 0000000..2af419f --- /dev/null +++ b/src/controller.rs @@ -0,0 +1,92 @@ +use { + std::time::{Instant, Duration}, + crate::waveform::Waveform, +}; + +pub struct Controller { + pub tbegin: Instant, + pub transition_begin: Instant, + pub last_tap: Instant +} + +impl Controller { + pub fn new() -> Self { + Controller { + tbegin: Instant::now(), + transition_begin: Instant::now(), + last_tap: Instant::now() + } + } + + pub fn handle_key( + &mut self, + event: winit::event::KeyEvent, + inputs: &mut crate::inputs::Inputs, + ) { + if event.state == winit::event::ElementState::Pressed { + match event.logical_key { + winit::keyboard::Key::Character(c) => { + eprintln!("pressed {}", c); + if c.is_ascii() { + match &c[0..1] { + "x" => { + // tap tempo + let old_tap = self.last_tap; + self.last_tap = std::time::Instant::now(); + + if (self.last_tap - old_tap) < Duration::from_millis(20000) { + inputs.cycle_len = self.last_tap - old_tap; + } + } + "q" => { + // sync + inputs.t = Duration::from_millis(0); + self.tbegin = std::time::Instant::now(); + }, + "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9" => { + let idx = c.chars().nth(0).unwrap().to_digit(10).unwrap() as u32; + inputs.scene_select = idx as usize; + self.transition_begin = std::time::Instant::now(); + } + "r" => { inputs.master_wave = match inputs.master_wave { + None => Some(Waveform::Sine), + Some(Waveform::Sine) => Some(Waveform::Triangle), + Some(Waveform::Triangle) => Some(Waveform::Square), + Some(Waveform::Square) => Some(Waveform::Sawtooth), + Some(Waveform::Sawtooth) => None + } + } + "," => { inputs.master_wave = None; } + "n" => { inputs.master_intensity += 0.1; } + "m" => { inputs.master_intensity -= 0.1; } + "s" => { inputs.master_subdivision +=1; } + "b" => { inputs.master_subdivision -=1; } + "o" => { inputs.wheel +=1; } + "z" => { inputs.wheel -=1; } + "e" => { inputs.wheel2 += 1; } + "p"=> { inputs.wheel2 -= 1; } + + "-" => { inputs.master_intensity *= -1.0; } + "." => { + if inputs.active { + eprintln!("DEACTIVATED"); + inputs.active = false; + } else { + inputs.active = true; + eprintln!("ACTIVATED"); + } + } + + _=>{} + } + + eprintln!("--------------"); + eprintln!("updated inputs:\n {:?}", inputs); + eprintln!("--------------"); + } + } + _ => {} + } + } + } +} diff --git a/src/fixture.rs b/src/fixture.rs index b1178d7..f430c1d 100644 --- a/src/fixture.rs +++ b/src/fixture.rs @@ -70,7 +70,7 @@ impl Fixture { self.position + centered_pixpos * self.scale } - pub fn update_buffer(&mut self, view: &Box) { + pub fn update_buffer(&mut self, view: &dyn crate::view::Animation) { for xi in 0 .. self.resolution.x { for yi in 0 ..self.resolution.y { let gpos = self.get_global_pos(&Vector2::new(xi, yi)); diff --git a/src/inputs.rs b/src/inputs.rs index 1dfaaaa..7797cb6 100644 --- a/src/inputs.rs +++ b/src/inputs.rs @@ -19,6 +19,29 @@ pub struct Inputs { pub master_intensity: f32, pub wheel: i32, pub wheel2: i32, + + pub active: bool, +} + +impl Default for Inputs { + fn default() -> Inputs { + Inputs { + t: Duration::from_millis(0), + transition_time: Duration::from_millis(0), + cycle_len: Duration::from_millis(300), + wave_peak: 0.5, + + scene_select: 0, + + master_wave: None, + master_subdivision: 0, + master_intensity: 1.0, + wheel: 0, + wheel2: 0, + + active: false, + } + } } diff --git a/src/main.rs b/src/main.rs index eddc3bc..55d9aba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,6 +21,7 @@ mod view; mod stripe_driver; mod jack; mod waveform; +mod controller; mod patterns; mod scene_library; @@ -50,22 +51,7 @@ async fn main() { socket.write().unwrap().set_read_timeout(Some(std::time::Duration::from_millis(1))); socket.write().unwrap().set_write_timeout(Some(std::time::Duration::from_millis(1))); - let inputs = Arc::new(RwLock::new( - Inputs { - t: Duration::from_millis(0), - transition_time: Duration::from_millis(0), - cycle_len: Duration::from_millis(300), - wave_peak: 0.5, - - scene_select: 0, - - master_wave: None, - master_subdivision: 0, - master_intensity: 1.0, - wheel: 0, - wheel2: 0 - } - )); + let mut inputs = Inputs::default(); let mut lighting_setup = LightingSetup::new( vec![ @@ -89,25 +75,28 @@ async fn main() { .offset(Vector2::new(0.5, 0.0)) ], - Box::new( SceneLibrary::new(inputs.clone()) ) + Box::new( SceneLibrary::new() ) ); - let mut tbegin = std::time::Instant::now(); - let mut transition_begin = std::time::Instant::now(); - let mut last_tap = std::time::Instant::now(); - let mut z = 0; + let mut controller = controller::Controller::new(); let mut frame_count = 0; let mut fps_sum_window = std::time::Instant::now(); - let mut active = false; - + lighting_setup.advance( &inputs ); for i in 0..5 { lighting_setup.sync_fixture(i); } event_loop.run(move |event, elwt| { let tcur = std::time::Instant::now(); + + elwt.set_control_flow( + ControlFlow::WaitUntil( + tcur + Duration::from_millis(25) + )); + + // FPS statistics if (tcur - fps_sum_window).as_millis() > 5000 { let avg_fps = (1000.0 * frame_count as f32) / ((tcur - fps_sum_window).as_millis() as f32); eprintln!("avg fps: {}", avg_fps); @@ -117,15 +106,13 @@ async fn main() { frame_count += 1; } - elwt.set_control_flow(ControlFlow:: - WaitUntil( - tcur + Duration::from_millis(25) - )); - inputs.write().unwrap().t = tcur - tbegin; - inputs.write().unwrap().transition_time = tcur - transition_begin; - lighting_setup.update_buffers(); + // update animation + inputs.t = tcur - controller.tbegin; + inputs.transition_time = tcur - controller.transition_begin; + lighting_setup.advance( &inputs ); - if active { + // refresh fixture outputs + if inputs.active { // sync let mut rbuf = [0 as u8; 8]; @@ -171,76 +158,12 @@ async fn main() { window_id: _, event: winit::event::WindowEvent::KeyboardInput{ device_id, event, is_synthetic } } => { - if event.state == winit::event::ElementState::Pressed { - match event.logical_key { - winit::keyboard::Key::Character(c) => { - eprintln!("pressed {}", c); + controller.handle_key( + event, &mut inputs + ); + } - let mut inputs = inputs.write().unwrap(); - if c.is_ascii() { - match &c[0..1] { - "x" => { - // tap tempo - let old_tap = last_tap; - last_tap = std::time::Instant::now(); - - if (last_tap - old_tap) < Duration::from_millis(20000) { - inputs.cycle_len = last_tap - old_tap; - } - } - "q" => { - // sync - inputs.t = Duration::from_millis(0); - tbegin = std::time::Instant::now(); - }, - "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9" => { - let idx = c.chars().nth(0).unwrap().to_digit(10).unwrap() as u32; - inputs.scene_select = idx as usize; - transition_begin = std::time::Instant::now(); - } - "r" => { inputs.master_wave = match inputs.master_wave { - None => Some(Waveform::Sine), - Some(Waveform::Sine) => Some(Waveform::Triangle), - Some(Waveform::Triangle) => Some(Waveform::Square), - Some(Waveform::Square) => Some(Waveform::Sawtooth), - Some(Waveform::Sawtooth) => None - } - } - "," => { inputs.master_wave = None; } - "n" => { inputs.master_intensity += 0.1; } - "m" => { inputs.master_intensity -= 0.1; } - "s" => { inputs.master_subdivision +=1; } - "b" => { inputs.master_subdivision -=1; } - "o" => { inputs.wheel +=1; } - "z" => { inputs.wheel -=1; } - "e" => { inputs.wheel2 += 1; } - "p"=> { inputs.wheel2 -= 1; } - - "-" => { inputs.master_intensity *= -1.0; } - "." => { - if active { - eprintln!("DEACTIVATED"); - active = false; - } else { - active = true; - eprintln!("ACTIVATED"); - } - } - - _=>{} - } - - eprintln!("--------------"); - eprintln!("updated inputs:\n {:?}", inputs); - eprintln!("--------------"); - } - } - _ => {} - } - } - } - - _ => {} + _ => {} } let (width, height) = *dim.lock().unwrap(); diff --git a/src/patterns/alternate.rs b/src/patterns/alternate.rs index 52f57d8..be5c13d 100644 --- a/src/patterns/alternate.rs +++ b/src/patterns/alternate.rs @@ -10,22 +10,27 @@ use { std::time::Duration, angle::Turns, - crate::{Inputs, view::ColorGrid} + crate::{Inputs, view::{ColorGrid, Animation}} }; +#[derive(Default)] pub struct Alternate { - pub inputs: Arc>, + pub inputs: Inputs, +} + +impl Animation for Alternate { + fn advance(&mut self, inputs: &Inputs) { + self.inputs = inputs.clone(); + } } impl ColorGrid for Alternate { fn get(&self, p: &Vector2) -> Rgb { - let inputs = self.inputs.read().unwrap().clone(); - let switch = 0; - let t = (inputs.wheel as f32 * inputs.t.as_millis() as f32 / inputs.cycle_len.as_millis() as f32) % 1.0; + let t = (self.inputs.wheel as f32 * self.inputs.t.as_millis() as f32 / self.inputs.cycle_len.as_millis() as f32) % 1.0; - if ((50.0+p.y*128.0) / inputs.wheel as f32) as u32 % 2 == 0 { + if ((50.0+p.y*128.0) / self.inputs.wheel as f32) as u32 % 2 == 0 { if t < 0.5 { Rgb::new(0.5, 0.2, 0.2) } else { @@ -38,9 +43,6 @@ impl ColorGrid for Alternate { Rgb::new(0.0, 0.0, 0.6) } } - - - } } diff --git a/src/patterns/arctic_rain.rs b/src/patterns/arctic_rain.rs index 4c21ba8..e03b5e6 100644 --- a/src/patterns/arctic_rain.rs +++ b/src/patterns/arctic_rain.rs @@ -10,15 +10,21 @@ use { std::time::Duration, angle::Turns, - crate::{Inputs, view::ColorGrid} + crate::{Inputs, view::{ColorGrid, Animation}} }; -pub struct ArcticRain { pub inputs: Arc> } +#[derive(Default)] +pub struct ArcticRain { pub inputs: Inputs } + +impl Animation for ArcticRain { + fn advance(&mut self, inputs: &Inputs) { + self.inputs = inputs.clone(); + } +} + impl ColorGrid for ArcticRain { fn get(&self, p: &Vector2) -> Rgb { - let inputs = self.inputs.read().unwrap().clone(); - - let i = ( inputs.t.as_millis() as f32 / (4.0*inputs.cycle_len.as_millis() as f32) ) % 1.0; + let i = ( self.inputs.t.as_millis() as f32 / (4.0*self.inputs.cycle_len.as_millis() as f32) ) % 1.0; let pi2 = 2.0 * 3.1415926; @@ -26,7 +32,7 @@ impl ColorGrid for ArcticRain { Rgb::from_color( &Hsv::>::new( // Turns( 0.65 + 0.3*(inputs.wheel%10) as f32*0.1 ), - Turns( (inputs.wheel.abs() % 256) as f32 / 256.0 ), + Turns( (self.inputs.wheel.abs() % 256) as f32 / 256.0 ), 0.9, 1.0 - ((i + (2.0-p.y/4.0)) * 12.0) % 1.0, // (f32::sin(-p.y+i) * 12.0) % 1.0, diff --git a/src/patterns/breathing.rs b/src/patterns/breathing.rs index 6b23eda..7505392 100644 --- a/src/patterns/breathing.rs +++ b/src/patterns/breathing.rs @@ -9,17 +9,25 @@ use { cgmath::{Point2, Vector2}, std::time::Duration, angle::Turns, - - crate::{Inputs, view::ColorGrid, util::get_angle} + crate::{ + Inputs, + view::{ColorGrid, Animation}, + util::get_angle + } }; +#[derive(Default)] +pub struct Breathing { pub inputs: Inputs } + +impl Animation for Breathing { + fn advance(&mut self, inputs: &Inputs) { + self.inputs = inputs.clone(); + } +} -pub struct Breathing { pub inputs: Arc> } impl ColorGrid for Breathing { fn get(&self, p: &Vector2) -> Rgb { - let inputs = self.inputs.read().unwrap().clone(); - - let millis = inputs.t.as_millis(); + let millis = self.inputs.t.as_millis(); let p1 = p + Vector2::new(0.0,0.5); let r2 = p1.x*p1.x + p1.y*p1.y; @@ -32,8 +40,8 @@ impl ColorGrid for Breathing { mirrorphi * ( 0.5+ 0.5*f32::sin( - inputs.t.as_millis() as f32 - / inputs.cycle_len.as_millis() as f32 + self.inputs.t.as_millis() as f32 + / self.inputs.cycle_len.as_millis() as f32 ) ) ) % 1.0; @@ -42,7 +50,7 @@ impl ColorGrid for Breathing { &Hsv::>::new( Turns( 0.25+0.25*f32::sin(millis as f32/8000.0) + gamma*0.5 ), 0.5 + r2 * 0.5, - inputs.wave_peak, + self.inputs.wave_peak, ) ) } diff --git a/src/patterns/pastel_fade.rs b/src/patterns/pastel_fade.rs index cfa6dd2..ff3cd8a 100644 --- a/src/patterns/pastel_fade.rs +++ b/src/patterns/pastel_fade.rs @@ -10,15 +10,21 @@ use { std::time::Duration, angle::Turns, - crate::{Inputs, view::ColorGrid, util::get_angle} + crate::{Inputs, view::{ColorGrid, Animation}, util::get_angle} }; -pub struct PastelFade { pub inputs: Arc> } +#[derive(Default)] +pub struct PastelFade { pub inputs: Inputs } + +impl Animation for PastelFade { + fn advance(&mut self, inputs: &Inputs) { + self.inputs = inputs.clone(); + } +} + impl ColorGrid for PastelFade { fn get(&self, p: &Vector2) -> Rgb { - let inputs = self.inputs.read().unwrap().clone(); - - let i = ( 5.0 + 0.7 * inputs.t.as_millis() as f32 / (16.0*inputs.cycle_len.as_millis() as f32) ) % 1.0; + let i = ( 5.0 + 0.7 * self.inputs.t.as_millis() as f32 / (16.0*self.inputs.cycle_len.as_millis() as f32) ) % 1.0; Rgb::from_color( &Hsv::>::new( diff --git a/src/patterns/strobe.rs b/src/patterns/strobe.rs index 06f0f8b..eadd9cf 100644 --- a/src/patterns/strobe.rs +++ b/src/patterns/strobe.rs @@ -10,18 +10,23 @@ use { std::time::Duration, angle::Turns, - crate::{Inputs, view::ColorGrid} + crate::{Inputs, view::{ColorGrid, Animation}} }; +#[derive(Default)] pub struct Strobe { - pub inputs: Arc>, + pub inputs: Inputs, +} + +impl Animation for Strobe { + fn advance(&mut self, inputs: &Inputs) { + self.inputs = inputs.clone(); + } } impl ColorGrid for Strobe { fn get(&self, p: &Vector2) -> Rgb { - let inputs = self.inputs.read().unwrap().clone(); - - let t = (inputs.wheel as f32 * inputs.t.as_millis() as f32 / inputs.cycle_len.as_millis() as f32) % 1.0; + let t = (self.inputs.wheel as f32 * self.inputs.t.as_millis() as f32 / self.inputs.cycle_len.as_millis() as f32) % 1.0; if t < 0.6 { Rgb::new(0.3, 0.3, 0.3) diff --git a/src/patterns/uboot_prüfstand_fade.rs b/src/patterns/uboot_prüfstand_fade.rs index 38108fc..2747e95 100644 --- a/src/patterns/uboot_prüfstand_fade.rs +++ b/src/patterns/uboot_prüfstand_fade.rs @@ -10,16 +10,21 @@ use { std::time::Duration, angle::Turns, - crate::{Inputs, view::ColorGrid} + crate::{Inputs, view::{ColorGrid, Animation}} }; -pub struct UbootPrüfstandFade { pub inputs: Arc> } +#[derive(Default)] +pub struct UbootPrüfstandFade { pub inputs: Inputs } + +impl Animation for UbootPrüfstandFade { + fn advance(&mut self, inputs: &Inputs) { + self.inputs = inputs.clone(); + } +} + impl ColorGrid for UbootPrüfstandFade { fn get(&self, p: &Vector2) -> Rgb { - let inputs = self.inputs.read().unwrap().clone(); -// let millis = self - - let i = ( inputs.t.as_millis() as f32 / (4.0*inputs.cycle_len.as_millis() as f32) ) % 1.0; + let i = ( self.inputs.t.as_millis() as f32 / (4.0*self.inputs.cycle_len.as_millis() as f32) ) % 1.0; let pi2 = 2.0 * 3.1415926; @@ -34,7 +39,7 @@ impl ColorGrid for UbootPrüfstandFade { let col2 = Rgb::new(0.8, 0.0, 0.0); - let p = ( inputs.t.as_millis() as f32 / (32.0*inputs.cycle_len.as_millis() as f32)) % 1.0; + let p = ( self.inputs.t.as_millis() as f32 / (32.0*self.inputs.cycle_len.as_millis() as f32)) % 1.0; if p >= 0.7 { col2 } else { diff --git a/src/patterns/wave_fade.rs b/src/patterns/wave_fade.rs index d71643f..362c917 100644 --- a/src/patterns/wave_fade.rs +++ b/src/patterns/wave_fade.rs @@ -10,21 +10,25 @@ use { std::time::Duration, angle::Turns, - crate::{Inputs, view::ColorGrid, util::get_angle, waveform::Waveform} + crate::{Inputs, view::{ColorGrid, Animation}, util::get_angle, waveform::Waveform} }; -pub struct WaveFade { pub inputs: Arc>, +pub struct WaveFade { pub inputs: Inputs, pub hue: f32, } +impl Animation for WaveFade { + fn advance(&mut self, inputs: &Inputs) { + self.inputs = inputs.clone(); + } +} + impl ColorGrid for WaveFade { fn get(&self, p: &Vector2) -> Rgb { - let inputs = self.inputs.read().unwrap().clone(); - - let nt = ( inputs.t.as_millis() as f32 / inputs.cycle_len.as_millis() as f32 ); + let nt = ( self.inputs.t.as_millis() as f32 / self.inputs.cycle_len.as_millis() as f32 ); let i = - match inputs.wheel % 4 { + match self.inputs.wheel % 4 { 0 => Waveform::Sine{}.get_norm(nt), 1 => Waveform::Triangle{}.get_norm(nt), 2 => Waveform::Sawtooth{}.get_norm(nt), diff --git a/src/patterns/wheel.rs b/src/patterns/wheel.rs index 2be54ed..710a270 100644 --- a/src/patterns/wheel.rs +++ b/src/patterns/wheel.rs @@ -10,16 +10,21 @@ use { std::time::Duration, angle::Turns, - crate::{Inputs, view::ColorGrid, util::get_angle} + crate::{Inputs, view::{ColorGrid, Animation}, util::get_angle} }; +#[derive(Default)] +pub struct Wheel { pub inputs: Inputs } + +impl Animation for Wheel { + fn advance(&mut self, inputs: &Inputs) { + self.inputs = inputs.clone(); + } +} -pub struct Wheel { pub inputs: Arc> } impl ColorGrid for Wheel { fn get(&self, p: &Vector2) -> Rgb { - let inputs = self.inputs.read().unwrap().clone(); - - let millis = inputs.t.as_millis(); + let millis = self.inputs.t.as_millis(); let p1 = p + Vector2::new(0.0,0.5); let r2 = p1.x*p1.x + p1.y*p1.y; @@ -31,8 +36,8 @@ impl ColorGrid for Wheel { (5.0) * mirrorphi * ( - inputs.t.as_millis() as f32 - / (inputs.cycle_len.as_millis() as f32 * (1.0 + (inputs.wheel as f32).abs())) + self.inputs.t.as_millis() as f32 + / (self.inputs.cycle_len.as_millis() as f32 * (1.0 + (self.inputs.wheel as f32).abs())) ) ); @@ -40,7 +45,7 @@ impl ColorGrid for Wheel { &Hsv::>::new( Turns( gamma*0.5 ), 0.5 + r2 * 0.5, - (inputs.wheel as f32 / 16.0), + (self.inputs.wheel as f32 / 16.0), ) ) } diff --git a/src/scene_library.rs b/src/scene_library.rs index b7ece41..999bc1e 100644 --- a/src/scene_library.rs +++ b/src/scene_library.rs @@ -11,56 +11,67 @@ use { angle::Turns, crate::Inputs, - crate::view::ColorGrid, + crate::view::{ColorGrid, Animation}, crate::patterns::* }; - pub struct SceneLibrary { - library: Vec< Box >, - current_scene: RwLock, - inputs: Arc>, + library: Vec< Box >, + current_scene: usize, + inputs: Inputs, transition_length: Duration, // transition_curve: enum { Constant, Linear, Sigmoid, Sinus } } impl SceneLibrary { - pub fn new( inputs: Arc> ) -> Self { + pub fn new() -> Self { SceneLibrary { library: vec![ // 0 - Box::new( Breathing{ inputs: inputs.clone() } ), - + Box::new( Breathing::default() ), // 1 - Box::new( Strobe{ inputs: inputs.clone() } ), + Box::new( Strobe::default() ), // 2 - Box::new( WaveFade{ inputs: inputs.clone(), hue: 0.5 } ), +// Box::new( WaveFade{ inputs: inputs.clone(), hue: 0.5 } ), // 3 - Box::new( UbootPrüfstandFade{ inputs: inputs.clone() } ), + Box::new( UbootPrüfstandFade::default() ), //4 - Box::new( ArcticRain{ inputs: inputs.clone() } ), + Box::new( ArcticRain::default() ), //5 - Box::new( Wheel{ inputs: inputs.clone() } ), + Box::new( Wheel::default() ), //6 - Box::new( Alternate{ inputs: inputs.clone() } ), + Box::new( Alternate::default() ), //7 - Box::new( PastelFade{ inputs: inputs.clone() } ), + Box::new( PastelFade::default() ), + //8 + Box::new( OneShotMan::default() ) ], - current_scene: RwLock::new(0), - inputs, + current_scene: 0, + inputs: Inputs::default(), transition_length: Duration::from_millis(200), } } } +impl Animation for SceneLibrary { + fn advance(&mut self, inputs: &Inputs) { + self.inputs = inputs.clone(); + + if self.inputs.transition_time.as_millis() as f32 > self.transition_length.as_millis() as f32 { + // change own state: + self.current_scene = self.inputs.scene_select; + } + + if let Some(a) = self.library.get_mut(self.current_scene) { + a.advance( inputs ); + } + } +} + impl ColorGrid for SceneLibrary { fn get(&self, p: &Vector2) -> Rgb { - let inputs = self.inputs.read().unwrap().clone(); - - let sc = *self.current_scene.read().unwrap(); - - let mut intensity: f32 = inputs.master_intensity; + let mut intensity: f32 = self.inputs.master_intensity; if intensity > 1.0 { intensity = 1.0; } @@ -68,20 +79,19 @@ impl ColorGrid for SceneLibrary { intensity = -1.0; } - if let Some(w) = inputs.master_wave { + if let Some(w) = self.inputs.master_wave.clone() { intensity *= w.get_doub( - inputs.t.as_millis() as f32 - / inputs.cycle_len.as_millis() as f32 + self.inputs.t.as_millis() as f32 + / self.inputs.cycle_len.as_millis() as f32 ); } - if inputs.scene_select < self.library.len() { + if self.inputs.scene_select < self.library.len() { - - if inputs.scene_select == sc { + if self.inputs.scene_select == self.current_scene { // display only one animation let mut hsv = Hsv::from_color( - &self.library[ sc ].get(p) + &self.library[ self.current_scene ].get(p) ); hsv = Hsv::::new( @@ -93,24 +103,18 @@ impl ColorGrid for SceneLibrary { Rgb::from_color(&hsv) } else { // display transition - let cur_scene = &self.library[ sc ]; - let nxt_scene = &self.library[ inputs.scene_select ]; + let cur_scene = &self.library[ self.current_scene ]; + let nxt_scene = &self.library[ self.inputs.scene_select ]; // crossfade param - let w = ( inputs.transition_time.as_millis() as f32 / self.transition_length.as_millis() as f32 ); - - if w >= 1.0 { - // change own state: - *self.current_scene.write().unwrap() = inputs.scene_select; - } + let w = ( self.inputs.transition_time.as_millis() as f32 / self.transition_length.as_millis() as f32 ); cur_scene.get(p) .lerp( &nxt_scene.get(p), w ) - - } + } } else { Rgb::new(0.0, 0.0, 0.0) } diff --git a/src/setup.rs b/src/setup.rs index d7872e8..d00cddc 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -1,7 +1,8 @@ use { crate::{ fixture::Fixture, - view::ColorGrid + inputs::Inputs, + view::{ColorGrid, Animation} }, cgmath::Vector2, std::time::Duration, @@ -12,22 +13,22 @@ pub struct LightingSetup { fixtures: Vec, t: Arc>, - view: Box + animation: Box } impl LightingSetup { - pub fn new(fixtures: Vec, view: Box) -> Self { + pub fn new(fixtures: Vec, animation: Box) -> Self { let t = Arc::new(RwLock::new(Duration::from_millis(0))); LightingSetup { fixtures, t: t.clone(), - view + animation } } pub fn update_buffers(&mut self) { for fixture in self.fixtures.iter_mut() { - fixture.update_buffer( &self.view ); + fixture.update_buffer( self.animation.as_ref() ); } } @@ -46,6 +47,11 @@ impl LightingSetup { } } + pub fn advance(&mut self, inputs: &Inputs) { + self.animation.advance(inputs); + self.update_buffers(); + } + pub fn draw_preview( &self, buffer: &mut softbuffer::Buffer<'_, Arc, Arc>, @@ -65,7 +71,7 @@ impl LightingSetup { let xf = (x as f32 - width as f32/2.0) / mindim as f32; let yf = -(y as f32 - height as f32/2.0) / mindim as f32; - let color = self.view.get(&Vector2::new(xf, yf)); + let color = self.animation.get(&Vector2::new(xf, yf)); let red = (color.red() * 16.0) as u32; diff --git a/src/view.rs b/src/view.rs index 8263636..2e20fa1 100644 --- a/src/view.rs +++ b/src/view.rs @@ -8,8 +8,8 @@ use { pub trait ColorGrid { fn get(&self, pos: &Vector2) -> Rgb; } - -pub trait Animation { - fn advance(&mut self, inputs: Inputs); +pub trait Animation : ColorGrid { + fn advance(&mut self, inputs: &Inputs); } +