Compare commits

..

13 Commits

Author SHA1 Message Date
alban
560b3be71b fix: rename settings.toml 2023-06-08 20:22:36 +02:00
alban
6e97b1c441 fix: rename settings template 2023-06-08 20:21:51 +02:00
alban
50e9b43b71 Merge branch 'dev/marc' into feature/dac-trait 2023-06-08 20:20:42 +02:00
alban
4b135ce283 fix: rework device 2023-06-08 20:18:28 +02:00
9c996b1029 fix tests 2023-06-08 15:49:29 +02:00
22d007d938 fix warnings and make clippy happy 2023-06-07 18:25:33 +02:00
ad3b3803ce load transformers from config file 2023-06-07 17:26:30 +02:00
80ec78efd3 merge 2023-06-07 12:39:59 +02:00
40abb3ac57 no need for these mod to be pub anymore 2023-06-06 11:44:33 +02:00
bc78b30b09 refacto transformer with module hierarchy 2023-06-06 11:32:05 +02:00
e899d8061c refacto transformer with module hierarchy 2023-06-06 11:31:45 +02:00
7d7eec6695 refacto transformer with module hierarchy 2023-06-06 11:30:46 +02:00
alban
3588e3f4a2 wip 2023-06-05 21:21:35 +02:00
12 changed files with 172 additions and 79 deletions

2
.gitignore vendored
View File

@ -1,6 +1,6 @@
# Configuration file # Configuration file
Settings.* settings.*
# Generated by Cargo # Generated by Cargo
# will have compiled files and executables # will have compiled files and executables

View File

@ -14,3 +14,4 @@ log = "0.4.18"
redis = "0.23.0" redis = "0.23.0"
ron = "0.8.0" ron = "0.8.0"
serde = { version = "1.0.163", features = ["derive"] } serde = { version = "1.0.163", features = ["derive"] }
toml = "0.7.4"

View File

@ -18,3 +18,11 @@ id = 0
# For Etherdream. IP of the DAC # For Etherdream. IP of the DAC
# [dac.etherdream] # [dac.etherdream]
# url = "192.168.1.68" # url = "192.168.1.68"
[[transformers]]
[transformers.translate]
x = 2000
y = 2000
[[transformers]]
[transformers.replicate]
Until = 48

View File

