From a911c0cddf20666c1c9eb3adde2d4f2511bee02a Mon Sep 17 00:00:00 2001 From: Alain Emilia Anna Zscheile Date: Fri, 3 Jan 2025 05:17:16 +0100 Subject: [PATCH] refactor: replace multiple custom Recording* structures with single generic Recording<'a, T> struct --- src/autorouter/autorouter.rs | 1 + src/autorouter/place_via.rs | 2 +- src/autorouter/remove_bands.rs | 2 +- src/board/mod.rs | 6 +- src/drawing/drawing.rs | 314 +++++++++++++-------------- src/geometry/edit.rs | 140 ++++++++++++ src/geometry/recording_with_rtree.rs | 84 +++---- src/geometry/with_rtree.rs | 49 +++-- src/layout/layout.rs | 48 ++-- src/router/draw.rs | 14 +- src/router/navcord.rs | 1 + src/router/navcorder.rs | 1 + 12 files changed, 379 insertions(+), 283 deletions(-) diff --git a/src/autorouter/autorouter.rs b/src/autorouter/autorouter.rs index 406e696..418e967 100644 --- a/src/autorouter/autorouter.rs +++ b/src/autorouter/autorouter.rs @@ -12,6 +12,7 @@ use thiserror::Error; use crate::{ board::{mesadata::AccessMesadata, Board}, drawing::{band::BandTermsegIndex, dot::FixedDotIndex, Infringement}, + geometry::edit::Recordable, layout::{via::ViaWeight, LayoutEdit}, router::{astar::AstarError, navmesh::NavmeshError, RouterOptions}, triangulation::GetTrianvertexNodeIndex, diff --git a/src/autorouter/place_via.rs b/src/autorouter/place_via.rs index 361f76c..7270780 100644 --- a/src/autorouter/place_via.rs +++ b/src/autorouter/place_via.rs @@ -9,7 +9,7 @@ use crate::{ board::mesadata::AccessMesadata, drawing::graph::PrimitiveIndex, - geometry::primitive::PrimitiveShape, + geometry::{edit::Recordable, primitive::PrimitiveShape}, layout::{via::ViaWeight, LayoutEdit}, router::{navcord::NavcordStepper, navmesh::Navmesh}, }; diff --git a/src/autorouter/remove_bands.rs b/src/autorouter/remove_bands.rs index 0cbcea6..44bf7f0 100644 --- a/src/autorouter/remove_bands.rs +++ b/src/autorouter/remove_bands.rs @@ -7,7 +7,7 @@ use crate::{ board::mesadata::AccessMesadata, drawing::graph::PrimitiveIndex, - geometry::primitive::PrimitiveShape, + geometry::{edit::Recordable, primitive::PrimitiveShape}, layout::LayoutEdit, router::{navcord::NavcordStepper, navmesh::Navmesh}, }; diff --git a/src/board/mod.rs b/src/board/mod.rs index 6daa3be..fa92c63 100644 --- a/src/board/mod.rs +++ b/src/board/mod.rs @@ -25,7 +25,11 @@ use crate::{ graph::{GetLayer, GetMaybeNet, PrimitiveIndex, PrimitiveWeight}, seg::{FixedSegIndex, FixedSegWeight, SegIndex, SegWeight}, }, - geometry::{edit::ApplyGeometryEdit, shape::AccessShape, GenericNode}, + geometry::{ + edit::{ApplyGeometryEdit, Recordable}, + shape::AccessShape, + GenericNode, + }, graph::GenericIndex, layout::{ poly::{GetMaybeApex, MakePolyShape, PolyWeight}, diff --git a/src/drawing/drawing.rs b/src/drawing/drawing.rs index a7124da..e11ab69 100644 --- a/src/drawing/drawing.rs +++ b/src/drawing/drawing.rs @@ -12,11 +12,9 @@ use thiserror::Error; use crate::geometry::{ compound::ManageCompounds, - edit::{ApplyGeometryEdit, GeometryEdit}, + edit::{ApplyGeometryEdit, GeometryEdit, Recordable, Recording}, primitive::{AccessPrimitiveShape, PrimitiveShape}, - recording_with_rtree::RecordingGeometryWithRtree, - with_rtree::BboxedIndex, - with_rtree::GeometryWithRtree, + with_rtree::{BboxedIndex, GeometryWithRtree}, AccessBendWeight, AccessDotWeight, AccessSegWeight, GenericNode, Geometry, GeometryLabel, GetOffset, GetPos, GetWidth, }; @@ -100,12 +98,18 @@ pub struct Drawing { rules: R, } -pub struct RecordingDrawing<'a, CW, R> { - pub drawing: &'a mut Drawing, - pub recorder: &'a mut DrawingEdit, +impl Recordable for Drawing { + type PW = PrimitiveWeight; + type DW = DotWeight; + type SW = SegWeight; + type BW = BendWeight; + type CW = CW; + type PI = PrimitiveIndex; + type DI = DotIndex; + type SI = SegIndex; + type BI = BendIndex; } -#[debug_invariant(self.test_if_looses_dont_infringe_each_other())] impl Drawing { pub fn new(rules: R, layer_count: usize) -> Self { Self { @@ -114,17 +118,6 @@ impl Drawing { } } - #[inline(always)] - pub fn recording<'a>( - &'a mut self, - recorder: &'a mut DrawingEdit, - ) -> RecordingDrawing<'a, CW, R> { - RecordingDrawing { - drawing: self, - recorder, - } - } - #[inline(always)] fn graph( &self, @@ -317,6 +310,8 @@ impl Drawing { self.geometry_with_rtree.graph().node_count() } + // used for constraints checking on nightly Rust + #[allow(unused)] fn test_if_looses_dont_infringe_each_other(&self) -> bool { !self .primitive_nodes() @@ -359,24 +354,33 @@ impl Drawing { } } -impl RecordingDrawing<'_, CW, R> { +impl Recording<'_, Drawing> { fn recording_geometry_with_rtree( &mut self, - ) -> RecordingGeometryWithRtree< + ) -> Recording< '_, - PrimitiveWeight, - DotWeight, - SegWeight, - BendWeight, - CW, - PrimitiveIndex, - DotIndex, - SegIndex, - BendIndex, + GeometryWithRtree< + PrimitiveWeight, + DotWeight, + SegWeight, + BendWeight, + CW, + PrimitiveIndex, + DotIndex, + SegIndex, + BendIndex, + >, > { - self.drawing.geometry_with_rtree.recording(self.recorder) + self.inner.geometry_with_rtree.recording(self.recorder) } + pub fn rules_mut(&mut self) -> &mut R { + &mut self.inner.rules + } +} + +#[debug_invariant(self.inner.test_if_looses_dont_infringe_each_other())] +impl Recording<'_, Drawing> { pub fn remove_band(&mut self, band: BandTermsegIndex) -> Result<(), DrawingException> { match band { BandTermsegIndex::Straight(seg) => { @@ -406,16 +410,16 @@ impl RecordingDrawing<'_, CW, R> { LooseIndex::Bend(bend) => { bends.push(bend); - if let Some(outer) = self.drawing.primitive(bend).outer() { + if let Some(outer) = self.inner.primitive(bend).outer() { outers.push(outer); - self.reattach_bend(outer, self.drawing.primitive(bend).inner()); + self.reattach_bend(outer, self.inner.primitive(bend).inner()); } } } let prev_prev = prev; prev = maybe_loose; - maybe_loose = self.drawing.loose(loose).next_loose(prev_prev); + maybe_loose = self.inner.loose(loose).next_loose(prev_prev); } for bend in bends { @@ -443,27 +447,27 @@ impl RecordingDrawing<'_, CW, R> { Ok(()) } - #[debug_ensures(ret.is_ok() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count() + 1))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count()))] - #[debug_ensures(self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().node_count() == old(self.inner.graph().node_count() + 1))] + #[debug_ensures(ret.is_err() -> self.inner.graph().node_count() == old(self.inner.graph().node_count()))] + #[debug_ensures(self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] pub fn add_fixed_dot(&mut self, weight: FixedDotWeight) -> Result { self.add_dot_with_infringables(weight, Some(&[])) } - #[debug_ensures(self.drawing.graph().node_count() == old(self.drawing.graph().node_count() - 1))] - #[debug_ensures(self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] + #[debug_ensures(self.inner.graph().node_count() == old(self.inner.graph().node_count() - 1))] + #[debug_ensures(self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] pub fn remove_fixed_dot(&mut self, dot: FixedDotIndex) { self.recording_geometry_with_rtree().remove_dot(dot.into()); } - #[debug_ensures(self.drawing.graph().node_count() == old(self.drawing.graph().node_count() + 1))] - #[debug_ensures(self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] + #[debug_ensures(self.inner.graph().node_count() == old(self.inner.graph().node_count() + 1))] + #[debug_ensures(self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] pub fn add_fixed_dot_infringably(&mut self, weight: FixedDotWeight) -> FixedDotIndex { self.add_dot_infringably(weight) } - #[debug_ensures(ret.is_ok() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count() + 1))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count()))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().node_count() == old(self.inner.graph().node_count() + 1))] + #[debug_ensures(ret.is_err() -> self.inner.graph().node_count() == old(self.inner.graph().node_count()))] fn add_dot_with_infringables + GetLayer>( &mut self, weight: W, @@ -478,9 +482,9 @@ impl RecordingDrawing<'_, CW, R> { Ok(dot) } - #[debug_ensures(ret.is_ok() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count() + 1))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count()))] - #[debug_ensures(self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().node_count() == old(self.inner.graph().node_count() + 1))] + #[debug_ensures(ret.is_err() -> self.inner.graph().node_count() == old(self.inner.graph().node_count()))] + #[debug_ensures(self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] pub fn add_fixed_seg( &mut self, from: FixedDotIndex, @@ -490,8 +494,8 @@ impl RecordingDrawing<'_, CW, R> { self.add_seg_with_infringables(from.into(), to.into(), weight, Some(&[])) } - #[debug_ensures(self.drawing.graph().node_count() == old(self.drawing.graph().node_count() + 1))] - #[debug_ensures(self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count() + 2))] + #[debug_ensures(self.inner.graph().node_count() == old(self.inner.graph().node_count() + 1))] + #[debug_ensures(self.inner.graph().edge_count() == old(self.inner.graph().edge_count() + 2))] pub fn add_fixed_seg_infringably( &mut self, from: FixedDotIndex, @@ -501,10 +505,10 @@ impl RecordingDrawing<'_, CW, R> { self.add_seg_infringably(from.into(), to.into(), weight) } - #[debug_ensures(ret.is_ok() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count() + 1))] - #[debug_ensures(ret.is_ok() -> self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count() + 2))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count()))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().node_count() == old(self.inner.graph().node_count() + 1))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().edge_count() == old(self.inner.graph().edge_count() + 2))] + #[debug_ensures(ret.is_err() -> self.inner.graph().node_count() == old(self.inner.graph().node_count()))] + #[debug_ensures(ret.is_err() -> self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] pub fn add_lone_loose_seg( &mut self, from: FixedDotIndex, @@ -515,10 +519,10 @@ impl RecordingDrawing<'_, CW, R> { Ok(seg) } - #[debug_ensures(ret.is_ok() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count() + 1))] - #[debug_ensures(ret.is_ok() -> self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count() + 2))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count()))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().node_count() == old(self.inner.graph().node_count() + 1))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().edge_count() == old(self.inner.graph().edge_count() + 2))] + #[debug_ensures(ret.is_err() -> self.inner.graph().node_count() == old(self.inner.graph().node_count()))] + #[debug_ensures(ret.is_err() -> self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] pub fn add_seq_loose_seg( &mut self, from: DotIndex, @@ -529,10 +533,10 @@ impl RecordingDrawing<'_, CW, R> { Ok(seg) } - #[debug_ensures(ret.is_ok() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count() + 1))] - #[debug_ensures(ret.is_ok() -> self.drawing.graph().edge_count() >= old(self.drawing.graph().edge_count() + 2))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count()))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().node_count() == old(self.inner.graph().node_count() + 1))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().edge_count() >= old(self.inner.graph().edge_count() + 2))] + #[debug_ensures(ret.is_err() -> self.inner.graph().node_count() == old(self.inner.graph().node_count()))] + #[debug_ensures(ret.is_err() -> self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] fn add_seg_with_infringables + GetLayer>( &mut self, from: DotIndex, @@ -549,11 +553,11 @@ impl RecordingDrawing<'_, CW, R> { Ok(seg) } - #[debug_ensures(ret.is_ok() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count() + 1))] - #[debug_ensures(ret.is_ok() -> self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count() + 3) - || self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count() + 4))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count()))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().node_count() == old(self.inner.graph().node_count() + 1))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().edge_count() == old(self.inner.graph().edge_count() + 3) + || self.inner.graph().edge_count() == old(self.inner.graph().edge_count() + 4))] + #[debug_ensures(ret.is_err() -> self.inner.graph().node_count() == old(self.inner.graph().node_count()))] + #[debug_ensures(ret.is_err() -> self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] fn add_loose_bend_with_infringables( &mut self, from: LooseDotIndex, @@ -565,14 +569,14 @@ impl RecordingDrawing<'_, CW, R> { // It makes no sense to wrap something around or under one of its connectables. // if let Some(net) = weight.maybe_net { - if let Some(around_net) = around.primitive(self.drawing).maybe_net() { + if let Some(around_net) = around.primitive(self.inner).maybe_net() { if net == around_net { return Err(AlreadyConnected(net, around.into()).into()); } } // - if let Some(next_gear) = around.ref_(self.drawing).next_gear() { - if let Some(next_gear_net) = next_gear.primitive(self.drawing).maybe_net() { + if let Some(next_gear) = around.ref_(self.inner).next_gear() { + if let Some(next_gear_net) = next_gear.primitive(self.inner).maybe_net() { if net == next_gear_net { return Err(AlreadyConnected(net, next_gear.into()).into()); } @@ -593,10 +597,10 @@ impl RecordingDrawing<'_, CW, R> { } } - #[debug_ensures(ret.is_ok() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count() + 1))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count()))] - #[debug_ensures(ret.is_ok() -> self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count() + 3))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().node_count() == old(self.inner.graph().node_count() + 1))] + #[debug_ensures(ret.is_err() -> self.inner.graph().node_count() == old(self.inner.graph().node_count()))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().edge_count() == old(self.inner.graph().edge_count() + 3))] + #[debug_ensures(ret.is_err() -> self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] fn add_core_bend_with_infringables + GetLayer>( &mut self, from: DotIndex, @@ -616,10 +620,10 @@ impl RecordingDrawing<'_, CW, R> { Ok(bend) } - #[debug_ensures(ret.is_ok() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count() + 1))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count()))] - #[debug_ensures(ret.is_ok() -> self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count() + 4))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().node_count() == old(self.inner.graph().node_count() + 1))] + #[debug_ensures(ret.is_err() -> self.inner.graph().node_count() == old(self.inner.graph().node_count()))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().edge_count() == old(self.inner.graph().edge_count() + 4))] + #[debug_ensures(ret.is_err() -> self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] fn add_outer_bend_with_infringables( &mut self, from: LooseDotIndex, @@ -629,15 +633,15 @@ impl RecordingDrawing<'_, CW, R> { infringables: Option<&[PrimitiveIndex]>, ) -> Result, Infringement> { let core = *self - .drawing + .inner .graph() .neighbors(inner.petgraph_index()) .filter(|ni| { matches!( - self.drawing + self.inner .graph() .edge_weight( - self.drawing + self.inner .graph() .find_edge(inner.petgraph_index(), *ni) .unwrap() @@ -664,25 +668,25 @@ impl RecordingDrawing<'_, CW, R> { Ok(bend) } - #[debug_ensures(self.drawing.graph().node_count() == old(self.drawing.graph().node_count()))] - #[debug_ensures(self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] + #[debug_ensures(self.inner.graph().node_count() == old(self.inner.graph().node_count()))] + #[debug_ensures(self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] pub fn flip_bend(&mut self, bend: FixedBendIndex) { self.recording_geometry_with_rtree().flip_bend(bend.into()); } - #[debug_ensures(self.drawing.graph().node_count() == old(self.drawing.graph().node_count()))] - #[debug_ensures(self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()) - || self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count() - 1) - || self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count() + 1))] + #[debug_ensures(self.inner.graph().node_count() == old(self.inner.graph().node_count()))] + #[debug_ensures(self.inner.graph().edge_count() == old(self.inner.graph().edge_count()) + || self.inner.graph().edge_count() == old(self.inner.graph().edge_count() - 1) + || self.inner.graph().edge_count() == old(self.inner.graph().edge_count() + 1))] fn reattach_bend(&mut self, bend: LooseBendIndex, maybe_new_inner: Option) { self.recording_geometry_with_rtree() .reattach_bend(bend.into(), maybe_new_inner.map(Into::into)); } - #[debug_ensures(ret.is_ok() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count() + 4))] - #[debug_ensures(ret.is_ok() -> self.drawing.graph().edge_count() >= old(self.drawing.graph().edge_count() + 5))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count()))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().node_count() == old(self.inner.graph().node_count() + 4))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().edge_count() >= old(self.inner.graph().edge_count() + 5))] + #[debug_ensures(ret.is_err() -> self.inner.graph().node_count() == old(self.inner.graph().node_count()))] + #[debug_ensures(ret.is_err() -> self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] pub fn insert_cane( &mut self, from: DotIndex, @@ -692,7 +696,7 @@ impl RecordingDrawing<'_, CW, R> { bend_weight: LooseBendWeight, cw: bool, ) -> Result { - let maybe_next_gear = around.ref_(self.drawing).next_gear(); + let maybe_next_gear = around.ref_(self.inner).next_gear(); let cane = self.add_cane_with_infringables( from, around, @@ -707,16 +711,16 @@ impl RecordingDrawing<'_, CW, R> { self.reattach_bend(next_gear, Some(cane.bend)); } - if let Some(outer) = self.drawing.primitive(cane.bend).outer() { + if let Some(outer) = self.inner.primitive(cane.bend).outer() { self.update_this_and_outward_bows(outer).inspect_err(|_| { - let joint = self.drawing.primitive(cane.bend).other_joint(cane.dot); + let joint = self.inner.primitive(cane.bend).other_joint(cane.dot); self.remove_cane(&cane, joint); })?; } // Segs must not cross. - if let Some(collision) = self.drawing.detect_collision(cane.seg.into()) { - let joint = self.drawing.primitive(cane.bend).other_joint(cane.dot); + if let Some(collision) = self.inner.detect_collision(cane.seg.into()) { + let joint = self.inner.primitive(cane.bend).other_joint(cane.dot); self.remove_cane(&cane, joint); Err(collision.into()) } else { @@ -724,8 +728,8 @@ impl RecordingDrawing<'_, CW, R> { } } - #[debug_ensures(self.drawing.graph().node_count() == old(self.drawing.graph().node_count()))] - #[debug_ensures(self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] + #[debug_ensures(self.inner.graph().node_count() == old(self.inner.graph().node_count()))] + #[debug_ensures(self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] fn update_this_and_outward_bows( &mut self, around: LooseBendIndex, @@ -734,10 +738,10 @@ impl RecordingDrawing<'_, CW, R> { let mut maybe_rail = Some(around); while let Some(rail) = maybe_rail { - let rail_primitive = self.drawing.primitive(rail); + let rail_primitive = self.inner.primitive(rail); let joints = rail_primitive.joints(); - let guide = Guide::new(self.drawing); + let guide = Guide::new(self.inner); let from_head = guide.rear_head(joints.1); let to_head = guide.rear_head(joints.0); @@ -747,7 +751,7 @@ impl RecordingDrawing<'_, CW, R> { &from_head, inner.into(), true, - self.drawing.primitive(rail).width(), + self.inner.primitive(rail).width(), )? .end_point(); let to = guide @@ -755,30 +759,30 @@ impl RecordingDrawing<'_, CW, R> { &to_head, inner.into(), false, - self.drawing.primitive(rail).width(), + self.inner.primitive(rail).width(), )? .end_point(); let offset = guide.head_around_bend_offset( &from_head, inner.into(), - self.drawing.primitive(rail).width(), + self.inner.primitive(rail).width(), ); self.move_dot_with_infringables( joints.0.into(), from, - Some(&self.drawing.collect().bend_outer_bows(rail)), + Some(&self.inner.collect().bend_outer_bows(rail)), )?; self.move_dot_with_infringables( joints.1.into(), to, - Some(&self.drawing.collect().bend_outer_bows(rail)), + Some(&self.inner.collect().bend_outer_bows(rail)), )?; self.shift_bend_with_infringables( rail.into(), offset, - Some(&self.drawing.collect().bend_outer_bows(rail)), + Some(&self.inner.collect().bend_outer_bows(rail)), )?; // Update offsets in case the rule conditions changed. @@ -789,7 +793,7 @@ impl RecordingDrawing<'_, CW, R> { &from_head, core.into(), true, - self.drawing.primitive(rail).width(), + self.inner.primitive(rail).width(), )? .end_point(); let to = guide @@ -797,43 +801,43 @@ impl RecordingDrawing<'_, CW, R> { &to_head, core.into(), false, - self.drawing.primitive(rail).width(), + self.inner.primitive(rail).width(), )? .end_point(); let offset = guide.head_around_dot_offset( &from_head, core.into(), - self.drawing.primitive(rail).width(), + self.inner.primitive(rail).width(), ); self.move_dot_with_infringables( joints.0.into(), from, - Some(&self.drawing.collect().bend_outer_bows(rail)), + Some(&self.inner.collect().bend_outer_bows(rail)), )?; self.move_dot_with_infringables( joints.1.into(), to, - Some(&self.drawing.collect().bend_outer_bows(rail)), + Some(&self.inner.collect().bend_outer_bows(rail)), )?; self.shift_bend_with_infringables( rail.into(), offset, - Some(&self.drawing.collect().bend_outer_bows(rail)), + Some(&self.inner.collect().bend_outer_bows(rail)), )?; } - maybe_rail = self.drawing.primitive(rail).outer(); + maybe_rail = self.inner.primitive(rail).outer(); } Ok(()) } - #[debug_ensures(ret.is_ok() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count() + 4))] - #[debug_ensures(ret.is_ok() -> self.drawing.graph().edge_count() >= old(self.drawing.graph().edge_count() + 5))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count()))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().node_count() == old(self.inner.graph().node_count() + 4))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().edge_count() >= old(self.inner.graph().edge_count() + 5))] + #[debug_ensures(ret.is_err() -> self.inner.graph().node_count() == old(self.inner.graph().node_count()))] + #[debug_ensures(ret.is_err() -> self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] pub fn add_cane( &mut self, from: DotIndex, @@ -854,10 +858,10 @@ impl RecordingDrawing<'_, CW, R> { ) } - #[debug_ensures(ret.is_ok() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count() + 4))] - #[debug_ensures(ret.is_ok() -> self.drawing.graph().edge_count() >= old(self.drawing.graph().edge_count() + 5))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count()))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().node_count() == old(self.inner.graph().node_count() + 4))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().edge_count() >= old(self.inner.graph().edge_count() + 5))] + #[debug_ensures(ret.is_err() -> self.inner.graph().node_count() == old(self.inner.graph().node_count()))] + #[debug_ensures(ret.is_err() -> self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] fn add_cane_with_infringables( &mut self, from: DotIndex, @@ -902,13 +906,13 @@ impl RecordingDrawing<'_, CW, R> { }) } - #[debug_ensures(self.drawing.graph().node_count() == old(self.drawing.graph().node_count() - 4))] + #[debug_ensures(self.inner.graph().node_count() == old(self.inner.graph().node_count() - 4))] pub fn remove_cane(&mut self, cane: &Cane, face: LooseDotIndex) { - let maybe_outer = self.drawing.primitive(cane.bend).outer(); + let maybe_outer = self.inner.primitive(cane.bend).outer(); // Removing a loose bend affects its outer bends. if let Some(outer) = maybe_outer { - self.reattach_bend(outer, self.drawing.primitive(cane.bend).inner()); + self.reattach_bend(outer, self.inner.primitive(cane.bend).inner()); } self.recording_geometry_with_rtree() @@ -928,8 +932,8 @@ impl RecordingDrawing<'_, CW, R> { } } - #[debug_ensures(self.drawing.graph().node_count() == old(self.drawing.graph().node_count()))] - #[debug_ensures(self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] + #[debug_ensures(self.inner.graph().node_count() == old(self.inner.graph().node_count()))] + #[debug_ensures(self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] pub fn move_dot(&mut self, dot: DotIndex, to: Point) -> Result<(), Infringement> { match dot { DotIndex::Fixed(..) => self.move_dot_with_infringables(dot, to, Some(&[])), @@ -937,20 +941,19 @@ impl RecordingDrawing<'_, CW, R> { } } - #[debug_ensures(self.drawing.graph().node_count() == old(self.drawing.graph().node_count()))] - #[debug_ensures(self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] + #[debug_ensures(self.inner.graph().node_count() == old(self.inner.graph().node_count()))] + #[debug_ensures(self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] fn move_dot_with_infringables( &mut self, dot: DotIndex, to: Point, infringables: Option<&[PrimitiveIndex]>, ) -> Result<(), Infringement> { - let old_pos = self.drawing.geometry().dot_weight(dot).pos(); + let old_pos = self.inner.geometry().dot_weight(dot).pos(); self.recording_geometry_with_rtree().move_dot(dot, to); - for limb in dot.primitive(self.drawing).limbs() { - if let Some(infringement) = self.drawing.detect_infringement_except(limb, infringables) - { + for limb in dot.primitive(self.inner).limbs() { + if let Some(infringement) = self.inner.detect_infringement_except(limb, infringables) { // Restore original state. self.recording_geometry_with_rtree().move_dot(dot, old_pos); return Err(infringement); @@ -958,7 +961,7 @@ impl RecordingDrawing<'_, CW, R> { } if let Some(infringement) = self - .drawing + .inner .detect_infringement_except(dot.into(), infringables) { // Restore original state. @@ -969,20 +972,20 @@ impl RecordingDrawing<'_, CW, R> { Ok(()) } - #[debug_ensures(self.drawing.graph().node_count() == old(self.drawing.graph().node_count()))] - #[debug_ensures(self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] + #[debug_ensures(self.inner.graph().node_count() == old(self.inner.graph().node_count()))] + #[debug_ensures(self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] fn shift_bend_with_infringables( &mut self, bend: BendIndex, offset: f64, infringables: Option<&[PrimitiveIndex]>, ) -> Result<(), Infringement> { - let old_offset = self.drawing.geometry().bend_weight(bend).offset(); + let old_offset = self.inner.geometry().bend_weight(bend).offset(); self.recording_geometry_with_rtree() .shift_bend(bend, offset); if let Some(infringement) = self - .drawing + .inner .detect_infringement_except(bend.into(), infringables) { // Restore original state. @@ -994,8 +997,8 @@ impl RecordingDrawing<'_, CW, R> { Ok(()) } - #[debug_ensures(self.drawing.graph().node_count() == old(self.drawing.graph().node_count() + 1))] - #[debug_ensures(self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] + #[debug_ensures(self.inner.graph().node_count() == old(self.inner.graph().node_count() + 1))] + #[debug_ensures(self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] fn add_dot_infringably + GetLayer>( &mut self, weight: W, @@ -1006,8 +1009,8 @@ impl RecordingDrawing<'_, CW, R> { self.recording_geometry_with_rtree().add_dot(weight) } - #[debug_ensures(self.drawing.graph().node_count() == old(self.drawing.graph().node_count() + 1))] - #[debug_ensures(self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count() + 2))] + #[debug_ensures(self.inner.graph().node_count() == old(self.inner.graph().node_count() + 1))] + #[debug_ensures(self.inner.graph().edge_count() == old(self.inner.graph().edge_count() + 2))] fn add_seg_infringably + GetLayer>( &mut self, from: DotIndex, @@ -1035,15 +1038,15 @@ impl RecordingDrawing<'_, CW, R> { .add_to_compound(primitive, compound); } - #[debug_ensures(ret.is_ok() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count()))] - #[debug_ensures(ret.is_ok() -> self.drawing.graph().edge_count() == old(self.drawing.graph().edge_count()))] - #[debug_ensures(ret.is_err() -> self.drawing.graph().node_count() == old(self.drawing.graph().node_count() - 1))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().node_count() == old(self.inner.graph().node_count()))] + #[debug_ensures(ret.is_ok() -> self.inner.graph().edge_count() == old(self.inner.graph().edge_count()))] + #[debug_ensures(ret.is_err() -> self.inner.graph().node_count() == old(self.inner.graph().node_count() - 1))] fn fail_and_remove_if_infringes_except( &mut self, node: PrimitiveIndex, maybe_except: Option<&[PrimitiveIndex]>, ) -> Result<(), Infringement> { - if let Some(infringement) = self.drawing.detect_infringement_except(node, maybe_except) { + if let Some(infringement) = self.inner.detect_infringement_except(node, maybe_except) { let mut recording_geometry_with_rtree = self.recording_geometry_with_rtree(); if let Ok(dot) = node.try_into() { recording_geometry_with_rtree.remove_dot(dot); @@ -1056,10 +1059,6 @@ impl RecordingDrawing<'_, CW, R> { } Ok(()) } - - pub fn rules_mut(&mut self) -> &mut R { - &mut self.drawing.rules - } } impl @@ -1075,27 +1074,8 @@ impl BendIndex, > for Drawing { - #[inline] + #[inline(always)] fn apply(&mut self, edit: &DrawingEdit) { self.geometry_with_rtree.apply(edit); } } - -impl - ApplyGeometryEdit< - PrimitiveWeight, - DotWeight, - SegWeight, - BendWeight, - CW, - PrimitiveIndex, - DotIndex, - SegIndex, - BendIndex, - > for RecordingDrawing<'_, CW, R> -{ - #[inline] - fn apply(&mut self, edit: &DrawingEdit) { - self.drawing.geometry_with_rtree.apply(edit); - } -} diff --git a/src/geometry/edit.rs b/src/geometry/edit.rs index 2e9e1f4..a487320 100644 --- a/src/geometry/edit.rs +++ b/src/geometry/edit.rs @@ -2,6 +2,7 @@ // // SPDX-License-Identifier: MIT +use core::fmt; use std::{collections::HashMap, hash::Hash, marker::PhantomData}; use crate::{ @@ -87,3 +88,142 @@ impl< } } } + +pub trait Recordable { + type PW: GetWidth + + GetLayer + + TryInto + + TryInto + + TryInto + + Retag + + Copy; + type DW: AccessDotWeight + GetLayer; + type SW: AccessSegWeight + GetLayer; + type BW: AccessBendWeight + GetLayer; + type CW: Copy; + type PI: GetPetgraphIndex + + TryInto + + TryInto + + TryInto + + Copy + + Eq + + Hash; + type DI: GetPetgraphIndex + Into + Copy + Eq + Hash; + type SI: GetPetgraphIndex + Into + Copy + Eq + Hash; + type BI: GetPetgraphIndex + Into + Copy + Eq + Hash; + + #[inline(always)] + fn recording<'a>( + &'a mut self, + recorder: &'a mut GeometryEdit< + Self::PW, + Self::DW, + Self::SW, + Self::BW, + Self::CW, + Self::PI, + Self::DI, + Self::SI, + Self::BI, + >, + ) -> Recording<'a, Self> { + Recording { + inner: self, + recorder, + } + } +} + +pub type RecordingEdit = GeometryEdit< + ::PW, + ::DW, + ::SW, + ::BW, + ::CW, + ::PI, + ::DI, + ::SI, + ::BI, +>; + +pub struct Recording<'a, T: Recordable + ?Sized> { + pub inner: &'a mut T, + pub recorder: &'a mut RecordingEdit, +} + +impl<'a, T> fmt::Debug for Recording<'a, T> +where + T: Recordable + fmt::Debug + ?Sized, + ::PW: fmt::Debug, + ::DW: fmt::Debug, + ::SW: fmt::Debug, + ::BW: fmt::Debug, + ::CW: fmt::Debug, + ::PI: fmt::Debug, + ::DI: fmt::Debug, + ::SI: fmt::Debug, + ::BI: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Recording") + .field("inner", &self.inner) + .field("recorder", &self.recorder) + .finish() + } +} + +// this is a hack, but it allows us to not needing as much boilerplate for delegations +impl<'a, T: Recordable + ?Sized> core::ops::Deref for Recording<'a, T> { + type Target = T; + + #[inline(always)] + fn deref(&self) -> &T { + self.inner + } +} + +impl<'a, T> + ApplyGeometryEdit< + ::PW, + ::DW, + ::SW, + ::BW, + ::CW, + ::PI, + ::DI, + ::SI, + ::BI, + > for Recording<'a, T> +where + T: Recordable + + ?Sized + + ApplyGeometryEdit< + ::PW, + ::DW, + ::SW, + ::BW, + ::CW, + ::PI, + ::DI, + ::SI, + ::BI, + >, +{ + #[inline(always)] + fn apply( + &mut self, + edit: &GeometryEdit< + ::PW, + ::DW, + ::SW, + ::BW, + ::CW, + ::PI, + ::DI, + ::SI, + ::BI, + >, + ) { + self.inner.apply(edit) + } +} diff --git a/src/geometry/recording_with_rtree.rs b/src/geometry/recording_with_rtree.rs index 55553e0..1ac5bc1 100644 --- a/src/geometry/recording_with_rtree.rs +++ b/src/geometry/recording_with_rtree.rs @@ -16,18 +16,12 @@ use crate::{ use super::{ compound::ManageCompounds, - edit::{ApplyGeometryEdit, GeometryEdit}, + edit::{GeometryEdit, Recording}, with_rtree::{BboxedIndex, GeometryWithRtree}, AccessBendWeight, AccessDotWeight, AccessSegWeight, GenericNode, Geometry, GeometryLabel, GetWidth, }; -#[derive(Debug)] -pub struct RecordingGeometryWithRtree<'a, PW, DW, SW, BW, CW, PI, DI, SI, BI> { - pub geometry_with_rtree: &'a mut GeometryWithRtree, - pub recorder: &'a mut GeometryEdit, -} - impl< PW: GetWidth + GetLayer + TryInto + TryInto + TryInto + Retag + Copy, DW: AccessDotWeight + GetLayer, @@ -38,13 +32,13 @@ impl< DI: GetPetgraphIndex + Into + Eq + Hash + Copy, SI: GetPetgraphIndex + Into + Eq + Hash + Copy, BI: GetPetgraphIndex + Into + Eq + Hash + Copy, - > RecordingGeometryWithRtree<'_, PW, DW, SW, BW, CW, PI, DI, SI, BI> + > Recording<'_, GeometryWithRtree> { pub fn add_dot + GetLayer>(&mut self, weight: W) -> GenericIndex where GenericIndex: Into, { - let dot = self.geometry_with_rtree.add_dot(weight); + let dot = self.inner.add_dot(weight); self.recorder.dots.insert( Into::::into(dot) .try_into() @@ -66,7 +60,7 @@ impl< where GenericIndex: Into, { - let seg = self.geometry_with_rtree.add_seg(from, to, weight); + let seg = self.inner.add_seg(from, to, weight); self.recorder.segs.insert( Into::::into(seg) .try_into() @@ -92,7 +86,7 @@ impl< where GenericIndex: Into, { - let bend = self.geometry_with_rtree.add_bend(from, to, core, weight); + let bend = self.inner.add_bend(from, to, core, weight); self.recorder.bends.insert( Into::::into(bend) .try_into() @@ -109,7 +103,7 @@ impl< } pub fn add_compound(&mut self, weight: CW) -> GenericIndex { - let compound = self.geometry_with_rtree.add_compound(weight); + let compound = self.inner.add_compound(weight); self.recorder .compounds .insert(compound, (None, Some((vec![], weight)))); @@ -117,14 +111,13 @@ impl< } pub fn add_to_compound(&mut self, primitive: GenericIndex, compound: GenericIndex) { - let geometry = self.geometry_with_rtree.geometry(); + let geometry = self.inner.geometry(); let old_members = geometry.compound_members(compound).collect(); let old_weight = geometry.compound_weight(compound); - self.geometry_with_rtree - .add_to_compound(primitive, compound); + self.inner.add_to_compound(primitive, compound); - let geometry = self.geometry_with_rtree.geometry(); + let geometry = self.inner.geometry(); let new_members = geometry.compound_members(compound).collect(); let new_weight = geometry.compound_weight(compound); @@ -136,26 +129,26 @@ impl< } pub fn remove_dot(&mut self, dot: DI) -> Result<(), ()> { - let weight = self.geometry_with_rtree.geometry().dot_weight(dot); - self.geometry_with_rtree.remove_dot(dot)?; + let weight = self.inner.geometry().dot_weight(dot); + self.inner.remove_dot(dot)?; edit_remove_from_map(&mut self.recorder.dots, dot, weight); Ok(()) } pub fn remove_seg(&mut self, seg: SI) { - let geometry = self.geometry_with_rtree.geometry(); + let geometry = self.inner.geometry(); let weight = geometry.seg_weight(seg); let joints = geometry.seg_joints(seg); - self.geometry_with_rtree.remove_seg(seg); + self.inner.remove_seg(seg); edit_remove_from_map(&mut self.recorder.segs, seg, (joints, weight)); } pub fn remove_bend(&mut self, bend: BI) { - let geometry = self.geometry_with_rtree.geometry(); + let geometry = self.inner.geometry(); let weight = geometry.bend_weight(bend); let joints = geometry.bend_joints(bend); let core = geometry.core(bend); - self.geometry_with_rtree.remove_bend(bend); + self.inner.remove_bend(bend); edit_remove_from_map( &mut self.recorder.bends, bend, @@ -164,17 +157,17 @@ impl< } pub fn remove_compound(&mut self, compound: GenericIndex) { - let geometry = self.geometry_with_rtree.geometry(); + let geometry = self.inner.geometry(); let weight = geometry.compound_weight(compound); let members = geometry.compound_members(compound).collect(); - self.geometry_with_rtree.remove_compound(compound); + self.inner.remove_compound(compound); edit_remove_from_map(&mut self.recorder.compounds, compound, (members, weight)); } pub fn move_dot(&mut self, dot: DI, to: Point) { - let old_weight = self.geometry_with_rtree.geometry().dot_weight(dot); - self.geometry_with_rtree.move_dot(dot, to); - let new_weight = self.geometry_with_rtree.geometry().dot_weight(dot); + let old_weight = self.inner.geometry().dot_weight(dot); + self.inner.move_dot(dot, to); + let new_weight = self.inner.geometry().dot_weight(dot); self.recorder .dots @@ -187,14 +180,14 @@ impl< where F: FnOnce(&mut GeometryWithRtree, BI), { - let geometry = self.geometry_with_rtree.geometry(); + let geometry = self.inner.geometry(); let old_joints = geometry.bend_joints(bend); let old_core = geometry.core(bend); let old_weight = geometry.bend_weight(bend); - f(&mut self.geometry_with_rtree, bend); + f(&mut self.inner, bend); - let geometry = self.geometry_with_rtree.geometry(); + let geometry = self.inner.geometry(); let new_joints = geometry.bend_joints(bend); let new_core = geometry.core(bend); let new_weight = geometry.bend_weight(bend); @@ -228,14 +221,14 @@ impl< } pub fn compound_weight(&self, compound: GenericIndex) -> CW { - self.geometry_with_rtree.compound_weight(compound) + self.inner.compound_weight(compound) } pub fn compounds<'a, W: 'a>( &'a self, node: GenericIndex, ) -> impl Iterator> + 'a { - self.geometry_with_rtree.compounds(node) + self.inner.compounds(node) } pub fn recorder(&self) -> &GeometryEdit { @@ -243,19 +236,19 @@ impl< } pub fn geometry(&self) -> &Geometry { - self.geometry_with_rtree.geometry() + self.inner.geometry() } pub fn rtree(&self) -> &RTree>>> { - self.geometry_with_rtree.rtree() + self.inner.rtree() } pub fn layer_count(&self) -> usize { - *self.geometry_with_rtree.layer_count() + *self.inner.layer_count() } pub fn graph(&self) -> &StableDiGraph, GeometryLabel, usize> { - self.geometry_with_rtree.graph() + self.inner.graph() } } @@ -280,22 +273,3 @@ fn edit_remove_from_map( } } } - -impl< - PW: GetWidth + GetLayer + TryInto + TryInto + TryInto + Retag + Copy, - DW: AccessDotWeight + GetLayer, - SW: AccessSegWeight + GetLayer, - BW: AccessBendWeight + GetLayer, - CW: Copy, - PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Eq + Hash + Copy, - DI: GetPetgraphIndex + Into + Eq + Hash + Copy, - SI: GetPetgraphIndex + Into + Eq + Hash + Copy, - BI: GetPetgraphIndex + Into + Eq + Hash + Copy, - > ApplyGeometryEdit - for RecordingGeometryWithRtree<'_, PW, DW, SW, BW, CW, PI, DI, SI, BI> -{ - #[inline(always)] - fn apply(&mut self, edit: &GeometryEdit) { - self.geometry_with_rtree.apply(edit) - } -} diff --git a/src/geometry/with_rtree.rs b/src/geometry/with_rtree.rs index cee4dee..6ee1dfe 100644 --- a/src/geometry/with_rtree.rs +++ b/src/geometry/with_rtree.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: MIT use contracts_try::debug_invariant; -use core::hash::Hash; +use core::{cmp::Eq, hash::Hash}; use derive_getters::Getters; use geo::Point; use petgraph::stable_graph::StableDiGraph; @@ -13,7 +13,7 @@ use crate::{ drawing::graph::{GetLayer, Retag}, geometry::{ compound::ManageCompounds, - edit::{ApplyGeometryEdit, GeometryEdit}, + edit::{ApplyGeometryEdit, GeometryEdit, Recordable}, primitive::{AccessPrimitiveShape, PrimitiveShape}, AccessBendWeight, AccessDotWeight, AccessSegWeight, GenericNode, Geometry, GeometryLabel, GetWidth, @@ -48,6 +48,29 @@ pub struct GeometryWithRtree { layer_count: usize, } +impl< + PW: GetWidth + GetLayer + TryInto + TryInto + TryInto + Retag + Copy, + DW: AccessDotWeight + GetLayer, + SW: AccessSegWeight + GetLayer, + BW: AccessBendWeight + GetLayer, + CW: Copy, + PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Copy + Eq + Hash, + DI: GetPetgraphIndex + Into + Copy + Eq + Hash, + SI: GetPetgraphIndex + Into + Copy + Eq + Hash, + BI: GetPetgraphIndex + Into + Copy + Eq + Hash, + > Recordable for GeometryWithRtree +{ + type PW = PW; + type DW = DW; + type SW = SW; + type BW = BW; + type CW = CW; + type PI = PI; + type DI = DI; + type SI = SI; + type BI = BI; +} + #[debug_invariant(self.test_envelopes())] #[debug_invariant(self.geometry.graph().node_count() == self.rtree.size())] impl< @@ -70,28 +93,6 @@ impl< } } - #[inline(always)] - pub fn recording<'a>( - &'a mut self, - recorder: &'a mut super::edit::GeometryEdit, - ) -> super::recording_with_rtree::RecordingGeometryWithRtree< - 'a, - PW, - DW, - SW, - BW, - CW, - PI, - DI, - SI, - BI, - > { - super::recording_with_rtree::RecordingGeometryWithRtree { - geometry_with_rtree: self, - recorder, - } - } - pub fn add_dot + GetLayer>(&mut self, weight: W) -> GenericIndex where GenericIndex: Into, diff --git a/src/layout/layout.rs b/src/layout/layout.rs index 31bf2b7..39a0eb9 100644 --- a/src/layout/layout.rs +++ b/src/layout/layout.rs @@ -23,9 +23,13 @@ use crate::{ FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex, SegWeight, SeqLooseSegIndex, SeqLooseSegWeight, }, - Drawing, DrawingEdit, DrawingException, Infringement, RecordingDrawing, + Drawing, DrawingEdit, DrawingException, Infringement, + }, + geometry::{ + edit::{ApplyGeometryEdit, Recordable, Recording}, + shape::Shape, + GenericNode, }, - geometry::{edit::ApplyGeometryEdit, shape::Shape, GenericNode}, graph::{GenericIndex, GetPetgraphIndex}, layout::{ poly::{MakePolyShape, Poly, PolyWeight}, @@ -53,24 +57,23 @@ pub struct Layout { drawing: Drawing, } -pub struct RecordingLayout<'a, R> { - pub layout: &'a mut Layout, - pub recorder: &'a mut LayoutEdit, -} - impl Layout { #[inline(always)] pub fn new(drawing: Drawing) -> Self { Self { drawing } } +} - #[inline(always)] - pub fn recording<'a>(&'a mut self, recorder: &'a mut LayoutEdit) -> RecordingLayout<'a, R> { - RecordingLayout { - layout: self, - recorder, - } - } +impl Recordable for Layout { + type PW = PrimitiveWeight; + type DW = DotWeight; + type SW = SegWeight; + type BW = BendWeight; + type CW = CompoundWeight; + type PI = PrimitiveIndex; + type DI = DotIndex; + type SI = SegIndex; + type BI = BendIndex; } impl Layout { @@ -205,22 +208,13 @@ impl Layout { } } -// this is a hack, but it allows us to not needing as much boilerplate for delegations -impl core::ops::Deref for RecordingLayout<'_, R> { - type Target = Layout; - - fn deref(&self) -> &Layout { - self.layout - } -} - -impl RecordingLayout<'_, R> { - fn recording_drawing(&mut self) -> RecordingDrawing<'_, CompoundWeight, R> { - self.layout.drawing.recording(self.recorder) +impl Recording<'_, Layout> { + fn recording_drawing(&mut self) -> Recording<'_, Drawing> { + self.inner.drawing.recording(self.recorder) } pub fn rules_mut(&mut self) -> &mut R { - self.layout.drawing.rules_mut() + self.inner.drawing.rules_mut() } /// Insert [`Cane`] object into the [`Layout`] diff --git a/src/router/draw.rs b/src/router/draw.rs index 61b429c..1e0933e 100644 --- a/src/router/draw.rs +++ b/src/router/draw.rs @@ -13,14 +13,14 @@ use crate::{ dot::{DotIndex, FixedDotIndex, LooseDotIndex, LooseDotWeight}, gear::GearIndex, graph::{GetLayer, GetMaybeNet, MakePrimitive}, - guide::Guide, head::{CaneHead, GetFace, Head}, primitive::GetOtherJoint, rules::AccessRules, seg::{LoneLooseSegWeight, SeqLooseSegWeight}, - Drawing, DrawingException, Infringement, + DrawingException, Infringement, }, - layout::{CompoundWeight, Layout, LayoutEdit, RecordingLayout}, + geometry::edit::Recording, + layout::Layout, math::{Circle, NoTangents}, }; @@ -67,7 +67,7 @@ pub trait Draw { fn undo_cane(&mut self, head: CaneHead) -> Option; } -impl<'a, R: AccessRules> Draw for RecordingLayout<'a, R> { +impl<'a, R: AccessRules> Draw for Recording<'a, Layout> { fn start(&mut self, from: LooseDotIndex) -> Head { self.guide().cane_head(from).into() } @@ -188,7 +188,7 @@ impl<'a, R: AccessRules> Draw for RecordingLayout<'a, R> { #[debug_ensures(ret.is_ok() -> this.drawing().node_count() == old(this.drawing().node_count() + 4))] #[debug_ensures(ret.is_err() -> this.drawing().node_count() == old(this.drawing().node_count()))] fn cane_around( - this: &mut RecordingLayout<'_, R>, + this: &mut Recording<'_, Layout>, head: Head, around: GearIndex, from: Point, @@ -203,7 +203,7 @@ fn cane_around( #[debug_ensures(this.drawing().node_count() == old(this.drawing().node_count()))] fn extend_head( - this: &mut RecordingLayout<'_, R>, + this: &mut Recording<'_, Layout>, head: Head, to: Point, ) -> Result { @@ -218,7 +218,7 @@ fn extend_head( #[debug_ensures(ret.is_ok() -> this.drawing().node_count() == old(this.drawing().node_count() + 4))] #[debug_ensures(ret.is_err() -> this.drawing().node_count() == old(this.drawing().node_count()))] fn cane( - this: &mut RecordingLayout<'_, R>, + this: &mut Recording<'_, Layout>, head: Head, around: GearIndex, to: Point, diff --git a/src/router/navcord.rs b/src/router/navcord.rs index ba5922c..c631506 100644 --- a/src/router/navcord.rs +++ b/src/router/navcord.rs @@ -13,6 +13,7 @@ use crate::{ head::{BareHead, CaneHead, Head}, rules::AccessRules, }, + geometry::edit::Recordable, layout::LayoutEdit, }; diff --git a/src/router/navcorder.rs b/src/router/navcorder.rs index 96c50bf..dc422f8 100644 --- a/src/router/navcorder.rs +++ b/src/router/navcorder.rs @@ -7,6 +7,7 @@ use thiserror::Error; use crate::{ drawing::{band::BandTermsegIndex, dot::FixedDotIndex, rules::AccessRules}, + geometry::edit::Recordable, layout::{Layout, LayoutEdit}, };