refactor(board): move recording methods to Recording<'_, Board<M>>

This commit is contained in:
Alain Emilia Anna Zscheile 2025-01-03 05:34:50 +01:00
parent a911c0cddf
commit af18d82d7c
4 changed files with 191 additions and 196 deletions

View File

@ -78,7 +78,9 @@ impl<M: AccessMesadata> Autorouter<M> {
.node_index()
{
RatvertexIndex::FixedDot(dot) => dot,
RatvertexIndex::Poly(poly) => self.board.poly_apex(&mut LayoutEdit::new(), poly),
RatvertexIndex::Poly(poly) => {
self.board.recording(&mut LayoutEdit::new()).poly_apex(poly)
}
};
PointrouteExecutionStepper::new(self, origin_dot, point, options)
@ -198,7 +200,9 @@ impl<M: AccessMesadata> Autorouter<M> {
.node_index()
{
RatvertexIndex::FixedDot(dot) => dot,
RatvertexIndex::Poly(poly) => self.board.poly_apex(&mut LayoutEdit::new(), poly),
RatvertexIndex::Poly(poly) => {
self.board.recording(&mut LayoutEdit::new()).poly_apex(poly)
}
};
let target_dot = match self
@ -209,7 +213,9 @@ impl<M: AccessMesadata> Autorouter<M> {
.node_index()
{
RatvertexIndex::FixedDot(dot) => dot,
RatvertexIndex::Poly(poly) => self.board.poly_apex(&mut LayoutEdit::new(), poly),
RatvertexIndex::Poly(poly) => {
self.board.recording(&mut LayoutEdit::new()).poly_apex(poly)
}
};
(source_dot, target_dot)

View File

@ -12,6 +12,7 @@ use crate::{
band::BandTermsegIndex,
dot::{FixedDotIndex, FixedDotWeight},
},
geometry::edit::Recordable,
layout::LayoutEdit,
math::Circle,
router::{route::RouteStepper, Router},
@ -33,8 +34,10 @@ impl PointrouteExecutionStepper {
point: Point,
options: AutorouterOptions,
) -> Result<Self, AutorouterError> {
let destination = autorouter.board.add_fixed_dot_infringably(
&mut LayoutEdit::new(),
let destination = autorouter
.board
.recording(&mut LayoutEdit::new())
.add_fixed_dot_infringably(
FixedDotWeight {
circle: Circle {
pos: point,

View File

@ -26,7 +26,7 @@ use crate::{
seg::{FixedSegIndex, FixedSegWeight, SegIndex, SegWeight},
},
geometry::{
edit::{ApplyGeometryEdit, Recordable},
edit::{ApplyGeometryEdit, Recordable, Recording},
shape::AccessShape,
GenericNode,
},
@ -69,6 +69,18 @@ pub struct Board<M> {
band_bandname: BiHashMap<BandUid, BandName>,
}
impl<M> Recordable for Board<M> {
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<M> Board<M> {
/// Initializes the board with given [`Layout`]
pub fn new(layout: Layout<M>) -> Self {
@ -83,146 +95,6 @@ impl<M> Board<M> {
pub fn layout_mut(&mut self) -> &mut Layout<M> {
&mut self.layout
}
}
impl<M: AccessMesadata> Board<M> {
/// Adds a new fixed dot with an optional pin name.
///
/// Inserts the dot into the layout and, if a pin name is provided, maps it to the created dot's node.
pub fn add_fixed_dot_infringably(
&mut self,
recorder: &mut LayoutEdit,
weight: FixedDotWeight,
maybe_pin: Option<String>,
) -> FixedDotIndex {
let dot = self
.layout
.recording(recorder)
.add_fixed_dot_infringably(weight);
if let Some(pin) = maybe_pin {
self.node_to_pinname
.insert(GenericNode::Primitive(dot.into()), pin);
}
dot
}
/// Adds a fixed segment between two dots with an optional pin name.
///
/// Adds the segment to the layout and maps the pin name to the created segment if provided.
pub fn add_poly_fixed_dot_infringably(
&mut self,
recorder: &mut LayoutEdit,
weight: FixedDotWeight,
poly: GenericIndex<PolyWeight>,
) -> FixedDotIndex {
let dot = self
.layout
.recording(recorder)
.add_poly_fixed_dot_infringably(weight, poly);
if let Some(pin) = self.node_pinname(&GenericNode::Compound(poly.into())) {
self.node_to_pinname
.insert(GenericNode::Primitive(dot.into()), pin.to_string());
}
dot
}
/// Adds a fixed segment associated with a polygon in the layout.
///
/// Adds the segment to the layout and updates the internal mapping if necessary.
pub fn add_fixed_seg_infringably(
&mut self,
recorder: &mut LayoutEdit,
from: FixedDotIndex,
to: FixedDotIndex,
weight: FixedSegWeight,
maybe_pin: Option<String>,
) -> FixedSegIndex {
let seg = self
.layout
.recording(recorder)
.add_fixed_seg_infringably(from, to, weight);
if let Some(pin) = maybe_pin {
self.node_to_pinname
.insert(GenericNode::Primitive(seg.into()), pin);
}
seg
}
/// Adds a fixed segment associated with a polygon in the layout.
///
/// Adds the segment to the layout and updates the internal mapping if necessary.
pub fn add_poly_fixed_seg_infringably(
&mut self,
recorder: &mut LayoutEdit,
from: FixedDotIndex,
to: FixedDotIndex,
weight: FixedSegWeight,
poly: GenericIndex<PolyWeight>,
) -> FixedSegIndex {
let seg = self
.layout
.recording(recorder)
.add_poly_fixed_seg_infringably(from, to, weight, poly);
if let Some(pin) = self.node_pinname(&GenericNode::Compound(poly.into())) {
self.node_to_pinname
.insert(GenericNode::Primitive(seg.into()), pin.to_string());
}
seg
}
/// Adds a new polygon to the layout with an optional pin name.
///
/// Inserts the polygon into the layout and, if a pin name is provided, maps it to the created polygon's node.
pub fn add_poly(
&mut self,
recorder: &mut LayoutEdit,
weight: PolyWeight,
maybe_pin: Option<String>,
) -> GenericIndex<PolyWeight> {
let poly = self.layout.recording(recorder).add_poly(weight);
if let Some(pin) = maybe_pin {
self.node_to_pinname
.insert(GenericNode::Compound(poly.into()), pin);
}
poly
}
/// Retrieves or creates the apex (center point) of a polygon in the layout.
///
/// If the polygon already has an apex, returns it. Otherwise, creates and returns a new fixed dot as the apex.
pub fn poly_apex(
&mut self,
recorder: &mut LayoutEdit,
poly: GenericIndex<PolyWeight>,
) -> FixedDotIndex {
let resolved_poly = self.layout.poly(poly);
if let Some(apex) = resolved_poly.maybe_apex() {
apex
} else {
self.add_poly_fixed_dot_infringably(
recorder,
FixedDotWeight {
circle: Circle {
pos: resolved_poly.shape().center(),
r: 100.0,
},
layer: resolved_poly.layer(),
maybe_net: resolved_poly.maybe_net(),
},
poly,
)
}
}
/// Returns the pin name associated with a given node.
pub fn node_pinname(&self, node: &NodeIndex) -> Option<&String> {
@ -272,6 +144,139 @@ impl<M: AccessMesadata> Board<M> {
}
}
impl<M: AccessMesadata> Recording<'_, Board<M>> {
fn recording_layout(&mut self) -> Recording<'_, Layout<M>> {
self.inner.layout.recording(self.recorder)
}
/// Adds a new fixed dot with an optional pin name.
///
/// Inserts the dot into the layout and, if a pin name is provided, maps it to the created dot's node.
pub fn add_fixed_dot_infringably(
&mut self,
weight: FixedDotWeight,
maybe_pin: Option<String>,
) -> FixedDotIndex {
let dot = self.recording_layout().add_fixed_dot_infringably(weight);
if let Some(pin) = maybe_pin {
self.inner
.node_to_pinname
.insert(GenericNode::Primitive(dot.into()), pin);
}
dot
}
/// Adds a fixed segment between two dots with an optional pin name.
///
/// Adds the segment to the layout and maps the pin name to the created segment if provided.
pub fn add_poly_fixed_dot_infringably(
&mut self,
weight: FixedDotWeight,
poly: GenericIndex<PolyWeight>,
) -> FixedDotIndex {
let dot = self
.recording_layout()
.add_poly_fixed_dot_infringably(weight, poly);
if let Some(pin) = self.node_pinname(&GenericNode::Compound(poly.into())) {
self.inner
.node_to_pinname
.insert(GenericNode::Primitive(dot.into()), pin.to_string());
}
dot
}
/// Adds a fixed segment associated with a polygon in the layout.
///
/// Adds the segment to the layout and updates the internal mapping if necessary.
pub fn add_fixed_seg_infringably(
&mut self,
from: FixedDotIndex,
to: FixedDotIndex,
weight: FixedSegWeight,
maybe_pin: Option<String>,
) -> FixedSegIndex {
let seg = self
.recording_layout()
.add_fixed_seg_infringably(from, to, weight);
if let Some(pin) = maybe_pin {
self.inner
.node_to_pinname
.insert(GenericNode::Primitive(seg.into()), pin);
}
seg
}
/// Adds a fixed segment associated with a polygon in the layout.
///
/// Adds the segment to the layout and updates the internal mapping if necessary.
pub fn add_poly_fixed_seg_infringably(
&mut self,
from: FixedDotIndex,
to: FixedDotIndex,
weight: FixedSegWeight,
poly: GenericIndex<PolyWeight>,
) -> FixedSegIndex {
let seg = self
.recording_layout()
.add_poly_fixed_seg_infringably(from, to, weight, poly);
if let Some(pin) = self.node_pinname(&GenericNode::Compound(poly.into())) {
self.inner
.node_to_pinname
.insert(GenericNode::Primitive(seg.into()), pin.to_string());
}
seg
}
/// Adds a new polygon to the layout with an optional pin name.
///
/// Inserts the polygon into the layout and, if a pin name is provided, maps it to the created polygon's node.
pub fn add_poly(
&mut self,
weight: PolyWeight,
maybe_pin: Option<String>,
) -> GenericIndex<PolyWeight> {
let poly = self.recording_layout().add_poly(weight);
if let Some(pin) = maybe_pin {
self.inner
.node_to_pinname
.insert(GenericNode::Compound(poly.into()), pin);
}
poly
}
/// Retrieves or creates the apex (center point) of a polygon in the layout.
///
/// If the polygon already has an apex, returns it. Otherwise, creates and returns a new fixed dot as the apex.
pub fn poly_apex(&mut self, poly: GenericIndex<PolyWeight>) -> FixedDotIndex {
let resolved_poly = self.inner.layout.poly(poly);
if let Some(apex) = resolved_poly.maybe_apex() {
apex
} else {
self.add_poly_fixed_dot_infringably(
FixedDotWeight {
circle: Circle {
pos: resolved_poly.shape().center(),
r: 100.0,
},
layer: resolved_poly.layer(),
maybe_net: resolved_poly.maybe_net(),
},
poly,
)
}
}
}
impl<M: AccessMesadata>
ApplyGeometryEdit<
PrimitiveWeight,

View File

@ -18,7 +18,7 @@ use crate::{
seg::FixedSegWeight,
Drawing,
},
geometry::{primitive::PrimitiveShape, GetWidth},
geometry::{edit::Recordable, primitive::PrimitiveShape, GetWidth},
layout::{poly::SolidPolyWeight, Layout, LayoutEdit},
math::{Circle, PointWithRotation},
specctra::{
@ -431,8 +431,7 @@ impl SpecctraDesign {
r,
};
board.add_fixed_dot_infringably(
recorder,
board.recording(recorder).add_fixed_dot_infringably(
FixedDotWeight {
circle,
layer,
@ -455,15 +454,12 @@ impl SpecctraDesign {
maybe_net: Option<usize>,
maybe_pin: Option<String>,
) {
let poly = board.add_poly(
recorder,
SolidPolyWeight { layer, maybe_net }.into(),
maybe_pin,
);
let mut recording_board = board.recording(recorder);
let poly = recording_board.add_poly(SolidPolyWeight { layer, maybe_net }.into(), maybe_pin);
// Corners.
let dot_1_1 = board.add_poly_fixed_dot_infringably(
recorder,
let dot_1_1 = recording_board.add_poly_fixed_dot_infringably(
FixedDotWeight {
circle: Circle {
pos: Self::pos(place, pin, x1, y1),
@ -474,8 +470,7 @@ impl SpecctraDesign {
},
poly,
);
let dot_2_1 = board.add_poly_fixed_dot_infringably(
recorder,
let dot_2_1 = recording_board.add_poly_fixed_dot_infringably(
FixedDotWeight {
circle: Circle {
pos: Self::pos(place, pin, x2, y1),
@ -486,8 +481,7 @@ impl SpecctraDesign {
},
poly,
);
let dot_2_2 = board.add_poly_fixed_dot_infringably(
recorder,
let dot_2_2 = recording_board.add_poly_fixed_dot_infringably(
FixedDotWeight {
circle: Circle {
pos: Self::pos(place, pin, x2, y2),
@ -498,8 +492,7 @@ impl SpecctraDesign {
},
poly,
);
let dot_1_2 = board.add_poly_fixed_dot_infringably(
recorder,
let dot_1_2 = recording_board.add_poly_fixed_dot_infringably(
FixedDotWeight {
circle: Circle {
pos: Self::pos(place, pin, x1, y2),
@ -511,8 +504,7 @@ impl SpecctraDesign {
poly,
);
// Sides.
board.add_poly_fixed_seg_infringably(
recorder,
recording_board.add_poly_fixed_seg_infringably(
dot_1_1,
dot_2_1,
FixedSegWeight {
@ -522,8 +514,7 @@ impl SpecctraDesign {
},
poly,
);
board.add_poly_fixed_seg_infringably(
recorder,
recording_board.add_poly_fixed_seg_infringably(
dot_2_1,
dot_2_2,
FixedSegWeight {
@ -533,8 +524,7 @@ impl SpecctraDesign {
},
poly,
);
board.add_poly_fixed_seg_infringably(
recorder,
recording_board.add_poly_fixed_seg_infringably(
dot_2_2,
dot_1_2,
FixedSegWeight {
@ -544,8 +534,7 @@ impl SpecctraDesign {
},
poly,
);
board.add_poly_fixed_seg_infringably(
recorder,
recording_board.add_poly_fixed_seg_infringably(
dot_1_2,
dot_1_1,
FixedSegWeight {
@ -568,10 +557,10 @@ impl SpecctraDesign {
maybe_net: Option<usize>,
maybe_pin: Option<String>,
) {
let mut recording_board = board.recording(recorder);
// add the first coordinate in the wire path as a dot and save its index
let mut prev_pos = Self::pos(place, pin, coords[0].x, coords[0].y);
let mut prev_index = board.add_fixed_dot_infringably(
recorder,
let mut prev_index = recording_board.add_fixed_dot_infringably(
FixedDotWeight {
circle: Circle {
pos: prev_pos,
@ -591,8 +580,7 @@ impl SpecctraDesign {
continue;
}
let index = board.add_fixed_dot_infringably(
recorder,
let index = recording_board.add_fixed_dot_infringably(
FixedDotWeight {
circle: Circle {
pos,
@ -605,8 +593,7 @@ impl SpecctraDesign {
);
// add a seg between the current and previous coords
let _ = board.add_fixed_seg_infringably(
recorder,
let _ = recording_board.add_fixed_seg_infringably(
prev_index,
index,
FixedSegWeight {
@ -633,15 +620,11 @@ impl SpecctraDesign {
maybe_net: Option<usize>,
maybe_pin: Option<String>,
) {
let poly = board.add_poly(
recorder,
SolidPolyWeight { layer, maybe_net }.into(),
maybe_pin,
);
let mut recording_board = board.recording(recorder);
let poly = recording_board.add_poly(SolidPolyWeight { layer, maybe_net }.into(), maybe_pin);
// add the first coordinate in the wire path as a dot and save its index
let mut prev_index = board.add_poly_fixed_dot_infringably(
recorder,
let mut prev_index = recording_board.add_poly_fixed_dot_infringably(
FixedDotWeight {
circle: Circle {
pos: Self::pos(place, pin, coords[0].x, coords[0].y),
@ -657,8 +640,7 @@ impl SpecctraDesign {
// iterate through path coords starting from the second
for coord in coords.iter().skip(1) {
let index = board.add_poly_fixed_dot_infringably(
recorder,
let index = recording_board.add_poly_fixed_dot_infringably(
FixedDotWeight {
circle: Circle {
pos: Self::pos(place, pin, coord.x, coord.y),
@ -672,8 +654,7 @@ impl SpecctraDesign {
);
// add a seg between the current and previous coords
let _ = board.add_poly_fixed_seg_infringably(
recorder,
let _ = recording_board.add_poly_fixed_seg_infringably(
prev_index,
index,
FixedSegWeight {