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};
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)]
pub struct GeometryEdit<
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,
BI: GetPetgraphIndex + Into<PI> + Eq + Hash + Copy,
> {
pub(super) dots: HashMap<DI, (Option<DW>, Option<DW>)>,
pub(super) segs: HashMap<SI, (Option<((DI, DI), SW)>, Option<((DI, DI), SW)>)>,
pub(super) bends: HashMap<BI, (Option<((DI, DI, DI), BW)>, Option<((DI, DI, DI), BW)>)>,
pub(super) compounds: HashMap<GenericIndex<CW>, (Option<(Vec<PI>, CW)>, Option<(Vec<PI>, CW)>)>,
pub(super) dot_changes: HashMap<DI, DotChange<DW>>,
pub(super) seg_changes: HashMap<SI, SegChange<SW, DI>>,
pub(super) bend_changes: HashMap<BI, BendChange<BW, DI>>,
pub(super) compound_changes: HashMap<GenericIndex<CW>, CompoundChange<CW, PI>>,
primitive_weight_marker: PhantomData<PW>,
}
@ -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,
}
}

View File

@ -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<W>: Into<PI>,
{
let dot = self.geometry_with_rtree.add_dot(weight);
recorder.dots.insert(
recorder.dot_changes.insert(
Into::<PI>::into(dot)
.try_into()
.unwrap_or_else(|_| unreachable!()),
(
DotChange::<DW>(
None,
Some(weight.into().try_into().unwrap_or_else(|_| unreachable!())),
),
@ -84,11 +84,11 @@ impl<
GenericIndex<W>: Into<PI>,
{
let seg = self.geometry_with_rtree.add_seg(from, to, weight);
recorder.segs.insert(
recorder.seg_changes.insert(
Into::<PI>::into(seg)
.try_into()
.unwrap_or_else(|_| unreachable!()),
(
SegChange::<SW, DI>(
None,
Some((
(from, to),
@ -111,11 +111,11 @@ impl<
GenericIndex<W>: Into<PI>,
{
let bend = self.geometry_with_rtree.add_bend(from, to, core, weight);
recorder.bends.insert(
recorder.bend_changes.insert(
Into::<PI>::into(bend)
.try_into()
.unwrap_or_else(|_| unreachable!()),
(
BendChange::<BW, DI>(
None,
Some((
(from, to, core),
@ -132,9 +132,10 @@ impl<
weight: CW,
) -> GenericIndex<CW> {
let compound = self.geometry_with_rtree.add_compound(weight);
recorder
.compounds
.insert(compound, (None, Some((vec![], weight))));
recorder.compound_changes.insert(
compound,
CompoundChange::<CW, PI>(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::<CW, PI>(
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::<DW>(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::<SW, DI>(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::<BW, DI>(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::<CW, PI>(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::<DW>(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::<BW, DI>(
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::<BW, DI>(
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::<BW, DI>(
Some(((old_joints.0, old_joints.1, old_core), old_weight)),
Some(((new_joints.0, new_joints.1, new_core), new_weight)),
),