@ -1,13 +1,16 @@
use config::Config; use config::Config;
use serde::{Serialize,Deserialize}; use serde::{Serialize,Deserialize};
use crate::errors::LJResult; use crate::errors::LJResult;
use crate::transformer;
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Conf { pub struct Conf {
pub laser_id: u8, pub laser_id: u8,
pub debug: bool, pub debug: bool,
pub redis_url: String, pub redis_url: String,
pub dac: DacFamily pub dac: DacFamily,
#[serde(default)]
pub transformers: Vec<TransformConf>
} }
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
@ -28,6 +31,15 @@ pub struct EtherDreamConf {
pub url: String pub url: String
} }
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum TransformConf {
#[serde(rename = "translate")]
Translate(transformer::Translate),
#[serde(rename = "replicate")]
Replicate(transformer::Replicate)
}
impl Conf { impl Conf {
pub fn new(path: &str) -> LJResult<Conf> { pub fn new(path: &str) -> LJResult<Conf> {
let settings = Config::builder() let settings = Config::builder()
@ -37,4 +49,31 @@ impl Conf {
let conf : Conf = settings.try_deserialize()?; let conf : Conf = settings.try_deserialize()?;
Ok(conf) Ok(conf)
} }
pub fn get_transformers(&self) -> Vec<Box<dyn transformer::Transformers>> {
let mut v = vec![];
for t in &self.transformers {
let t : Box<dyn transformer::Transformers> = match t {
TransformConf::Translate(t) => Box::new(*t),
TransformConf::Replicate(r) => Box::new(*r)
};
v.push(t);
}
v
}
#[allow(dead_code)]
pub fn dump() {
let conf = Conf { laser_id: 0,
debug: true,
redis_url: "redis://127.0.0.1:6379/".to_string(),
dac: DacFamily::Helios(HeliosConf { id: 0 }),
transformers: vec![
TransformConf::Translate(transformer::Translate::new(2000.0,2000.0)),
TransformConf::Replicate(transformer::Replicate::Until(48))
]
};
let s = toml::to_string(&conf).unwrap();
println!("{}", s);
}
} }

View File

@ -2,7 +2,7 @@ use crate::point::Point;
mod helios; mod helios;
use crate::conf::{Conf, DacFamily, EtherDreamConf, HeliosConf}; use crate::conf::{Conf, DacFamily, /*EtherDreamConf, HeliosConf*/};
use crate::device::helios::HeliosDevice; use crate::device::helios::HeliosDevice;
use crate::errors::LJResult; use crate::errors::LJResult;
@ -29,7 +29,7 @@ pub struct Status {
pub trait Device { pub trait Device {
fn status( &self ) -> Status; fn status( &self ) -> Status;
fn draw( fn draw(
&self, &mut self,
frame: Vec<Point>, frame: Vec<Point>,
speed: u32, speed: u32,
) -> LJResult<()> ; ) -> LJResult<()> ;

31
src/device/common.rs Normal file
View File

@ -0,0 +1,31 @@
/*
self.protocol_version,
self.le_state,
self.playback_state,
self.source,
self.le_flags,
self.playback_flags,
self.source_flags,
self.fullness,
self.point_rate,
self.point_count
*/
pub struct Status {
pub active: bool,
pub last_traced_at: String,
pub properties: Vec<String>
}
pub trait Device {
/**
fn intersect(&self, orig : &Vec3, dir : &Vec3) -> Option<Float>;
fn get_surface(&self, v : &Vec3) -> Vec3;
fn get_normal(&self, v : &Vec3) -> Vec3;
fn get_material(&self) -> &dyn Material;
**/
fn status( &self ) -> Status;
}

View File

@ -5,10 +5,10 @@
use helios_dac::{NativeHeliosDac, NativeHeliosDacController}; use helios_dac::{NativeHeliosDac, NativeHeliosDacController};
use helios_dac::{ use helios_dac::{
// Coordinate, // Coordinate,
Color, // Color,
DeviceStatus, DeviceStatus,
Frame, Frame,
Point as HeliosPoint, // Point as HeliosPoint,
}; };
use crate::conf::HeliosConf; use crate::conf::HeliosConf;
use crate::device::{Device, Status}; use crate::device::{Device, Status};
@ -29,22 +29,20 @@ impl HeliosDevice {
return Err(Box::new(LJError::HeliosDeviceMissing)); return Err(Box::new(LJError::HeliosDeviceMissing));
}; };
let dac = device.open()?; let dac = device.open()?;
Ok(Self { Ok(Self { conf: (*conf).clone(), dac })
conf: (*conf).clone(), dac,
})
} }
} }
impl Device for HeliosDevice { impl Device for HeliosDevice {
fn status(&self) -> Status { fn status(&self) -> Status {
return Status { Status {
active: true, active: true,
last_traced_at: "now".to_string(), last_traced_at: "now".to_string(),
properties: vec!["foo".to_string()], properties: vec!["foo".to_string()],
}; }
} }
fn draw(&self, fn draw(&mut self,
line: Vec<Point>, line: Vec<Point>,
speed: u32, speed: u32,
) -> LJResult<()> { ) -> LJResult<()> {
@ -52,6 +50,11 @@ impl Device for HeliosDevice {
let points: Vec<helios_dac::Point> = line.into_iter().map(|p| p.into()).collect(); let points: Vec<helios_dac::Point> = line.into_iter().map(|p| p.into()).collect();
let frame = Frame::new(speed, points); let frame = Frame::new(speed, points);
while let Ok(DeviceStatus::NotReady) = self.dac.status() {
self.dac.write_frame(frame.clone())?;
}
Ok(()) Ok(())
} }

View File

@ -1,5 +1,6 @@
pub mod conf;
pub mod redis_ctrl; pub mod redis_ctrl;
pub mod conf;
pub mod errors; pub mod errors;
pub mod device; pub mod device;
pub mod point; pub mod point;
pub mod transformer;

View File

@ -10,20 +10,17 @@ mod transformer;
mod device; mod device;
use device::device_factory; use device::device_factory;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc; use std::sync::Arc;
use redis_ctrl::{RedisCtrl, Order}; use redis_ctrl::{RedisCtrl, Order};
use conf::Conf; use conf::Conf;
use errors::{LJError, LJResult}; use errors::LJResult;
use point::Point; use point::Point;
use transformer::{Transformers, Translate, Replicate}; use transformer::Transformers;
use log::{LevelFilter, info, /* warn, */ error}; use log::{LevelFilter, info, /* warn, */ error};
use env_logger::Builder; use env_logger::Builder;
const DEFAULT_CONF_FILE: &str = "settings.toml"; const DEFAULT_CONF_FILE: &str = "settings.toml";
const CENTER: (f32, f32) = (2000.0, 2000.0);
pub fn main() { pub fn main() {
match run_all() { match run_all() {
@ -35,16 +32,18 @@ pub fn main() {
} }
fn run_all() -> LJResult<()> { fn run_all() -> LJResult<()> {
// Setup configuration file and set up logs // Setup configuration file and set up logs
let filename = std::env::args().nth(1).unwrap_or_else(|| { let filename = std::env::args().nth(1).unwrap_or_else(|| {
DEFAULT_CONF_FILE.to_string() DEFAULT_CONF_FILE.to_string()
}); });
let config = Conf::new(&filename); let config = Conf::new(&filename);
init_logging(&config); init_logging(&config);
let config = config?; let config = config?;
info!("*** Starting up ***"); info!("*** Starting up ***");
info!("{:?}", config);
// Setup Redis Service // Setup Redis Service
let mut rs = RedisCtrl::new(&config.redis_url)?; let mut rs = RedisCtrl::new(&config.redis_url)?;
@ -62,11 +61,7 @@ fn run_all() -> LJResult<()> {
//dbg!(tracer); //dbg!(tracer);
// Setup geometry transformers on points lists // Setup geometry transformers on points lists
// @todo use the config let transformers = config.get_transformers();
let transformers: Vec<Box<dyn Transformers>> = vec![
Box::new(Translate::new(CENTER.0, CENTER.1)),
Box::new(Replicate::Until(48)),
];
// Dispatch based on redis requests // Dispatch based on redis requests
while running.load(Ordering::SeqCst) { while running.load(Ordering::SeqCst) {
@ -74,6 +69,7 @@ fn run_all() -> LJResult<()> {
if order != Order::Draw { if order != Order::Draw {
info!("Order: {:?}", order); info!("Order: {:?}", order);
} }
let frame = get_next_frame(&config, &transformers, let frame = get_next_frame(&config, &transformers,
&mut rs, order == Order::Black)?; &mut rs, order == Order::Black)?;

View File

@ -1,60 +1,13 @@
//pub mod common;
mod translate;
mod replicate;
use crate::point::Point; use crate::point::Point;
// re-export transformers to be abe to use it directly from transformer::
pub use translate::Translate;
pub use replicate::Replicate;
pub trait Transformers { pub trait Transformers {
fn apply(&self, point_list: &[Point]) -> Vec<Point>; fn apply(&self, point_list: &[Point]) -> Vec<Point>;
} }
/// Translate
#[derive(Debug,Clone,Copy)]
pub struct Translate {
x: f32,
y: f32
}
impl Translate {
pub fn new(x: f32, y: f32) -> Self {
Self { x, y }
}
}
impl Transformers for Translate {
fn apply(&self, point_list: &[Point]) -> Vec<Point> {
point_list.iter()
.map(| pt | {
Point { x: pt.x + self.x,
y: pt.y + self.y,
..*pt
}
}).collect()
}
}
/// Replicate
#[allow(dead_code)]
#[derive(Debug,Clone,Copy)]
pub enum Replicate {
Until(usize),
Times(usize)
}
impl Transformers for Replicate {
fn apply(&self, point_list: &[Point]) -> Vec<Point> {
let mut point_list2 = vec![];
match self {
Replicate::Until(n) => {
while point_list2.len() < *n {
point_list2.append(&mut point_list.to_vec());
}
},
Replicate::Times(n) => {
for _ in 0..*n {
point_list2.append(&mut point_list.to_vec());
}
}
}
point_list2
}
}

View File

@ -0,0 +1,32 @@
use crate::transformer::Transformers;
use crate::point::Point;
use serde::{Serialize,Deserialize};
/// Replicate
#[allow(dead_code)]
#[derive(Serialize,Deserialize,Debug,Clone,Copy)]
pub enum Replicate {
Until(usize),
Times(usize)
}
impl Transformers for Replicate {
fn apply(&self, point_list: &[Point]) -> Vec<Point> {
let mut point_list2 = vec![];
match self {
Replicate::Until(n) => {
while point_list2.len() < *n {
point_list2.append(&mut point_list.to_vec());
}
},
Replicate::Times(n) => {
for _ in 0..*n {
point_list2.append(&mut point_list.to_vec());
}
}
}
point_list2
}
}

View File

@ -0,0 +1,29 @@
use crate::transformer::Transformers;
use crate::point::Point;
use serde::{Serialize,Deserialize};
/// Translate
#[derive(Serialize,Deserialize,Debug,Clone,Copy)]
pub struct Translate {
x: f32,
y: f32
}
impl Translate {
pub fn new(x: f32, y: f32) -> Self {
Self { x, y }
}
}
impl Transformers for Translate {
fn apply(&self, point_list: &[Point]) -> Vec<Point> {
point_list.iter()
.map(| pt | {
Point { x: pt.x + self.x,
y: pt.y + self.y,
..*pt
}
}).collect()
}
}