diff --git a/crates/fj-core/src/layers/layer.rs b/crates/fj-core/src/layers/layer.rs index eb44cec4f..efa1efcbe 100644 --- a/crates/fj-core/src/layers/layer.rs +++ b/crates/fj-core/src/layers/layer.rs @@ -1,20 +1,17 @@ use std::ops::Deref; -/// A service that controls access to some state +/// A generic layer, which controls access to layer state /// -/// `Service` is a generic wrapper around some state, as well as code that knows -/// how to operate on that state. It processes commands, changes the state based -/// on those command, and produces events that capture these changes. These -/// events are stored, providing a log of all changes to the state, and can be -/// replayed later to re-create the state at any point in time. +/// `Layer` is a generic wrapper around some state and controls access to it. It +/// [`Deref`]s to the state it wraps, for easy read access, but prevents any +/// direct write access. /// -/// The wrapped state must implement [`State`], which defines the type of -/// command that this service processes, and the type of event that captures -/// state changes. It also defines methods that operate on the state, commands, -/// and events. +/// Instead, each write access to state is reified as a command, which are +/// processed by [`Layer::process`]. Processing a command can result in any +/// number of events, which can then be used as commands for other layers. /// -/// Implementations of [`State`] might also define an extension trait for a -/// specific `Service`, to provide a convenient API to callers. +/// All of this is mediated through [`State`], which the wrapped state must +/// implement. /// /// This design takes inspiration from, and uses the nomenclature of, this /// article: @@ -24,15 +21,15 @@ pub struct Layer { } impl Layer { - /// Create an instance of `Service` + /// Create an instance of `Layer` pub fn new(state: S) -> Self { Self { state } } - /// Execute a command + /// Process a command /// - /// The command is executed synchronously. When this method returns, the - /// state has been updated and any events have been logged. + /// The command is processed synchronously. When this method returns, the + /// state has been updated. pub fn process(&mut self, command: S::Command, events: &mut Vec) { self.state.decide(command, events); @@ -64,16 +61,19 @@ where } } -/// Implemented for state that can be wrapped by a [`Layer`] +/// The state of a specific layer /// -/// See [`Layer`] for a detailed explanation. +/// Implementations of this trait are wrapped by the generic [`Layer`], which is +/// the consumer of this trait's API. +/// +/// See [`Layer`] for a more detailed explanation. pub trait State { - /// A command that relates to the state + /// A command that encodes a request to update the state /// /// Commands are processed by [`State::decide`]. type Command; - /// An event that captures modifications to this state + /// An event that encodes a change to the state /// /// Events are produced by [`State::decide`] and processed by /// [`State::evolve`]. @@ -87,8 +87,8 @@ pub trait State { /// Evolve the state according to the provided event /// - /// This is the only method gets mutable access to the state, making sure - /// that all changes to the state are captured as events. + /// This is the only method that gets mutable access to the state, making + /// sure that all changes to the state are captured as events. /// /// Implementations of this method are supposed to be relatively dumb. Any /// decisions that go into updating the state should be made in diff --git a/crates/fj-core/src/layers/mod.rs b/crates/fj-core/src/layers/mod.rs index b533746fb..780f1a15a 100644 --- a/crates/fj-core/src/layers/mod.rs +++ b/crates/fj-core/src/layers/mod.rs @@ -1,4 +1,4 @@ -//! Service API that promotes monitoring and interactivity +//! Loosely coupled layers, that together define shapes //! //! See [`Layers`]. @@ -17,27 +17,41 @@ pub use self::{ validation::{Validation, ValidationCommand, ValidationEvent}, }; -/// The kernel services +/// # Loosely coupled layers, that together define shapes +/// +/// Shapes are not a monolithic thing in Fornjot, but instead are defined by +/// several, loosely coupled layers. These layers are owned by this struct. +/// +/// ## Implementation Note +/// +/// It is totally conceivable that one day, this system of layers is extensible +/// and more layers can be defined by third-party code. The foundation for that, +/// the loose coupling and inter-layer communication via events, is already +/// there, conceptually. +/// +/// For now, there is no need for this, and all layers are just hardcoded here. +/// That can be changed, once necessary. #[derive(Default)] pub struct Layers { - /// The objects service + /// The objects layers /// - /// Allows for inserting objects into a store after they were created. + /// Manages the stores of topological and geometric objects that make up + /// shapes. pub objects: Layer, - /// The validation service + /// The validation layer /// - /// Validates objects that are inserted using the objects service. + /// Monitors objects and validates them, as they are inserted. pub validation: Layer, } impl Layers { - /// Construct an instance of `Services` + /// Construct an instance of `Layers` pub fn new() -> Self { Self::default() } - /// Construct an instance of `Services`, using the provided configuration + /// Construct an instance of `Layers`, using the provided configuration pub fn with_validation_config(config: ValidationConfig) -> Self { let objects = Layer::default(); let validation = Layer::new(Validation::with_validation_config(config)); @@ -62,7 +76,7 @@ impl Layers { } } - /// Drop `Services`; return any unhandled validation error + /// Drop `Layers`; return any unhandled validation error pub fn drop_and_validate(self) -> Result<(), ValidationErrors> { let errors = self.validation.into_state().into_errors(); diff --git a/crates/fj-core/src/layers/objects.rs b/crates/fj-core/src/layers/objects.rs index 745432627..916a7ff13 100644 --- a/crates/fj-core/src/layers/objects.rs +++ b/crates/fj-core/src/layers/objects.rs @@ -16,7 +16,7 @@ impl State for Objects { } } -/// Command for `Service` +/// Command for `Layer` #[derive(Debug)] pub enum Operation { /// Insert an object into the stores @@ -29,7 +29,7 @@ pub enum Operation { }, } -/// Event produced by `Service` +/// Event produced by `Layer` #[derive(Clone, Debug)] pub struct InsertObject { /// The object to insert diff --git a/crates/fj-core/src/layers/validation.rs b/crates/fj-core/src/layers/validation.rs index 0c41e492d..a9e28bb25 100644 --- a/crates/fj-core/src/layers/validation.rs +++ b/crates/fj-core/src/layers/validation.rs @@ -19,7 +19,7 @@ pub struct Validation { } impl Validation { - /// A constructor for the validation service that allows a validation configuration to be set for the service + /// Construct an instance of `Validation`, using the provided configuration pub fn with_validation_config(config: ValidationConfig) -> Self { let errors = HashMap::new(); Self { errors, config } @@ -91,7 +91,7 @@ impl State for Validation { } } -/// The command accepted by the validation service +/// Command for `Layer` pub enum ValidationCommand { /// Validate the provided object ValidateObject { @@ -100,7 +100,7 @@ pub enum ValidationCommand { }, } -/// The event produced by the validation service +/// Event produced by `Layer` #[derive(Clone)] pub enum ValidationEvent { /// Validation of an object failed