fix(board/edit): Record changes to pin nodes too, which was something I forgot

This commit is contained in:
Mikolaj Wielgus 2025-10-25 00:32:28 +02:00
parent 91fb18b166
commit c1880cfbb3
3 changed files with 71 additions and 18 deletions

View File

@ -11,7 +11,7 @@ use std::{
///
/// - Each key can have multiple associated values (`BTreeSet<V>`).
/// - Each value maps to exactly one key (i.e., it's unique across keys).
#[derive(Debug)]
#[derive(Clone, Debug, Default)]
pub struct BiBTreeMapSet<K, V> {
key_to_values: BTreeMap<K, BTreeSet<V>>, // Forward mapping: key -> set of values.
value_to_key: BTreeMap<V, K>, // Reverse mapping: value -> key.

View File

@ -5,12 +5,16 @@
use std::collections::BTreeMap;
use crate::{
board::BandName, drawing::band::BandUid, geometry::edit::Edit, layout::LayoutEdit,
board::BandName,
drawing::band::BandUid,
geometry::edit::Edit,
layout::{LayoutEdit, NodeIndex},
router::ng::EtchedPath,
};
#[derive(Debug, Clone, Default)]
pub struct BoardDataEdit {
pub(super) pinname_nodes: BTreeMap<NodeIndex, (Option<String>, Option<String>)>,
pub(super) bands_by_id: BTreeMap<EtchedPath, (Option<BandUid>, Option<BandUid>)>,
pub(super) bands_by_name: BTreeMap<BandName, (Option<BandUid>, Option<BandUid>)>,
}
@ -23,11 +27,13 @@ impl BoardDataEdit {
impl Edit for BoardDataEdit {
fn reverse_inplace(&mut self) {
self.pinname_nodes.reverse_inplace();
self.bands_by_id.reverse_inplace();
self.bands_by_name.reverse_inplace();
}
fn merge(&mut self, edit: Self) {
self.pinname_nodes.merge(edit.pinname_nodes);
self.bands_by_id.merge(edit.bands_by_id);
self.bands_by_name.merge(edit.bands_by_name);
}

View File

@ -81,10 +81,10 @@ impl<'a> ResolvedSelector<'a> {
#[derive(Debug, Getters)]
pub struct Board<M> {
layout: Layout<M>,
bands_by_id: BiBTreeMap<EtchedPath, BandUid>,
// TODO: Simplify access logic to these members so that `#[getter(skip)]`s can be removed.
#[getter(skip)]
pinname_nodes: BiBTreeMapSet<String, NodeIndex>,
bands_by_id: BiBTreeMap<EtchedPath, BandUid>,
// TODO: Simplify access logic to these members so that `#[getter(skip)]`s can be removed.
#[getter(skip)]
band_bandname: BiBTreeMap<BandUid, BandName>,
}
@ -117,8 +117,11 @@ impl<M: AccessMesadata> Board<M> {
if let Some(pin) = maybe_pin {
for dot in dots.clone() {
self.pinname_nodes
.insert(pin.clone(), GenericNode::Primitive(dot.into()));
self.insert_pinname_node(
&mut recorder.board_data_edit,
pin.clone(),
GenericNode::Primitive(dot.into()),
);
}
}
@ -132,8 +135,10 @@ impl<M: AccessMesadata> Board<M> {
dots: Vec<FixedDotIndex>,
) {
for dot in dots.clone() {
self.pinname_nodes
.remove_by_value(&GenericNode::Primitive(dot.into()));
self.remove_pinname_node(
&mut recorder.board_data_edit,
GenericNode::Primitive(dot.into()),
);
}
self.layout.remove_via(&mut recorder.layout_edit, via, dots);
@ -153,8 +158,11 @@ impl<M: AccessMesadata> Board<M> {
.add_fixed_dot_infringably(&mut recorder.layout_edit, weight);
if let Some(pin) = maybe_pin {
self.pinname_nodes
.insert(pin, GenericNode::Primitive(dot.into()));
self.insert_pinname_node(
&mut recorder.board_data_edit,
pin,
GenericNode::Primitive(dot.into()),
);
}
dot
@ -176,8 +184,11 @@ impl<M: AccessMesadata> Board<M> {
.add_fixed_seg_infringably(&mut recorder.layout_edit, from, to, weight);
if let Some(pin) = maybe_pin {
self.pinname_nodes
.insert(pin, GenericNode::Primitive(seg.into()));
self.insert_pinname_node(
&mut recorder.board_data_edit,
pin,
GenericNode::Primitive(seg.into()),
);
}
seg
@ -200,15 +211,24 @@ impl<M: AccessMesadata> Board<M> {
if let Some(pin) = maybe_pin {
for i in nodes {
self.pinname_nodes
.insert(pin.clone(), GenericNode::Primitive(*i));
self.insert_pinname_node(
&mut recorder.board_data_edit,
pin.clone(),
GenericNode::Primitive(*i),
);
}
self.pinname_nodes
.insert(pin.clone(), GenericNode::Primitive(apex.into()));
self.insert_pinname_node(
&mut recorder.board_data_edit,
pin.clone(),
GenericNode::Primitive(apex.into()),
);
self.pinname_nodes
.insert(pin, GenericNode::Compound(poly.into()));
self.insert_pinname_node(
&mut recorder.board_data_edit,
pin,
GenericNode::Compound(poly.into()),
);
}
poly
@ -371,7 +391,28 @@ impl<M: AccessMesadata> Board<M> {
.copied()
}
fn insert_pinname_node(
&mut self,
recorder: &mut BoardDataEdit,
pinname: String,
node: NodeIndex,
) {
self.pinname_nodes.insert(pinname.clone(), node);
recorder.pinname_nodes.insert(node, (None, Some(pinname)));
}
fn remove_pinname_node(&mut self, recorder: &mut BoardDataEdit, node: NodeIndex) {
let prev = self.pinname_nodes.remove_by_value(&node);
recorder.pinname_nodes.insert(node, (prev, None));
}
pub fn apply_edit(&mut self, edit: &BoardEdit) {
for (node, (maybe_old_pinname, _)) in &edit.board_data_edit.pinname_nodes {
if maybe_old_pinname.is_some() {
self.pinname_nodes.remove_by_value(node);
}
}
for (bandname, (maybe_old_band_uid, _)) in &edit.board_data_edit.bands_by_name {
if maybe_old_band_uid.is_some() {
self.band_bandname.remove_by_right(bandname);
@ -397,6 +438,12 @@ impl<M: AccessMesadata> Board<M> {
self.bands_by_id.insert(*ep, *band_uid);
}
}
for (node, (_, maybe_new_pinname)) in &edit.board_data_edit.pinname_nodes {
if let Some(pinname) = maybe_new_pinname {
self.pinname_nodes.insert(pinname.clone(), *node);
}
}
}
/// Returns the mesadata associated with the layout's drawing rules.