use crate::util::*;
use num_traits::Zero;
use rayon::prelude::*;
#[derive(Clone, Debug)]
pub struct AbstractNode<T> {
pub size: T,
pub mass: T,
}
impl<T: Coord> Default for AbstractNode<T> {
fn default() -> Self {
AbstractNode {
size: T::one(),
mass: T::one(),
}
}
}
#[derive(Clone, Debug)]
pub struct Node<T, const N: usize> {
pub pos: VecN<T, N>,
pub speed: VecN<T, N>,
pub old_speed: VecN<T, N>,
pub size: T,
pub mass: T,
}
impl<T: Coord, const N: usize> Node<T, N> {
pub fn to_abstract(&self) -> AbstractNode<T> {
AbstractNode {
size: self.size,
mass: self.mass,
}
}
}
impl<T: Coord, const N: usize> Default for Node<T, N> {
fn default() -> Self {
Node {
pos: Zero::zero(),
speed: Zero::zero(),
old_speed: Zero::zero(),
size: T::one(),
mass: T::one(),
}
}
}
pub trait Nodes<T, const N: usize, Id> {
fn iter_nodes<'a>(&'a self) -> impl Iterator<Item = &'a Node<T, N>>
where
T: 'a;
fn iter_nodes_mut<'a>(&'a mut self) -> impl Iterator<Item = &'a mut Node<T, N>>
where
T: 'a;
fn par_iter_nodes_mut<'a>(&'a mut self) -> impl ParallelIterator<Item = &'a mut Node<T, N>>
where
T: 'a + Send,
Id: Sync;
fn get_2_mut(&mut self, i1: Id, i2: Id) -> (&mut Node<T, N>, &mut Node<T, N>);
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
}
pub type NodeVec<T, const N: usize> = Vec<Node<T, N>>;
impl<T: Clone, const N: usize> Nodes<T, N, usize> for NodeVec<T, N> {
fn iter_nodes<'a>(&'a self) -> impl Iterator<Item = &'a Node<T, N>>
where
T: 'a,
{
self.iter()
}
fn iter_nodes_mut<'a>(&'a mut self) -> impl Iterator<Item = &'a mut Node<T, N>>
where
T: 'a,
{
self.iter_mut()
}
fn par_iter_nodes_mut<'a>(&'a mut self) -> impl ParallelIterator<Item = &'a mut Node<T, N>>
where
T: 'a + Send,
{
self.par_iter_mut()
}
fn get_2_mut(&mut self, i1: usize, i2: usize) -> (&mut Node<T, N>, &mut Node<T, N>) {
let (i1, i2) = if i1 < i2 { (i1, i2) } else { (i2, i1) };
let (s1, s2) = self.split_at_mut(i2);
(&mut s1[i1], &mut s2[0])
}
fn len(&self) -> usize {
self.len()
}
}
pub type NodeHashMap<T, const N: usize, Id> = std::collections::HashMap<Id, Node<T, N>>;
impl<T: Clone, const N: usize, Id: Eq + std::hash::Hash> Nodes<T, N, Id> for NodeHashMap<T, N, Id> {
fn iter_nodes<'a>(&'a self) -> impl Iterator<Item = &'a Node<T, N>>
where
T: 'a,
{
self.values()
}
fn iter_nodes_mut<'a>(&'a mut self) -> impl Iterator<Item = &'a mut Node<T, N>>
where
T: 'a,
{
self.values_mut()
}
fn par_iter_nodes_mut<'a>(&'a mut self) -> impl ParallelIterator<Item = &'a mut Node<T, N>>
where
T: 'a + Send,
Id: Sync,
{
self.par_iter_mut().map(|(_id, node)| node)
}
fn get_2_mut(&mut self, i1: Id, i2: Id) -> (&mut Node<T, N>, &mut Node<T, N>) {
let [n1, n2] = self.get_disjoint_mut([&i1, &i2]);
(n1.unwrap(), n2.unwrap())
}
fn len(&self) -> usize {
self.len()
}
}
pub trait BuildableNodes<T, const N: usize, Id> {
fn add_node(&mut self, id: Id, node: Node<T, N>);
}
impl<T: Clone, const N: usize> BuildableNodes<T, N, usize> for NodeVec<T, N> {
fn add_node(&mut self, id: usize, node: Node<T, N>) {
assert_eq!(id, self.len(), "not contiguous node id");
self.push(node);
}
}
impl<T: Clone, const N: usize, Id: Eq + std::hash::Hash> BuildableNodes<T, N, Id>
for NodeHashMap<T, N, Id>
{
fn add_node(&mut self, id: Id, node: Node<T, N>) {
if self.insert(id, node).is_some() {
panic!("node id already exists");
}
}
}