Skip to content

Commit

Permalink
Merge pull request #2220 from hannobraun/presentation
Browse files Browse the repository at this point in the history
Add presentation layer
  • Loading branch information
hannobraun authored Feb 16, 2024
2 parents fc0b8ce + a9bf98a commit f079566
Show file tree
Hide file tree
Showing 10 changed files with 172 additions and 11 deletions.
6 changes: 6 additions & 0 deletions crates/fj-core/src/layers/layers.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{
objects::Objects,
presentation::Presentation,
validate::{Validation, ValidationConfig},
};

Expand Down Expand Up @@ -31,6 +32,11 @@ pub struct Layers {
///
/// Monitors objects and validates them, as they are inserted.
pub validation: Layer<Validation>,

/// The presentation layer
///
/// Stores data concerning the presentation of objects.
pub presentation: Layer<Presentation>,
}

impl Layers {
Expand Down
1 change: 1 addition & 0 deletions crates/fj-core/src/layers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! See [`Layers`].
pub mod objects;
pub mod presentation;
pub mod validation;

mod layer;
Expand Down
104 changes: 104 additions & 0 deletions crates/fj-core/src/layers/presentation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
//! Layer infrastructure for [`Presentation`]
use fj_interop::Color;

use crate::{
objects::{AnyObject, Region, Stored},
presentation::Presentation,
storage::Handle,
};

use super::{Command, Event, Layer};

impl Layer<Presentation> {
/// Set the color of a region
pub fn set_color(&mut self, region: Handle<Region>, color: Color) {
let mut events = Vec::new();
self.process(SetColor { region, color }, &mut events);
}

/// Mark an object as being derived from another
pub fn derive_object(
&mut self,
original: AnyObject<Stored>,
derived: AnyObject<Stored>,
) {
let mut events = Vec::new();
self.process(DeriveObject { original, derived }, &mut events);
}
}

/// Set the color of a region
pub struct SetColor {
/// The region to set the color for
region: Handle<Region>,

/// The color to set
color: Color,
}

impl Command<Presentation> for SetColor {
type Result = ();
type Event = Self;

fn decide(
self,
_: &Presentation,
events: &mut Vec<Self::Event>,
) -> Self::Result {
events.push(self);
}
}

impl Event<Presentation> for SetColor {
fn evolve(&self, state: &mut Presentation) {
state.color.insert(self.region.clone(), self.color);
}
}

/// Handle an object being derived from another
pub struct DeriveObject {
/// The original object
original: AnyObject<Stored>,

/// The derived object
derived: AnyObject<Stored>,
}

impl Command<Presentation> for DeriveObject {
type Result = ();
type Event = SetColor;

fn decide(
self,
state: &Presentation,
events: &mut Vec<Self::Event>,
) -> Self::Result {
if let (AnyObject::Region(original), AnyObject::Region(derived)) =
(self.original, self.derived)
{
if let Some(color) = state.color.get(&original.0).cloned() {
events.push(SetColor {
region: derived.into(),
color,
});
}
}
}
}

/// Command for `Layer<Presentation>`
pub enum PresentationCommand {}

/// Event produced by `Layer<Presentation>`
#[derive(Clone)]
pub enum PresentationEvent {
/// The color of a region is being set
SetColor {
/// The region the color is being set for
region: Handle<Region>,

/// The color being set
color: Color,
},
}
1 change: 1 addition & 0 deletions crates/fj-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ pub mod geometry;
pub mod layers;
pub mod objects;
pub mod operations;
pub mod presentation;
pub mod queries;
pub mod storage;
pub mod validate;
Expand Down
18 changes: 13 additions & 5 deletions crates/fj-core/src/operations/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,26 @@
//!
//! See [`DeriveFrom`].
use crate::{storage::Handle, Core};
use crate::{
objects::{AnyObject, Stored},
storage::Handle,
Core,
};

/// Mark a store object as derived from another
pub trait DeriveFrom {
/// Mark this object as derived from the other object provided
fn derive_from(self, other: &Self, core: &mut Core) -> Self;
}

impl<T> DeriveFrom for Handle<T> {
fn derive_from(self, _other: &Self, _core: &mut Core) -> Self {
// This is currently a no-op. Eventually, it will trigger a command to
// the layers that this information is relevant for.
impl<T> DeriveFrom for Handle<T>
where
Self: Into<AnyObject<Stored>>,
{
fn derive_from(self, other: &Self, core: &mut Core) -> Self {
core.layers
.presentation
.derive_object(other.clone().into(), self.clone().into());
self
}
}
19 changes: 16 additions & 3 deletions crates/fj-core/src/operations/presentation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,33 @@ use fj_interop::Color;
use crate::{
objects::{IsObject, Region},
storage::Handle,
Core,
};

/// Set the color of an object
pub trait SetColor: IsObject {
/// Set the color of the object
fn set_color(&self, color: impl Into<Color>) -> Self::BareObject;
fn set_color(
&self,
color: impl Into<Color>,
core: &mut Core,
) -> Self::BareObject;
}

impl SetColor for Handle<Region> {
fn set_color(&self, color: impl Into<Color>) -> Self::BareObject {
fn set_color(
&self,
color: impl Into<Color>,
core: &mut Core,
) -> Self::BareObject {
let color = color.into();

core.layers.presentation.set_color(self.clone(), color);

Region::new(
self.exterior().clone(),
self.interiors().into_iter().cloned(),
Some(color.into()),
Some(color),
)
}
}
4 changes: 2 additions & 2 deletions crates/fj-core/src/operations/split/face.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ impl SplitFace for Shell {

if let Some(color) = face.region().color() {
region = region
.set_color(color)
.set_color(color, core)
.insert(core)
.derive_from(&region, core);
}
Expand Down Expand Up @@ -194,7 +194,7 @@ impl SplitFace for Shell {

if let Some(color) = face.region().color() {
region = region
.set_color(color)
.set_color(color, core)
.insert(core)
.derive_from(&region, core);
}
Expand Down
2 changes: 2 additions & 0 deletions crates/fj-core/src/operations/transform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use fj_math::{Transform, Vector};
use type_map::TypeMap;

use crate::{
objects::{AnyObject, Stored},
operations::insert::Insert,
storage::{Handle, ObjectId},
Core,
Expand Down Expand Up @@ -69,6 +70,7 @@ pub trait TransformObject: Sized {
impl<T> TransformObject for Handle<T>
where
T: Clone + Insert<Inserted = Handle<T>> + TransformObject + 'static,
Handle<T>: Into<AnyObject<Stored>>,
{
fn transform_with_cache(
&self,
Expand Down
26 changes: 26 additions & 0 deletions crates/fj-core/src/presentation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//! Presentation data for the object graph
//!
//! See [`Presentation`].
use std::collections::BTreeMap;

use fj_interop::Color;

use crate::{objects::Region, storage::Handle};

/// Presentation data for the object graph
///
/// Assigns attributes relating to the presentation of objects (currently just a
/// color) to those objects (currently only to regions).
///
/// This data is made available through [`Layers`].
///
/// [`Layers`]: crate::layers::Layers
#[derive(Default)]
pub struct Presentation {
/// Color assigned to regions
///
/// Having a color is optional, so map does not necessarily contain
/// assignments for all existing regions.
pub color: BTreeMap<Handle<Region>, Color>,
}
2 changes: 1 addition & 1 deletion models/color/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub fn model(core: &mut fj::core::Core) -> Solid {
shell.faces().first(),
|face, core| {
[face.update_region(
|region, _| region.set_color([0., 1., 0.]),
|region, core| region.set_color([0., 1., 0.], core),
core,
)]
},
Expand Down

0 comments on commit f079566

Please sign in to comment.