use crate::Unit;
use std::ops::{Deref, DerefMut};
#[derive(PartialEq, Debug, Clone, Copy)]
pub struct Particle<T: Copy> {
pub pos: T,
pub vel: T,
pub fit: f64,
pub best_pos: T,
pub best_fit: f64,
}
pub struct ParticleRefMut<'a, T> {
pub pos: &'a mut T,
pub vel: &'a mut T,
pub fit: &'a mut f64,
pub best_pos: &'a mut T,
pub best_fit: &'a mut f64,
}
impl<T: Copy> Particle<T> {
pub fn as_ref_mut(&mut self) -> ParticleRefMut<'_, T> {
ParticleRefMut {
pos: &mut self.pos,
vel: &mut self.vel,
fit: &mut self.fit,
best_pos: &mut self.best_pos,
best_fit: &mut self.best_fit,
}
}
}
#[derive(Clone, Debug)]
pub struct Group<T: Copy> {
particles: Vec<Particle<T>>,
}
impl<T: Copy> Group<T> {
#[must_use]
pub fn new() -> Self {
Self {
particles: Vec::new(),
}
}
#[must_use]
pub fn with_capacity(n: usize) -> Self {
Self {
particles: Vec::with_capacity(n),
}
}
pub fn push(&mut self, particle: Particle<T>) {
self.particles.push(particle);
}
}
impl<T: Copy> Default for Group<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: Copy> Deref for Group<T> {
type Target = [Particle<T>];
fn deref(&self) -> &[Particle<T>] {
&self.particles
}
}
impl<T: Copy> DerefMut for Group<T> {
fn deref_mut(&mut self) -> &mut [Particle<T>] {
&mut self.particles
}
}
impl<T: Copy> From<Vec<Particle<T>>> for Group<T> {
fn from(particles: Vec<Particle<T>>) -> Self {
Self { particles }
}
}
impl<T: Copy> FromIterator<Particle<T>> for Group<T> {
fn from_iter<I: IntoIterator<Item = Particle<T>>>(iter: I) -> Self {
Self {
particles: iter.into_iter().collect(),
}
}
}
#[derive(Clone, Debug)]
#[must_use]
pub struct Evolution<T: Unit> {
frames: Vec<Vec<Particle<T>>>,
}
impl<T: Unit> Evolution<T> {
pub fn new() -> Self {
Self { frames: Vec::new() }
}
pub fn from_frames(frames: Vec<Vec<Particle<T>>>) -> Self {
Self { frames }
}
pub fn frames(&self) -> &[Vec<Particle<T>>] {
&self.frames
}
pub fn frames_mut(&mut self) -> &mut [Vec<Particle<T>>] {
&mut self.frames
}
pub fn push_snapshot(&mut self, group: &Group<T>) {
self.frames.push(group.to_vec());
}
}
impl<T: Unit> Default for Evolution<T> {
fn default() -> Self {
Self::new()
}
}