refactor(geometry): create traits for applying edits

This commit is contained in:
Mikolaj Wielgus 2024-11-26 06:07:22 +01:00
parent f17c8ce756
commit 12f0dc1b8b
2 changed files with 115 additions and 41 deletions

View File

@ -7,6 +7,73 @@ use crate::{
use super::{AccessBendWeight, AccessDotWeight, AccessSegWeight, GetWidth}; use super::{AccessBendWeight, AccessDotWeight, AccessSegWeight, GetWidth};
pub trait ApplyGeometryEdit<
PW: GetWidth + GetLayer + TryInto<DW> + TryInto<SW> + TryInto<BW> + Retag<PI> + Copy,
DW: AccessDotWeight<PW> + GetLayer,
SW: AccessSegWeight<PW> + GetLayer,
BW: AccessBendWeight<PW> + GetLayer,
CW: Copy,
PI: GetPetgraphIndex + TryInto<DI> + TryInto<SI> + TryInto<BI> + Eq + Hash + Copy,
DI: GetPetgraphIndex + Into<PI> + Eq + Hash + Copy,
SI: GetPetgraphIndex + Into<PI> + Eq + Hash + Copy,
BI: GetPetgraphIndex + Into<PI> + Eq + Hash + Copy,
>: ApplyGeometryChange<PW, DW, SW, BW, CW, PI, DI, SI, BI>
{
fn apply(&mut self, edit: &GeometryEdit<PW, DW, SW, BW, CW, PI, DI, SI, BI>) {
// Dot changes must be done first since segs and bends depend on them.
for (dot, change) in &edit.dot_changes {
self.apply_dot_change(*dot, change);
}
for (seg, change) in &edit.seg_changes {
self.apply_seg_change(*seg, change);
}
for (bend, change) in &edit.bend_changes {
self.apply_bend_change(*bend, change);
}
// Compound changes must be done last since they depend on primitives.
for (compound, change) in &edit.compound_changes {
self.apply_compound_change(*compound, change);
}
}
}
pub(super) trait ApplyGeometryChange<
PW: GetWidth + GetLayer + TryInto<DW> + TryInto<SW> + TryInto<BW> + Retag<PI> + Copy,
DW: AccessDotWeight<PW> + GetLayer,
SW: AccessSegWeight<PW> + GetLayer,
BW: AccessBendWeight<PW> + GetLayer,
CW: Copy,
PI: GetPetgraphIndex + TryInto<DI> + TryInto<SI> + TryInto<BI> + Eq + Hash + Copy,
DI: GetPetgraphIndex + Into<PI> + Eq + Hash + Copy,
SI: GetPetgraphIndex + Into<PI> + Eq + Hash + Copy,
BI: GetPetgraphIndex + Into<PI> + Eq + Hash + Copy,
>
{
fn apply_dot_change(&mut self, dot: DI, change: &DotChange<DW>);
fn apply_seg_change(&mut self, seg: SI, change: &SegChange<SW, DI>);
fn apply_bend_change(&mut self, bend: BI, change: &BendChange<BW, DI>);
fn apply_compound_change(
&mut self,
compound: GenericIndex<CW>,
change: &CompoundChange<CW, PI>,
);
}
#[derive(Debug)]
pub(super) struct DotChange<DW>(pub Option<DW>, pub Option<DW>);
#[derive(Debug)]
pub(super) struct SegChange<SW, DI>(pub Option<((DI, DI), SW)>, pub Option<((DI, DI), SW)>);
#[derive(Debug)]
pub(super) struct BendChange<BW, DI>(
pub Option<((DI, DI, DI), BW)>,
pub Option<((DI, DI, DI), BW)>,
);
#[derive(Debug)]
pub(super) struct CompoundChange<CW, PI>(pub Option<(Vec<PI>, CW)>, pub Option<(Vec<PI>, CW)>);
#[derive(Debug)] #[derive(Debug)]
pub struct GeometryEdit< pub struct GeometryEdit<
PW: GetWidth + GetLayer + TryInto<DW> + TryInto<SW> + TryInto<BW> + Retag<PI> + Copy, PW: GetWidth + GetLayer + TryInto<DW> + TryInto<SW> + TryInto<BW> + Retag<PI> + Copy,
@ -19,10 +86,10 @@ pub struct GeometryEdit<
SI: GetPetgraphIndex + Into<PI> + Eq + Hash + Copy, SI: GetPetgraphIndex + Into<PI> + Eq + Hash + Copy,
BI: GetPetgraphIndex + Into<PI> + Eq + Hash + Copy, BI: GetPetgraphIndex + Into<PI> + Eq + Hash + Copy,
> { > {
pub(super) dots: HashMap<DI, (Option<DW>, Option<DW>)>, pub(super) dot_changes: HashMap<DI, DotChange<DW>>,
pub(super) segs: HashMap<SI, (Option<((DI, DI), SW)>, Option<((DI, DI), SW)>)>, pub(super) seg_changes: HashMap<SI, SegChange<SW, DI>>,
pub(super) bends: HashMap<BI, (Option<((DI, DI, DI), BW)>, Option<((DI, DI, DI), BW)>)>, pub(super) bend_changes: HashMap<BI, BendChange<BW, DI>>,
pub(super) compounds: HashMap<GenericIndex<CW>, (Option<(Vec<PI>, CW)>, Option<(Vec<PI>, CW)>)>, pub(super) compound_changes: HashMap<GenericIndex<CW>, CompoundChange<CW, PI>>,
primitive_weight_marker: PhantomData<PW>, primitive_weight_marker: PhantomData<PW>,
} }
@ -40,10 +107,10 @@ impl<
{ {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
dots: HashMap::new(), dot_changes: HashMap::new(),
segs: HashMap::new(), seg_changes: HashMap::new(),
bends: HashMap::new(), bend_changes: HashMap::new(),
compounds: HashMap::new(), compound_changes: HashMap::new(),
primitive_weight_marker: PhantomData, primitive_weight_marker: PhantomData,
} }
} }

