Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

replace Any by UnknownAttributeStorage to handle collections in attribute manager #97

Merged
merged 11 commits into from
Jun 12, 2024
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ cfg-if = "1"
rustversion = "1.0.15"

# core
downcast-rs = "1.2.1"
num = "0.4.2"
vtkio = { version = "0.6.3" }

Expand Down
1 change: 1 addition & 0 deletions honeycomb-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ utils = []

[dependencies]
cfg-if.workspace = true
downcast-rs.workspace = true
num.workspace = true
vtkio = { workspace = true, optional = true }

Expand Down
296 changes: 277 additions & 19 deletions honeycomb-core/src/attributes/manager.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
//! Module short description
//! attribute super structure code
//!
//! Should you interact with this module directly?
//!
//! Content description if needed
//! this module contains all code used to implement a manager struct, used to handle generic
//! attributes embedded in a given combinatorial map.

// ------ IMPORTS

use crate::{AttributeBind, AttributeStorage, OrbitPolicy, UnknownAttributeStorage};
use std::any::{Any, TypeId};
use crate::{
AttributeBind, AttributeStorage, DartIdentifier, OrbitPolicy, UnknownAttributeStorage,
};
use std::any::TypeId;
use std::collections::HashMap;

// ------ CONTENT
Expand Down Expand Up @@ -72,15 +73,247 @@ pub enum ManagerError {
#[derive(Default)]
pub struct AttrStorageManager {
/// Vertex attributes' storages.
vertices: HashMap<TypeId, Box<dyn Any>>,
vertices: HashMap<TypeId, Box<dyn UnknownAttributeStorage>>,
/// Edge attributes' storages.
edges: HashMap<TypeId, Box<dyn Any>>,
edges: HashMap<TypeId, Box<dyn UnknownAttributeStorage>>,
/// Face attributes' storages.
faces: HashMap<TypeId, Box<dyn Any>>,
faces: HashMap<TypeId, Box<dyn UnknownAttributeStorage>>,
/// Other storages.
others: HashMap<TypeId, Box<dyn Any>>, // Orbit::Custom
others: HashMap<TypeId, Box<dyn UnknownAttributeStorage>>, // Orbit::Custom
}

// --- manager-wide methods

impl AttrStorageManager {
/// Extend the size of all storages in the manager.
///
/// # Arguments
///
/// - `length: usize` -- Length by which storages should be extended.
pub fn extend_storages(&mut self, length: usize) {
for storage in self.vertices.values_mut() {
storage.extend(length);
}
for storage in self.edges.values_mut() {
storage.extend(length);
}
for storage in self.faces.values_mut() {
storage.extend(length);
}
for storage in self.others.values_mut() {
storage.extend(length);
}
}

// merges

/// Execute a merging operation on all attributes associated with a given orbit
/// for specified cells.
///
/// # Arguments
///
/// - `orbit_policy: OrbitPolicy` -- Orbit associated with affected attributes.
/// - `id_out: DartIdentifier` -- Identifier to write the result to.
/// - `id_in_lhs: DartIdentifier` -- Identifier of one attribute value to merge.
/// - `id_in_rhs: DartIdentifier` -- Identifier of the other attribute value to merge.
pub fn merge_attributes(
&mut self,
orbit_policy: &OrbitPolicy,
id_out: DartIdentifier,
id_in_lhs: DartIdentifier,
id_in_rhs: DartIdentifier,
) {
match orbit_policy {
OrbitPolicy::Vertex => self.merge_vertex_attributes(id_out, id_in_lhs, id_in_rhs),
OrbitPolicy::Edge => self.merge_edge_attributes(id_out, id_in_lhs, id_in_rhs),
OrbitPolicy::Face => self.merge_face_attributes(id_out, id_in_lhs, id_in_rhs),
OrbitPolicy::Custom(_) => {
self.merge_other_attributes(orbit_policy, id_out, id_in_lhs, id_in_rhs);
}
}
}

/// Execute a merging operation on all attributes associated with vertices for specified cells.
///
/// # Arguments
///
/// - `id_out: DartIdentifier` -- Identifier to write the result to.
/// - `id_in_lhs: DartIdentifier` -- Identifier of one attribute value to merge.
/// - `id_in_rhs: DartIdentifier` -- Identifier of the other attribute value to merge.
pub fn merge_vertex_attributes(
&mut self,
id_out: DartIdentifier,
id_in_lhs: DartIdentifier,
id_in_rhs: DartIdentifier,
) {
for storage in self.vertices.values_mut() {
storage.merge(id_out, id_in_lhs, id_in_rhs);
}
}

/// Execute a merging operation on all attributes associated with edges for specified cells.
///
/// # Arguments
///
/// - `id_out: DartIdentifier` -- Identifier to write the result to.
/// - `id_in_lhs: DartIdentifier` -- Identifier of one attribute value to merge.
/// - `id_in_rhs: DartIdentifier` -- Identifier of the other attribute value to merge.
pub fn merge_edge_attributes(
&mut self,
id_out: DartIdentifier,
id_in_lhs: DartIdentifier,
id_in_rhs: DartIdentifier,
) {
for storage in self.edges.values_mut() {
storage.merge(id_out, id_in_lhs, id_in_rhs);
}
}

/// Execute a merging operation on all attributes associated with faces for specified cells.
///
/// # Arguments
///
/// - `id_out: DartIdentifier` -- Identifier to write the result to.
/// - `id_in_lhs: DartIdentifier` -- Identifier of one attribute value to merge.
/// - `id_in_rhs: DartIdentifier` -- Identifier of the other attribute value to merge.
pub fn merge_face_attributes(
&mut self,
id_out: DartIdentifier,
id_in_lhs: DartIdentifier,
id_in_rhs: DartIdentifier,
) {
for storage in self.faces.values_mut() {
storage.merge(id_out, id_in_lhs, id_in_rhs);
}
}

/// Execute a merging operation on all attributes associated with a given orbit
/// for specified cells.
///
/// # Arguments
///
/// - `orbit_policy: OrbitPolicy` -- Orbit associated with affected attributes.
/// - `id_out: DartIdentifier` -- Identifier to write the result to.
/// - `id_in_lhs: DartIdentifier` -- Identifier of one attribute value to merge.
/// - `id_in_rhs: DartIdentifier` -- Identifier of the other attribute value to merge.
pub fn merge_other_attributes(
&mut self,
_orbit_policy: &OrbitPolicy,
_id_out: DartIdentifier,
_id_in_lhs: DartIdentifier,
_id_in_rhs: DartIdentifier,
) {
todo!("custom orbit binding is a special case that will be treated later")
}

// splits

/// Execute a splitting operation on all attributes associated with a given orbit
/// for specified cells.
///
/// # Arguments
///
/// - `orbit_policy: OrbitPolicy` -- Orbit associated with affected attributes.
/// - `id_out_lhs: DartIdentifier` -- Identifier to write the result to.
/// - `id_out_rhs: DartIdentifier` -- Identifier to write the result to.
/// - `id_in: DartIdentifier` -- Identifier of the attribute value to split.
pub fn split_attributes(
&mut self,
orbit_policy: &OrbitPolicy,
id_out_lhs: DartIdentifier,
id_out_rhs: DartIdentifier,
id_in: DartIdentifier,
) {
match orbit_policy {
OrbitPolicy::Vertex => self.split_vertex_attributes(id_out_lhs, id_out_rhs, id_in),
OrbitPolicy::Edge => self.split_edge_attributes(id_out_lhs, id_out_rhs, id_in),
OrbitPolicy::Face => self.split_face_attributes(id_out_lhs, id_out_rhs, id_in),
OrbitPolicy::Custom(_) => {
self.split_other_attributes(orbit_policy, id_out_lhs, id_out_rhs, id_in);
}
}
}

/// Execute a splitting operation on all attributes associated with vertices
/// for specified cells.
///
/// # Arguments
///
/// - `orbit_policy: OrbitPolicy` -- Orbit associated with affected attributes.
/// - `id_out_lhs: DartIdentifier` -- Identifier to write the result to.
/// - `id_out_rhs: DartIdentifier` -- Identifier to write the result to.
/// - `id_in: DartIdentifier` -- Identifier of the attribute value to split.
pub fn split_vertex_attributes(
&mut self,
id_out_lhs: DartIdentifier,
id_out_rhs: DartIdentifier,
id_in: DartIdentifier,
) {
for storage in self.vertices.values_mut() {
storage.split(id_out_lhs, id_out_rhs, id_in);
}
}

/// Execute a splitting operation on all attributes associated with edges for specified cells.
///
/// # Arguments
///
/// - `orbit_policy: OrbitPolicy` -- Orbit associated with affected attributes.
/// - `id_out_lhs: DartIdentifier` -- Identifier to write the result to.
/// - `id_out_rhs: DartIdentifier` -- Identifier to write the result to.
/// - `id_in: DartIdentifier` -- Identifier of the attribute value to split.
pub fn split_edge_attributes(
&mut self,
id_out_lhs: DartIdentifier,
id_out_rhs: DartIdentifier,
id_in: DartIdentifier,
) {
for storage in self.edges.values_mut() {
storage.split(id_out_lhs, id_out_rhs, id_in);
}
}

/// Execute a splitting operation on all attributes associated with faces for specified cells.
///
/// # Arguments
///
/// - `orbit_policy: OrbitPolicy` -- Orbit associated with affected attributes.
/// - `id_out_lhs: DartIdentifier` -- Identifier to write the result to.
/// - `id_out_rhs: DartIdentifier` -- Identifier to write the result to.
/// - `id_in: DartIdentifier` -- Identifier of the attribute value to split.
pub fn split_face_attributes(
&mut self,
id_out_lhs: DartIdentifier,
id_out_rhs: DartIdentifier,
id_in: DartIdentifier,
) {
for storage in self.faces.values_mut() {
storage.split(id_out_lhs, id_out_rhs, id_in);
}
}

/// Execute a splitting operation on all attributes associated with a given orbit
/// for specified cells.
///
/// # Arguments
///
/// - `orbit_policy: OrbitPolicy` -- Orbit associated with affected attributes.
/// - `id_out_lhs: DartIdentifier` -- Identifier to write the result to.
/// - `id_out_rhs: DartIdentifier` -- Identifier to write the result to.
/// - `id_in: DartIdentifier` -- Identifier of the attribute value to split.
pub fn split_other_attributes(
&mut self,
_orbit_policy: &OrbitPolicy,
_id_out_lhs: DartIdentifier,
_id_out_rhs: DartIdentifier,
_id_in: DartIdentifier,
) {
todo!("custom orbit binding is a special case that will be treated later")
}
}

// --- attribute-specific methods

macro_rules! get_storage {
($slf: ident, $id: ident) => {
let probably_storage = match A::binds_to() {
Expand Down Expand Up @@ -152,15 +385,6 @@ impl AttrStorageManager {
}
}

/// UNIMPLEMENTED
pub fn extend_storages(&mut self, _length: usize) {
// not sure if this is actually possible since we need to fetch the attribute from storages,
// which cannot be interpreted as such without the attribute in the first place
for _storage in self.vertices.values_mut() {
todo!()
}
}

/// Extend the size of the storage of a given attribute.
///
/// # Arguments
Expand Down Expand Up @@ -329,4 +553,38 @@ impl AttrStorageManager {
get_storage_mut!(self, storage);
storage.remove(id)
}

/// Merge given attribute values.
///
/// # Arguments
///
/// - `id_out: DartIdentifier` -- Identifier to write the result to.
/// - `id_in_lhs: DartIdentifier` -- Identifier of one attribute value to merge.
/// - `id_in_rhs: DartIdentifier` -- Identifier of the other attribute value to merge.
pub fn merge_attribute<A: AttributeBind>(
&mut self,
id_out: DartIdentifier,
id_in_lhs: DartIdentifier,
id_in_rhs: DartIdentifier,
) {
get_storage_mut!(self, storage);
storage.merge(id_out, id_in_lhs, id_in_rhs);
}

/// Split given attribute value.
///
/// # Arguments
///
/// - `id_out_lhs: DartIdentifier` -- Identifier to write the result to.
/// - `id_out_rhs: DartIdentifier` -- Identifier to write the result to.
/// - `id_in: DartIdentifier` -- Identifier of the attribute value to split.
pub fn split_attribute<A: AttributeBind>(
&mut self,
id_out_lhs: DartIdentifier,
id_out_rhs: DartIdentifier,
id_in: DartIdentifier,
) {
get_storage_mut!(self, storage);
storage.split(id_out_lhs, id_out_rhs, id_in);
}
}
5 changes: 4 additions & 1 deletion honeycomb-core/src/attributes/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// ------ IMPORTS

use crate::{DartIdentifier, OrbitPolicy};
use downcast_rs::{impl_downcast, Downcast};
use std::any::Any;
use std::fmt::Debug;

Expand Down Expand Up @@ -131,7 +132,7 @@ pub trait AttributeBind: Debug + Sized + Any {
/// This trait contain attribute-agnostic function & methods.
///
/// The documentation of this trait describe the behavior each function & method should have.
pub trait UnknownAttributeStorage: Debug + Any {
pub trait UnknownAttributeStorage: Any + Debug + Downcast {
/// Constructor
///
/// # Arguments
Expand Down Expand Up @@ -205,6 +206,8 @@ pub trait UnknownAttributeStorage: Debug + Any {
fn split(&mut self, lhs_out: DartIdentifier, rhs_out: DartIdentifier, inp: DartIdentifier);
}

impl_downcast!(UnknownAttributeStorage);

/// Common trait implemented by generic attribute storages.
///
/// This trait contain attribute-specific methods.
Expand Down