From c06c0499eb8be807ba0f905c58b9a8a17567906a Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 18 Nov 2022 12:13:26 +0100 Subject: [PATCH 1/3] Add `Object` enum --- crates/fj-kernel/src/objects/mod.rs | 2 + crates/fj-kernel/src/objects/object.rs | 93 ++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 crates/fj-kernel/src/objects/object.rs diff --git a/crates/fj-kernel/src/objects/mod.rs b/crates/fj-kernel/src/objects/mod.rs index ab0976fbc..8cfa8facc 100644 --- a/crates/fj-kernel/src/objects/mod.rs +++ b/crates/fj-kernel/src/objects/mod.rs @@ -74,6 +74,7 @@ //! [#1021]: https://github.com/hannobraun/Fornjot/issues/1021 mod full; +mod object; mod stores; pub use self::{ @@ -88,6 +89,7 @@ pub use self::{ surface::Surface, vertex::{GlobalVertex, SurfaceVertex, Vertex}, }, + object::{Bare, BehindHandle, Form, Object, WithHandle}, stores::{ Curves, Cycles, Faces, GlobalCurves, GlobalEdges, GlobalVertices, HalfEdges, Objects, Shells, Sketches, Solids, SurfaceVertices, diff --git a/crates/fj-kernel/src/objects/object.rs b/crates/fj-kernel/src/objects/object.rs new file mode 100644 index 000000000..1c552c717 --- /dev/null +++ b/crates/fj-kernel/src/objects/object.rs @@ -0,0 +1,93 @@ +use crate::{ + objects::{ + Curve, Cycle, Face, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, + Shell, Sketch, Solid, Surface, SurfaceVertex, Vertex, + }, + storage::Handle, +}; + +macro_rules! object { + ($($ty:ident, $name:expr;)*) => { + /// An object + /// + /// This enum is generic over the form that the object takes. An + /// `Object` contains bare objects, like `Curve`. An + /// `Object` contains handles, like `Handle`. + #[derive(Clone)] + pub enum Object { + $( + #[doc = concat!("A ", $name)] + $ty(F::Form<$ty>), + )* + } + + $( + impl From<$ty> for Object { + fn from(object: $ty) -> Self { + Self::$ty(object) + } + } + + impl From> for Object { + fn from(object: Handle<$ty>) -> Self { + Self::$ty(object) + } + } + + impl From<(Handle<$ty>, $ty)> for Object { + fn from((handle, object): (Handle<$ty>, $ty)) -> Self { + Self::$ty((handle, object)) + } + } + )* + }; +} + +object!( + Curve, "curve"; + Cycle, "cycle"; + Face, "face"; + GlobalCurve, "global curve"; + GlobalEdge, "global edge"; + GlobalVertex, "global vertex"; + HalfEdge, "half-edge"; + Shell, "shell"; + Sketch, "sketch"; + Solid, "solid"; + Surface, "surface"; + SurfaceVertex, "surface vertex"; + Vertex, "vertex"; +); + +/// The form that an object can take +/// +/// An object can be bare (see [`Bare`]) or behind a [`Handle`] (see +/// [`BehindHandle`]). +pub trait Form { + /// The form that the object takes + type Form; +} + +/// Implementation of [`Form`] for bare objects +#[derive(Clone)] +pub struct Bare; + +impl Form for Bare { + type Form = T; +} + +/// Implementation of [`Form`] for objects behind a handle +#[derive(Clone)] +pub struct BehindHandle; + +impl Form for BehindHandle { + type Form = Handle; +} + +/// Implementation of [`Form`] for objects that are paired with their handle +#[derive(Clone)] +pub struct WithHandle; + +impl Form for WithHandle { + type Form = (Handle, T); +} From ba6aab0a687cb7b18dd8e7f4b0905ec8390256c3 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 18 Nov 2022 13:21:24 +0100 Subject: [PATCH 2/3] Add `Object::insert` --- crates/fj-kernel/src/objects/object.rs | 55 +++++++++++++++++++------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/crates/fj-kernel/src/objects/object.rs b/crates/fj-kernel/src/objects/object.rs index 1c552c717..ccfbdd600 100644 --- a/crates/fj-kernel/src/objects/object.rs +++ b/crates/fj-kernel/src/objects/object.rs @@ -1,13 +1,15 @@ use crate::{ + insert::Insert, objects::{ Curve, Cycle, Face, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, - Shell, Sketch, Solid, Surface, SurfaceVertex, Vertex, + Objects, Shell, Sketch, Solid, Surface, SurfaceVertex, Vertex, }, storage::Handle, + validate::{Validate, ValidationError}, }; macro_rules! object { - ($($ty:ident, $name:expr;)*) => { + ($($ty:ident, $name:expr, $store:ident;)*) => { /// An object /// /// This enum is generic over the form that the object takes. An @@ -21,6 +23,29 @@ macro_rules! object { )* } + impl Object { + /// Insert the object into its respective store + pub fn insert( + self, + objects: &mut Objects, + ) -> Result, ValidationError> + where + $( + crate::objects::$ty: Insert, + ValidationError: From<<$ty as Validate>::Error>, + )* + { + match self { + $( + Self::$ty((handle, object)) => { + objects.$store.insert(handle.clone(), object)?; + Ok(handle.into()) + } + )* + } + } + } + $( impl From<$ty> for Object { fn from(object: $ty) -> Self { @@ -44,19 +69,19 @@ macro_rules! object { } object!( - Curve, "curve"; - Cycle, "cycle"; - Face, "face"; - GlobalCurve, "global curve"; - GlobalEdge, "global edge"; - GlobalVertex, "global vertex"; - HalfEdge, "half-edge"; - Shell, "shell"; - Sketch, "sketch"; - Solid, "solid"; - Surface, "surface"; - SurfaceVertex, "surface vertex"; - Vertex, "vertex"; + Curve, "curve", curves; + Cycle, "cycle", cycles; + Face, "face", faces; + GlobalCurve, "global curve", global_curves; + GlobalEdge, "global edge", global_edges; + GlobalVertex, "global vertex", global_vertices; + HalfEdge, "half-edge", half_edges; + Shell, "shell", shells; + Sketch, "sketch", sketches; + Solid, "solid", solids; + Surface, "surface", surfaces; + SurfaceVertex, "surface vertex", surface_vertices; + Vertex, "vertex", vertices; ); /// The form that an object can take From a6050587d420f759d44a5ef9d2102b8531fc9ab9 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 18 Nov 2022 15:21:54 +0100 Subject: [PATCH 3/3] Add `Object::as_inner` --- crates/fj-kernel/src/objects/object.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/crates/fj-kernel/src/objects/object.rs b/crates/fj-kernel/src/objects/object.rs index ccfbdd600..fd04a2280 100644 --- a/crates/fj-kernel/src/objects/object.rs +++ b/crates/fj-kernel/src/objects/object.rs @@ -1,3 +1,5 @@ +use std::any::Any; + use crate::{ insert::Insert, objects::{ @@ -23,6 +25,23 @@ macro_rules! object { )* } + impl Object { + /// Convert the `Object` into the requested inner type + pub fn as_inner(&self) -> Option<&F::Form> + where + Self: 'static, + F::Form: Any, + { + match self { + $( + Self::$ty(object) => + (object as &dyn Any).downcast_ref(), + + )* + } + } + } + impl Object { /// Insert the object into its respective store pub fn insert(