mirror of https://codeberg.org/topola/topola.git
refactor(geometry/edit): Put reverse and merge functionality into trait (DRY)
This commit is contained in:
parent
2b95832cf7
commit
8732ee7fbb
|
|
@ -14,7 +14,7 @@ use crate::{
|
||||||
AccessMesadata,
|
AccessMesadata,
|
||||||
},
|
},
|
||||||
drawing::{band::BandTermsegIndex, graph::PrimitiveIndex, Collect},
|
drawing::{band::BandTermsegIndex, graph::PrimitiveIndex, Collect},
|
||||||
geometry::primitive::PrimitiveShape,
|
geometry::{edit::Edit, primitive::PrimitiveShape},
|
||||||
graph::MakeRef,
|
graph::MakeRef,
|
||||||
layout::LayoutEdit,
|
layout::LayoutEdit,
|
||||||
router::{
|
router::{
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ use thiserror::Error;
|
||||||
use crate::{
|
use crate::{
|
||||||
board::AccessMesadata,
|
board::AccessMesadata,
|
||||||
drawing::graph::PrimitiveIndex,
|
drawing::graph::PrimitiveIndex,
|
||||||
geometry::primitive::PrimitiveShape,
|
geometry::{edit::Edit, primitive::PrimitiveShape},
|
||||||
graph::GenericIndex,
|
graph::GenericIndex,
|
||||||
layout::poly::PolyWeight,
|
layout::poly::PolyWeight,
|
||||||
router::{
|
router::{
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,7 @@
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use crate::{drawing::band::BandUid, layout::LayoutEdit};
|
use crate::{board::BandName, drawing::band::BandUid, geometry::edit::Edit, layout::LayoutEdit};
|
||||||
|
|
||||||
use super::BandName;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct BoardDataEdit {
|
pub struct BoardDataEdit {
|
||||||
|
|
@ -21,6 +19,16 @@ impl BoardDataEdit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Edit for BoardDataEdit {
|
||||||
|
fn reverse_inplace(&mut self) {
|
||||||
|
self.bands.reverse_inplace();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn merge(&mut self, edit: Self) {
|
||||||
|
self.bands.merge(edit.bands);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct BoardEdit {
|
pub struct BoardEdit {
|
||||||
pub data_edit: BoardDataEdit,
|
pub data_edit: BoardDataEdit,
|
||||||
|
|
@ -41,22 +49,16 @@ impl BoardEdit {
|
||||||
layout_edit,
|
layout_edit,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn reverse_inplace(&mut self) {
|
impl Edit for BoardEdit {
|
||||||
self.data_edit
|
fn reverse_inplace(&mut self) {
|
||||||
.bands
|
self.data_edit.reverse_inplace();
|
||||||
.values_mut()
|
|
||||||
.for_each(Self::swap_tuple_inplace);
|
|
||||||
self.layout_edit.reverse_inplace();
|
self.layout_edit.reverse_inplace();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn swap_tuple_inplace<D>(x: &mut (D, D)) {
|
fn merge(&mut self, edit: Self) {
|
||||||
core::mem::swap(&mut x.0, &mut x.1);
|
self.data_edit.merge(edit.data_edit);
|
||||||
}
|
self.layout_edit.merge(edit.layout_edit);
|
||||||
|
|
||||||
pub fn reverse(&self) -> Self {
|
|
||||||
let mut rev = self.clone();
|
|
||||||
rev.reverse_inplace();
|
|
||||||
rev
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,21 @@ use crate::graph::{GenericIndex, GetPetgraphIndex};
|
||||||
|
|
||||||
use super::{AccessBendWeight, AccessDotWeight, AccessSegWeight, GetLayer};
|
use super::{AccessBendWeight, AccessDotWeight, AccessSegWeight, GetLayer};
|
||||||
|
|
||||||
|
pub trait Edit: Sized {
|
||||||
|
fn reverse(&self) -> Self
|
||||||
|
where
|
||||||
|
Self: Clone,
|
||||||
|
{
|
||||||
|
let mut rev = self.clone();
|
||||||
|
rev.reverse_inplace();
|
||||||
|
rev
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reverse_inplace(&mut self);
|
||||||
|
|
||||||
|
fn merge(&mut self, edit: Self);
|
||||||
|
}
|
||||||
|
|
||||||
pub trait ApplyGeometryEdit<
|
pub trait ApplyGeometryEdit<
|
||||||
DW: AccessDotWeight + GetLayer,
|
DW: AccessDotWeight + GetLayer,
|
||||||
SW: AccessSegWeight + GetLayer,
|
SW: AccessSegWeight + GetLayer,
|
||||||
|
|
@ -58,50 +73,56 @@ impl<
|
||||||
compounds: BTreeMap::new(),
|
compounds: BTreeMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn merge(&mut self, edit: GeometryEdit<DW, SW, BW, CW, Cel, PI, DI, SI, BI>) {
|
impl<
|
||||||
Self::merge_btmap(&mut self.dots, &edit.dots);
|
DW: AccessDotWeight + GetLayer,
|
||||||
Self::merge_btmap(&mut self.segs, &edit.segs);
|
SW: AccessSegWeight + GetLayer,
|
||||||
Self::merge_btmap(&mut self.bends, &edit.bends);
|
BW: AccessBendWeight + GetLayer,
|
||||||
Self::merge_btmap(&mut self.compounds, &edit.compounds);
|
CW: Clone,
|
||||||
|
Cel: Copy,
|
||||||
|
PI: GetPetgraphIndex + TryInto<DI> + TryInto<SI> + TryInto<BI> + Eq + Ord + Copy,
|
||||||
|
DI: GetPetgraphIndex + Into<PI> + Eq + Ord + Copy,
|
||||||
|
SI: GetPetgraphIndex + Into<PI> + Eq + Ord + Copy,
|
||||||
|
BI: GetPetgraphIndex + Into<PI> + Eq + Ord + Copy,
|
||||||
|
> Edit for GeometryEdit<DW, SW, BW, CW, Cel, PI, DI, SI, BI>
|
||||||
|
{
|
||||||
|
fn reverse_inplace(&mut self) {
|
||||||
|
self.dots.reverse_inplace();
|
||||||
|
self.segs.reverse_inplace();
|
||||||
|
self.bends.reverse_inplace();
|
||||||
|
self.compounds.reverse_inplace();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn merge_btmap<I: Copy + Eq + Ord, D: Clone>(
|
fn merge(&mut self, edit: Self) {
|
||||||
main: &mut BTreeMap<I, (Option<D>, Option<D>)>,
|
self.dots.merge(edit.dots);
|
||||||
edit: &BTreeMap<I, (Option<D>, Option<D>)>,
|
self.segs.merge(edit.segs);
|
||||||
) {
|
self.bends.merge(edit.bends);
|
||||||
|
self.compounds.merge(edit.compounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K: Eq + Ord, V> Edit for BTreeMap<K, (Option<V>, Option<V>)> {
|
||||||
|
fn reverse_inplace(&mut self) {
|
||||||
|
self.values_mut()
|
||||||
|
.for_each(|x| core::mem::swap(&mut x.0, &mut x.1));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn merge(&mut self, edit: Self) {
|
||||||
for (index, (old, new)) in edit {
|
for (index, (old, new)) in edit {
|
||||||
match main.entry(*index) {
|
match self.entry(index) {
|
||||||
Entry::Vacant(vac) => {
|
Entry::Vacant(vac) => {
|
||||||
vac.insert((old.clone(), new.clone()));
|
vac.insert((old, new));
|
||||||
}
|
}
|
||||||
Entry::Occupied(mut occ) => {
|
Entry::Occupied(mut occ) => match (occ.get(), new) {
|
||||||
if let ((None, ..), None) = (occ.get(), new) {
|
((None, _), None) => {
|
||||||
occ.remove();
|
occ.remove();
|
||||||
} else {
|
|
||||||
occ.get_mut().1 = new.clone();
|
|
||||||
}
|
}
|
||||||
}
|
(_, new) => {
|
||||||
|
occ.get_mut().1 = new;
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reverse_inplace(&mut self) {
|
|
||||||
self.dots.values_mut().for_each(Self::swap_tuple_inplace);
|
|
||||||
self.segs.values_mut().for_each(Self::swap_tuple_inplace);
|
|
||||||
self.bends.values_mut().for_each(Self::swap_tuple_inplace);
|
|
||||||
self.compounds
|
|
||||||
.values_mut()
|
|
||||||
.for_each(Self::swap_tuple_inplace);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn swap_tuple_inplace<D>(x: &mut (D, D)) {
|
|
||||||
core::mem::swap(&mut x.0, &mut x.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reverse(&self) -> Self {
|
|
||||||
let mut rev = self.clone();
|
|
||||||
rev.reverse_inplace();
|
|
||||||
rev
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue