diff --git a/rust/src/js_api.rs b/rust/src/js_api.rs index 43ef77d..1334afc 100644 --- a/rust/src/js_api.rs +++ b/rust/src/js_api.rs @@ -24,9 +24,6 @@ extern "C" { pub type JsWall; pub type JsWallData; - #[wasm_bindgen(method, getter)] - fn id(this: &JsWall) -> String; - #[wasm_bindgen(method, getter)] fn data(this: &JsWall) -> JsWallData; @@ -100,9 +97,8 @@ impl TryFrom for DoorType { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy)] pub struct Wall { - pub id: String, pub p1: Point, pub p2: Point, pub door_type: DoorType, @@ -111,14 +107,12 @@ pub struct Wall { impl Wall { pub fn new( - id: String, p1: Point, p2: Point, door_type: DoorType, door_state: DoorState, ) -> Self { Self { - id, p1, p2, door_type, @@ -141,7 +135,6 @@ impl Wall { let mut c = data.c(); c.iter_mut().for_each(|val| *val = val.round()); Self::new( - wall.id(), Point::new(c[0], c[1]), Point::new(c[2], c[3]), data.door_type(), diff --git a/rust/src/pathfinder.rs b/rust/src/pathfinder.rs index 4e49db3..36ba062 100644 --- a/rust/src/pathfinder.rs +++ b/rust/src/pathfinder.rs @@ -18,8 +18,6 @@ pub struct Edge { pub struct Node { pub point: Point, edges: Option>, - dynamic_neighbors: Option>, - dynamic_edges: Option>, final_edge: Option>, } @@ -28,17 +26,18 @@ impl Node { Self { point, edges: None, - dynamic_neighbors: None, - dynamic_edges: None, final_edge: None, } } - fn iter_edges(&self) -> impl Iterator { - let edge_iter = self.edges.as_ref().unwrap().iter(); - let dynamic_edges_iter = self.dynamic_edges.as_ref().unwrap().iter(); - let final_edge_iter = self.final_edge.as_ref().unwrap().iter(); - edge_iter.chain(dynamic_edges_iter).chain(final_edge_iter) + fn iter_edges( + &self, + ) -> std::iter::Chain, std::option::Iter<'_, Edge>> { + self.edges + .as_ref() + .unwrap() + .iter() + .chain(self.final_edge.as_ref().unwrap().iter()) } } @@ -85,7 +84,7 @@ impl NodeStorage { self.regular_nodes.push(node); } - fn initialize_edges(&mut self, node: &NodePtr, walls: &WallStorage) { + fn initialize_edges(&mut self, node: &NodePtr, walls: &[LineSegment]) { if node.borrow().final_edge.is_none() { let final_edge = self .final_node @@ -93,7 +92,7 @@ impl NodeStorage { .filter(|neighbor| { !self.collides_with_wall( &LineSegment::new(node.borrow().point, neighbor.borrow().point), - walls.iter_all(), + walls, ) }) .map(|neighbor| Edge { @@ -103,63 +102,30 @@ impl NodeStorage { node.borrow_mut().final_edge = Some(final_edge); } - let persistent_initialized = node.borrow().edges.is_some(); - if persistent_initialized && node.borrow().dynamic_edges.is_some() { + if node.borrow().edges.is_some() { return; } let point = node.borrow().point; - let mut dynamic_edges = Vec::new(); - if persistent_initialized { - for neighbor in node.borrow().dynamic_neighbors.as_ref().unwrap() { - let neighbor_point = neighbor.borrow().point; - let line = LineSegment::new(point, neighbor_point); - if !self.collides_with_wall(&line, walls.iter_dynamic_active()) { - let cost = point.distance_to(neighbor_point); - let edge = Edge { - target: neighbor.clone(), - cost, - }; - dynamic_edges.push(edge); - } + let mut edges = Vec::new(); + for neighbor in &self.regular_nodes { + if Rc::ptr_eq(neighbor, node) { + continue; } - } else { - let mut edges = Vec::new(); - let mut dynamic_neighbors = Vec::new(); - for neighbor in &self.regular_nodes { - if Rc::ptr_eq(neighbor, node) { - continue; - } - let neighbor_point = neighbor.borrow().point; - let line = LineSegment::new(point, neighbor_point); - if !self.collides_with_wall(&line, &walls.persistent) { - let cost = point.distance_to(neighbor_point); - let edge = Edge { - target: neighbor.clone(), - cost, - }; - if self.collides_with_wall(&line, walls.iter_dynamic_active()) { - dynamic_neighbors.push(neighbor.clone()); - } else if self.collides_with_wall(&line, walls.iter_dynamic_inactive()) { - dynamic_neighbors.push(neighbor.clone()); - dynamic_edges.push(edge); - } else { - edges.push(edge); - } - } + let neighbor_point = neighbor.borrow().point; + if !self.collides_with_wall(&LineSegment::new(point, neighbor_point), walls) { + let cost = point.distance_to(neighbor_point); + edges.push(Edge { + target: neighbor.clone(), + cost, + }); } - node.borrow_mut().edges = Some(edges); } - node.borrow_mut().dynamic_edges = Some(dynamic_edges); + node.borrow_mut().edges = Some(edges); } - fn collides_with_wall<'a, I>(&self, line: &LineSegment, walls: I) -> bool - where - I: IntoIterator, - { - walls - .into_iter() - .any(|wall| line.intersection(wall).is_some()) + fn collides_with_wall(&self, line: &LineSegment, walls: &[LineSegment]) -> bool { + walls.iter().any(|wall| line.intersection(wall).is_some()) } pub fn cleanup_final_edges(&mut self) { @@ -173,50 +139,12 @@ impl NodeStorage { } } -#[derive(Debug, Clone, Copy)] -pub struct DynamicWall { - pub line: LineSegment, - pub active: bool, -} - -impl DynamicWall { - fn new(line: LineSegment, active: bool) -> Self { - Self { line, active } - } -} - -#[derive(Debug, Default)] -pub struct WallStorage { - pub persistent: Vec, - pub dynamic: FxHashMap, -} - -impl WallStorage { - pub fn iter_dynamic_inactive(&self) -> impl Iterator { - self.dynamic - .values() - .filter(|wall| !wall.active) - .map(|wall| &wall.line) - } - - pub fn iter_dynamic_active(&self) -> impl Iterator { - self.dynamic - .values() - .filter(|wall| wall.active) - .map(|wall| &wall.line) - } - - pub fn iter_all(&self) -> impl Iterator { - self.persistent.iter().chain(self.iter_dynamic_active()) - } -} - #[wasm_bindgen] pub struct Pathfinder { #[wasm_bindgen(skip)] pub nodes: NodeStorage, #[wasm_bindgen(skip)] - pub walls: WallStorage, + pub walls: Vec, } impl Pathfinder { @@ -226,8 +154,7 @@ impl Pathfinder { { let distance_from_walls = token_size / 2.0; let mut endpoints = FxHashMap::>::default(); - let mut wall_storage = WallStorage::default(); - + let mut line_segments = Vec::new(); for wall in walls { let x_diff = wall.p2.x - wall.p1.x; let y_diff = wall.p2.y - wall.p1.y; @@ -237,15 +164,7 @@ impl Pathfinder { let angles = endpoints.entry(point).or_insert_with(Vec::new); angles.push(angle); } - let line = LineSegment::new(wall.p1, wall.p2); - if !wall.is_door() { - wall_storage.persistent.push(line); - } else { - let is_open = wall.is_open(); - wall_storage - .dynamic - .insert(wall.id, DynamicWall::new(line, !is_open)); - } + line_segments.push(LineSegment::new(wall.p1, wall.p2)); } endpoints .values_mut() @@ -269,20 +188,20 @@ impl Pathfinder { point, angle_between, distance_from_walls, - &mut wall_storage.persistent, + &mut line_segments, )); } nodes.push(calc_pathfinding_node( point, angle1 + 0.5 * PI, distance_from_walls, - &mut wall_storage.persistent, + &mut line_segments, )); nodes.push(calc_pathfinding_node( point, angle2 - 0.5 * PI, distance_from_walls, - &mut wall_storage.persistent, + &mut line_segments, )); } let angle1 = angles.last().unwrap(); @@ -297,26 +216,26 @@ impl Pathfinder { point, angle_between, distance_from_walls, - &mut wall_storage.persistent, + &mut line_segments, )); } nodes.push(calc_pathfinding_node( point, angle1 + 0.5 * PI, distance_from_walls, - &mut wall_storage.persistent, + &mut line_segments, )); nodes.push(calc_pathfinding_node( point, angle2 - 0.5 * PI, distance_from_walls, - &mut wall_storage.persistent, + &mut line_segments, )); } // TODO Eliminating nodes close to each other may improve performance Self { nodes, - walls: wall_storage, + walls: line_segments, } }