From ae498767944fe668a76a511d98d863bb186eab43 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Sat, 28 Sep 2024 22:53:31 +0200
Subject: [PATCH] add separate display function for controller and add names
 for patterns

---
 src/controller.rs                    | 49 +++++++++++++++++++++++-----
 src/main.rs                          | 43 +++++++++++++++---------
 src/patterns/alternate.rs            |  3 ++
 src/patterns/arctic_rain.rs          |  3 ++
 src/patterns/breathing.rs            |  3 ++
 src/patterns/gastel_fade.rs          | 17 +++++++---
 src/patterns/oneshotman.rs           |  3 ++
 src/patterns/pastel_fade.rs          |  3 ++
 src/patterns/strobe.rs               |  3 ++
 src/patterns/uboot_prüfstand_fade.rs |  3 ++
 src/patterns/wave_fade.rs            |  3 ++
 src/patterns/wheel.rs                |  3 ++
 src/scene_library.rs                 |  9 +++++
 src/setup.rs                         | 11 ++++---
 src/uboot_prüfstand_fade.rs          | 17 ++++++++--
 src/view.rs                          |  3 ++
 16 files changed, 139 insertions(+), 37 deletions(-)

diff --git a/src/controller.rs b/src/controller.rs
index 96e1244..2054fa4 100644
--- a/src/controller.rs
+++ b/src/controller.rs
@@ -1,6 +1,11 @@
 use {
     std::time::{Instant, Duration},
-    crate::waveform::Waveform,
+    std::sync::{Arc, RwLock},
+    crate::{
+        waveform::Waveform,
+        SceneLibrary,
+        inputs::Inputs
+    }
 };
 
 pub struct Controller {
@@ -8,25 +13,55 @@ pub struct Controller {
     pub transition_begin: Instant,
     pub last_tap: Instant,
 
-    pub ctrl: bool
+    pub ctrl: bool,
+
+    pub inputs: Arc<RwLock<Inputs>>,
+    pub library: Arc<RwLock<SceneLibrary>>
 }
 
 impl Controller {
-    pub fn new() -> Self {
+    pub fn new(library: Arc<RwLock<SceneLibrary>>, inputs: Arc<RwLock<Inputs>>) -> Self {
         Controller {
             tbegin: Instant::now(),
             transition_begin: Instant::now(),
             last_tap: Instant::now(),
-            ctrl: false
+            ctrl: false,
+            library,
+            inputs
         }
     }
 
+    pub fn display(&self) {
+        let inputs = self.inputs.read().unwrap();
+        let lib = self.library.read().unwrap();
+
+        eprintln!("----------");
+        
+        if inputs.active {
+            eprintln!("(ACTIVE)");
+        } else {
+            eprintln!("(FROZEN)");
+        }
+
+        if let Some(scene) = lib.get(inputs.scene_select) {
+            eprintln!("current animation: {}", scene.name());
+        }
+
+        for si in 0..lib.len() {
+            if let Some(scene) = lib.get(si) {
+                eprintln!("({}) {}", si, scene.name());
+            }
+        }
+
+        eprintln!("inputs:\n {:?}", inputs);
+    }
+
     pub fn handle_key(
         &mut self,
         event: winit::event::KeyEvent,
-        inputs: &mut crate::inputs::Inputs,
         setup: &mut crate::setup::LightingSetup
     ) {
+        let mut inputs = self.inputs.write().unwrap();
         if event.state == winit::event::ElementState::Released {
             match event.logical_key {
                 winit::keyboard::Key::Named(
@@ -141,10 +176,6 @@ impl Controller {
                         _=>{}
                     }
                 }
-
-                    eprintln!("--------------");
-                    eprintln!("updated inputs:\n {:?}", inputs);
-                    eprintln!("--------------");
                 }
             }
             _ => {}
diff --git a/src/main.rs b/src/main.rs
index 5a90483..11a3ac4 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -51,13 +51,15 @@ 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 mut inputs = Inputs::default();
+    let mut inputs = Arc::new(RwLock::new(Inputs::default()));
+
+    let scene_library = Arc::new(RwLock::new(SceneLibrary::new()));
 
     let mut lighting_setup = LightingSetup::new(
         vec![
             Fixture::new_matrix(),
 //                .with_driver( Box::new(MatrixTcpDriver::new("ip:port")) ),
-
+/*
             Fixture::new_stripe(false)
                 .with_driver( Box::new(StripeDriver::new("192.168.0.114:4210", socket.clone())) )
                 .offset(Vector2::new(-0.5, 0.0)),
@@ -65,7 +67,7 @@ async fn main() {
             Fixture::new_stripe(true)
                 .with_driver( Box::new(StripeDriver::new("192.168.0.113:4210", socket.clone())) )
                 .offset(Vector2::new(-0.4, 0.0)),
-
+*/
             Fixture::new_stripe(true)
                 .with_driver( Box::new(StripeDriver::new("192.168.0.112:4210", socket.clone())) )
             .offset(Vector2::new(0.4, 0.0)),
@@ -75,18 +77,20 @@ async fn main() {
                 .offset(Vector2::new(0.5, 0.0))
         ],
 
-        Box::new( SceneLibrary::new() )
+        scene_library.clone()
     );
 
-    let mut controller = controller::Controller::new();
+    let mut controller = controller::Controller::new( scene_library, inputs.clone() );
 
     let mut frame_count = 0;
     let mut fps_sum_window = std::time::Instant::now();
-
-    lighting_setup.advance( &inputs );
-    for i in 0..5 {
+    {
+    let inputs = controller.inputs.read().unwrap();
+    lighting_setup.advance(&(*inputs) );
+    for i in 0 .. lighting_setup.fixtures.len() {
         lighting_setup.sync_fixture(i);
     }
+    }
 
     event_loop.run(move |event, elwt| {
         let tcur = std::time::Instant::now();
@@ -107,12 +111,16 @@ async fn main() {
         }
 
         // update animation
-        inputs.t = tcur - controller.tbegin;
-        inputs.transition_time = tcur - controller.transition_begin;    
-        lighting_setup.advance( &inputs );
+        let active = {
+            let mut inputs = inputs.write().unwrap();
+            inputs.t = tcur - controller.tbegin;
+            inputs.transition_time = tcur - controller.transition_begin;    
+            lighting_setup.advance( &inputs );
+            inputs.active
+        };
 
         // refresh fixture outputs
-        if inputs.active {
+        if active {
             // sync
             let mut rbuf = [0 as u8; 8];
 
@@ -124,16 +132,18 @@ async fn main() {
                     }
                 if src_addr == "192.168.0.112:4210".parse().expect("parse socketaddr") {
                         lighting_setup.sync_fixture(2);
-                    }
+                }
+                /*
                 if src_addr == "192.168.0.113:4210".parse().expect("parse socketaddr") {
                         lighting_setup.sync_fixture(3);
                     }
                 if src_addr == "192.168.0.114:4210".parse().expect("parse socketaddr") {
                         lighting_setup.sync_fixture(4);
-                    }
+            }
+                */
             }
 
-            for i in 1 .. 5 {
+            for i in 1 .. 3 {
                 lighting_setup.update_outputs(i);
             }
         }
@@ -159,8 +169,9 @@ async fn main() {
                 event: winit::event::WindowEvent::KeyboardInput{ device_id, event, is_synthetic }
             } => {
                 controller.handle_key(
-                    event, &mut inputs, &mut lighting_setup
+                    event, &mut lighting_setup
                 );
+                controller.display();
             }
 
             _ => {}
diff --git a/src/patterns/alternate.rs b/src/patterns/alternate.rs
index be5c13d..1dc04d2 100644
--- a/src/patterns/alternate.rs
+++ b/src/patterns/alternate.rs
@@ -19,6 +19,9 @@ pub struct Alternate {
 }
 
 impl Animation for Alternate {
+    fn name(&self) -> String {
+        "Alternate".into()
+    }
     fn advance(&mut self, inputs: &Inputs) {
         self.inputs = inputs.clone();
     }
diff --git a/src/patterns/arctic_rain.rs b/src/patterns/arctic_rain.rs
index 64b1446..dc1945f 100644
--- a/src/patterns/arctic_rain.rs
+++ b/src/patterns/arctic_rain.rs
@@ -17,6 +17,9 @@ use {
 pub struct ArcticRain { pub inputs: Inputs }
 
 impl Animation for ArcticRain {
+    fn name(&self) -> String {
+        "Arctic Rain".into()
+    }
     fn advance(&mut self, inputs: &Inputs) {
         self.inputs = inputs.clone();
     }
diff --git a/src/patterns/breathing.rs b/src/patterns/breathing.rs
index 7505392..900c97c 100644
--- a/src/patterns/breathing.rs
+++ b/src/patterns/breathing.rs
@@ -20,6 +20,9 @@ use {
 pub struct Breathing { pub inputs: Inputs }
 
 impl Animation for Breathing {
+    fn name(&self) -> String {
+        "Breathing".into()
+    }
     fn advance(&mut self, inputs: &Inputs) {
         self.inputs = inputs.clone();
     }
diff --git a/src/patterns/gastel_fade.rs b/src/patterns/gastel_fade.rs
index 2df81ee..a5fcd3d 100644
--- a/src/patterns/gastel_fade.rs
+++ b/src/patterns/gastel_fade.rs
@@ -10,14 +10,23 @@ use {
     std::time::Duration,
     angle::Turns,
 
-    crate::{Inputs, view::ColorGrid, util::get_angle}
+    crate::{Inputs, view::{ColorGrid, Animation}, util::get_angle}
 };
 
-pub struct GastelFade { pub inputs: Arc<RwLock< Inputs >> }
+pub struct GastelFade { pub inputs:Inputs }
+
+impl Animation for GastelFade {
+    fn name(&self) -> String {
+        "Gastel Fade".into()
+    }
+    fn advance(&mut self, inputs: &Inputs) {
+        self.inputs = inputs.clone();
+    }
+}
+
 impl ColorGrid for GastelFade {
     fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
-        let inputs = self.inputs.read().unwrap().clone();
-
+        let inputs = self.inputs.clone();
         let i = ( inputs.t.as_millis() as f32 / (4.0*inputs.cycle_len.as_millis() as f32) ) % 1.0;
 
         let w = (inputs.t.as_millis() as f32 / (inputs.wheel as f32*inputs.cycle_len.as_millis() as f32)) % 1.0;
diff --git a/src/patterns/oneshotman.rs b/src/patterns/oneshotman.rs
index 14a766c..0f875a0 100644
--- a/src/patterns/oneshotman.rs
+++ b/src/patterns/oneshotman.rs
@@ -22,6 +22,9 @@ pub struct OneShotMan {
 }
 
 impl Animation for OneShotMan {
+    fn name(&self) -> String {
+        "OneShotMan".into()
+    }
     fn advance(&mut self, inputs: &Inputs) {
         self.inputs = inputs.clone();
         self.velocity = (inputs.wheel as f32) / 16.0;
diff --git a/src/patterns/pastel_fade.rs b/src/patterns/pastel_fade.rs
index ff3cd8a..c9d7198 100644
--- a/src/patterns/pastel_fade.rs
+++ b/src/patterns/pastel_fade.rs
@@ -17,6 +17,9 @@ use {
 pub struct PastelFade { pub inputs: Inputs }
 
 impl Animation for PastelFade {
+    fn name(&self) -> String {
+        "Pastel Fade".into()
+    }
     fn advance(&mut self, inputs: &Inputs) {
         self.inputs = inputs.clone();
     }
diff --git a/src/patterns/strobe.rs b/src/patterns/strobe.rs
index 732953a..1aa4dec 100644
--- a/src/patterns/strobe.rs
+++ b/src/patterns/strobe.rs
@@ -19,6 +19,9 @@ pub struct Strobe {
 }
 
 impl Animation for Strobe {
+    fn name(&self) -> String {
+        "Strobe".into()
+    }
     fn advance(&mut self, inputs: &Inputs) {
         self.inputs = inputs.clone();
     }
diff --git a/src/patterns/uboot_prüfstand_fade.rs b/src/patterns/uboot_prüfstand_fade.rs
index 2747e95..adb3650 100644
--- a/src/patterns/uboot_prüfstand_fade.rs
+++ b/src/patterns/uboot_prüfstand_fade.rs
@@ -17,6 +17,9 @@ use {
 pub struct UbootPrüfstandFade { pub inputs: Inputs }
 
 impl Animation for UbootPrüfstandFade {
+    fn name(&self) -> String {
+        "UbootPrüstand Fade".into()
+    }
     fn advance(&mut self, inputs: &Inputs) {
         self.inputs = inputs.clone();
     }
diff --git a/src/patterns/wave_fade.rs b/src/patterns/wave_fade.rs
index 362c917..d94339a 100644
--- a/src/patterns/wave_fade.rs
+++ b/src/patterns/wave_fade.rs
@@ -18,6 +18,9 @@ pub struct WaveFade { pub inputs: Inputs,
 }
 
 impl Animation for WaveFade {
+    fn name(&self) -> String {
+        "Wave Fade".into()
+    }
     fn advance(&mut self, inputs: &Inputs) {
         self.inputs = inputs.clone();
     }
diff --git a/src/patterns/wheel.rs b/src/patterns/wheel.rs
index 710a270..7231510 100644
--- a/src/patterns/wheel.rs
+++ b/src/patterns/wheel.rs
@@ -17,6 +17,9 @@ use {
 pub struct Wheel { pub inputs: Inputs }
 
 impl Animation for Wheel {
+    fn name(&self) -> String {
+        "Wheel".into()
+    }
     fn advance(&mut self, inputs: &Inputs) {
         self.inputs = inputs.clone();
     }
diff --git a/src/scene_library.rs b/src/scene_library.rs
index 999bc1e..316e00b 100644
--- a/src/scene_library.rs
+++ b/src/scene_library.rs
@@ -25,6 +25,12 @@ pub struct SceneLibrary {
 }
 
 impl SceneLibrary {
+    pub fn len(&self) -> usize {
+        self.library.len()
+    }
+    pub fn get(&self, idx: usize) -> Option<&Box<dyn Animation>> {
+        self.library.get(idx)
+    }
     pub fn new() -> Self {
         SceneLibrary {
             library: vec![
@@ -55,6 +61,9 @@ impl SceneLibrary {
 }
 
 impl Animation for SceneLibrary {
+    fn name(&self) -> String {
+        "master".into()
+    }
     fn advance(&mut self, inputs: &Inputs) {
         self.inputs = inputs.clone();
 
diff --git a/src/setup.rs b/src/setup.rs
index d455036..5f3f4f0 100644
--- a/src/setup.rs
+++ b/src/setup.rs
@@ -13,11 +13,11 @@ pub struct LightingSetup {
     pub fixtures: Vec<Fixture>,
     t: Arc<RwLock<Duration>>,
 
-    animation: Box<dyn Animation>
+    animation: Arc<RwLock<dyn Animation>>
 }
 
 impl LightingSetup {
-    pub fn new(fixtures: Vec<Fixture>, animation: Box<dyn Animation>) -> Self {
+    pub fn new(fixtures: Vec<Fixture>, animation: Arc<RwLock<dyn Animation>>) -> Self {
         let t = Arc::new(RwLock::new(Duration::from_millis(0)));
         LightingSetup {
             fixtures,
@@ -28,7 +28,8 @@ impl LightingSetup {
 
     pub fn update_buffers(&mut self) {
         for fixture in self.fixtures.iter_mut() {
-            fixture.update_buffer( self.animation.as_ref() );
+            let anim = self.animation.read().unwrap();
+            fixture.update_buffer( &*anim );
         }
     }
 
@@ -48,7 +49,7 @@ impl LightingSetup {
     }
 
     pub fn advance(&mut self, inputs: &Inputs) {
-        self.animation.advance(inputs);
+        self.animation.write().unwrap().advance(inputs);
         self.update_buffers();
     }
 
@@ -71,7 +72,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.animation.get(&Vector2::new(xf, yf));
+            let color = self.animation.read().unwrap().get(&Vector2::new(xf, yf));
 
             
             let red = (color.red() * 16.0) as u32;
diff --git a/src/uboot_prüfstand_fade.rs b/src/uboot_prüfstand_fade.rs
index 73330b4..a7cc1b0 100644
--- a/src/uboot_prüfstand_fade.rs
+++ b/src/uboot_prüfstand_fade.rs
@@ -14,11 +14,22 @@ use {
 };
 
 
-pub struct UbootPrüfstandFade { inputs: Arc<RwLock< Inputs >> }
+pub struct UbootPrüfstandFade { inputs: Inputs }
+
+impl Animation for UbootPrüfstandFade {
+    fn name(&self) -> String {
+        "UbootPrüfstand Fade".into()
+    }
+
+    fn advance(&mut self, inputs: &Inputs) {
+        self.inputs = inputs.clone();
+    }
+}
+
 impl ColorGrid for UbootPrüfstandFade {
     fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
-        let inputs = self.inputs.read().unwrap().clone();
-//        let millis = self
+        
+        let inputs = self.inputs.clone();
 
         let i = ( inputs.t.as_millis() as f32 / (4.0*inputs.cycle_len.as_millis() as f32) ) % 1.0;
 
diff --git a/src/view.rs b/src/view.rs
index 2e20fa1..d9339e1 100644
--- a/src/view.rs
+++ b/src/view.rs
@@ -9,6 +9,9 @@ pub trait ColorGrid {
     fn get(&self, pos: &Vector2<f32>) -> Rgb<f32>;
 }
 pub trait Animation : ColorGrid {
+    fn name(&self) -> String {
+        String::from("unnamed")
+    }
     fn advance(&mut self, inputs: &Inputs);
 }