Skip to content

Commit

Permalink
Replace Number type with a simpler Option<f32> (#144)
Browse files Browse the repository at this point in the history
* Update RELEASES.md

* Implement extension traits for Option<f32>

* Replace usages of Number with Option<f32>

* Rename module from number.rs to math.rs

* Note removal of associated traits

* Make behavior of maybe_sub consistent

* Thanks clippy!

* dead_code XD

* Update math operations to be consistent with previous impl

* Reduce churn in PR

* Follow line length calculation spec correctly

* Fix undefined math logic for MaybeMath trait
  • Loading branch information
alice-i-cecile committed Jun 11, 2022
1 parent ab22fd7 commit b1ea679
Show file tree
Hide file tree
Showing 17 changed files with 310 additions and 436 deletions.
3 changes: 3 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

### 0.2.0 Changed

- removed the public `Number` type; a more idiomatic `Option<f32>` is used instead
- the associated public `MinMax` and `OrElse` traits have also been removed; these should never have been public
- `Sprawl::remove` now returns a `Result<usize, Error>`, to indicate if the operation was sucessful, and if it was, which ID was invalidated.
- renamed `taffy::forest::Forest.new-node(..)` `taffy::forest::Forest.new_with_children(..)`
- renamed `taffy::node::Taffy.new-node(..)` -> `taffy::node::Taffy.new_with_children(..)`
Expand All @@ -19,6 +21,7 @@

- fixed rounding of fractional values to follow latest Chrome - values are now rounded the same regardless of their position
- fixed computing free space when using both `flex-grow` and a minimum size
- padding is now only subtracted when determining the available space if the node size is unspecified, following [section 9.2.2 of the flexbox spec](https://www.w3.org/TR/css-flexbox-1/#line-sizing)

### 0.2.0 Removed

Expand Down
2 changes: 1 addition & 1 deletion examples/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ fn main() -> Result<(), taffy::error::InvalidNode> {
&[child],
)?;

taffy.compute_layout(node, Size { height: Number::Defined(100.0), width: Number::Defined(100.0) })?;
taffy.compute_layout(node, Size { height: Some(100.0), width: Some(100.0) })?;

// or just use undefined for 100 x 100
// taffy.compute_layout(node, Size::undefined())?;
Expand Down
2 changes: 1 addition & 1 deletion examples/nested.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ fn main() -> Result<(), taffy::error::InvalidNode> {
&[div1, div2],
)?;

taffy.compute_layout(container, Size { height: Number::Defined(100.0), width: Number::Defined(100.0) })?;
taffy.compute_layout(container, Size { height: Some(100.0), width: Some(100.0) })?;

println!("node: {:#?}", taffy.layout(container)?);

Expand Down
230 changes: 126 additions & 104 deletions src/flexbox.rs

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions src/forest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
use crate::geometry::Size;
use crate::layout::{Cache, Layout};
use crate::node::{MeasureFunc, NodeId};
use crate::number::Number;
use crate::style::FlexboxLayout;
use crate::sys::{new_vec_with_capacity, ChildrenVec, ParentsVec, Vec};

Expand All @@ -14,7 +13,7 @@ use crate::sys::{new_vec_with_capacity, ChildrenVec, ParentsVec, Vec};
pub(crate) struct NodeData {
/// The layout strategy used by this node
pub(crate) style: FlexboxLayout,
/// The mapping from the Size<Number> (in units) to Size<f32> (in points) for this node
/// The mapping from the Size<Option<f32>> (in real units) to Size<f32> (in points) for this node
pub(crate) measure: Option<MeasureFunc>,
/// The results of the layout computation
pub(crate) layout: Layout,
Expand Down Expand Up @@ -236,7 +235,7 @@ impl Forest {
}

/// Computes the layout of the `node` and its children
pub(crate) fn compute_layout(&mut self, node: NodeId, size: Size<Number>) {
pub(crate) fn compute_layout(&mut self, node: NodeId, size: Size<Option<f32>>) {
// TODO: It's not clear why this method is distinct
self.compute(node, size)
}
Expand Down
12 changes: 5 additions & 7 deletions src/geometry.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
//! Geometric primitives useful for layout

use core::ops::Add;

use crate::number::Number;
use crate::style::{Dimension, FlexDirection};
use core::ops::Add;

/// An axis-aligned UI rectangle
#[derive(Debug, Copy, Clone, PartialEq)]
Expand Down Expand Up @@ -162,10 +160,10 @@ pub struct Size<T> {
}

impl Size<()> {
/// Generates a `Size<Number>` with undefined width and height
/// Generates a `Size<Option<f32>>` with undefined width and height
#[must_use]
pub fn undefined() -> Size<Number> {
Size { width: Number::Undefined, height: Number::Undefined }
pub fn undefined() -> Size<Option<f32>> {
Size { width: None, height: None }
}
}

Expand Down Expand Up @@ -235,7 +233,7 @@ impl Size<f32> {

impl Size<Dimension> {
/// Converts any `parent`-relative values for size into an absolute size
pub(crate) fn resolve(&self, parent: Size<Number>) -> Size<Number> {
pub(crate) fn resolve(&self, parent: Size<Option<f32>>) -> Size<Option<f32>> {
Size { width: self.width.resolve(parent.width), height: self.height.resolve(parent.height) }
}
}
Expand Down
5 changes: 2 additions & 3 deletions src/layout.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Final and cached data structures that represent the high-level UI layout

use crate::geometry::{Point, Size};
use crate::number::Number;

/// The final result of a layout algorithm for a single [`Node`](crate::node::Node).
#[derive(Copy, Debug, Clone)]
Expand Down Expand Up @@ -29,9 +28,9 @@ impl Layout {
#[derive(Debug, Clone)]
pub(crate) struct Cache {
/// The initial cached size of the node itself
pub(crate) node_size: Size<Number>,
pub(crate) node_size: Size<Option<f32>>,
/// The initial cached size of the parent's node
pub(crate) parent_size: Size<Number>,
pub(crate) parent_size: Size<Option<f32>>,
/// Whether or not layout should be recomputed
pub(crate) perform_layout: bool,

Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ extern crate serde;
pub mod error;
pub mod geometry;
pub mod layout;
pub mod math;
pub mod node;
pub mod number;
pub mod prelude;
pub mod style;

Expand Down
123 changes: 123 additions & 0 deletions src/math.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
//! Contains numberical helper traits and functions

/// A trait to conveniently calculate minimums and maximums when some data may not be defined
///
/// If the left-hand value is [`None`], these operations return [`None`].
/// If the right-hand value is [`None`], it is treated as zero.
pub(crate) trait MaybeMath<In, Out> {
/// Returns the minimum of `self` and `rhs`
fn maybe_min(self, rhs: In) -> Out;

/// Returns the maximum of `self` and `rhs`
fn maybe_max(self, rhs: In) -> Out;

/// Adds `self` and `rhs`.
fn maybe_add(self, rhs: In) -> Out;

/// Subracts rhs from `self`, treating [`None`] values as default
fn maybe_sub(self, rhs: In) -> Out;
}

impl MaybeMath<Option<f32>, Option<f32>> for Option<f32> {
fn maybe_min(self, rhs: Option<f32>) -> Option<f32> {
match (self, rhs) {
(Some(l), Some(r)) => Some(l.min(r)),
(Some(_l), None) => self,
(None, Some(_r)) => None,
(None, None) => None,
}
}

fn maybe_max(self, rhs: Option<f32>) -> Option<f32> {
match (self, rhs) {
(Some(l), Some(r)) => Some(l.max(r)),
(Some(_l), None) => self,
(None, Some(_r)) => None,
(None, None) => None,
}
}

fn maybe_add(self, rhs: Option<f32>) -> Option<f32> {
match (self, rhs) {
(Some(l), Some(r)) => Some(l + r),
(Some(_l), None) => self,
(None, Some(_r)) => None,
(None, None) => None,
}
}

fn maybe_sub(self, rhs: Option<f32>) -> Option<f32> {
match (self, rhs) {
(Some(l), Some(r)) => Some(l - r),
(Some(_l), None) => self,
(None, Some(_r)) => None,
(None, None) => None,
}
}
}

impl MaybeMath<f32, Option<f32>> for Option<f32> {
// The logic here is subtle and critical;
// explicit match statements make it more clear what's going on
#[allow(clippy::manual_map)]
fn maybe_min(self, rhs: f32) -> Option<f32> {
match self {
Some(val) => Some(val.min(rhs)),
None => None,
}
}

#[allow(clippy::manual_map)]
fn maybe_max(self, rhs: f32) -> Option<f32> {
match self {
Some(val) => Some(val.max(rhs)),
None => None,
}
}

#[allow(clippy::manual_map)]
fn maybe_add(self, rhs: f32) -> Option<f32> {
match self {
Some(val) => Some(val + rhs),
None => None,
}
}

#[allow(clippy::manual_map)]
fn maybe_sub(self, rhs: f32) -> Option<f32> {
match self {
Some(val) => Some(val - rhs),
None => None,
}
}
}

impl MaybeMath<Option<f32>, f32> for f32 {
fn maybe_min(self, rhs: Option<f32>) -> f32 {
match rhs {
Some(val) => self.min(val),
None => self,
}
}

fn maybe_max(self, rhs: Option<f32>) -> f32 {
match rhs {
Some(val) => self.max(val),
None => self,
}
}

fn maybe_add(self, rhs: Option<f32>) -> f32 {
match rhs {
Some(val) => self + val,
None => self,
}
}

fn maybe_sub(self, rhs: Option<f32>) -> f32 {
match rhs {
Some(val) => self - val,
None => self,
}
}
}
9 changes: 4 additions & 5 deletions src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@ use crate::error;
use crate::forest::Forest;
use crate::geometry::Size;
use crate::layout::Layout;
use crate::number::Number;
use crate::style::FlexboxLayout;
#[cfg(any(feature = "std", feature = "alloc"))]
use crate::sys::Box;
use crate::sys::{new_map_with_capacity, ChildrenVec, Map, Vec};
use core::sync::atomic::{AtomicUsize, Ordering};

/// A function that can be applied to a `Size<Number>` to obtain a `Size<f32>`
/// A function that can be applied to a `Size<Option<f32>>` to obtain a `Size<f32>`
pub enum MeasureFunc {
/// Stores an unboxed function
Raw(fn(Size<Number>) -> Size<f32>),
Raw(fn(Size<Option<f32>>) -> Size<f32>),
/// Stores a boxed function
#[cfg(any(feature = "std", feature = "alloc"))]
Boxed(Box<dyn Fn(Size<Number>) -> Size<f32>>),
Boxed(Box<dyn Fn(Size<Option<f32>>) -> Size<f32>>),
}

/// Global taffy instance id allocator.
Expand Down Expand Up @@ -288,7 +287,7 @@ impl Taffy {
}

/// Updates the stored layout of the provided `node` and its children
pub fn compute_layout(&mut self, node: Node, size: Size<Number>) -> Result<(), error::InvalidNode> {
pub fn compute_layout(&mut self, node: Node, size: Size<Option<f32>>) -> Result<(), error::InvalidNode> {
let id = self.find_node(node)?;
self.forest.compute_layout(id, size);
Ok(())
Expand Down
Loading

0 comments on commit b1ea679

Please sign in to comment.