use std::error::Error;
use std::sync::mpsc::Sender;
use log::debug;
use super::analog_output::AxRequest;
use super::data_requests::{DataRequest};
use super::pulse_output::PxRequest;
pub(super) const NULL_REQ: [u8; 2] = [0, 0xFF];
pub(super) trait ScopeCommand {
fn fill_tx_buffer_legacy(&self, usb_buf: &mut [u8; 65]) -> Result<(), Box<dyn Error>>;
fn fill_tx_buffer(&self, usb_buf: &mut [u8; 64]) -> Result<(), Box<dyn Error>>;
fn handle_rx_legacy(&self, usb_buf: &[u8; 64]);
fn handle_rx(&self, usb_buf: &[u8; 64]);
fn is_finished(&self) -> bool;
}
#[derive(Debug)]
pub(crate) enum Command {
Quit,
Initialize(bool, Sender<()>),
SetAnalogOutput(AxRequest),
SetPulseOutput(PxRequest),
RequestData(DataRequest),
StopData,
}
impl Command {
pub(super) fn fill_tx_buffer_legacy(&mut self, usb_buf: &mut [u8; 65]) -> Result<(), Box<dyn Error>> {
debug!("Processed command: {self:?}");
match self {
Command::Quit => { Ok(()) }
Command::Initialize(power_on, _) => {
if *power_on {
usb_buf[1] = 0x07;
} else {
usb_buf[1] = 0x06;
}
Ok(())
}
Command::SetAnalogOutput(cmd) => { cmd.fill_tx_buffer_legacy(usb_buf) }
Command::SetPulseOutput(cmd) => { cmd.fill_tx_buffer_legacy(usb_buf) }
Command::RequestData(cmd) => { cmd.fill_tx_buffer_legacy(usb_buf) }
Command::StopData => {
usb_buf[1] = 0x05;
Ok(())
}
}
}
pub(super) fn handle_rx_legacy(&self, buffer: &[u8; 64]) {
match self {
Command::Quit => {}
Command::Initialize(_, _) => {}
Command::SetAnalogOutput(cmd) => { cmd.handle_rx_legacy(buffer) }
Command::SetPulseOutput(cmd) => { cmd.handle_rx_legacy(buffer) }
Command::RequestData(cmd) => { cmd.handle_rx_legacy(buffer) }
Command::StopData => {}
}
}
pub(super) fn handle_rx(&self, buffer: &[u8; 64]) {
match self {
Command::Quit => {}
Command::Initialize(_, sender) => { sender.send(()).unwrap() }
Command::SetAnalogOutput(cmd) => { cmd.handle_rx(buffer) }
Command::SetPulseOutput(cmd) => { cmd.handle_rx(buffer) }
Command::RequestData(cmd) => { cmd.handle_rx(buffer) }
Command::StopData => { }
}
}
pub(super) fn is_finished(&self) -> bool {
match self {
Command::Quit => { true }
Command::Initialize(_, _) => { true }
Command::SetAnalogOutput(cmd) => { cmd.is_finished() }
Command::SetPulseOutput(cmd) => { cmd.is_finished() }
Command::RequestData(cmd) => { cmd.is_finished() }
Command::StopData => { true }
}
}
pub(crate) fn id_byte(&self) -> u8 {
match self {
Command::Quit => { 0 }
Command::Initialize(_, _) => { 1 }
Command::SetAnalogOutput(_) => { 2 }
Command::SetPulseOutput(_) => { 3 }
Command::RequestData(_) => { 4 }
Command::StopData => { 5 }
}
}
}