lj_rust/src/main.rs

199 lines
4.6 KiB
Rust
Raw Normal View History

2023-06-01 21:11:40 +00:00
///
/// Configure udev:
/// https://github.com/Grix/helios_dac/blob/master/docs/udev_rules_for_linux.md
///
2023-06-03 13:21:36 +00:00
mod redis_ctrl;
mod conf;
mod errors;
2023-06-04 19:31:32 +00:00
mod point;
2023-06-05 09:21:16 +00:00
mod transformer;
2023-06-05 19:03:55 +00:00
mod device;
2023-06-29 20:36:00 +00:00
mod worldstate;
2023-06-05 19:03:55 +00:00
use device::device_factory;
2023-06-03 13:21:36 +00:00
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
2023-07-09 20:44:15 +00:00
use redis_ctrl::{RedisCtrl, Order};
2023-06-04 10:08:44 +00:00
use conf::Conf;
2023-06-07 15:26:30 +00:00
use errors::LJResult;
2023-07-09 20:16:01 +00:00
use point::{Point, Color};
2023-06-07 16:25:33 +00:00
use transformer::Transformers;
use log::{LevelFilter, info, /* warn, */ error};
2023-06-05 11:07:43 +00:00
use env_logger::Builder;
2023-06-29 20:36:00 +00:00
use worldstate::WorldState;
2023-06-01 21:11:40 +00:00
2023-06-05 19:03:55 +00:00
const DEFAULT_CONF_FILE: &str = "settings.toml";
2023-06-01 21:11:40 +00:00
2023-06-05 19:03:55 +00:00
pub fn main() {
match run_all() {
Ok(()) => {}
Err(err) => {
error!("Error: {}", err);
}
2023-06-03 16:11:55 +00:00
}
}
2023-06-29 20:36:00 +00:00
2023-06-04 13:09:15 +00:00
fn run_all() -> LJResult<()> {
// 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 configuration file and set up logs
2023-06-05 19:03:55 +00:00
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 ***");
2023-06-07 15:26:30 +00:00
info!("{:?}", config);
// Setup Redis Service
2023-06-12 17:23:59 +00:00
let mut rs = RedisCtrl::new(&config.redis_url, &config.laser_id)?;
2023-06-05 19:03:55 +00:00
let mut world_state = rs.init_world_state().unwrap();
2023-07-09 20:16:01 +00:00
info!("WorldState: {:?}", world_state);
2023-06-05 19:03:55 +00:00
// Setup Laser Device based on conf
let mut tracer = device_factory(&config)?;
2023-07-09 20:16:01 +00:00
world_state.grid = tracer.grid();
// can't work, but we can add + Debug to Device to make it work...
//dbg!(tracer);
2023-06-03 14:20:35 +00:00
// Setup geometry transformers on points lists
2023-06-29 20:36:00 +00:00
let transformers = config.get_transformers();
2023-06-05 19:03:55 +00:00
// Dispatch based on redis requests
2023-06-05 19:03:55 +00:00
while running.load(Ordering::SeqCst) {
2023-06-29 20:36:00 +00:00
rs.set_status(tracer.status())?;
2023-06-05 19:03:55 +00:00
let order = rs.get_order(config.laser_id)?;
2023-06-29 20:36:00 +00:00
match order {
2023-07-09 20:16:01 +00:00
Order::Draw | Order::Black | Order::Grid => {
2023-07-09 20:44:15 +00:00
// 0 : Draw Normal point list
// 2 : Draw BLACK point list
// 3 : Draw GRID point list
2023-07-09 20:16:01 +00:00
world_state.draw_black = order == Order::Black;
world_state.draw_grid = order == Order::Grid;
2023-06-29 20:36:00 +00:00
let frame = get_next_frame(
&config,
&transformers,
2023-07-09 20:16:01 +00:00
&mut rs,
&world_state,
2023-06-29 20:36:00 +00:00
)?;
// For now, draw all the time
2023-07-06 20:17:49 +00:00
tracer.draw(frame, world_state.kpps)?;
2023-07-09 20:16:01 +00:00
}
Order::Intensity => {
2023-07-09 20:44:15 +00:00
// 6 : Max Intensity Change = reread redis key /intensity
2023-07-09 20:16:01 +00:00
world_state.intensity = rs.get_int("intensity")?
.try_into()?;
}
2023-06-29 20:36:00 +00:00
Order::Edh => {
2023-07-09 20:44:15 +00:00
// 1 : Get the new EDH = reread redis key /EDH/lasernumber
2023-06-29 21:24:56 +00:00
world_state.edh = rs.get_edh()?;
2023-07-09 20:16:01 +00:00
}
2023-07-06 20:17:49 +00:00
Order::Kpps => {
2023-07-09 20:44:15 +00:00
// 7 : kpps change = reread redis key /kpps
2023-07-06 20:17:49 +00:00
world_state.kpps = rs.get_int("kpps")?;
2023-07-09 20:16:01 +00:00
}
2023-07-09 20:44:15 +00:00
Order::ClientKey => {
world_state.client_key = rs.get_client_key()?;
}
2023-06-29 20:36:00 +00:00
// Order::ColorBalance => {},
_ => {
2023-07-09 20:44:15 +00:00
// 4 : Resampler Change (longs and shorts lsteps)
// 5 : Client Key Change = reread redis key /clientkey
// 8 : color balance change = reread redis keys /red /green /blue
2023-07-16 18:28:06 +00:00
// 9 : poweroff LJ
2023-06-29 20:36:00 +00:00
info!("Order: {:?}", order);
}
2023-06-05 19:03:55 +00:00
}
2023-06-01 21:11:40 +00:00
}
2023-06-03 13:21:36 +00:00
2023-06-05 19:03:55 +00:00
info!("Exiting, stoping device.");
tracer.stop()?;
2023-06-05 19:03:55 +00:00
Ok(())
2023-06-01 21:11:40 +00:00
}
2023-06-05 11:07:43 +00:00
fn init_logging(config: &LJResult<Conf>) {
2023-06-05 19:03:55 +00:00
if let Ok(ref config) = config {
let level = if config.debug {
LevelFilter::Debug
} else {
LevelFilter::Info
};
let mut builder = Builder::from_default_env();
builder
.filter(None, level)
.init();
info!("Debug mode enabled from configuration file");
return;
2023-06-05 11:07:43 +00:00
}
2023-06-05 19:03:55 +00:00
info!("Logging level inherited from env");
env_logger::init();
2023-06-05 11:07:43 +00:00
}
2023-06-01 21:11:40 +00:00
fn get_next_frame(
2023-06-05 19:03:55 +00:00
config: &Conf,
transformers: &[Box<dyn Transformers>],
rs: &mut RedisCtrl,
2023-07-09 20:16:01 +00:00
world_state: &WorldState,
) -> LJResult<Vec<Point>> {
2023-07-09 20:16:01 +00:00
let format_key = format!("{}{}",
world_state.client_key,
config.laser_id);
// Handle the grid case
2023-07-16 18:28:06 +00:00
let mut line: Vec<Point> = if world_state.draw_grid {
world_state.grid.clone()
2023-07-09 20:16:01 +00:00
} else {
let redis_line = rs.get_line(&format_key)?;
2023-07-16 18:28:06 +00:00
redis_line.into_iter()
2023-07-09 20:16:01 +00:00
.map(|tpl| tpl.into())
2023-07-16 18:28:06 +00:00
.collect()
2023-07-09 20:16:01 +00:00
};
for transformer in transformers {
line = transformer.apply(&line, world_state);
}
// info!("Draw Black -> {}", world_state.draw_black);
// info!("Draw Grid -> {}", world_state.draw_grid);
2023-07-09 20:16:01 +00:00
// LIMITER and BLACK
line = line.into_iter()
.map(|p| {
let color = if world_state.draw_black {
Color { r: 0, g: 0, b: 0 }
} else {
Color {
r: p.color.r.min(world_state.intensity),
g: p.color.g.min(world_state.intensity),
b: p.color.b.min(world_state.intensity),
}
};
Point {
color,
..p
}
})
.collect();
//info!("Line: {:?}", line);
Ok(line)
2023-06-01 21:11:40 +00:00
}
2023-06-29 20:36:00 +00:00