Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Number type with a simpler Option<f32> #144

Merged
merged 14 commits into from
Jun 11, 2022
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
110 changes: 110 additions & 0 deletions src/math.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
//! 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> {
fn maybe_min(self, rhs: f32) -> Option<f32> {
self.map(|val| val.min(rhs))
}

fn maybe_max(self, rhs: f32) -> Option<f32> {
self.map(|val| val.max(rhs))
}

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

fn maybe_sub(self, rhs: f32) -> Option<f32> {
match self {
Some(val) => Some(val - rhs),
None => Some(-rhs),
}
}
}
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,
}
}
alice-i-cecile marked this conversation as resolved.
Show resolved Hide resolved

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