use helios_dac_sys::*;
use crate::frame::*;
use crate::DeviceStatus;
pub struct HeliosDacWrapper {
dac: HeliosDac,
}
impl HeliosDacWrapper {
pub fn new() -> Self {
let dac = unsafe { HeliosDac::new() };
HeliosDacWrapper { dac }
}
pub fn open_devices(&mut self) -> Result<u32, HeliosError> {
let device_count = unsafe { self.dac.OpenDevices() };
if device_count < 0 {
parse_error(device_count)?;
}
Ok(device_count as u32)
}
pub fn close_devices(&mut self) -> Result<(), HeliosError> {
let result = unsafe { self.dac.CloseDevices() };
parse_error(result)
}
pub fn write_frame(&mut self, device_number: u32, frame: Frame) -> Result<(), HeliosError> {
let mut points = frame.points.into_iter().map(HeliosPoint::from).collect::<Vec<_>>();
let point_count = points.len() as u32;
let point_ptr = points.as_mut_ptr();
let result = unsafe { self.dac.WriteFrame(device_number, frame.pps, 0, point_ptr, point_count) };
parse_error(result)
}
pub fn status(&mut self, device_number: u32) -> Result<DeviceStatus, HeliosError> {
let status = unsafe { self.dac.GetStatus(device_number) };
if status < 0 {
parse_error(status)?;
}
match status {
0 => Ok(DeviceStatus::NotReady),
1 => Ok(DeviceStatus::Ready),
_ => unreachable!("invalid status returned")
}
}
pub fn firmware_version(&mut self, device_number: u32) -> Result<u32, HeliosError> {
let result = unsafe { self.dac.GetFirmwareVersion(device_number) };
if result < 0 {
parse_error(result)?;
}
Ok(result as u32)
}
pub fn name(&mut self, device_number: u32) -> Result<String, HeliosError> {
let mut name = String::new();
let name_ptr = name.as_mut_ptr() as *mut i8;
let result = unsafe { self.dac.GetName(device_number, name_ptr) };
parse_error(result)?;
Ok(name)
}
pub fn set_name(&mut self, device_number: u32, mut name: String) -> Result<(), HeliosError> {
let name_ptr = name.as_mut_ptr() as *mut i8;
let result = unsafe { self.dac.SetName(device_number, name_ptr) };
parse_error(result)
}
pub fn stop(&mut self, device_number: u32) -> Result<(), HeliosError> {
let result = unsafe { self.dac.Stop(device_number) };
parse_error(result)
}
pub fn set_shutter(&mut self, device_number: u32, level: bool) -> Result<(), HeliosError> {
let result = unsafe { self.dac.SetShutter(device_number, level) };
parse_error(result)
}
pub fn erase_firmware(&mut self, device_number: u32) -> Result<(), HeliosError> {
let result = unsafe { self.dac.EraseFirmware(device_number) };
parse_error(result)
}
}
fn parse_error(code: i32) -> Result<(), HeliosError> {
if code == helios_dac_sys::HELIOS_SUCCESS as i32 {
Ok(())
}else {
unimplemented!("error parsing not done yet")
}
}
#[derive(Debug)]
pub enum HeliosError {
NotInitialized = HELIOS_ERROR_NOT_INITIALIZED as isize,
InvalidDevNum = HELIOS_ERROR_INVALID_DEVNUM as isize,
NullPoints = HELIOS_ERROR_NULL_POINTS as isize,
TooManyPoints = HELIOS_ERROR_TOO_MANY_POINTS as isize,
PPSTooHigh = HELIOS_ERROR_PPS_TOO_HIGH as isize,
PPSTooLow = HELIOS_ERROR_PPS_TOO_LOW as isize,
DeviceClosed = HELIOS_ERROR_DEVICE_CLOSED as isize,
DeviceFrameReady = HELIOS_ERROR_DEVICE_FRAME_READY as isize,
DeviceSendControl = HELIOS_ERROR_DEVICE_SEND_CONTROL as isize,
DeviceResult = HELIOS_ERROR_DEVICE_RESULT as isize,
DeviceNullBuffer = HELIOS_ERROR_DEVICE_NULL_BUFFER as isize,
DeviceSignalTooLong = HELIOS_ERROR_DEVICE_SIGNAL_TOO_LONG as isize,
Libusb = HELIOS_ERROR_LIBUSB_BASE as isize
}
impl Drop for HeliosDacWrapper {
fn drop(&mut self) {
unsafe {
self.dac.destruct();
}
}
}
impl From<Point> for HeliosPoint {
fn from(point: Point) -> Self {
HeliosPoint {
x: point.coordinate.x,
y: point.coordinate.y,
r: point.color.r,
g: point.color.g,
b: point.color.b,
i: point.intensity
}
}
}