From 5113f30fd5cf11669df21f22bab7d995aedf3777 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Fri, 13 Mar 2026 14:50:33 +0100 Subject: [PATCH] Add selector and selection data structures --- topola/src/layout.rs | 102 +++++++++++++++++++++++----------------- topola/src/lib.rs | 1 + topola/src/selection.rs | 28 +++++++++++ 3 files changed, 88 insertions(+), 43 deletions(-) create mode 100644 topola/src/selection.rs diff --git a/topola/src/layout.rs b/topola/src/layout.rs index 6219010..50ac71b 100644 --- a/topola/src/layout.rs +++ b/topola/src/layout.rs @@ -5,19 +5,19 @@ use std::collections::BTreeMap; use derive_getters::{Dissolve, Getters}; +use derive_more::Constructor; +use serde::{Deserialize, Serialize}; use stable_vec::StableVec; use undoredo::{ApplyDelta, Delta, FlushDelta, Recorder}; -#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] +use crate::selection::PinSelector; + +#[derive( + Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize, +)] pub struct PinId(usize); impl PinId { - /// Wrap a pin index in a newtype struct. - #[inline] - pub fn new(id: usize) -> Self { - Self(id) - } - /// Returns the underlying index. #[inline] pub fn id(self) -> usize { @@ -44,16 +44,12 @@ impl Pin { } } -#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] +#[derive( + Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize, +)] pub struct NetId(usize); impl NetId { - /// Wrap a joint index in a newtype struct. - #[inline] - pub fn new(id: usize) -> Self { - Self(id) - } - /// Returns the underlying index. #[inline] pub fn id(self) -> usize { @@ -61,16 +57,12 @@ impl NetId { } } -#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] +#[derive( + Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize, +)] pub struct JointId(usize); impl JointId { - /// Wrap a joint index in a newtype struct. - #[inline] - pub fn new(id: usize) -> Self { - Self(id) - } - /// Returns the underlying index. #[inline] pub fn id(self) -> usize { @@ -87,16 +79,21 @@ pub struct Joint { pub pin: Option, } -#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] +impl Joint { + pub fn pin_selector(&self) -> Option { + Some(PinSelector { + pin: self.pin?, + layer: self.layer, + }) + } +} + +#[derive( + Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize, +)] pub struct SegmentId(usize); impl SegmentId { - /// Wrap a segment index in a newtype struct. - #[inline] - pub fn new(id: usize) -> Self { - Self(id) - } - /// Returns the underlying index. #[inline] pub fn id(self) -> usize { @@ -113,16 +110,21 @@ pub struct Segment { pub pin: Option, } -#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] +impl Segment { + pub fn pin_selector(&self) -> Option { + Some(PinSelector { + pin: self.pin?, + layer: self.layer, + }) + } +} + +#[derive( + Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize, +)] pub struct ViaId(usize); impl ViaId { - /// Wrap a via index in a newtype struct. - #[inline] - pub fn new(id: usize) -> Self { - Self(id) - } - /// Returns the underlying index. #[inline] pub fn id(self) -> usize { @@ -133,22 +135,27 @@ impl ViaId { #[derive(Clone, Copy, Debug)] pub struct Via { pub endpoints: [JointId; 2], - pub layer: usize, + pub layer: usize, // ??? This should be a range. pub radius: u64, pub net: NetId, pub pin: Option, } -#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] +impl Via { + pub fn pin_selector(&self) -> Option { + Some(PinSelector { + pin: self.pin?, + layer: self.layer, + }) + } +} + +#[derive( + Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize, +)] pub struct PolygonId(usize); impl PolygonId { - /// Wrap a polygon index in a newtype struct. - #[inline] - pub fn new(id: usize) -> Self { - Self(id) - } - /// Returns the underlying index. #[inline] pub fn id(self) -> usize { @@ -164,6 +171,15 @@ pub struct Polygon { pub pin: Option, } +impl Polygon { + pub fn pin_selector(&self) -> Option { + Some(PinSelector { + pin: self.pin?, + layer: self.layer, + }) + } +} + #[derive(Clone, Debug, Getters)] pub struct Layout { boundary: Vec<[i64; 2]>, diff --git a/topola/src/lib.rs b/topola/src/lib.rs index 5638fdf..2f73b3b 100644 --- a/topola/src/lib.rs +++ b/topola/src/lib.rs @@ -6,6 +6,7 @@ mod board; mod layout; mod math; mod navmesher; +mod selection; mod specctra; pub use crate::board::Board; diff --git a/topola/src/selection.rs b/topola/src/selection.rs new file mode 100644 index 0000000..fef8a4c --- /dev/null +++ b/topola/src/selection.rs @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: 2026 Topola contributors +// +// SPDX-License-Identifier: MIT OR Apache-2.0 + +use std::collections::BTreeSet; + +use serde::{Deserialize, Serialize}; + +use crate::layout::PinId; + +#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] +pub struct PinSelector { + pub pin: PinId, + pub layer: usize, +} + +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct PinSelection(pub BTreeSet); + +impl PinSelection { + pub fn toggle(&mut self, pin_selector: PinSelector) { + if self.0.contains(&pin_selector) { + self.0.remove(&pin_selector); + } else { + self.0.insert(pin_selector); + } + } +}