use crate::error::InternalError;
use crate::event::Channel;
use std::collections::HashMap;
use std::ops::{Index, IndexMut};
pub struct State {
toggles: Vec<ToggleState>,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct ToggleIndex(usize);
impl State {
pub fn new() -> State {
State {
toggles: Vec::new(),
}
}
pub fn push_toggle(&mut self, value: ToggleState) -> ToggleIndex {
self.toggles.push(value);
ToggleIndex(self.toggles.len() - 1)
}
pub fn get_toggles_except<'a>(
&'a mut self,
excluded_indices: &'a [ToggleIndex],
) -> impl Iterator<Item = &'a mut ToggleState> {
self.toggles
.iter_mut()
.enumerate()
.filter(move |(index, _)| {
!excluded_indices
.iter()
.any(|excluded_index| *index == excluded_index.0)
})
.map(|(_, item)| item)
}
pub fn create_toggle_with_size(&mut self, size: usize) -> Result<ToggleIndex, InternalError> {
let toggle_state = ToggleState::new(size)?;
Ok(self.push_toggle(toggle_state))
}
}
impl Index<ToggleIndex> for State {
type Output = ToggleState;
fn index(&self, index: ToggleIndex) -> &ToggleState {
&self.toggles[index.0]
}
}
impl IndexMut<ToggleIndex> for State {
fn index_mut(&mut self, index: ToggleIndex) -> &mut ToggleState {
&mut self.toggles[index.0]
}
}
pub struct ToggleState {
value: usize,
size: usize,
pub memory: HashMap<Channel, usize>,
}
impl ToggleState {
pub fn new(size: usize) -> Result<ToggleState, InternalError> {
if size > 0 {
Ok(ToggleState {
size,
value: 0,
memory: HashMap::new(),
})
} else {
Err(InternalError::new("A toggle requires at least one state."))
}
}
pub fn advance(&mut self) {
self.value += 1;
self.value %= self.size;
}
pub fn value(&self) -> usize {
self.value
}
pub fn set_value_wrapped(&mut self, value: usize) {
self.value = value % self.size
}
pub fn size(&self) -> usize {
self.size
}
}