From 12f0dc1b8bc2849f97d9a5e6cb7012e9c0e57a74 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Tue, 26 Nov 2024 06:07:22 +0100 Subject: [PATCH] refactor(geometry): create traits for applying edits --- src/geometry/edit.rs | 83 +++++++++++++++++++++++++--- src/geometry/recording_with_rtree.rs | 73 +++++++++++++----------- 2 files changed, 115 insertions(+), 41 deletions(-) diff --git a/src/geometry/edit.rs b/src/geometry/edit.rs index 8ec85f8..b9d26b9 100644 --- a/src/geometry/edit.rs +++ b/src/geometry/edit.rs @@ -7,6 +7,73 @@ use crate::{ use super::{AccessBendWeight, AccessDotWeight, AccessSegWeight, GetWidth}; +pub trait ApplyGeometryEdit< + PW: GetWidth + GetLayer + TryInto + TryInto + TryInto + Retag + Copy, + DW: AccessDotWeight + GetLayer, + SW: AccessSegWeight + GetLayer, + BW: AccessBendWeight + GetLayer, + CW: Copy, + PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Eq + Hash + Copy, + DI: GetPetgraphIndex + Into + Eq + Hash + Copy, + SI: GetPetgraphIndex + Into + Eq + Hash + Copy, + BI: GetPetgraphIndex + Into + Eq + Hash + Copy, +>: ApplyGeometryChange +{ + fn apply(&mut self, edit: &GeometryEdit) { + // 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 + TryInto + TryInto + Retag + Copy, + DW: AccessDotWeight + GetLayer, + SW: AccessSegWeight + GetLayer, + BW: AccessBendWeight + GetLayer, + CW: Copy, + PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Eq + Hash + Copy, + DI: GetPetgraphIndex + Into + Eq + Hash + Copy, + SI: GetPetgraphIndex + Into + Eq + Hash + Copy, + BI: GetPetgraphIndex + Into + Eq + Hash + Copy, +> +{ + fn apply_dot_change(&mut self, dot: DI, change: &DotChange); + fn apply_seg_change(&mut self, seg: SI, change: &SegChange); + fn apply_bend_change(&mut self, bend: BI, change: &BendChange); + fn apply_compound_change( + &mut self, + compound: GenericIndex, + change: &CompoundChange, + ); +} + +#[derive(Debug)] +pub(super) struct DotChange(pub Option, pub Option); +#[derive(Debug)] +pub(super) struct SegChange(pub Option<((DI, DI), SW)>, pub Option<((DI, DI), SW)>); +#[derive(Debug)] +pub(super) struct BendChange( + pub Option<((DI, DI, DI), BW)>, + pub Option<((DI, DI, DI), BW)>, +); +#[derive(Debug)] +pub(super) struct CompoundChange(pub Option<(Vec, CW)>, pub Option<(Vec, CW)>); + #[derive(Debug)] pub struct GeometryEdit< PW: GetWidth + GetLayer + TryInto + TryInto + TryInto + Retag + Copy, @@ -19,10 +86,10 @@ pub struct GeometryEdit< SI: GetPetgraphIndex + Into + Eq + Hash + Copy, BI: GetPetgraphIndex + Into + Eq + Hash + Copy, > { - pub(super) dots: HashMap, Option)>, - pub(super) segs: HashMap, Option<((DI, DI), SW)>)>, - pub(super) bends: HashMap, Option<((DI, DI, DI), BW)>)>, - pub(super) compounds: HashMap, (Option<(Vec, CW)>, Option<(Vec, CW)>)>, + pub(super) dot_changes: HashMap>, + pub(super) seg_changes: HashMap>, + pub(super) bend_changes: HashMap>, + pub(super) compound_changes: HashMap, CompoundChange>, primitive_weight_marker: PhantomData, } @@ -40,10 +107,10 @@ impl< { pub fn new() -> Self { Self { - dots: HashMap::new(), - segs: HashMap::new(), - bends: HashMap::new(), - compounds: HashMap::new(), + dot_changes: HashMap::new(), + seg_changes: HashMap::new(), + bend_changes: HashMap::new(), + compound_changes: HashMap::new(), primitive_weight_marker: PhantomData, } } diff --git a/src/geometry/recording_with_rtree.rs b/src/geometry/recording_with_rtree.rs index 99325f3..be82f34 100644 --- a/src/geometry/recording_with_rtree.rs +++ b/src/geometry/recording_with_rtree.rs @@ -11,7 +11,7 @@ use crate::{ use super::{ compound::ManageCompounds, - edit::GeometryEdit, + edit::{BendChange, CompoundChange, DotChange, GeometryEdit, SegChange}, with_rtree::{BboxedIndex, GeometryWithRtree}, AccessBendWeight, AccessDotWeight, AccessSegWeight, GenericNode, Geometry, GeometryLabel, GetWidth, @@ -61,11 +61,11 @@ impl< GenericIndex: Into, { let dot = self.geometry_with_rtree.add_dot(weight); - recorder.dots.insert( + recorder.dot_changes.insert( Into::::into(dot) .try_into() .unwrap_or_else(|_| unreachable!()), - ( + DotChange::( None, Some(weight.into().try_into().unwrap_or_else(|_| unreachable!())), ), @@ -84,11 +84,11 @@ impl< GenericIndex: Into, { let seg = self.geometry_with_rtree.add_seg(from, to, weight); - recorder.segs.insert( + recorder.seg_changes.insert( Into::::into(seg) .try_into() .unwrap_or_else(|_| unreachable!()), - ( + SegChange::( None, Some(( (from, to), @@ -111,11 +111,11 @@ impl< GenericIndex: Into, { let bend = self.geometry_with_rtree.add_bend(from, to, core, weight); - recorder.bends.insert( + recorder.bend_changes.insert( Into::::into(bend) .try_into() .unwrap_or_else(|_| unreachable!()), - ( + BendChange::( None, Some(( (from, to, core), @@ -132,9 +132,10 @@ impl< weight: CW, ) -> GenericIndex { let compound = self.geometry_with_rtree.add_compound(weight); - recorder - .compounds - .insert(compound, (None, Some((vec![], weight)))); + recorder.compound_changes.insert( + compound, + CompoundChange::(None, Some((vec![], weight))), + ); compound } @@ -164,12 +165,12 @@ impl< .geometry() .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)); } else { - recorder.compounds.insert( + recorder.compound_changes.insert( compound, - ( + CompoundChange::( Some((old_members, old_weight)), Some((new_members, new_weight)), ), @@ -184,7 +185,9 @@ impl< ) -> Result<(), ()> { let weight = self.geometry_with_rtree.geometry().dot_weight(dot); self.geometry_with_rtree.remove_dot(dot)?; - recorder.dots.insert(dot, (Some(weight), None)); + recorder + .dot_changes + .insert(dot, DotChange::(Some(weight), None)); Ok(()) } @@ -196,7 +199,9 @@ impl< let weight = self.geometry_with_rtree.geometry().seg_weight(seg); let joints = self.geometry_with_rtree.geometry().seg_joints(seg); self.geometry_with_rtree.remove_seg(seg); - recorder.segs.insert(seg, (Some((joints, weight)), None)); + recorder + .seg_changes + .insert(seg, SegChange::(Some((joints, weight)), None)); } pub fn remove_bend( @@ -208,9 +213,10 @@ impl< let joints = self.geometry_with_rtree.geometry().bend_joints(bend); let core = self.geometry_with_rtree.geometry().core(bend); self.geometry_with_rtree.remove_bend(bend); - recorder - .bends - .insert(bend, (Some(((joints.0, joints.1, core), weight)), None)); + recorder.bend_changes.insert( + bend, + BendChange::(Some(((joints.0, joints.1, core), weight)), None), + ); } pub fn remove_compound( @@ -228,9 +234,10 @@ impl< .compound_members(compound) .collect(); self.geometry_with_rtree.remove_compound(compound); - recorder - .compounds - .insert(compound, (Some((members, weight)), None)); + recorder.compound_changes.insert( + compound, + CompoundChange::(Some((members, weight)), None), + ); } pub fn move_dot( @@ -243,12 +250,12 @@ impl< self.geometry_with_rtree.move_dot(dot, to); 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); } else { recorder - .dots - .insert(dot, (Some(old_weight), Some(new_weight))); + .dot_changes + .insert(dot, DotChange::(Some(old_weight), Some(new_weight))); } } @@ -266,12 +273,12 @@ impl< let new_core = self.geometry_with_rtree.geometry().core(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)); } else { - recorder.bends.insert( + recorder.bend_changes.insert( bend, - ( + BendChange::( Some(((old_joints.0, old_joints.1, old_core), old_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_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)); } else { - recorder.bends.insert( + recorder.bend_changes.insert( bend, - ( + BendChange::( Some(((old_joints.0, old_joints.1, old_core), old_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_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)); } else { - recorder.bends.insert( + recorder.bend_changes.insert( bend, - ( + BendChange::( Some(((old_joints.0, old_joints.1, old_core), old_weight)), Some(((new_joints.0, new_joints.1, new_core), new_weight)), ),