Skip to content

Commit

Permalink
Merge handle into stores
Browse files Browse the repository at this point in the history
  • Loading branch information
hannobraun committed Mar 31, 2022
1 parent 2bc2903 commit 30c9afe
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 68 deletions.
63 changes: 0 additions & 63 deletions fj-kernel/src/shape/handle.rs

This file was deleted.

4 changes: 1 addition & 3 deletions fj-kernel/src/shape/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@
mod api;
mod geometry;
mod handle;
mod stores;
mod topology;
mod validate;

pub use self::{
api::Shape,
geometry::Geometry,
handle::Handle,
stores::Iter,
stores::{Handle, Iter},
topology::Topology,
validate::{StructuralIssues, ValidationError, ValidationResult},
};
60 changes: 58 additions & 2 deletions fj-kernel/src/shape/stores.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ use crate::{
topology::{Cycle, Edge, Face, Vertex},
};

use super::Handle;

pub type Points = Store<Point<3>>;
pub type Curves = Store<Curve>;
pub type Surfaces = Store<Surface>;
Expand Down Expand Up @@ -116,6 +114,64 @@ impl<T> Hash for Store<T> {

pub type Objects<T> = SlotMap<DefaultKey, T>;

/// A handle to an object stored within [`Shape`]
///
/// If an object of type `T` (this could be `Curve`, `Vertex`, etc.) is added to
/// `Shape`, a `Handle<T>` is returned. This handle is then used in topological
/// types to refer to the object, instead of having those types own an instance
/// of the object.
///
/// This approach has two advantages:
///
/// 1. The object can't be mutated through the handle. Since an object can be
/// referred to by multiple other objects, mutating it locally would have no
/// effect on those other references. `Handle` preventing that removes this
/// source of errors.
/// 2. The object is guaranteed to be in `Shape`, as `Handle`s can't be created
/// any other way. This means that if the `Shape` needs to be modified, any
/// objects can be updated once, without requiring an update of all the other
/// objects that reference it.
///
/// # Equality
///
/// The equality of [`Handle`] is very strictly defined in terms of identity.
/// Two [`Handle`]s are considered equal, if they refer to objects in the same
/// memory location.
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct Handle<T> {
key: DefaultKey,
store: Store<T>,
}

impl<T> Handle<T> {
pub(super) fn new(key: DefaultKey, store: Store<T>) -> Self {
Self { key, store }
}

pub(super) fn key(&self) -> DefaultKey {
self.key
}

pub(super) fn store(&self) -> &Store<T> {
&self.store
}

/// Access the object that the handle references
pub fn get(&self) -> T
where
T: Clone,
{
self.store
.read()
.get(self.key)
// Can't panic, unless the handle was invalid in the first place.
// Objects are never removed from `Store`, so if we have a handle
// pointing to it, it should be there.
.unwrap()
.clone()
}
}

/// An iterator over geometric or topological objects
///
/// Returned by various methods of the [`Shape`] API.
Expand Down

0 comments on commit 30c9afe

Please sign in to comment.