#![allow(dead_code)]
use crate::util::utils::GroupErrors;
use std::sync::Arc;
use vexide_async::sync::Mutex;
use vexide_devices::adi::digital::*;
#[derive(Clone)]
pub struct SolenoidGroup {
pneumatics: Arc<Mutex<Vec<AdiDigitalOut>>>,
}
impl SolenoidGroup {
pub fn new(pneumatics: Vec<AdiDigitalOut>) -> Self {
SolenoidGroup {
pneumatics: Arc::new(Mutex::new(pneumatics)),
}
}
pub async fn use_at<F, R>(&self, index: usize, f: F) -> R
where
F: FnOnce(&mut AdiDigitalOut) -> R
{
let mut guard = self.pneumatics.lock().await;
f(&mut guard[index])
}
pub async fn set_level(&self, logic: LogicLevel) -> Result<(), GroupErrors> {
let mut guard = self.pneumatics.lock().await;
let ret: GroupErrors = guard
.iter_mut()
.filter_map(|sol| sol.set_level(logic).err())
.collect();
if ret.is_empty() { Ok(()) } else { Err(ret) }
}
pub async fn extend(&self) -> Result<(), GroupErrors> {
self.set_level(LogicLevel::High).await
}
pub async fn retract(&self) -> Result<(), GroupErrors> {
self.set_level(LogicLevel::Low).await
}
pub async fn toggle(&self) -> Result<(), GroupErrors> {
let mut guard = self.pneumatics.lock().await;
let ret: GroupErrors = guard
.iter_mut()
.filter_map(|sol| sol.toggle().err())
.collect();
if ret.is_empty() { Ok(()) } else { Err(ret) }
}
pub async fn is_level(&self, logic: LogicLevel) -> bool {
let guard = self.pneumatics.lock().await;
guard.iter().all(|sol| sol.level().unwrap_or(!logic) == logic)
}
}