#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum EnabledState {
#[default]
Disabled,
EStopped,
Enabled,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum Mode {
#[default]
Teleop,
Auto,
Test,
}
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct JoystickData {
pub plugged_in: bool,
pub axies: [f32; 8],
pub buttons: [u8; 6],
pub povs: [i16; 3],
}
#[allow(missing_docs)]
#[derive(Debug, Clone, Copy, Default)]
pub struct StationData {
pub enabled_state: EnabledState,
pub mode: Mode,
pub station_attached: bool,
pub fms_attached: bool,
pub team_number: u16,
pub joysticks: [JoystickData; 8],
}
pub trait StationInterfaceDriver: 'static {
fn send_console_line_error(line: &str, location: &str, callstack: &str);
fn send_console_line_warn(line: &str, location: &str);
fn send_console_line_info(line: &str, location: &str);
fn send_console_line_debug(line: &str, location: &str);
fn refresh();
fn get_station_data() -> StationData;
}
#[derive(Debug, Clone, Copy)]
pub struct StationInterfaceVTable {
pub(crate) send_console_line_error: fn(line: &str, location: &str, callstack: &str),
pub(crate) send_console_line_warn: fn(line: &str, location: &str),
pub(crate) send_console_line_info: fn(line: &str, location: &str),
pub(crate) send_console_line_debug: fn(line: &str, location: &str),
pub(crate) refresh: fn(),
pub(crate) get_station_data: fn() -> StationData,
}
impl StationInterfaceVTable {
pub(crate) fn from_driver<T: StationInterfaceDriver>() -> Self {
assert!(
std::mem::size_of::<T>() == 0,
"Station Interface Driver must be zero sized"
);
Self {
send_console_line_error: T::send_console_line_error,
send_console_line_warn: T::send_console_line_warn,
send_console_line_info: T::send_console_line_info,
send_console_line_debug: T::send_console_line_debug,
refresh: T::refresh,
get_station_data: T::get_station_data,
}
}
pub fn send_console_line_error(&self, line: &str, location: &str, callstack: &str) {
(self.send_console_line_error)(line, location, callstack);
}
pub fn send_console_line_warn(&self, line: &str, location: &str) {
(self.send_console_line_warn)(line, location);
}
pub fn send_console_line_info(&self, line: &str, location: &str) {
(self.send_console_line_info)(line, location);
}
pub fn send_console_line_debug(&self, line: &str, location: &str) {
(self.send_console_line_debug)(line, location);
}
pub fn refresh(&self) {
(self.refresh)();
}
#[must_use]
pub fn get_station_data(&self) -> StationData {
(self.get_station_data)()
}
#[must_use]
pub fn is_enabled(&self) -> bool {
self.get_station_data().enabled_state == EnabledState::Enabled
}
#[must_use]
pub fn is_disabled(&self) -> bool {
self.get_station_data().enabled_state == EnabledState::Disabled
}
#[must_use]
pub fn is_estopped(&self) -> bool {
self.get_station_data().enabled_state == EnabledState::EStopped
}
#[must_use]
pub fn is_teleop(&self) -> bool {
self.get_station_data().mode == Mode::Teleop
}
#[must_use]
pub fn is_auto(&self) -> bool {
self.get_station_data().mode == Mode::Auto
}
#[must_use]
pub fn is_test(&self) -> bool {
self.get_station_data().mode == Mode::Test
}
#[must_use]
pub fn is_fms_attached(&self) -> bool {
self.get_station_data().fms_attached
}
#[must_use]
pub fn is_station_attached(&self) -> bool {
self.get_station_data().station_attached
}
#[must_use]
pub fn get_station_team_number(&self) -> u16 {
self.get_station_data().team_number
}
}