diff --git a/Cargo.toml b/Cargo.toml index ec24376..94f8e3d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ derive-getters = "0.5" derive_more = { version = "2.1", features = ["full"] } serde = { version = "1", features = ["derive", "rc"] } thiserror = "2.0" -undoredo = { version = "0.8", features = ["stable-vec"] } +undoredo = { version = "0.10", features = ["derive", "stable-vec", "rstar"] } [profile.release] opt-level = 2 # Fast and small WASM. diff --git a/topola/Cargo.toml b/topola/Cargo.toml index 0e26470..4fd4922 100644 --- a/topola/Cargo.toml +++ b/topola/Cargo.toml @@ -14,7 +14,7 @@ dearcut = { version = "0.3", features = ["serde", "undoredo"] } derive-getters.workspace = true derive_more.workspace = true i_triangle = "0.40" -polygon_unionfind = "0.5" +polygon_unionfind = "0.7" rstar = "0.12" serde.workspace = true spade = "2.15" diff --git a/topola/src/board.rs b/topola/src/board.rs index 2c571b2..6c05fcf 100644 --- a/topola/src/board.rs +++ b/topola/src/board.rs @@ -201,11 +201,11 @@ pub struct BoardHalfDelta { } impl ApplyDelta for Board { - fn apply_delta(&mut self, delta: &Delta) { - let (removed, inserted) = delta.clone().dissolve(); + fn apply_delta(&mut self, delta: Delta) { + let (removed, inserted) = delta.dissolve(); let layout_delta = Delta::with_removed_inserted(removed.layout, inserted.layout); - self.layout.apply_delta(&layout_delta); + self.layout.apply_delta(layout_delta); } } diff --git a/topola/src/connectivity.rs b/topola/src/connectivity.rs index 605ca83..411a576 100644 --- a/topola/src/connectivity.rs +++ b/topola/src/connectivity.rs @@ -16,13 +16,13 @@ impl Connectivity { pub fn new(board: &Board) -> Self { let mut this = Connectivity { joints_unionfind: UnionFind::with_len( - board.layout().joints().collection().num_elements(), + board.layout().joints().container().num_elements(), ), segments_unionfind: UnionFind::with_len( - board.layout().segments().collection().num_elements(), + board.layout().segments().container().num_elements(), ), polygons_unionfind: UnionFind::with_len( - board.layout().polygons().collection().num_elements(), + board.layout().polygons().container().num_elements(), ), }; diff --git a/topola/src/layout.rs b/topola/src/layout.rs index 3f2876e..09e04c0 100644 --- a/topola/src/layout.rs +++ b/topola/src/layout.rs @@ -2,9 +2,7 @@ // // SPDX-License-Identifier: MIT OR Apache-2.0 -use std::collections::BTreeMap; - -use derive_getters::{Dissolve, Getters}; +use derive_getters::Getters; use derive_more::Constructor; use rstar::{ AABB, RTree, @@ -12,7 +10,8 @@ use rstar::{ }; use serde::{Deserialize, Serialize}; use stable_vec::StableVec; -use undoredo::{ApplyDelta, Delta, FlushDelta, Recorder}; +use undoredo::aliases::RTreeHalfDelta; +use undoredo::{Delta, Recorder}; use crate::{ Joint, JointId, Polygon, PolygonId, Segment, SegmentId, Vector2, Via, ViaId, @@ -64,12 +63,16 @@ impl NetId { } } -#[derive(Clone, Debug, Getters)] +#[derive(Delta, Clone, Debug, Getters)] pub struct Layout { + #[undoredo(skip)] boundary: Vec<[i64; 2]>, + #[undoredo(skip)] place_boundary: Vec<[i64; 2]>, + #[undoredo(skip)] layer_count: usize, + #[undoredo(skip)] pins: StableVec, joints: Recorder>, @@ -77,10 +80,22 @@ pub struct Layout { vias: Recorder>, polygons: Recorder>, - joints_rtree: Recorder, JointId>>>, - segments_rtree: Recorder, SegmentId>>>, - vias_rtree: Recorder, ViaId>>>, - polygons_rtree: Recorder, PolygonId>>>, + joints_rtree: Recorder< + RTree, JointId>>, + RTreeHalfDelta, JointId>>, + >, + segments_rtree: Recorder< + RTree, SegmentId>>, + RTreeHalfDelta, SegmentId>>, + >, + vias_rtree: Recorder< + RTree, ViaId>>, + RTreeHalfDelta, ViaId>>, + >, + polygons_rtree: Recorder< + RTree, PolygonId>>, + RTreeHalfDelta, PolygonId>>, + >, } impl Layout { @@ -201,7 +216,7 @@ impl Layout { .as_ref() .locate_all_at_point(&[point.x, point.y, layer as i64]) .map(|geom_with_data| geom_with_data.data) - .filter(move |joint_id| { + .filter(move |&joint_id| { self.joints .get(&joint_id.index()) .unwrap() @@ -232,7 +247,7 @@ impl Layout { .as_ref() .locate_all_at_point(&[point.x, point.y, layer as i64]) .map(|geom_with_data| geom_with_data.data) - .filter(move |polygon_id| { + .filter(move |&polygon_id| { self.polygons .get(&polygon_id.index()) .unwrap() @@ -290,57 +305,3 @@ impl Layout { &self.pins[pin_id.index()] } } - -#[derive(Clone, Debug, Dissolve)] -pub struct LayoutHalfDelta { - joints: BTreeMap, - segments: BTreeMap, - vias: BTreeMap, - polygons: BTreeMap, -} - -impl ApplyDelta for Layout { - fn apply_delta(&mut self, delta: &Delta) { - let (removed, inserted) = delta.clone().dissolve(); - - let joints_delta = Delta::with_removed_inserted(removed.joints, inserted.joints); - self.joints.apply_delta(&joints_delta); - - let segments_delta = Delta::with_removed_inserted(removed.segments, inserted.segments); - self.segments.apply_delta(&segments_delta); - - let vias_delta = Delta::with_removed_inserted(removed.vias, inserted.vias); - self.vias.apply_delta(&vias_delta); - - let polygons_delta = Delta::with_removed_inserted(removed.polygons, inserted.polygons); - self.polygons.apply_delta(&polygons_delta); - - // TODO R-trees. - } -} - -impl FlushDelta for Layout { - fn flush_delta(&mut self) -> Delta { - let (removed_joints, inserted_joints) = self.joints.flush_delta().dissolve(); - let (removed_segments, inserted_segments) = self.segments.flush_delta().dissolve(); - let (removed_vias, inserted_vias) = self.vias.flush_delta().dissolve(); - let (removed_polygons, inserted_polygons) = self.polygons.flush_delta().dissolve(); - - // TODO R-trees. - - Delta::with_removed_inserted( - LayoutHalfDelta { - joints: removed_joints, - segments: removed_segments, - vias: removed_vias, - polygons: removed_polygons, - }, - LayoutHalfDelta { - joints: inserted_joints, - segments: inserted_segments, - vias: inserted_vias, - polygons: inserted_polygons, - }, - ) - } -} diff --git a/topola/src/navmesher.rs b/topola/src/navmesher.rs index cceb41a..e22e4e7 100644 --- a/topola/src/navmesher.rs +++ b/topola/src/navmesher.rs @@ -6,6 +6,7 @@ use dearcut::{RecordingTriangulator, VertexId}; use derive_getters::Getters; use derive_more::Constructor; use serde::{Deserialize, Serialize}; +use stable_vec::StableVec; use undoredo::Recorder; use crate::{Board, Joint, JointId, Polygon, PolygonId, Segment, SegmentId, Vector2}; @@ -176,9 +177,9 @@ pub struct NavmesherBoard { navmesher: Navmesher, board: Board, - joint_multiobstacles: Recorder>, - segment_multiobstacles: Recorder>, - polygon_multiobstacles: Recorder>, + joint_multiobstacles: Recorder>, + segment_multiobstacles: Recorder>, + polygon_multiobstacles: Recorder>, } impl NavmesherBoard { @@ -194,12 +195,12 @@ impl NavmesherBoard { ), board, - joint_multiobstacles: Recorder::new(Vec::new()), - segment_multiobstacles: Recorder::new(Vec::new()), - polygon_multiobstacles: Recorder::new(Vec::new()), + joint_multiobstacles: Recorder::new(StableVec::new()), + segment_multiobstacles: Recorder::new(StableVec::new()), + polygon_multiobstacles: Recorder::new(StableVec::new()), }; - for (i, joint) in this.board.layout().joints().collection() { + for (i, joint) in this.board.layout().joints().container().iter() { this.joint_multiobstacles.insert( i, this.navmesher @@ -207,7 +208,7 @@ impl NavmesherBoard { ); } - for (i, segment) in this.board.layout().segments().collection() { + for (i, segment) in this.board.layout().segments().container().iter() { this.segment_multiobstacles.insert( i, this.navmesher @@ -215,7 +216,7 @@ impl NavmesherBoard { ); } - for (i, polygon) in this.board.layout().polygons().collection() { + for (i, polygon) in this.board.layout().polygons().container().iter() { this.polygon_multiobstacles.insert( i, this.navmesher diff --git a/topola/src/ratsnest.rs b/topola/src/ratsnest.rs index a842549..9ea08b3 100644 --- a/topola/src/ratsnest.rs +++ b/topola/src/ratsnest.rs @@ -46,7 +46,7 @@ impl Ratsnest { let mut triangulations: BTreeMap<(NetId, usize), DelaunayTriangulation> = BTreeMap::new(); - for (i, joint) in board.layout().joints().collection() { + for (i, joint) in board.layout().joints().container().iter() { let _ = triangulations .entry((joint.net, joint.layer)) .or_insert_with(DelaunayTriangulation::new) @@ -58,7 +58,7 @@ impl Ratsnest { }); } - for (i, segment) in board.layout().segments().collection() { + for (i, segment) in board.layout().segments().container().iter() { let segment_center = segment.center(); let _ = triangulations .entry((segment.net, segment.layer)) @@ -71,7 +71,7 @@ impl Ratsnest { }); } - for (i, polygon) in board.layout().polygons().collection() { + for (i, polygon) in board.layout().polygons().container().iter() { let _ = triangulations .entry((polygon.net, polygon.layer)) .or_insert_with(DelaunayTriangulation::new)