From 692ec68ec2b29af2ce9a30d0cabf3bfaf1039c95 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Tue, 19 May 2026 20:54:39 +0200 Subject: [PATCH] Expand `board.rs` into a new module directory --- topola-egui/src/display.rs | 15 +- topola-egui/src/viewport.rs | 2 +- topola/src/board.rs | 403 ------------------ topola/src/board/mod.rs | 171 ++++++++ topola/src/board/select.rs | 230 ++++++++++ .../src/{ => board}/selections/component.rs | 0 topola/src/board/selections/mod.rs | 11 + .../src/{ => board}/selections/persistable.rs | 6 +- .../selections/pin.rs} | 8 +- topola/src/layout.rs | 2 +- topola/src/lib.rs | 2 +- topola/src/selections/mod.rs | 11 - 12 files changed, 425 insertions(+), 436 deletions(-) delete mode 100644 topola/src/board.rs create mode 100644 topola/src/board/mod.rs create mode 100644 topola/src/board/select.rs rename topola/src/{ => board}/selections/component.rs (100%) create mode 100644 topola/src/board/selections/mod.rs rename topola/src/{ => board}/selections/persistable.rs (73%) rename topola/src/{selections/pin_with_layer.rs => board/selections/pin.rs} (74%) delete mode 100644 topola/src/selections/mod.rs diff --git a/topola-egui/src/display.rs b/topola-egui/src/display.rs index eda886a..a092096 100644 --- a/topola-egui/src/display.rs +++ b/topola-egui/src/display.rs @@ -53,10 +53,7 @@ impl Display { workspace.appearance_panel.layer_color( ctx, board.layer_name(joint.spec.layer), - board.pin_with_layer_selection_contains_joint( - &workspace.selection.pins, - joint_id, - ), + board.pin_selection_contains_joint(&workspace.selection.pins, joint_id), ), ); } @@ -71,10 +68,7 @@ impl Display { workspace.appearance_panel.layer_color( ctx, board.layer_name(segment.layer), - board.pin_with_layer_selection_contains_segment( - &workspace.selection.pins, - segment_id, - ), + board.pin_selection_contains_segment(&workspace.selection.pins, segment_id), ), ); } @@ -91,10 +85,7 @@ impl Display { workspace.appearance_panel.layer_color( ctx, board.layer_name(polygon.layer), - board.pin_with_layer_selection_contains_polygon( - &workspace.selection.pins, - polygon_id, - ), + board.pin_selection_contains_polygon(&workspace.selection.pins, polygon_id), ), ); } diff --git a/topola-egui/src/viewport.rs b/topola-egui/src/viewport.rs index 26febda..39e10ae 100644 --- a/topola-egui/src/viewport.rs +++ b/topola-egui/src/viewport.rs @@ -58,7 +58,7 @@ impl Viewport { .router() .navmesher_board() .board() - .point_pin_with_layer_selector( + .point_pin_selector( 0, Vector2::new( pointer_scene_pos.x as i64, diff --git a/topola/src/board.rs b/topola/src/board.rs deleted file mode 100644 index a69d3be..0000000 --- a/topola/src/board.rs +++ /dev/null @@ -1,403 +0,0 @@ -// SPDX-FileCopyrightText: 2026 Topola contributors -// -// SPDX-License-Identifier: MIT OR Apache-2.0 - -use bimap::BiBTreeMap; -use derive_getters::{Dissolve, Getters}; -use undoredo::{ApplyDelta, Delta, FlushDelta}; - -use crate::{ - compounds::{ComponentId, NetId, PinId}, - layout::{Layout, LayoutHalfDelta}, - math::Vector2, - primitives::{ - JointId, JointSpec, Polygon, PolygonId, Segment, SegmentId, SegmentSpec, Via, ViaId, - ViaSpec, - }, - selections::{ - ComponentSelection, ComponentSelector, PinWithLayerSelection, PinWithLayerSelector, - }, -}; - -#[derive(Clone, Debug, Getters)] -pub struct Board { - layout: Layout, - #[getter(skip)] - component_names: BiBTreeMap, - #[getter(skip)] - pin_names: BiBTreeMap, - #[getter(skip)] - layer_names: BiBTreeMap, - #[getter(skip)] - net_names: BiBTreeMap, -} - -impl Board { - pub fn new(boundary: Vec>, layer_count: usize) -> Self { - Self { - layout: Layout::new(boundary.into_iter().map(Into::into).collect(), layer_count), - component_names: BiBTreeMap::new(), - pin_names: BiBTreeMap::new(), - layer_names: BiBTreeMap::new(), - net_names: BiBTreeMap::new(), - } - } - - pub fn with_names( - boundary: Vec>, - layer_count: usize, - layer_names: BiBTreeMap, - net_names: BiBTreeMap, - ) -> Self { - Self { - layout: Layout::new(boundary.into_iter().map(Into::into).collect(), layer_count), - component_names: BiBTreeMap::new(), - pin_names: BiBTreeMap::new(), - layer_names, - net_names, - } - } - - pub fn ensure_named_component(&mut self, component_name: String) -> ComponentId { - if let Some(component) = self.component_names.get_by_right(&component_name) { - return *component; - }; - - let component_id = self.layout.add_component(); - self.component_names.insert(component_id, component_name); - - component_id - } - - pub fn ensure_named_pin(&mut self, pin_name: String) -> PinId { - if let Some(pin) = self.pin_names.get_by_right(&pin_name) { - return *pin; - }; - - let pin_id = self.layout.add_pin(); - self.pin_names.insert(pin_id, pin_name); - - pin_id - } - - pub fn add_component(&mut self) -> ComponentId { - self.layout.add_component() - } - - pub fn add_joint(&mut self, spec: JointSpec) -> JointId { - self.layout.add_joint(spec) - } - - pub fn add_segment(&mut self, spec: SegmentSpec) -> SegmentId { - self.layout.add_segment(spec) - } - - pub fn add_segment_raw(&mut self, segment: Segment) -> SegmentId { - self.layout.add_segment_raw(segment) - } - - pub fn add_via(&mut self, spec: ViaSpec) -> ViaId { - self.layout.add_via(spec) - } - - pub fn add_via_raw(&mut self, via: Via) -> ViaId { - self.layout.add_via_raw(via) - } - - pub fn add_polygon(&mut self, polygon: Polygon) -> PolygonId { - self.layout.add_polygon(polygon) - } - - pub fn pin_with_layer_selection_to_component_selection( - &mut self, - pin_with_layer_selection: PinWithLayerSelection, - ) -> ComponentSelection { - let mut component_selection = ComponentSelection::new(); - - for selector in pin_with_layer_selection.0 { - let Some(pin_id) = self.pin_id(&selector.pin) else { - continue; - }; - - let Some(layer_id) = self.layer_id(&selector.layer) else { - continue; - }; - - for joint_id in self.layout.layer_joints(layer_id) { - if self.layout.joint(joint_id).spec.pin != Some(pin_id) { - continue; - } - - let Some(component_selector) = self.joint_component_selector(joint_id) else { - continue; - }; - - component_selection.0.insert(component_selector); - } - - // TODO: Vias. - - for segment_id in self.layout.layer_segments(layer_id) { - if self.layout.segment(segment_id).spec.pin != Some(pin_id) { - continue; - } - - let Some(component_selector) = self.segment_component_selector(segment_id) else { - continue; - }; - - component_selection.0.insert(component_selector); - } - - for polygon_id in self.layout.layer_polygons(layer_id) { - if self.layout.polygon(polygon_id).pin != Some(pin_id) { - continue; - } - - let Some(component_selector) = self.polygon_component_selector(polygon_id) else { - continue; - }; - - component_selection.0.insert(component_selector); - } - } - - component_selection - } - - pub fn component_selection_contains_joint( - &self, - selection: &ComponentSelection, - id: JointId, - ) -> bool { - let Some(selector) = self.joint_component_selector(id) else { - return false; - }; - - selection.0.contains(&selector) - } - - pub fn component_selection_contains_segment( - &self, - selection: &ComponentSelection, - id: SegmentId, - ) -> bool { - let Some(selector) = self.segment_component_selector(id) else { - return false; - }; - - selection.0.contains(&selector) - } - - // TODO: Vias. - - pub fn component_selection_contains_polygon( - &self, - selection: &ComponentSelection, - id: PolygonId, - ) -> bool { - let Some(selector) = self.polygon_component_selector(id) else { - return false; - }; - - selection.0.contains(&selector) - } - - pub fn point_component_selector( - &self, - layer: usize, - point: Vector2, - ) -> Option { - if let Some(joint_id) = self.layout.locate_joints_at_point(layer, point).next() { - return self.joint_component_selector(joint_id); - } - - if let Some(segment_id) = self.layout.locate_segments_at_point(layer, point).next() { - return self.segment_component_selector(segment_id); - } - - // TODO: Vias. - - if let Some(polygon_id) = self.layout.locate_polygons_at_point(layer, point).next() { - return self.polygon_component_selector(polygon_id); - } - - None - } - - pub fn joint_component_selector(&self, id: JointId) -> Option { - let joint = self.layout.joint(id); - - Some(ComponentSelector { - component: self.component_name(joint.spec.component?)?.to_string(), - }) - } - - pub fn segment_component_selector(&self, id: SegmentId) -> Option { - let segment = self.layout.segment(id); - - Some(ComponentSelector { - component: self.component_name(segment.spec.component?)?.to_string(), - }) - } - - // TODO: Vias. - - pub fn polygon_component_selector(&self, id: PolygonId) -> Option { - let polygon = self.layout.polygon(id); - - Some(ComponentSelector { - component: self.component_name(polygon.component?)?.to_string(), - }) - } - - pub fn pin_with_layer_selection_contains_joint( - &self, - selection: &PinWithLayerSelection, - id: JointId, - ) -> bool { - let Some(selector) = self.joint_pin_with_layer_selector(id) else { - return false; - }; - - selection.0.contains(&selector) - } - - pub fn pin_with_layer_selection_contains_segment( - &self, - selection: &PinWithLayerSelection, - id: SegmentId, - ) -> bool { - let Some(selector) = self.segment_pin_with_layer_selector(id) else { - return false; - }; - - selection.0.contains(&selector) - } - - // TODO: Vias. - - pub fn pin_with_layer_selection_contains_polygon( - &self, - selection: &PinWithLayerSelection, - id: PolygonId, - ) -> bool { - let Some(selector) = self.polygon_pin_with_layer_selector(id) else { - return false; - }; - - selection.0.contains(&selector) - } - - pub fn point_pin_with_layer_selector( - &self, - layer: usize, - point: Vector2, - ) -> Option { - if let Some(joint_id) = self.layout.locate_joints_at_point(layer, point).next() { - return self.joint_pin_with_layer_selector(joint_id); - } - - if let Some(segment_id) = self.layout.locate_segments_at_point(layer, point).next() { - return self.segment_pin_with_layer_selector(segment_id); - } - - // TODO: Vias. - - if let Some(polygon_id) = self.layout.locate_polygons_at_point(layer, point).next() { - return self.polygon_pin_with_layer_selector(polygon_id); - } - - None - } - - pub fn joint_pin_with_layer_selector(&self, id: JointId) -> Option { - let joint = self.layout.joint(id); - - Some(PinWithLayerSelector { - pin: self.pin_name(joint.spec.pin?)?.to_string(), - layer: self.layer_name(joint.spec.layer)?.to_string(), - }) - } - - pub fn segment_pin_with_layer_selector(&self, id: SegmentId) -> Option { - let segment = self.layout.segment(id); - - Some(PinWithLayerSelector { - pin: self.pin_name(segment.spec.pin?)?.to_string(), - layer: self.layer_name(segment.layer)?.to_string(), - }) - } - - // TODO: Vias. - - pub fn polygon_pin_with_layer_selector(&self, id: PolygonId) -> Option { - let polygon = self.layout.polygon(id); - - Some(PinWithLayerSelector { - pin: self.pin_name(polygon.pin?)?.to_string(), - layer: self.layer_name(polygon.layer)?.to_string(), - }) - } - - pub fn component_name(&self, id: ComponentId) -> Option<&str> { - self.component_names.get_by_left(&id).map(String::as_str) - } - - pub fn component_id(&self, component_name: &str) -> Option { - self.component_names.get_by_right(component_name).copied() - } - - pub fn pin_name(&self, id: PinId) -> Option<&str> { - self.pin_names.get_by_left(&id).map(String::as_str) - } - - pub fn pin_id(&self, pin_name: &str) -> Option { - self.pin_names.get_by_right(pin_name).copied() - } - - pub fn layer_name(&self, layer: usize) -> Option<&str> { - self.layer_names.get_by_left(&layer).map(String::as_str) - } - - pub fn layer_id(&self, layer_name: &str) -> Option { - self.layer_names.get_by_right(layer_name).copied() - } - - pub fn net_name(&self, id: NetId) -> Option<&str> { - self.net_names.get_by_left(&id).map(String::as_str) - } - - pub fn net_id(&self, net_name: &str) -> Option { - self.net_names.get_by_right(net_name).copied() - } -} - -#[derive(Clone, Debug, Dissolve)] -pub struct BoardHalfDelta { - layout: LayoutHalfDelta, -} - -impl ApplyDelta for Board { - 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); - } -} - -impl FlushDelta for Board { - fn flush_delta(&mut self) -> Delta { - let (removed_layout, inserted_layout) = self.layout.flush_delta().dissolve(); - - Delta::with_removed_inserted( - BoardHalfDelta { - layout: removed_layout, - }, - BoardHalfDelta { - layout: inserted_layout, - }, - ) - } -} diff --git a/topola/src/board/mod.rs b/topola/src/board/mod.rs new file mode 100644 index 0000000..8b8a63c --- /dev/null +++ b/topola/src/board/mod.rs @@ -0,0 +1,171 @@ +// SPDX-FileCopyrightText: 2026 Topola contributors +// +// SPDX-License-Identifier: MIT OR Apache-2.0 + +mod select; +pub mod selections; + +use bimap::BiBTreeMap; +use derive_getters::{Dissolve, Getters}; +use undoredo::{ApplyDelta, Delta, FlushDelta}; + +use crate::{ + compounds::{ComponentId, NetId, PinId}, + layout::{Layout, LayoutHalfDelta}, + math::Vector2, + primitives::{ + JointId, JointSpec, Polygon, PolygonId, Segment, SegmentId, SegmentSpec, Via, ViaId, + ViaSpec, + }, +}; + +#[derive(Clone, Debug, Getters)] +pub struct Board { + layout: Layout, + #[getter(skip)] + component_names: BiBTreeMap, + #[getter(skip)] + pin_names: BiBTreeMap, + #[getter(skip)] + layer_names: BiBTreeMap, + #[getter(skip)] + net_names: BiBTreeMap, +} + +impl Board { + pub fn new(boundary: Vec>, layer_count: usize) -> Self { + Self { + layout: Layout::new(boundary.into_iter().map(Into::into).collect(), layer_count), + component_names: BiBTreeMap::new(), + pin_names: BiBTreeMap::new(), + layer_names: BiBTreeMap::new(), + net_names: BiBTreeMap::new(), + } + } + + pub fn with_names( + boundary: Vec>, + layer_count: usize, + layer_names: BiBTreeMap, + net_names: BiBTreeMap, + ) -> Self { + Self { + layout: Layout::new(boundary.into_iter().map(Into::into).collect(), layer_count), + component_names: BiBTreeMap::new(), + pin_names: BiBTreeMap::new(), + layer_names, + net_names, + } + } + + pub fn ensure_named_component(&mut self, component_name: String) -> ComponentId { + if let Some(component) = self.component_names.get_by_right(&component_name) { + return *component; + }; + + let component_id = self.layout.add_component(); + self.component_names.insert(component_id, component_name); + + component_id + } + + pub fn ensure_named_pin(&mut self, pin_name: String) -> PinId { + if let Some(pin) = self.pin_names.get_by_right(&pin_name) { + return *pin; + }; + + let pin_id = self.layout.add_pin(); + self.pin_names.insert(pin_id, pin_name); + + pin_id + } + + pub fn add_component(&mut self) -> ComponentId { + self.layout.add_component() + } + + pub fn add_joint(&mut self, spec: JointSpec) -> JointId { + self.layout.add_joint(spec) + } + + pub fn add_segment(&mut self, spec: SegmentSpec) -> SegmentId { + self.layout.add_segment(spec) + } + + pub fn add_segment_raw(&mut self, segment: Segment) -> SegmentId { + self.layout.add_segment_raw(segment) + } + + pub fn add_via(&mut self, spec: ViaSpec) -> ViaId { + self.layout.add_via(spec) + } + + pub fn add_via_raw(&mut self, via: Via) -> ViaId { + self.layout.add_via_raw(via) + } + + pub fn add_polygon(&mut self, polygon: Polygon) -> PolygonId { + self.layout.add_polygon(polygon) + } + + pub fn component_name(&self, id: ComponentId) -> Option<&str> { + self.component_names.get_by_left(&id).map(String::as_str) + } + + pub fn component_id(&self, component_name: &str) -> Option { + self.component_names.get_by_right(component_name).copied() + } + + pub fn pin_name(&self, id: PinId) -> Option<&str> { + self.pin_names.get_by_left(&id).map(String::as_str) + } + + pub fn pin_id(&self, pin_name: &str) -> Option { + self.pin_names.get_by_right(pin_name).copied() + } + + pub fn layer_name(&self, layer: usize) -> Option<&str> { + self.layer_names.get_by_left(&layer).map(String::as_str) + } + + pub fn layer_id(&self, layer_name: &str) -> Option { + self.layer_names.get_by_right(layer_name).copied() + } + + pub fn net_name(&self, id: NetId) -> Option<&str> { + self.net_names.get_by_left(&id).map(String::as_str) + } + + pub fn net_id(&self, net_name: &str) -> Option { + self.net_names.get_by_right(net_name).copied() + } +} + +#[derive(Clone, Debug, Dissolve)] +pub struct BoardHalfDelta { + layout: LayoutHalfDelta, +} + +impl ApplyDelta for Board { + 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); + } +} + +impl FlushDelta for Board { + fn flush_delta(&mut self) -> Delta { + let (removed_layout, inserted_layout) = self.layout.flush_delta().dissolve(); + + Delta::with_removed_inserted( + BoardHalfDelta { + layout: removed_layout, + }, + BoardHalfDelta { + layout: inserted_layout, + }, + ) + } +} diff --git a/topola/src/board/select.rs b/topola/src/board/select.rs new file mode 100644 index 0000000..dec3a47 --- /dev/null +++ b/topola/src/board/select.rs @@ -0,0 +1,230 @@ +// SPDX-FileCopyrightText: 2026 Topola contributors +// +// SPDX-License-Identifier: MIT OR Apache-2.0 + +use crate::{ + board::{ + Board, + selections::{ComponentSelection, ComponentSelector, PinSelection, PinSelector}, + }, + math::Vector2, + primitives::{JointId, PolygonId, SegmentId}, +}; + +impl Board { + pub fn pin_selection_to_component_selection( + &mut self, + pin_selection: PinSelection, + ) -> ComponentSelection { + let mut component_selection = ComponentSelection::new(); + + for selector in pin_selection.0 { + let Some(pin_id) = self.pin_id(&selector.pin) else { + continue; + }; + + let Some(layer_id) = self.layer_id(&selector.layer) else { + continue; + }; + + for joint_id in self.layout.layer_joints(layer_id) { + if self.layout.joint(joint_id).spec.pin != Some(pin_id) { + continue; + } + + let Some(component_selector) = self.joint_component_selector(joint_id) else { + continue; + }; + + component_selection.0.insert(component_selector); + } + + // TODO: Vias. + + for segment_id in self.layout.layer_segments(layer_id) { + if self.layout.segment(segment_id).spec.pin != Some(pin_id) { + continue; + } + + let Some(component_selector) = self.segment_component_selector(segment_id) else { + continue; + }; + + component_selection.0.insert(component_selector); + } + + for polygon_id in self.layout.layer_polygons(layer_id) { + if self.layout.polygon(polygon_id).pin != Some(pin_id) { + continue; + } + + let Some(component_selector) = self.polygon_component_selector(polygon_id) else { + continue; + }; + + component_selection.0.insert(component_selector); + } + } + + component_selection + } + + pub fn component_selection_contains_joint( + &self, + selection: &ComponentSelection, + id: JointId, + ) -> bool { + let Some(selector) = self.joint_component_selector(id) else { + return false; + }; + + selection.0.contains(&selector) + } + + pub fn component_selection_contains_segment( + &self, + selection: &ComponentSelection, + id: SegmentId, + ) -> bool { + let Some(selector) = self.segment_component_selector(id) else { + return false; + }; + + selection.0.contains(&selector) + } + + // TODO: Vias. + + pub fn component_selection_contains_polygon( + &self, + selection: &ComponentSelection, + id: PolygonId, + ) -> bool { + let Some(selector) = self.polygon_component_selector(id) else { + return false; + }; + + selection.0.contains(&selector) + } + + pub fn point_component_selector( + &self, + layer: usize, + point: Vector2, + ) -> Option { + if let Some(joint_id) = self.layout.locate_joints_at_point(layer, point).next() { + return self.joint_component_selector(joint_id); + } + + if let Some(segment_id) = self.layout.locate_segments_at_point(layer, point).next() { + return self.segment_component_selector(segment_id); + } + + // TODO: Vias. + + if let Some(polygon_id) = self.layout.locate_polygons_at_point(layer, point).next() { + return self.polygon_component_selector(polygon_id); + } + + None + } + + pub fn joint_component_selector(&self, id: JointId) -> Option { + let joint = self.layout.joint(id); + + Some(ComponentSelector { + component: self.component_name(joint.spec.component?)?.to_string(), + }) + } + + pub fn segment_component_selector(&self, id: SegmentId) -> Option { + let segment = self.layout.segment(id); + + Some(ComponentSelector { + component: self.component_name(segment.spec.component?)?.to_string(), + }) + } + + // TODO: Vias. + + pub fn polygon_component_selector(&self, id: PolygonId) -> Option { + let polygon = self.layout.polygon(id); + + Some(ComponentSelector { + component: self.component_name(polygon.component?)?.to_string(), + }) + } + + pub fn pin_selection_contains_joint(&self, selection: &PinSelection, id: JointId) -> bool { + let Some(selector) = self.joint_pin_selector(id) else { + return false; + }; + + selection.0.contains(&selector) + } + + pub fn pin_selection_contains_segment(&self, selection: &PinSelection, id: SegmentId) -> bool { + let Some(selector) = self.segment_pin_selector(id) else { + return false; + }; + + selection.0.contains(&selector) + } + + // TODO: Vias. + + pub fn pin_selection_contains_polygon(&self, selection: &PinSelection, id: PolygonId) -> bool { + let Some(selector) = self.polygon_pin_selector(id) else { + return false; + }; + + selection.0.contains(&selector) + } + + pub fn point_pin_selector(&self, layer: usize, point: Vector2) -> Option { + if let Some(joint_id) = self.layout.locate_joints_at_point(layer, point).next() { + return self.joint_pin_selector(joint_id); + } + + if let Some(segment_id) = self.layout.locate_segments_at_point(layer, point).next() { + return self.segment_pin_selector(segment_id); + } + + // TODO: Vias. + + if let Some(polygon_id) = self.layout.locate_polygons_at_point(layer, point).next() { + return self.polygon_pin_selector(polygon_id); + } + + None + } + + pub fn joint_pin_selector(&self, id: JointId) -> Option { + let joint = self.layout.joint(id); + + Some(PinSelector { + pin: self.pin_name(joint.spec.pin?)?.to_string(), + layer: self.layer_name(joint.spec.layer)?.to_string(), + }) + } + + pub fn segment_pin_selector(&self, id: SegmentId) -> Option { + let segment = self.layout.segment(id); + + Some(PinSelector { + pin: self.pin_name(segment.spec.pin?)?.to_string(), + layer: self.layer_name(segment.layer)?.to_string(), + }) + } + + // TODO: Vias. + + pub fn polygon_pin_selector(&self, id: PolygonId) -> Option { + let polygon = self.layout.polygon(id); + + Some(PinSelector { + pin: self.pin_name(polygon.pin?)?.to_string(), + layer: self.layer_name(polygon.layer)?.to_string(), + }) + } +} diff --git a/topola/src/selections/component.rs b/topola/src/board/selections/component.rs similarity index 100% rename from topola/src/selections/component.rs rename to topola/src/board/selections/component.rs diff --git a/topola/src/board/selections/mod.rs b/topola/src/board/selections/mod.rs new file mode 100644 index 0000000..49deb88 --- /dev/null +++ b/topola/src/board/selections/mod.rs @@ -0,0 +1,11 @@ +// SPDX-FileCopyrightText: 2026 Topola contributors +// +// SPDX-License-Identifier: MIT OR Apache-2.0 + +mod component; +mod persistable; +mod pin; + +pub use component::{ComponentSelection, ComponentSelector}; +pub use persistable::PersistableSelection; +pub use pin::{PinSelection, PinSelector}; diff --git a/topola/src/selections/persistable.rs b/topola/src/board/selections/persistable.rs similarity index 73% rename from topola/src/selections/persistable.rs rename to topola/src/board/selections/persistable.rs index af8fea1..ac137a3 100644 --- a/topola/src/selections/persistable.rs +++ b/topola/src/board/selections/persistable.rs @@ -4,19 +4,19 @@ use serde::{Deserialize, Serialize}; -use crate::selections::{ComponentSelection, PinWithLayerSelection}; +use crate::board::selections::{ComponentSelection, PinSelection}; #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub struct PersistableSelection { pub components: ComponentSelection, - pub pins: PinWithLayerSelection, + pub pins: PinSelection, } impl PersistableSelection { pub fn new() -> Self { Self { components: ComponentSelection::new(), - pins: PinWithLayerSelection::new(), + pins: PinSelection::new(), } } } diff --git a/topola/src/selections/pin_with_layer.rs b/topola/src/board/selections/pin.rs similarity index 74% rename from topola/src/selections/pin_with_layer.rs rename to topola/src/board/selections/pin.rs index c2990a1..2226ed3 100644 --- a/topola/src/selections/pin_with_layer.rs +++ b/topola/src/board/selections/pin.rs @@ -7,20 +7,20 @@ use std::collections::BTreeSet; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] -pub struct PinWithLayerSelector { +pub struct PinSelector { pub pin: String, pub layer: String, } #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] -pub struct PinWithLayerSelection(pub BTreeSet); +pub struct PinSelection(pub BTreeSet); -impl PinWithLayerSelection { +impl PinSelection { pub fn new() -> Self { Self(BTreeSet::new()) } - pub fn toggle(&mut self, selector: PinWithLayerSelector) { + pub fn toggle(&mut self, selector: PinSelector) { if self.0.contains(&selector) { self.0.remove(&selector); } else { diff --git a/topola/src/layout.rs b/topola/src/layout.rs index ed8a7f7..15b371b 100644 --- a/topola/src/layout.rs +++ b/topola/src/layout.rs @@ -20,7 +20,7 @@ use crate::{ }, }; -#[derive(Delta, Clone, Debug, Getters)] +#[derive(Clone, Debug, Delta, Getters)] pub struct Layout { #[undoredo(skip)] boundary: Vec<[i64; 2]>, diff --git a/topola/src/lib.rs b/topola/src/lib.rs index f7325df..8d045fd 100644 --- a/topola/src/lib.rs +++ b/topola/src/lib.rs @@ -13,11 +13,11 @@ mod pathfinder; pub mod primitives; mod ratsnest; mod router; -pub mod selections; mod specctra; pub use crate::autorouter::Autorouter; pub use crate::board::Board; +pub use crate::board::selections; pub use crate::compounds::{Pin, PinId}; pub use crate::layout::Layout; pub use crate::math::Vector2; diff --git a/topola/src/selections/mod.rs b/topola/src/selections/mod.rs deleted file mode 100644 index 5481dfe..0000000 --- a/topola/src/selections/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-FileCopyrightText: 2026 Topola contributors -// -// SPDX-License-Identifier: MIT OR Apache-2.0 - -mod component; -mod persistable; -mod pin_with_layer; - -pub use component::*; -pub use persistable::*; -pub use pin_with_layer::*;