mirror of https://codeberg.org/topola/topola.git
refactor(board): move recording methods to Recording<'_, Board<M>>
This commit is contained in:
parent
a911c0cddf
commit
af18d82d7c
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
287
src/board/mod.rs
287
src/board/mod.rs
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Reference in New Issue