mirror of https://codeberg.org/topola/topola.git
feat: use OrderedPair instead of custon BandName/BandUid (note: changes ordering of BandUid)
This commit is contained in:
parent
910ab5b76a
commit
c5a87d9bdf
|
|
@ -61,6 +61,10 @@ thiserror.workspace = true
|
||||||
path = "crates/specctra-core"
|
path = "crates/specctra-core"
|
||||||
features = ["rstar"]
|
features = ["rstar"]
|
||||||
|
|
||||||
|
[dependencies.topola-rules]
|
||||||
|
path = "crates/topola-rules"
|
||||||
|
features = ["serde"]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ impl MeasureLengthExecutionStepper {
|
||||||
let mut length = 0.0;
|
let mut length = 0.0;
|
||||||
|
|
||||||
for selector in self.selection.selectors() {
|
for selector in self.selection.selectors() {
|
||||||
let band = autorouter.board.bandname_band(&selector.band).unwrap().0;
|
let band = autorouter.board.bandname_band(&selector.band).unwrap()[false];
|
||||||
length += band.ref_(autorouter.board.layout().drawing()).length();
|
length += band.ref_(autorouter.board.layout().drawing()).length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ impl RemoveBandsExecutionStepper {
|
||||||
|
|
||||||
let mut edit = LayoutEdit::new();
|
let mut edit = LayoutEdit::new();
|
||||||
for selector in self.selection.selectors() {
|
for selector in self.selection.selectors() {
|
||||||
let band = autorouter.board.bandname_band(&selector.band).unwrap().0;
|
let band = autorouter.board.bandname_band(&selector.band).unwrap()[false];
|
||||||
autorouter.board.layout_mut().remove_band(&mut edit, band);
|
autorouter.board.layout_mut().remove_band(&mut edit, band);
|
||||||
}
|
}
|
||||||
Ok(Some(edit))
|
Ok(Some(edit))
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ use std::{cmp::Ordering, collections::BTreeMap};
|
||||||
use bimap::BiBTreeMap;
|
use bimap::BiBTreeMap;
|
||||||
use derive_getters::Getters;
|
use derive_getters::Getters;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use topola_rules::OrderedPair;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drawing::{
|
drawing::{
|
||||||
|
|
@ -33,21 +34,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Represents a band between two pins.
|
/// Represents a band between two pins.
|
||||||
#[derive(Clone, Debug, Deserialize, Eq, PartialOrd, Ord, PartialEq, Serialize)]
|
pub type BandName = OrderedPair<String>;
|
||||||
pub struct BandName(String, String);
|
|
||||||
|
|
||||||
impl BandName {
|
|
||||||
/// Creates a new [`BandName`] and manages their order.
|
|
||||||
///
|
|
||||||
/// This function ensures that the two pin names are sorted in lexicographical order, so that the smaller name always comes first.
|
|
||||||
pub fn new(pinname1: String, pinname2: String) -> Self {
|
|
||||||
if pinname1.cmp(&pinname2) == Ordering::Greater {
|
|
||||||
BandName(pinname2, pinname1)
|
|
||||||
} else {
|
|
||||||
BandName(pinname1, pinname2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub enum ResolvedSelector<'a> {
|
pub enum ResolvedSelector<'a> {
|
||||||
|
|
@ -290,14 +277,14 @@ impl<M: AccessMesadata> Board<M> {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_string();
|
.to_string();
|
||||||
self.band_bandname
|
self.band_bandname
|
||||||
.insert(band, BandName::new(source_pinname, target_pinname));
|
.insert(band, BandName::from((source_pinname, target_pinname)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds a band between two pin names.
|
/// Finds a band between two pin names.
|
||||||
pub fn band_between_pins(&self, pinname1: &str, pinname2: &str) -> Option<BandUid> {
|
pub fn band_between_pins(&self, pinname1: &str, pinname2: &str) -> Option<BandUid> {
|
||||||
self.band_bandname
|
self.band_bandname
|
||||||
// note: it doesn't matter in what order pinnames are given, the constructor sorts them
|
// note: it doesn't matter in what order pinnames are given, the constructor sorts them
|
||||||
.get_by_right(&BandName::new(pinname1.to_string(), pinname2.to_string()))
|
.get_by_right(&BandName::from((pinname1.to_string(), pinname2.to_string())))
|
||||||
.copied()
|
.copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
use core::{cmp, hash};
|
use core::{cmp, hash};
|
||||||
use enum_dispatch::enum_dispatch;
|
use enum_dispatch::enum_dispatch;
|
||||||
use petgraph::stable_graph::NodeIndex;
|
use petgraph::stable_graph::NodeIndex;
|
||||||
|
use topola_rules::OrderedPair;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
geometry::shape::MeasureLength,
|
geometry::shape::MeasureLength,
|
||||||
|
|
@ -19,54 +20,10 @@ use super::{
|
||||||
AccessRules, Drawing,
|
AccessRules, Drawing,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
pub type BandUid = OrderedPair<BandTermsegIndex>;
|
||||||
pub struct BandUid(pub BandTermsegIndex, pub BandTermsegIndex);
|
|
||||||
|
|
||||||
impl BandUid {
|
|
||||||
pub fn new(first_seg1: BandTermsegIndex, first_seg2: BandTermsegIndex) -> Self {
|
|
||||||
if first_seg1.petgraph_index() <= first_seg2.petgraph_index() {
|
|
||||||
BandUid(first_seg1, first_seg2)
|
|
||||||
} else {
|
|
||||||
BandUid(first_seg2, first_seg1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq for BandUid {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.0.petgraph_index() == other.0.petgraph_index()
|
|
||||||
&& self.1.petgraph_index() == other.1.petgraph_index()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Eq for BandUid {}
|
|
||||||
|
|
||||||
impl hash::Hash for BandUid {
|
|
||||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
|
||||||
self.0.petgraph_index().hash(state);
|
|
||||||
self.1.petgraph_index().hash(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl cmp::PartialOrd for BandUid {
|
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
|
|
||||||
Some(self.cmp(other))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl cmp::Ord for BandUid {
|
|
||||||
fn cmp(&self, other: &Self) -> cmp::Ordering {
|
|
||||||
use cmp::Ordering as O;
|
|
||||||
match self.0.petgraph_index().cmp(&other.0.petgraph_index()) {
|
|
||||||
O::Less => O::Less,
|
|
||||||
O::Greater => O::Greater,
|
|
||||||
O::Equal => self.1.petgraph_index().cmp(&other.1.petgraph_index()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[enum_dispatch(GetPetgraphIndex)]
|
#[enum_dispatch(GetPetgraphIndex)]
|
||||||
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
|
||||||
pub enum BandTermsegIndex {
|
pub enum BandTermsegIndex {
|
||||||
Straight(LoneLooseSegIndex),
|
Straight(LoneLooseSegIndex),
|
||||||
Bended(SeqLooseSegIndex),
|
Bended(SeqLooseSegIndex),
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,10 @@ pub trait Collect {
|
||||||
|
|
||||||
impl<CW: Copy, R: AccessRules> Collect for Drawing<CW, R> {
|
impl<CW: Copy, R: AccessRules> Collect for Drawing<CW, R> {
|
||||||
fn loose_band_uid(&self, start_loose: LooseIndex) -> BandUid {
|
fn loose_band_uid(&self, start_loose: LooseIndex) -> BandUid {
|
||||||
BandUid::new(
|
BandUid::from((
|
||||||
self.loose_band_first_seg(start_loose),
|
self.loose_band_first_seg(start_loose),
|
||||||
self.loose_band_last_seg(start_loose),
|
self.loose_band_last_seg(start_loose),
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bend_bow(&self, bend: LooseBendIndex) -> Vec<PrimitiveIndex> {
|
fn bend_bow(&self, bend: LooseBendIndex) -> Vec<PrimitiveIndex> {
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,13 @@ impl<W> Ord for GenericIndex<W> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<W> core::hash::Hash for GenericIndex<W> {
|
||||||
|
#[inline]
|
||||||
|
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||||
|
self.node_index.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<W> GetPetgraphIndex for GenericIndex<W> {
|
impl<W> GetPetgraphIndex for GenericIndex<W> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn petgraph_index(&self) -> NodeIndex<usize> {
|
fn petgraph_index(&self) -> NodeIndex<usize> {
|
||||||
|
|
|
||||||
|
|
@ -208,7 +208,7 @@ pub fn assert_band_length(
|
||||||
rel_err: f64,
|
rel_err: f64,
|
||||||
) {
|
) {
|
||||||
let band = board.band_between_pins(source_pin, target_pin).unwrap();
|
let band = board.band_between_pins(source_pin, target_pin).unwrap();
|
||||||
let band_length = band.0.ref_(board.layout().drawing()).length();
|
let band_length = band[false].ref_(board.layout().drawing()).length();
|
||||||
assert!(
|
assert!(
|
||||||
(band_length - expected_length).abs() < expected_length * rel_err,
|
(band_length - expected_length).abs() < expected_length * rel_err,
|
||||||
"band_length = {}, expected_length = {}, epsilon = {}",
|
"band_length = {}, expected_length = {}, epsilon = {}",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue