Cleanup edge to the last node when done with pathfinding
This commit is contained in:
+47
-11
@@ -18,11 +18,20 @@ pub struct Edge {
|
|||||||
pub struct Node {
|
pub struct Node {
|
||||||
pub point: Point,
|
pub point: Point,
|
||||||
edges: Option<Vec<Edge>>,
|
edges: Option<Vec<Edge>>,
|
||||||
|
final_edge: Option<Option<Edge>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node {
|
impl Node {
|
||||||
pub fn new(point: Point) -> Self {
|
pub fn new(point: Point) -> Self {
|
||||||
Self { point, edges: None }
|
Self {
|
||||||
|
point,
|
||||||
|
edges: None,
|
||||||
|
final_edge: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn iter_edges(&self) -> std::iter::Chain<std::slice::Iter<'_, Edge>, std::option::Iter<'_, Edge>> {
|
||||||
|
self.edges.as_ref().unwrap().iter().chain(self.final_edge.as_ref().unwrap().iter())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +59,10 @@ impl From<DiscoveredNode> for DiscoveredNodePtr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct NodeStorage(Vec<NodePtr>);
|
pub struct NodeStorage {
|
||||||
|
regular_nodes: Vec<NodePtr>,
|
||||||
|
final_node: Option<NodePtr>,
|
||||||
|
}
|
||||||
|
|
||||||
impl NodeStorage {
|
impl NodeStorage {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
@@ -58,16 +70,30 @@ impl NodeStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn push(&mut self, node: NodePtr) {
|
fn push(&mut self, node: NodePtr) {
|
||||||
self.0.push(node);
|
self.regular_nodes.push(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn initialize_edges(&mut self, node: &NodePtr) {
|
||||||
|
if node.borrow().final_edge.is_none() {
|
||||||
|
let final_edge = self
|
||||||
|
.final_node
|
||||||
|
.as_ref()
|
||||||
|
.filter(|neighbor| {
|
||||||
|
!collides_with_wall(node.borrow().point, neighbor.borrow().point)
|
||||||
|
})
|
||||||
|
.map(|neighbor| Edge {
|
||||||
|
target: neighbor.clone(),
|
||||||
|
cost: node.borrow().point.distance_to(neighbor.borrow().point),
|
||||||
|
});
|
||||||
|
node.borrow_mut().final_edge = Some(final_edge);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize_edges(&self, node: &NodePtr) {
|
|
||||||
if node.borrow().edges.is_some() {
|
if node.borrow().edges.is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let point = node.borrow().point;
|
let point = node.borrow().point;
|
||||||
let mut edges = Vec::new();
|
let mut edges = Vec::new();
|
||||||
for neighbor in &self.0 {
|
for neighbor in &self.regular_nodes {
|
||||||
if Rc::ptr_eq(neighbor, node) {
|
if Rc::ptr_eq(neighbor, node) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -80,12 +106,22 @@ impl NodeStorage {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node.borrow_mut().edges = Some(edges);
|
node.borrow_mut().edges = Some(edges);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter(&self) -> std::slice::Iter<'_, NodePtr> {
|
pub fn cleanup_final_edges(&mut self) {
|
||||||
self.0.iter()
|
for node in &self.regular_nodes {
|
||||||
|
node.borrow_mut().final_edge = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter(
|
||||||
|
&self,
|
||||||
|
) -> std::iter::Chain<
|
||||||
|
std::slice::Iter<'_, Rc<RefCell<Node>>>,
|
||||||
|
std::option::Iter<'_, Rc<RefCell<Node>>>,
|
||||||
|
> {
|
||||||
|
self.regular_nodes.iter().chain(self.final_node.iter())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,9 +173,9 @@ impl Pathfinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_path(&mut self, from: Point, to: Point) -> Option<DiscoveredNodePtr> {
|
pub fn find_path(&mut self, from: Point, to: Point) -> Option<DiscoveredNodePtr> {
|
||||||
|
self.nodes.cleanup_final_edges();
|
||||||
let mut nodes = self.nodes.clone();
|
let mut nodes = self.nodes.clone();
|
||||||
nodes.push(NodePtr::from(Node::new(from)));
|
nodes.final_node = Some(NodePtr::from(Node::new(from)));
|
||||||
let nodes = nodes;
|
|
||||||
let to_node = NodePtr::from(Node::new(to));
|
let to_node = NodePtr::from(Node::new(to));
|
||||||
nodes.initialize_edges(&to_node);
|
nodes.initialize_edges(&to_node);
|
||||||
let to = DiscoveredNode {
|
let to = DiscoveredNode {
|
||||||
@@ -169,7 +205,7 @@ impl Pathfinder {
|
|||||||
return Some(current_node);
|
return Some(current_node);
|
||||||
}
|
}
|
||||||
previous_nodes.insert(current_node.borrow().node.clone());
|
previous_nodes.insert(current_node.borrow().node.clone());
|
||||||
for edge in current_node.borrow().node.borrow().edges.as_ref().unwrap() {
|
for edge in current_node.borrow().node.borrow().iter_edges() {
|
||||||
let neighbor = &edge.target;
|
let neighbor = &edge.target;
|
||||||
if previous_nodes.contains(neighbor) {
|
if previous_nodes.contains(neighbor) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user