From 5c56b54622616d810d9828f873359b27f1dad84f Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 2 Aug 2023 11:39:59 +0200 Subject: [PATCH 1/4] Add dedicated directory for `insert` module --- crates/fj-core/src/operations/{insert.rs => insert/mod.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename crates/fj-core/src/operations/{insert.rs => insert/mod.rs} (100%) diff --git a/crates/fj-core/src/operations/insert.rs b/crates/fj-core/src/operations/insert/mod.rs similarity index 100% rename from crates/fj-core/src/operations/insert.rs rename to crates/fj-core/src/operations/insert/mod.rs From 9b1fcde81fe9c13eb7812be452cda760552c1e83 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 2 Aug 2023 11:45:02 +0200 Subject: [PATCH 2/4] Split `insert` into sub-modules --- .../src/operations/insert/insert_trait.rs | 84 +++++++++++++ .../src/operations/insert/is_inserted.rs | 28 +++++ crates/fj-core/src/operations/insert/mod.rs | 115 +----------------- 3 files changed, 118 insertions(+), 109 deletions(-) create mode 100644 crates/fj-core/src/operations/insert/insert_trait.rs create mode 100644 crates/fj-core/src/operations/insert/is_inserted.rs diff --git a/crates/fj-core/src/operations/insert/insert_trait.rs b/crates/fj-core/src/operations/insert/insert_trait.rs new file mode 100644 index 000000000..cd19325c2 --- /dev/null +++ b/crates/fj-core/src/operations/insert/insert_trait.rs @@ -0,0 +1,84 @@ +use crate::{ + objects::{ + Curve, Cycle, Face, GlobalEdge, HalfEdge, Region, Shell, Sketch, Solid, + Surface, Vertex, + }, + operations::{Polygon, TetrahedronShell}, + services::Services, + storage::Handle, +}; + +use super::{IsInsertedNo, IsInsertedYes}; + +/// Insert an object into its respective store +/// +/// This is the only primitive operation that is directly understood by +/// `Service`. All other operations are built on top of it. +pub trait Insert: Sized { + /// The type of `Self`, once it has been inserted + /// + /// Usually this is just `Handle`, but there are some more complex + /// cases where this type needs to be customized. + type Inserted; + + /// Insert the object into its respective store + #[must_use] + fn insert(self, services: &mut Services) -> Self::Inserted; +} + +macro_rules! impl_insert { + ($($ty:ty, $store:ident;)*) => { + $( + impl Insert for $ty { + type Inserted = Handle; + + fn insert(self, services: &mut Services) -> Self::Inserted { + let handle = services.objects.$store.reserve(); + let object = (handle.clone(), self).into(); + services.insert_object(object); + handle + } + } + )* + }; +} + +impl_insert!( + Curve, curves; + Cycle, cycles; + Face, faces; + GlobalEdge, global_edges; + HalfEdge, half_edges; + Region, regions; + Shell, shells; + Sketch, sketches; + Solid, solids; + Surface, surfaces; + Vertex, vertices; +); + +impl Insert for Polygon { + type Inserted = Polygon; + + fn insert(self, services: &mut Services) -> Self::Inserted { + Polygon { + face: self.face.insert(services), + edges: self.edges, + vertices: self.vertices, + } + } +} + +impl Insert for TetrahedronShell { + type Inserted = TetrahedronShell; + + fn insert(self, services: &mut Services) -> Self::Inserted { + TetrahedronShell { + shell: self.shell.insert(services), + abc: self.abc, + bad: self.bad, + dac: self.dac, + cbd: self.cbd, + } + } +} diff --git a/crates/fj-core/src/operations/insert/is_inserted.rs b/crates/fj-core/src/operations/insert/is_inserted.rs new file mode 100644 index 000000000..dd4d00a95 --- /dev/null +++ b/crates/fj-core/src/operations/insert/is_inserted.rs @@ -0,0 +1,28 @@ +use crate::storage::Handle; + +/// Indicate whether an object has been inserted +/// +/// Intended to be used as a type parameter bound for structs that need to track +/// whether their contents have been inserted or not. +pub trait IsInserted { + /// The type of the object for which the insertion status is tracked + type T; +} + +/// Indicate that an object has been inserted +/// +/// See [`IsInserted`]. +pub struct IsInsertedYes; + +impl IsInserted for IsInsertedYes { + type T = Handle; +} + +/// Indicate that an object has not been inserted +/// +/// See [`IsInserted`]. +pub struct IsInsertedNo; + +impl IsInserted for IsInsertedNo { + type T = T; +} diff --git a/crates/fj-core/src/operations/insert/mod.rs b/crates/fj-core/src/operations/insert/mod.rs index 2e6f382dc..bc3815384 100644 --- a/crates/fj-core/src/operations/insert/mod.rs +++ b/crates/fj-core/src/operations/insert/mod.rs @@ -1,110 +1,7 @@ -use crate::{ - objects::{ - Curve, Cycle, Face, GlobalEdge, HalfEdge, Region, Shell, Sketch, Solid, - Surface, Vertex, - }, - services::Services, - storage::Handle, -}; - -use super::{Polygon, TetrahedronShell}; - -/// Insert an object into its respective store -/// -/// This is the only primitive operation that is directly understood by -/// `Service`. All other operations are built on top of it. -pub trait Insert: Sized { - /// The type of `Self`, once it has been inserted - /// - /// Usually this is just `Handle`, but there are some more complex - /// cases where this type needs to be customized. - type Inserted; - - /// Insert the object into its respective store - #[must_use] - fn insert(self, services: &mut Services) -> Self::Inserted; -} - -macro_rules! impl_insert { - ($($ty:ty, $store:ident;)*) => { - $( - impl Insert for $ty { - type Inserted = Handle; - - fn insert(self, services: &mut Services) -> Self::Inserted { - let handle = services.objects.$store.reserve(); - let object = (handle.clone(), self).into(); - services.insert_object(object); - handle - } - } - )* - }; -} - -impl_insert!( - Curve, curves; - Cycle, cycles; - Face, faces; - GlobalEdge, global_edges; - HalfEdge, half_edges; - Region, regions; - Shell, shells; - Sketch, sketches; - Solid, solids; - Surface, surfaces; - Vertex, vertices; -); - -/// Indicate whether an object has been inserted -/// -/// Intended to be used as a type parameter bound for structs that need to track -/// whether their contents have been inserted or not. -pub trait IsInserted { - /// The type of the object for which the insertion status is tracked - type T; -} +mod insert_trait; +mod is_inserted; -/// Indicate that an object has been inserted -/// -/// See [`IsInserted`]. -pub struct IsInsertedYes; - -impl IsInserted for IsInsertedYes { - type T = Handle; -} - -/// Indicate that an object has not been inserted -/// -/// See [`IsInserted`]. -pub struct IsInsertedNo; - -impl IsInserted for IsInsertedNo { - type T = T; -} - -impl Insert for Polygon { - type Inserted = Polygon; - - fn insert(self, services: &mut Services) -> Self::Inserted { - Polygon { - face: self.face.insert(services), - edges: self.edges, - vertices: self.vertices, - } - } -} - -impl Insert for TetrahedronShell { - type Inserted = TetrahedronShell; - - fn insert(self, services: &mut Services) -> Self::Inserted { - TetrahedronShell { - shell: self.shell.insert(services), - abc: self.abc, - bad: self.bad, - dac: self.dac, - cbd: self.cbd, - } - } -} +pub use self::{ + insert_trait::Insert, + is_inserted::{IsInserted, IsInsertedNo, IsInsertedYes}, +}; From 935425725fc0a78377ec781eee7e9779a268be97 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 2 Aug 2023 11:21:55 +0200 Subject: [PATCH 3/4] Implement `Borrow` for `Handle` This makes `Handle` more useful in some generic code, and I'm about to make use of that. --- crates/fj-core/src/storage/handle.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/storage/handle.rs b/crates/fj-core/src/storage/handle.rs index 15b5f8d18..63eea2908 100644 --- a/crates/fj-core/src/storage/handle.rs +++ b/crates/fj-core/src/storage/handle.rs @@ -1,4 +1,6 @@ -use std::{any::type_name, cmp::Ordering, fmt, hash::Hash, ops::Deref}; +use std::{ + any::type_name, borrow::Borrow, cmp::Ordering, fmt, hash::Hash, ops::Deref, +}; use super::{blocks::Index, store::StoreInner}; @@ -82,6 +84,12 @@ impl Deref for Handle { } } +impl Borrow for Handle { + fn borrow(&self) -> &T { + self.deref() + } +} + impl Clone for Handle { fn clone(&self) -> Self { Self { From e82d79bf99279b57a6b27ac4d71987369d6c1696 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 2 Aug 2023 11:24:29 +0200 Subject: [PATCH 4/4] Make `IsInserted` more useful Requiring the `Borrow` trait here allows code that is generic over `IsInserted` to call methods on `T`. --- crates/fj-core/src/operations/insert/is_inserted.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/operations/insert/is_inserted.rs b/crates/fj-core/src/operations/insert/is_inserted.rs index dd4d00a95..992e2f43d 100644 --- a/crates/fj-core/src/operations/insert/is_inserted.rs +++ b/crates/fj-core/src/operations/insert/is_inserted.rs @@ -1,3 +1,5 @@ +use std::borrow::Borrow; + use crate::storage::Handle; /// Indicate whether an object has been inserted @@ -6,7 +8,7 @@ use crate::storage::Handle; /// whether their contents have been inserted or not. pub trait IsInserted { /// The type of the object for which the insertion status is tracked - type T; + type T: Borrow; } /// Indicate that an object has been inserted