lj_rust/src/main.rs

165 lines
3.8 KiB
Rust

///
/// Configure udev:
/// https://github.com/Grix/helios_dac/blob/master/docs/udev_rules_for_linux.md
///
mod redis_ctrl;
mod conf;
mod errors;
mod point;
mod transformer;
mod device;
mod worldstate;
use device::device_factory;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use redis_ctrl::{RedisCtrl, Order};
use conf::Conf;
use errors::LJResult;
use point::Point;
use transformer::Transformers;
use log::{LevelFilter, info, /* warn, */ error};
use env_logger::Builder;
use worldstate::WorldState;
const DEFAULT_CONF_FILE: &str = "settings.toml";
pub fn main() {
match run_all() {
Ok(()) => {}
Err(err) => {
error!("Error: {}", err);
}
}
}
fn run_all() -> LJResult<()> {
// Setup configuration file and set up logs
let filename = std::env::args().nth(1).unwrap_or_else(|| {
DEFAULT_CONF_FILE.to_string()
});
let config = Conf::new(&filename);
init_logging(&config);
let config = config?;
info!("*** Starting up ***");
info!("{:?}", config);
// Setup Redis Service
let mut rs = RedisCtrl::new(&config.redis_url, &config.laser_id)?;
let mut world_state = rs.init_world_state()?;
info!("WorldState: {:?}", world_state);
// Setup handler for interrupt Signals
let running = Arc::new(AtomicBool::new(true));
let r = running.clone();
ctrlc::set_handler(move || {
r.store(false, Ordering::SeqCst);
})?;
// Setup Laser Device based on conf
let mut tracer = device_factory(&config)?;
// can't work, but we can add + Debug to Device to make it work...
//dbg!(tracer);
// Setup geometry transformers on points lists
let transformers = config.get_transformers();
// Dispatch based on redis requests
while running.load(Ordering::SeqCst) {
rs.set_status(tracer.status())?;
let order = rs.get_order(config.laser_id)?;
// 0 : Draw Normal point list
// 2 : Draw BLACK point list
// 3 : Draw GRID point list
// /worldstate.rs
// /edh.rs
// 1 : Get the new EDH = reread redis key /EDH/lasernumber
// 4 : Resampler Change (longs and shorts lsteps)
// 5 : Client Key Change = reread redis key /clientkey
// 6 : Max Intensity Change = reread redis key /intensity
// 7 : kpps change = reread redis key /kpps
// 8 : color balance change = reread redis keys /red /green /blue
match order {
Order::Draw => {
let frame = get_next_frame(
&config,
&transformers,
&mut rs,
&world_state
)?;
// For now, draw all the time
tracer.draw(frame, world_state.kpps)?;
},
Order::Intensity => {
world_state.intensity = rs.get_int("intensity")?
.try_into()?;
},
Order::Black => {
},
Order::Edh => {
world_state.edh = rs.get_edh()?;
},
Order::Kpps => {
world_state.kpps = rs.get_int("kpps")?;
},
// Order::ClientKey => rs.client_key(),
// Order::ColorBalance => {},
_ => {
info!("Order: {:?}", order);
}
}
}
info!("Exiting, stoping device.");
tracer.stop()?;
Ok(())
}
fn init_logging(config: &LJResult<Conf>) {
if let Ok(ref config) = config {
if config.debug {
let mut builder = Builder::from_default_env();
builder
.filter(None, LevelFilter::Info)
.init();
info!("Debug mode enabled from configuration file");
return;
}
}
info!("Logging level inherited from env");
env_logger::init();
}
fn get_next_frame(
config: &Conf,
transformers: &[Box<dyn Transformers>],
rs: &mut RedisCtrl,
world_state : &WorldState
) -> LJResult<Vec<Point>> {
let format_key = format!("{}{}",
world_state.client_key,
config.laser_id);
let line = rs.get_line(&format_key)?;
let mut line: Vec<Point> = line.into_iter()
.map(|tpl| tpl.into())
.collect();
for transformer in transformers {
line = transformer.apply(&line, world_state);
}
//info!("Line: {:?}", line);
Ok(line)
}