1
1
use std:: collections:: HashMap ;
2
2
use std:: error:: Error ;
3
- use std:: path:: { Path , PathBuf } ;
4
3
use std:: sync:: Arc ;
5
4
6
5
use animation_api:: event:: Event ;
7
6
use animation_api:: schema:: { Configuration , ParameterValue } ;
8
7
use animation_wrapper:: config:: PluginConfig ;
9
8
use chrono:: { DateTime , Duration , Utc } ;
10
- use client:: combined:: { CombinedLightClient , CombinedLightClientBuilder } ;
9
+ use client:: combined:: CombinedLightClient ;
11
10
#[ cfg( feature = "audio" ) ]
12
11
use events:: beat_generator:: BeatEventGenerator ;
13
12
use events:: event_generator:: EventGenerator ;
@@ -22,7 +21,7 @@ use rustmas_light_client::LightClientError;
22
21
use tokio:: sync:: { mpsc, Mutex } ;
23
22
use tokio:: task:: JoinHandle ;
24
23
25
- use crate :: factory:: { AnimationFactory , AnimationFactoryError } ;
24
+ use crate :: factory:: AnimationFactoryError ;
26
25
use crate :: plugin:: { AnimationPluginError , Plugin } ;
27
26
use crate :: ControllerConfig ;
28
27
@@ -71,7 +70,6 @@ pub struct Controller {
71
70
animation_join_handle : JoinHandle < ( ) > ,
72
71
event_generator_join_handle : JoinHandle < ( ) > ,
73
72
state : Arc < Mutex < ControllerState > > ,
74
- animation_factory : AnimationFactory ,
75
73
event_sender : mpsc:: Sender < Event > ,
76
74
}
77
75
@@ -81,10 +79,9 @@ enum PollFrameResult {
81
79
}
82
80
83
81
impl Controller {
84
- fn new < P : AsRef < Path > > (
85
- points : Vec < ( f64 , f64 , f64 ) > ,
86
- plugin_dir : P ,
82
+ fn new (
87
83
client : Box < dyn rustmas_light_client:: LightClient + Sync + Send > ,
84
+ points_count : usize ,
88
85
) -> Self {
89
86
let now = Utc :: now ( ) ;
90
87
let ( event_sender, event_receiver) = mpsc:: channel ( 16 ) ;
@@ -97,16 +94,14 @@ impl Controller {
97
94
event_generators : Self :: start_generators ( event_sender. clone ( ) ) ,
98
95
} ) ) ;
99
96
100
- let animation_join_handle = tokio:: spawn ( Self :: run ( state. clone ( ) , client, points . len ( ) ) ) ;
97
+ let animation_join_handle = tokio:: spawn ( Self :: run ( state. clone ( ) , client, points_count ) ) ;
101
98
let event_generator_join_handle =
102
99
tokio:: spawn ( Self :: event_loop ( state. clone ( ) , event_receiver) ) ;
103
- let animation_factory = AnimationFactory :: new ( plugin_dir, points) ;
104
100
105
101
Self {
106
102
state,
107
103
animation_join_handle,
108
104
event_generator_join_handle,
109
- animation_factory,
110
105
event_sender,
111
106
}
112
107
}
@@ -220,25 +215,19 @@ impl Controller {
220
215
}
221
216
}
222
217
223
- pub fn builder ( ) -> ControllerBuilder {
224
- ControllerBuilder {
225
- points : None ,
226
- plugin_dir_ : None ,
227
- client_builder : CombinedLightClient :: builder ( ) ,
228
- }
229
- }
230
-
231
- pub fn builder_from ( config : & ControllerConfig ) -> Result < ControllerBuilder , Box < dyn Error > > {
232
- ControllerBuilder {
233
- points : None ,
234
- plugin_dir_ : Some ( config. plugin_path . clone ( ) ) ,
235
- client_builder : CombinedLightClient :: builder ( ) . with_config ( & config. lights ) ?,
218
+ pub fn from_config (
219
+ config : & ControllerConfig ,
220
+ feedback : Option < mpsc:: Sender < lightfx:: Frame > > ,
221
+ point_count : usize ,
222
+ ) -> Result < Self , Box < dyn Error > > {
223
+ let mut light_client_builder =
224
+ CombinedLightClient :: builder ( ) . with_config ( & config. lights ) ?;
225
+ if let Some ( sender) = feedback {
226
+ light_client_builder =
227
+ light_client_builder. with ( client:: feedback:: FeedbackLightClient :: new ( sender) ) ;
236
228
}
237
- . points_from_file ( & config. points_path )
238
- }
239
229
240
- pub fn points ( & self ) -> & [ ( f64 , f64 , f64 ) ] {
241
- self . animation_factory . points ( )
230
+ Ok ( Self :: new ( light_client_builder. build ( ) , point_count) )
242
231
}
243
232
244
233
pub async fn restart_event_generators ( & self ) {
@@ -296,28 +285,10 @@ impl Controller {
296
285
} )
297
286
}
298
287
299
- pub async fn reload_animation ( & self ) -> Result < Configuration , ControllerError > {
300
- let mut state = self . state . lock ( ) . await ;
301
- let Some ( id) = state
302
- . animation
303
- . as_ref ( )
304
- . map ( |a| a. plugin_config ( ) . animation_id ( ) )
305
- else {
306
- return Err ( ControllerError :: NoAnimationSelected ) ;
307
- } ;
308
- info ! ( "Reloading animation \" {}\" " , id) ;
309
- let animation = self . animation_factory . make ( id) . await ?;
310
- let configuration = animation. configuration ( ) . await ?;
311
- state. set_animation ( Some ( animation) ) . await ?;
312
- Ok ( configuration)
313
- }
314
-
315
288
pub async fn switch_animation (
316
289
& self ,
317
- animation_id : & str ,
290
+ animation : Box < dyn Plugin > ,
318
291
) -> Result < Configuration , ControllerError > {
319
- info ! ( "Trying to switch animation to \" {}\" " , animation_id) ;
320
- let animation = self . animation_factory . make ( animation_id) . await ?;
321
292
let configuration = animation. configuration ( ) . await ?;
322
293
let mut state = self . state . lock ( ) . await ;
323
294
state. set_animation ( Some ( animation) ) . await ?;
@@ -377,73 +348,4 @@ impl Controller {
377
348
378
349
Ok ( ( ) )
379
350
}
380
-
381
- pub fn discover_animations ( & mut self ) -> Result < ( ) , ControllerError > {
382
- self . animation_factory . discover ( ) ?;
383
- Ok ( ( ) )
384
- }
385
-
386
- pub fn list_animations ( & self ) -> & HashMap < String , PluginConfig > {
387
- self . animation_factory . list ( )
388
- }
389
- }
390
-
391
- pub struct ControllerBuilder {
392
- points : Option < Vec < ( f64 , f64 , f64 ) > > ,
393
- plugin_dir_ : Option < PathBuf > ,
394
- client_builder : CombinedLightClientBuilder ,
395
- }
396
-
397
- impl ControllerBuilder {
398
- pub fn points_from_file < P : AsRef < Path > > ( mut self , path : P ) -> Result < Self , Box < dyn Error > > {
399
- fn points_from_path ( path : & Path ) -> Result < Vec < ( f64 , f64 , f64 ) > , ControllerError > {
400
- let points: Vec < _ > = csv:: ReaderBuilder :: new ( )
401
- . has_headers ( false )
402
- . from_path ( path)
403
- . map_err ( |e| ControllerError :: InternalError {
404
- reason : format ! ( "Could not read CSV file: {}" , e) ,
405
- } ) ?
406
- . deserialize ( )
407
- . filter_map ( |record : Result < ( f64 , f64 , f64 ) , _ > | record. ok ( ) )
408
- . collect ( ) ;
409
- info ! (
410
- "Loaded {} points from {}" ,
411
- points. len( ) ,
412
- path. to_string_lossy( )
413
- ) ;
414
- Ok ( points)
415
- }
416
-
417
- let path = path. as_ref ( ) ;
418
- self . points = Some ( points_from_path ( path) ?) ;
419
- Ok ( self )
420
- }
421
-
422
- pub fn lights (
423
- mut self ,
424
- config : & [ rustmas_light_client:: LightsConfig ] ,
425
- ) -> Result < Self , Box < dyn Error > > {
426
- self . client_builder = self . client_builder . with_config ( config) ?;
427
- Ok ( self )
428
- }
429
-
430
- pub fn lights_feedback ( mut self , sender : mpsc:: Sender < lightfx:: Frame > ) -> Self {
431
- self . client_builder = self
432
- . client_builder
433
- . with ( client:: feedback:: FeedbackLightClient :: new ( sender) ) ;
434
- self
435
- }
436
-
437
- pub fn plugin_dir < P : AsRef < Path > > ( mut self , path : P ) -> Self {
438
- self . plugin_dir_ = Some ( path. as_ref ( ) . into ( ) ) ;
439
- self
440
- }
441
-
442
- pub fn build ( self ) -> Controller {
443
- Controller :: new (
444
- self . points . unwrap ( ) ,
445
- self . plugin_dir_ . unwrap ( ) ,
446
- self . client_builder . build ( ) ,
447
- )
448
- }
449
351
}
0 commit comments