use super::types::*;
pub struct SwarmControl<'a, ItemType, Properties> {
pub(crate) max: &'a usize,
pub(crate) spawns: &'a mut Vec<Spawn>,
pub(crate) free: &'a mut Vec<Spawn>,
pub(crate) order: &'a mut Vec<usize>,
pub(crate) len: usize,
pub(crate) pos: usize,
pub pool: &'a mut Vec<ItemType>,
pub properties: &'a mut Properties,
}
impl<'a, ItemType, Properties> SwarmControl<'a, ItemType, Properties>
where ItemType: Default + Clone {
pub fn target(&mut self) -> &mut ItemType {
&mut self.pool[self.pos]
}
pub fn target_spawn(&self) -> Spawn {
self.spawns[self.pos].mirror()
}
pub fn head(&self) -> ObjectPosition {
self.order[self.pos]
}
pub fn fetch_spawn(&self, pos: &ObjectPosition) -> Spawn {
self.spawns[*pos].mirror()
}
pub fn fetch(&mut self, spawn: &Spawn) -> &mut ItemType {
&mut self.pool[spawn.0.borrow().pos]
}
pub fn fetch_ref(&self, spawn: &Spawn) -> &ItemType {
&self.pool[spawn.0.borrow().pos]
}
pub fn count(&self) -> usize { self.len }
pub fn capacity(&self) -> usize { self.max.clone() }
pub fn find<Predicate> (&self, predicate: Predicate) -> Option<Spawn>
where Predicate: Fn(&ItemType) -> bool {
let count = self.len;
let mut i = 0;
while &i < &count {
if predicate(&self.pool[self.order[i]]) {
return Some(self.spawns[i].mirror());
}
i += 1;
}
return None
}
pub fn for_while<Predicate> (&self, predicate: Predicate) -> Option<Spawn>
where Predicate: Fn(&ItemType) -> bool {
let count = self.len;
let mut i = 0;
while &i < &count {
if predicate(&self.pool[self.order[i]]) {
return Some( self.spawns[i].mirror());
}
i += 1;
}
return None
}
pub fn enumerate(&mut self, handler: EnumerateHandler<ItemType>) {
let len = self.len;
let mut i = 0;
while &i < &len {
handler(&i, &mut self.pool[i]);
i += 1;
}
}
pub fn for_each(&mut self, handler: ForEachHandler<ItemType>) {
let count = self.len;
let mut i = 0;
while &i < &count {
handler(&mut self.pool[self.order[i]]);
i += 1;
}
}
pub fn for_all(&mut self, handler: ForAllHandler<ItemType, Properties>) {
let len = self.len;
let mut i = 0;
while &i < &len {
handler(&i, &mut self.pool, &mut self.properties);
i += 1;
}
}
pub fn spawn(&mut self) -> Option<Spawn> {
if self.len < *self.max {
self.len += 1;
let pos = self.len - 1;
if self.free.len() > 0 {
self.free.pop().map(|s| {
s.0.borrow_mut().pos = pos;
s.0.borrow_mut().active = true;
s
})
} else {
let s = &self.spawns[pos];
s.0.borrow_mut().pos = pos;
s.0.borrow_mut().active = true;
Some(s.mirror())
}
} else {
None
}
}
pub fn kill_current(&mut self) {
self.kill(&self.target_spawn())
}
pub fn kill(&mut self, target: &Spawn) {
target.0.borrow_mut().active = false;
let last_pos = self.len - 1;
let target_pos = target.pos();
if self.len > 1 && target_pos < last_pos {
let last_val = self.pool[last_pos].clone();
let target_val = self.pool[target_pos].clone();
self.pool[target_pos] = last_val;
self.pool[last_pos] = target_val;
self.spawns[target_pos] = self.spawns[last_pos].mirror();
self.spawns[last_pos] = target.mirror();
self.spawns[target_pos].0.borrow_mut().pos = target_pos;
self.spawns[last_pos].0.borrow_mut().pos = last_pos;
if target_pos > self.pos { self.order[target_pos] = last_pos; }
if last_pos > self.pos { self.order[last_pos] = target_pos; }
}
if self.len > 0 {
self.free.push(target.mirror());
self.len -= 1;
}
}
}