use std::any::Any;
use soil_core::AtomData;
pub const CONTACT_HISTORY_LEN: usize = 23;
pub type ContactHistory = [f64; CONTACT_HISTORY_LEN];
pub struct ContactHistoryStore {
pub contacts: Vec<Vec<(u32, ContactHistory, bool)>>,
}
impl ContactHistoryStore {
pub fn new() -> Self {
ContactHistoryStore {
contacts: Vec::new(),
}
}
}
impl AtomData for ContactHistoryStore {
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
fn snapshot(&self) -> Box<dyn AtomData> {
Box::new(ContactHistoryStore {
contacts: self.contacts.clone(),
})
}
fn len(&self) -> usize {
self.contacts.len()
}
unsafe fn push_default(&mut self) {
self.contacts.push(Vec::new());
}
unsafe fn truncate(&mut self, n: usize) {
self.contacts.resize_with(n, Vec::new);
self.contacts.truncate(n);
}
unsafe fn swap_remove(&mut self, i: usize) {
if i < self.contacts.len() {
self.contacts.swap_remove(i);
}
}
unsafe fn apply_permutation(&mut self, perm: &[usize], n: usize) {
let new_contacts: Vec<Vec<(u32, ContactHistory, bool)>> =
perm.iter().map(|&p| self.contacts[p].clone()).collect();
self.contacts[..n].clone_from_slice(&new_contacts);
}
fn pack(&self, i: usize, buf: &mut Vec<f64>) {
if i < self.contacts.len() {
let list = &self.contacts[i];
buf.push(list.len() as f64);
for &(tag, ref s, _) in list {
buf.push(tag as f64);
for value in s {
buf.push(*value);
}
}
} else {
buf.push(0.0); }
}
unsafe fn unpack(&mut self, buf: &[f64]) -> usize {
let count = buf[0] as usize;
let mut list = Vec::with_capacity(count);
let mut pos = 1;
let old_seven_slot_format = buf.len() == 1 + count * 8;
let old_eight_slot_format = buf.len() == 1 + count * 9;
for _ in 0..count {
let tag = buf[pos] as u32;
let mut s = [0.0; CONTACT_HISTORY_LEN];
if old_seven_slot_format {
s[..7].copy_from_slice(&buf[pos + 1..pos + 8]);
pos += 8;
} else if old_eight_slot_format {
s[..8].copy_from_slice(&buf[pos + 1..pos + 9]);
pos += 9;
} else {
s[..CONTACT_HISTORY_LEN]
.copy_from_slice(&buf[pos + 1..pos + 1 + CONTACT_HISTORY_LEN]);
pos += 1 + CONTACT_HISTORY_LEN;
}
list.push((tag, s, false));
}
self.contacts.push(list);
pos
}
}