feat(geometry): implement interface to apply edits for `Geometry`

Untested.
This commit is contained in:
Mikolaj Wielgus 2024-11-26 20:49:39 +01:00
parent 12f0dc1b8b
commit 0e5ef7cac1
2 changed files with 210 additions and 35 deletions

View File

@ -1,22 +1,22 @@
use std::{collections::HashMap, hash::Hash, marker::PhantomData};
use crate::{
drawing::graph::{GetLayer, Retag},
drawing::graph::Retag,
graph::{GenericIndex, GetPetgraphIndex},
};
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,
PW: GetWidth + TryInto<DW> + TryInto<SW> + TryInto<BW> + Retag<PI> + Copy,
DW: AccessDotWeight<PW>,
SW: AccessSegWeight<PW>,
BW: AccessBendWeight<PW>,
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,
PI: GetPetgraphIndex + TryInto<DI> + TryInto<SI> + TryInto<BI> + Copy,
DI: GetPetgraphIndex + Into<PI> + Copy,
SI: GetPetgraphIndex + Into<PI> + Copy,
BI: GetPetgraphIndex + Into<PI> + 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>) {
@ -41,15 +41,15 @@ pub trait ApplyGeometryEdit<
}
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,
PW: GetWidth + TryInto<DW> + TryInto<SW> + TryInto<BW> + Retag<PI> + Copy,
DW: AccessDotWeight<PW>,
SW: AccessSegWeight<PW>,
BW: AccessBendWeight<PW>,
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,
PI: GetPetgraphIndex + TryInto<DI> + TryInto<SI> + TryInto<BI> + Copy,
DI: GetPetgraphIndex + Into<PI> + Copy,
SI: GetPetgraphIndex + Into<PI> + Copy,
BI: GetPetgraphIndex + Into<PI> + Copy,
>
{
fn apply_dot_change(&mut self, dot: DI, change: &DotChange<DW>);
@ -76,15 +76,15 @@ pub(super) struct CompoundChange<CW, PI>(pub Option<(Vec<PI>, CW)>, pub Option<(
#[derive(Debug)]
pub struct GeometryEdit<
PW: GetWidth + GetLayer + TryInto<DW> + TryInto<SW> + TryInto<BW> + Retag<PI> + Copy,
DW: AccessDotWeight<PW> + GetLayer,
SW: AccessSegWeight<PW> + GetLayer,
BW: AccessBendWeight<PW> + GetLayer,
PW: GetWidth + TryInto<DW> + TryInto<SW> + TryInto<BW> + Retag<PI> + Copy,
DW: AccessDotWeight<PW>,
SW: AccessSegWeight<PW>,
BW: AccessBendWeight<PW>,
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,
PI: GetPetgraphIndex + TryInto<DI> + TryInto<SI> + TryInto<BI> + Copy,
DI: GetPetgraphIndex + Into<PI> + Copy,
SI: GetPetgraphIndex + Into<PI> + Copy,
BI: GetPetgraphIndex + Into<PI> + Copy,
> {
pub(super) dot_changes: HashMap<DI, DotChange<DW>>,
pub(super) seg_changes: HashMap<SI, SegChange<SW, DI>>,
@ -94,15 +94,15 @@ pub struct GeometryEdit<
}
impl<
PW: GetWidth + GetLayer + TryInto<DW> + TryInto<SW> + TryInto<BW> + Retag<PI> + Copy,
DW: AccessDotWeight<PW> + GetLayer,
SW: AccessSegWeight<PW> + GetLayer,
BW: AccessBendWeight<PW> + GetLayer,
PW: GetWidth + TryInto<DW> + TryInto<SW> + TryInto<BW> + Retag<PI> + Copy,
DW: AccessDotWeight<PW>,
SW: AccessSegWeight<PW>,
BW: AccessBendWeight<PW>,
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,
PI: GetPetgraphIndex + TryInto<DI> + TryInto<SI> + TryInto<BI> + Copy,
DI: GetPetgraphIndex + Into<PI> + Copy,
SI: GetPetgraphIndex + Into<PI> + Copy,
BI: GetPetgraphIndex + Into<PI> + Copy,
> GeometryEdit<PW, DW, SW, BW, CW, PI, DI, SI, BI>
{
pub fn new() -> Self {

View File

@ -1,4 +1,4 @@
use std::marker::PhantomData;
use std::{hash::Hash, marker::PhantomData};
use derive_getters::Getters;
use enum_dispatch::enum_dispatch;
@ -13,7 +13,7 @@ use crate::{
drawing::{
bend::BendWeight,
dot::DotWeight,
graph::{PrimitiveWeight, Retag},
graph::{GetLayer, PrimitiveWeight, Retag},
primitive::Primitive,
rules::AccessRules,
seg::SegWeight,
@ -26,6 +26,8 @@ use crate::{
math::Circle,
};
use super::edit::{ApplyGeometryChange, BendChange, CompoundChange, DotChange, SegChange};
#[enum_dispatch]
pub trait GetPos {
fn pos(&self) -> Point;
@ -543,3 +545,176 @@ impl<
.map(|ni| GenericIndex::new(ni))
}
}
impl<
PW: GetWidth + TryInto<DW> + TryInto<SW> + TryInto<BW> + Retag<PI> + Copy,
DW: AccessDotWeight<PW>,
SW: AccessSegWeight<PW>,
BW: AccessBendWeight<PW>,
CW: Copy,
PI: GetPetgraphIndex + TryInto<DI> + TryInto<SI> + TryInto<BI> + Copy,
DI: GetPetgraphIndex + Into<PI> + Copy,
SI: GetPetgraphIndex + Into<PI> + Copy,
BI: GetPetgraphIndex + Into<PI> + Copy,
> ApplyGeometryChange<PW, DW, SW, BW, CW, PI, DI, SI, BI>
for Geometry<PW, DW, SW, BW, CW, PI, DI, SI, BI>
{
fn apply_dot_change(&mut self, dot: DI, change: &DotChange<DW>) {
let DotChange::<DW>(old_weight, new_weight) = change;
// XXX: Debug assertion commented out to give more room to
// `GeometryWithRtree<...>` and `RecordingGeometryWithRtree<...>`.
// Still keeping the assertions for future reference.
/*debug_assert!(
old_weight.is_some() || !self.graph.contains_node(dot.petgraph_index()),
"attempted to create a dot at an already taken index",
);*/
self.graph.remove_node(dot.petgraph_index());
if let Some(weight) = new_weight {
// XXX: This can't compile because Eq trait is not implemented.
/*debug_assert_eq!(
Some(old_weight),
self.graph.node_weight(dot.petgraph_index()),
);*/
self.graph.update_node(
dot.petgraph_index(),
GenericNode::<PW, CW>::Primitive((*weight).into()),
);
}
}
fn apply_seg_change(&mut self, seg: SI, change: &SegChange<SW, DI>) {
let SegChange::<SW, DI>(old_seg, new_seg) = change;
// XXX: Debug assertion commented out to give more room to
// `GeometryWithRtree<...>` and `RecordingGeometryWithRtree<...>`.
// Still keeping the assertions for future reference.
/*debug_assert!(
old_seg.is_some() || !self.graph.contains_node(seg.petgraph_index()),
"attempted to create a seg at an index but it already exists",
);*/
self.graph.remove_node(seg.petgraph_index());
if let Some(((new_from, new_to), new_weight)) = new_seg {
// XXX: This can't compile because Eq trait is not implemented.
/*if let Some(((old_from, old_to), old_weight)) = new_weight {
let (curr_from, curr_to) = self.seg_joints(new_seg);
debug_assert_eq!(
old_from,
curr_from,
);
debug_assert_eq!(
old_to,
curr_to,
);
debug_assert_eq!(
Some(old_weight),
self.graph.node_weight(seg.petgraph_index()),
);
}*/
self.graph.update_node(
seg.petgraph_index(),
GenericNode::<PW, CW>::Primitive((*new_weight).into()),
);
self.init_seg_joints(
GenericIndex::<SW>::new(seg.petgraph_index()),
*new_from,
*new_to,
);
}
}
fn apply_bend_change(&mut self, bend: BI, change: &BendChange<BW, DI>) {
let BendChange::<BW, DI>(old_bend, new_bend) = change;
// XXX: Debug assertion commented out to give more room to
// `GeometryWithRtree<...>` and `RecordingGeometryWithRtree<...>`.
// Still keeping the assertions for future reference.
/*debug_assert!(
old_bend.is_some() || !self.graph.contains_node(bend.petgraph_index()),
"attempted to create a bend at an already taken index",
);*/
self.graph.remove_node(bend.petgraph_index());
if let Some(((from, to, core), weight)) = new_bend {
// XXX: This can't compile because Eq trait is not implemented.
/*if let Some(((old_from, old_to, old_core), old_weight)) = old_bend {
let (curr_from, curr_to) = self.bend_joints(new_bend);
debug_assert_eq!(
old_from,
curr_from,
);
debug_assert_eq!(
old_to,
curr_to,
);
debug_assert_eq!(
old_core,
curr_core,
)
debug_assert_eq!(
Some(old_weight),
self.graph.node_weight(bend.petgraph_index()),
);
}*/
self.graph.update_node(
bend.petgraph_index(),
GenericNode::<PW, CW>::Primitive((*weight).into()),
);
self.init_bend_joints_and_core(
GenericIndex::<BW>::new(bend.petgraph_index()),
*from,
*to,
*core,
);
}
}
fn apply_compound_change(
&mut self,
compound: GenericIndex<CW>,
change: &CompoundChange<CW, PI>,
) {
let CompoundChange::<CW, PI>(old_maybe_compound, new_maybe_compound) = change;
// XXX: Debug assertion commented out to give more room to
// `GeometryWithRtree<...>` and `RecordingGeometryWithRtree<...>`.
// Still keeping the assertions for future reference.
/*debug_assert!(
old_maybe_compound.is_some() || !self.graph.contains_node(compound.petgraph_index()),
"attempted to create a compound at an already taken index",
);*/
self.graph.remove_node(compound.petgraph_index());
if let Some((members, weight)) = new_maybe_compound {
// XXX: This can't compile because Eq trait is not implemented.
/*debug_assert_eq(
Some(old_compound_weight),
self.graph.node_weight(compound.petgraph_index()),
);*/
self.graph.update_node(
compound.petgraph_index(),
GenericNode::<PW, CW>::Compound((*weight).into()),
);
for member in members {
self.add_to_compound(GenericIndex::<PW>::new(member.petgraph_index()), compound);
}
}
}
}