View File

@ -11,7 +11,7 @@ use crate::{
use super::{ use super::{
compound::ManageCompounds, compound::ManageCompounds,
edit::GeometryEdit, edit::{BendChange, CompoundChange, DotChange, GeometryEdit, SegChange},
with_rtree::{BboxedIndex, GeometryWithRtree}, with_rtree::{BboxedIndex, GeometryWithRtree},
AccessBendWeight, AccessDotWeight, AccessSegWeight, GenericNode, Geometry, GeometryLabel, AccessBendWeight, AccessDotWeight, AccessSegWeight, GenericNode, Geometry, GeometryLabel,
GetWidth, GetWidth,
@ -61,11 +61,11 @@ impl<
GenericIndex<W>: Into<PI>, GenericIndex<W>: Into<PI>,
{ {
let dot = self.geometry_with_rtree.add_dot(weight); let dot = self.geometry_with_rtree.add_dot(weight);
recorder.dots.insert( recorder.dot_changes.insert(
Into::<PI>::into(dot) Into::<PI>::into(dot)
.try_into() .try_into()
.unwrap_or_else(|_| unreachable!()), .unwrap_or_else(|_| unreachable!()),
( DotChange::<DW>(
None, None,
Some(weight.into().try_into().unwrap_or_else(|_| unreachable!())), Some(weight.into().try_into().unwrap_or_else(|_| unreachable!())),
), ),
@ -84,11 +84,11 @@ impl<
GenericIndex<W>: Into<PI>, GenericIndex<W>: Into<PI>,
{ {
let seg = self.geometry_with_rtree.add_seg(from, to, weight); let seg = self.geometry_with_rtree.add_seg(from, to, weight);
recorder.segs.insert( recorder.seg_changes.insert(
Into::<PI>::into(seg) Into::<PI>::into(seg)
.try_into() .try_into()
.unwrap_or_else(|_| unreachable!()), .unwrap_or_else(|_| unreachable!()),
( SegChange::<SW, DI>(
None, None,
Some(( Some((
(from, to), (from, to),
@ -111,11 +111,11 @@ impl<
GenericIndex<W>: Into<PI>, GenericIndex<W>: Into<PI>,
{ {
let bend = self.geometry_with_rtree.add_bend(from, to, core, weight); let bend = self.geometry_with_rtree.add_bend(from, to, core, weight);
recorder.bends.insert( recorder.bend_changes.insert(
Into::<PI>::into(bend) Into::<PI>::into(bend)
.try_into() .try_into()
.unwrap_or_else(|_| unreachable!()), .unwrap_or_else(|_| unreachable!()),
( BendChange::<BW, DI>(
None, None,
Some(( Some((
(from, to, core), (from, to, core),
@ -132,9 +132,10 @@ impl<
weight: CW, weight: CW,
) -> GenericIndex<CW> { ) -> GenericIndex<CW> {
let compound = self.geometry_with_rtree.add_compound(weight); let compound = self.geometry_with_rtree.add_compound(weight);
recorder recorder.compound_changes.insert(
.compounds compound,
.insert(compound, (None, Some((vec![], weight)))); CompoundChange::<CW, PI>(None, Some((vec![], weight))),
);
compound compound
} }
@ -164,12 +165,12 @@ impl<
.geometry() .geometry()
.compound_weight(compound); .compound_weight(compound);
if let Some(value) = recorder.compounds.get_mut(&compound) { if let Some(value) = recorder.compound_changes.get_mut(&compound) {
value.1 = Some((new_members, new_weight)); value.1 = Some((new_members, new_weight));
} else { } else {
recorder.compounds.insert( recorder.compound_changes.insert(
compound, compound,
( CompoundChange::<CW, PI>(
Some((old_members, old_weight)), Some((old_members, old_weight)),
Some((new_members, new_weight)), Some((new_members, new_weight)),
), ),
@ -184,7 +185,9 @@ impl<
) -> Result<(), ()> { ) -> Result<(), ()> {
let weight = self.geometry_with_rtree.geometry().dot_weight(dot); let weight = self.geometry_with_rtree.geometry().dot_weight(dot);
self.geometry_with_rtree.remove_dot(dot)?; self.geometry_with_rtree.remove_dot(dot)?;
recorder.dots.insert(dot, (Some(weight), None)); recorder
.dot_changes
.insert(dot, DotChange::<DW>(Some(weight), None));
Ok(()) Ok(())
} }
@ -196,7 +199,9 @@ impl<
let weight = self.geometry_with_rtree.geometry().seg_weight(seg); let weight = self.geometry_with_rtree.geometry().seg_weight(seg);
let joints = self.geometry_with_rtree.geometry().seg_joints(seg); let joints = self.geometry_with_rtree.geometry().seg_joints(seg);
self.geometry_with_rtree.remove_seg(seg); self.geometry_with_rtree.remove_seg(seg);
recorder.segs.insert(seg, (Some((joints, weight)), None)); recorder
.seg_changes
.insert(seg, SegChange::<SW, DI>(Some((joints, weight)), None));
} }
pub fn remove_bend( pub fn remove_bend(
@ -208,9 +213,10 @@ impl<
let joints = self.geometry_with_rtree.geometry().bend_joints(bend); let joints = self.geometry_with_rtree.geometry().bend_joints(bend);
let core = self.geometry_with_rtree.geometry().core(bend); let core = self.geometry_with_rtree.geometry().core(bend);
self.geometry_with_rtree.remove_bend(bend); self.geometry_with_rtree.remove_bend(bend);
recorder recorder.bend_changes.insert(
.bends bend,
.insert(bend, (Some(((joints.0, joints.1, core), weight)), None)); BendChange::<BW, DI>(Some(((joints.0, joints.1, core), weight)), None),
);
} }
pub fn remove_compound( pub fn remove_compound(
@ -228,9 +234,10 @@ impl<
.compound_members(compound) .compound_members(compound)
.collect(); .collect();
self.geometry_with_rtree.remove_compound(compound); self.geometry_with_rtree.remove_compound(compound);
recorder recorder.compound_changes.insert(
.compounds compound,
.insert(compound, (Some((members, weight)), None)); CompoundChange::<CW, PI>(Some((members, weight)), None),
);
} }
pub fn move_dot( pub fn move_dot(
@ -243,12 +250,12 @@ impl<
self.geometry_with_rtree.move_dot(dot, to); self.geometry_with_rtree.move_dot(dot, to);
let new_weight = self.geometry_with_rtree.geometry().dot_weight(dot); let new_weight = self.geometry_with_rtree.geometry().dot_weight(dot);
if let Some(value) = recorder.dots.get_mut(&dot) { if let Some(value) = recorder.dot_changes.get_mut(&dot) {
value.1 = Some(new_weight); value.1 = Some(new_weight);
} else { } else {
recorder recorder
.dots .dot_changes
.insert(dot, (Some(old_weight), Some(new_weight))); .insert(dot, DotChange::<DW>(Some(old_weight), Some(new_weight)));
} }
} }
@ -266,12 +273,12 @@ impl<
let new_core = self.geometry_with_rtree.geometry().core(bend); let new_core = self.geometry_with_rtree.geometry().core(bend);
let new_weight = self.geometry_with_rtree.geometry().bend_weight(bend); let new_weight = self.geometry_with_rtree.geometry().bend_weight(bend);
if let Some(value) = recorder.bends.get_mut(&bend) { if let Some(value) = recorder.bend_changes.get_mut(&bend) {
value.1 = Some(((new_joints.0, new_joints.1, new_core), new_weight)); value.1 = Some(((new_joints.0, new_joints.1, new_core), new_weight));
} else { } else {
recorder.bends.insert( recorder.bend_changes.insert(
bend, bend,
( BendChange::<BW, DI>(
Some(((old_joints.0, old_joints.1, old_core), old_weight)), Some(((old_joints.0, old_joints.1, old_core), old_weight)),
Some(((new_joints.0, new_joints.1, new_core), new_weight)), Some(((new_joints.0, new_joints.1, new_core), new_weight)),
), ),
@ -292,12 +299,12 @@ impl<
let new_core = self.geometry_with_rtree.geometry().core(bend); let new_core = self.geometry_with_rtree.geometry().core(bend);
let new_weight = self.geometry_with_rtree.geometry().bend_weight(bend); let new_weight = self.geometry_with_rtree.geometry().bend_weight(bend);
if let Some(value) = recorder.bends.get_mut(&bend) { if let Some(value) = recorder.bend_changes.get_mut(&bend) {
value.1 = Some(((new_joints.0, new_joints.1, new_core), new_weight)); value.1 = Some(((new_joints.0, new_joints.1, new_core), new_weight));
} else { } else {
recorder.bends.insert( recorder.bend_changes.insert(
bend, bend,
( BendChange::<BW, DI>(
Some(((old_joints.0, old_joints.1, old_core), old_weight)), Some(((old_joints.0, old_joints.1, old_core), old_weight)),
Some(((new_joints.0, new_joints.1, new_core), new_weight)), Some(((new_joints.0, new_joints.1, new_core), new_weight)),
), ),
@ -320,12 +327,12 @@ impl<
let new_core = self.geometry_with_rtree.geometry().core(bend); let new_core = self.geometry_with_rtree.geometry().core(bend);
let new_weight = self.geometry_with_rtree.geometry().bend_weight(bend); let new_weight = self.geometry_with_rtree.geometry().bend_weight(bend);
if let Some(value) = recorder.bends.get_mut(&bend) { if let Some(value) = recorder.bend_changes.get_mut(&bend) {
value.1 = Some(((new_joints.0, new_joints.1, new_core), new_weight)); value.1 = Some(((new_joints.0, new_joints.1, new_core), new_weight));
} else { } else {
recorder.bends.insert( recorder.bend_changes.insert(
bend, bend,
( BendChange::<BW, DI>(
Some(((old_joints.0, old_joints.1, old_core), old_weight)), Some(((old_joints.0, old_joints.1, old_core), old_weight)),
Some(((new_joints.0, new_joints.1, new_core), new_weight)), Some(((new_joints.0, new_joints.1, new_core), new_weight)),
), ),