Adding generic attributes to maps
Entrypoint
The attributes
module of the core crate provides the necessary tools for to add custom attributes
to given orbits of the map. Each attribute should be uniquely typed (i.e. to type aliases) as the
maps' internal storages use std::any::TypeId
for identification.
An attribute struct should implement both AttributeBind
and AttributeUpdate
. It can then be
added to the map using the dedicated CMapBuilder
method.
Example
Implementing a Weight
attribute
#![allow(unused)] fn main() { use honeycomb_core::attributes::{AttributeBind, AttributeUpdate, AttributeError, AttrSparseVec}; use honeycomb_core::cmap::{OrbitPolicy, VertexIdType}; #[derive(Debug, Clone, Copy, Default, PartialEq)] struct Weight(pub u32); impl AttributeUpdate for Weight { // when merging two weights, we add them fn merge(attr1: Self, attr2: Self) -> Result<Self, AttributeError> { Ok(Self(attr1.0 + attr2.0)) } // when splitting, we do an approximate 50/50 fn split(attr: Self) -> Result<(Self, Self), AttributeError> { // adding the % to keep things conservative Ok((Self(attr.0 / 2 + attr.0 % 2), Self(attr.0 / 2))) } // if we have to merge from a single value, we assume the "other" is 0 fn merge_incomplete(attr: Self) -> Result<Self, AttributeError> { Ok(attr) } } impl AttributeBind for Weight { // Weight values will be stored in an `AttrSparseVec` type StorageType = AttrSparseVec<Self>; // Weights bind to vertices type IdentifierType = VertexIdType; const BIND_POLICY: OrbitPolicy = OrbitPolicy::Vertex; } }
Map integration
use honeycomb_core::cmap::{CMapBuilder, CMap2}; fn main() { let map: CMap2<f64> = CMapBuilder::default() .n_darts(4) .add_attribute::<Weight>() .build() .unwrap(); let _ = map.force_link::<2>(1, 2); let _ = map.force_link::<2>(3, 4); map.force_write_vertex(2, (0.0, 1.0)); map.force_write_vertex(3, (1.0, 1.0)); map.force_write_attribute::<Weight>(2, Weight(5)); map.force_write_attribute::<Weight>(3, Weight(6)); let _ = map.force_sew::<1>(1, 3); assert_eq!(map.force_read_attribute::<Weight>(2), Some(Weight(11))); let _ = map.force_unsew::<1>(1); assert_eq!(map.force_read_attribute::<Weight>(2), Some(Weight(6))); assert_eq!(map.force_read_attribute::<Weight>(3), Some(Weight(5))); }