wip refactor without rc/refcell
This commit is contained in:
parent
6a0f480c8a
commit
0b892980ca
@ -27,6 +27,15 @@ impl Attractor {
|
||||
}
|
||||
}
|
||||
|
||||
/// A Node of the graph that is connected to one or more other nodes
|
||||
///
|
||||
/// Use cases :
|
||||
/// - Rendering
|
||||
/// - Must be easy and fast to find connections
|
||||
/// - Must know the number of descendent generations to calculate vein thickness
|
||||
/// - Growing
|
||||
/// - Must be easy and fast to find nodes in a cell
|
||||
/// - Probably worth marking nodes as dead when no attractor is in range
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Node {
|
||||
pub position: Point,
|
||||
|
||||
@ -1,6 +1,4 @@
|
||||
use log::info;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, PartialOrd)]
|
||||
pub struct Point {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
@ -46,6 +44,25 @@ impl Point {
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Point {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
if self.x > other.x {
|
||||
return std::cmp::Ordering::Greater;
|
||||
}
|
||||
if self.x < other.x {
|
||||
return std::cmp::Ordering::Less;
|
||||
}
|
||||
if self.y > other.y {
|
||||
return std::cmp::Ordering::Greater;
|
||||
}
|
||||
if self.y < other.y {
|
||||
return std::cmp::Ordering::Less;
|
||||
}
|
||||
|
||||
std::cmp::Ordering::Equal
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Point;
|
||||
@ -164,28 +181,35 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scale_does_nothing_when_right_length() {
|
||||
fn movement_does_nothing_when_right_length() {
|
||||
let root = Point::new((0,0));
|
||||
let node = Point::new((0,1));
|
||||
assert_eq!(root.movement(node.clone(), 1), node);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scale_adjusts_to_asked_length() {
|
||||
fn movement_does_not_overlap() {
|
||||
let root = Point::new((0,1));
|
||||
let node = Point::new((0,0));
|
||||
assert_eq!(root.movement(node.clone(), 2), node);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn movement_adjusts_to_asked_length() {
|
||||
let root = Point::new((0,0));
|
||||
let node = Point::new((0,1));
|
||||
assert_eq!(root.movement(node, 10), Point::new((0,10)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scale_works_away_from_origin() {
|
||||
fn movement_works_away_from_origin() {
|
||||
let root = Point::new((10,10));
|
||||
let node = Point::new((10,11));
|
||||
assert_eq!(root.movement(node, 10), Point::new((10,20)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scale_works_in_two_dimension() {
|
||||
fn movement_works_in_two_dimension() {
|
||||
let root = Point::new((10,10));
|
||||
let node = Point::new((40,50));
|
||||
assert_eq!(root.movement(node, 50), Point::new((40,50)));
|
||||
@ -196,7 +220,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scale_works_in_all_directions() {
|
||||
fn movement_works_in_all_directions() {
|
||||
let root = Point::new((40,50));
|
||||
let node = Point::new((10,10));
|
||||
assert_eq!(root.movement(node, 5), Point::new((37,46)));
|
||||
|
||||
@ -102,7 +102,7 @@ impl SpaceColonization {
|
||||
F: Copy + Fn(&Node, &Node),
|
||||
{
|
||||
info!("Rendering {} nodes", self.nodes.len());
|
||||
for n in self.nodes_tree.iter() {
|
||||
for n in self.nodes.iter() {
|
||||
n.render(render_id, render_fn);
|
||||
}
|
||||
}
|
||||
@ -221,8 +221,25 @@ impl SpaceColonization {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::cell::RefCell;
|
||||
|
||||
use super::*;
|
||||
|
||||
fn assert_nodes(sc: &SpaceColonization, expected_nodes: Vec<(Point, Point)>) {
|
||||
let rendered_nodes = RefCell::new(Vec::new());
|
||||
sc.render_nodes(0.0, |n1, n2| {
|
||||
rendered_nodes.borrow_mut().push((n1.position, n2.position));
|
||||
});
|
||||
|
||||
rendered_nodes.borrow_mut().sort_by(|line1, line2| {
|
||||
if line1.0 != line2.0 {
|
||||
return line1.0.cmp(&line2.0);
|
||||
}
|
||||
|
||||
return line1.1.cmp(&line2.1);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grow_should_reach_single_attractor_and_die() {
|
||||
let mut nodes = Vec::new();
|
||||
@ -232,62 +249,33 @@ mod test {
|
||||
|
||||
let sc = SpaceColonization::new_for_tests(100, 100, nodes, attractors);
|
||||
|
||||
assert_nodes(&sc, Vec::from([(Point::new((0,0)), Point::new((10,0)))]));
|
||||
assert_eq!(sc.attractors.len(), 1);
|
||||
assert!(sc
|
||||
.attractors
|
||||
.iter()
|
||||
.find(|a| a.dead == true)
|
||||
.is_none());
|
||||
assert_eq!(sc.nodes_tree[0].children.len(), 0);
|
||||
|
||||
sc.grow();
|
||||
|
||||
assert_eq!(sc.new_nodes.len(), 0);
|
||||
assert_eq!(sc.nodes_tree.[0].children.len(), 1);
|
||||
assert!(sc
|
||||
.attractors
|
||||
.iter()
|
||||
.find(|a| a.dead == true)
|
||||
.is_none());
|
||||
assert_eq!(
|
||||
sc.nodes_tree.[0].children.[0].position,
|
||||
Point::new((3, 0))
|
||||
);
|
||||
assert_eq!(
|
||||
sc.nodes_tree[0].children.len(),
|
||||
1,
|
||||
);
|
||||
assert_eq!(
|
||||
sc.nodes_tree.len(),
|
||||
1,
|
||||
);
|
||||
println!("root node direct children iteration 1 {:?}", sc.nodes_tree.[0].children);
|
||||
// TODO assert point 3,0
|
||||
|
||||
sc.grow();
|
||||
|
||||
assert_eq!(
|
||||
sc.nodes_tree.len(),
|
||||
1,
|
||||
);
|
||||
assert_eq!(sc
|
||||
.attractors
|
||||
.iter()
|
||||
.filter(|a| a.dead == true)
|
||||
.collect::<Vec<&Attractor>>().len(), 1);
|
||||
|
||||
println!("root node direct children iteration 2 {:?}", sc.nodes_tree.[0].children);
|
||||
assert_eq!(
|
||||
sc.nodes_tree[0].children.len(),
|
||||
1,
|
||||
);
|
||||
assert_eq!(
|
||||
sc.nodes_tree[0].children[0].position,
|
||||
Point::new((3, 0))
|
||||
);
|
||||
assert_eq!(
|
||||
sc.nodes_tree[0].children[0].children[0].position,
|
||||
Point::new((6, 0))
|
||||
);
|
||||
// TODO assert nodes 3,0 and 6,0
|
||||
assert_eq!(sc.nodes.len(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user