use crate::types::{DacCapabilities, DacType, LaserPoint};
pub use crate::error::{Error, Result};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WriteOutcome {
Written,
WouldBlock,
}
pub trait DacBackend: Send + 'static {
fn dac_type(&self) -> DacType;
fn caps(&self) -> &DacCapabilities;
fn connect(&mut self) -> Result<()>;
fn disconnect(&mut self) -> Result<()>;
fn is_connected(&self) -> bool;
fn stop(&mut self) -> Result<()>;
fn set_shutter(&mut self, open: bool) -> Result<()>;
}
pub trait FifoBackend: DacBackend {
fn try_write_points(&mut self, pps: u32, points: &[LaserPoint]) -> Result<WriteOutcome>;
fn queued_points(&self) -> Option<u64> {
None
}
}
pub trait FrameSwapBackend: DacBackend {
fn frame_capacity(&self) -> usize;
fn is_ready_for_frame(&mut self) -> bool;
fn write_frame(&mut self, pps: u32, points: &[LaserPoint]) -> Result<WriteOutcome>;
}
pub enum BackendKind {
Fifo(Box<dyn FifoBackend>),
FrameSwap(Box<dyn FrameSwapBackend>),
}
impl BackendKind {
pub fn dac_type(&self) -> DacType {
match self {
BackendKind::Fifo(b) => b.dac_type(),
BackendKind::FrameSwap(b) => b.dac_type(),
}
}
pub fn caps(&self) -> &DacCapabilities {
match self {
BackendKind::Fifo(b) => b.caps(),
BackendKind::FrameSwap(b) => b.caps(),
}
}
pub fn connect(&mut self) -> Result<()> {
match self {
BackendKind::Fifo(b) => b.connect(),
BackendKind::FrameSwap(b) => b.connect(),
}
}
pub fn disconnect(&mut self) -> Result<()> {
match self {
BackendKind::Fifo(b) => b.disconnect(),
BackendKind::FrameSwap(b) => b.disconnect(),
}
}
pub fn is_connected(&self) -> bool {
match self {
BackendKind::Fifo(b) => b.is_connected(),
BackendKind::FrameSwap(b) => b.is_connected(),
}
}
pub fn stop(&mut self) -> Result<()> {
match self {
BackendKind::Fifo(b) => b.stop(),
BackendKind::FrameSwap(b) => b.stop(),
}
}
pub fn set_shutter(&mut self, open: bool) -> Result<()> {
match self {
BackendKind::Fifo(b) => b.set_shutter(open),
BackendKind::FrameSwap(b) => b.set_shutter(open),
}
}
pub fn try_write(&mut self, pps: u32, points: &[LaserPoint]) -> Result<WriteOutcome> {
match self {
BackendKind::Fifo(b) => b.try_write_points(pps, points),
BackendKind::FrameSwap(b) => b.write_frame(pps, points),
}
}
pub fn queued_points(&self) -> Option<u64> {
match self {
BackendKind::Fifo(b) => b.queued_points(),
BackendKind::FrameSwap(_) => None,
}
}
pub fn is_frame_swap(&self) -> bool {
matches!(self, BackendKind::FrameSwap(_))
}
pub fn is_ready_for_frame(&mut self) -> bool {
match self {
BackendKind::Fifo(_) => true,
BackendKind::FrameSwap(b) => b.is_ready_for_frame(),
}
}
pub fn frame_capacity(&self) -> Option<usize> {
match self {
BackendKind::Fifo(_) => None,
BackendKind::FrameSwap(b) => Some(b.frame_capacity()),
}
}
}
#[cfg(feature = "helios")]
pub use crate::protocols::helios::HeliosBackend;
#[cfg(feature = "ether-dream")]
pub use crate::protocols::ether_dream::EtherDreamBackend;
#[cfg(feature = "idn")]
pub use crate::protocols::idn::IdnBackend;
#[cfg(feature = "lasercube-wifi")]
pub use crate::protocols::lasercube_wifi::LasercubeWifiBackend;
#[cfg(feature = "lasercube-usb")]
pub use crate::protocols::lasercube_usb::LasercubeUsbBackend;
#[cfg(feature = "avb")]
pub use crate::protocols::avb::AvbBackend;