tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 231Rust 9TOML 3CSS 1345 Sutichaykuna

⎇ devin/980-canonical-license benches/src/lib.rs Rust · 135 siq'ikuna · 4.6 KB Ñawpa willay Pi imata llamkarqan ch'uya

Upgrade rand and rand_chacha (bench deps) to 0.9 (#798) ff58be174 · Nico Burns ·

1// As each benchmark suite is compiled as a separate crate and uses different helpers, we end up with a bunch
2// of false positives for this lint. So let's just disable it for this code.
3#![allow(dead_code)]
4
5pub mod taffy_helpers;
6pub use taffy_helpers::TaffyTreeBuilder;
7
8#[cfg(feature = "taffy03")]
9pub mod taffy_03_helpers;
10
11#[cfg(feature = "yoga")]
12pub mod yoga_helpers;
13#[cfg(feature = "yoga")]
14pub use yoga_helpers::YogaTreeBuilder;
15
16use rand::distr::uniform::SampleRange;
17use rand::{Rng, SeedableRng};
18use rand_chacha::ChaCha8Rng;
19use taffy::style::Style as TaffyStyle;
20
21pub const STANDARD_RNG_SEED: u64 = 12345;
22
23pub trait GenStyle<Style: Default>: Clone {
24    fn create_leaf_style(&mut self, rng: &mut impl Rng) -> Style;
25    fn create_container_style(&mut self, rng: &mut impl Rng) -> Style;
26    fn create_root_style(&mut self, _rng: &mut impl Rng) -> Style {
27        Default::default()
28    }
29}
30
31#[derive(Clone)]
32pub struct FixedStyleGenerator(pub TaffyStyle);
33impl GenStyle<TaffyStyle> for FixedStyleGenerator {
34    fn create_leaf_style(&mut self, _rng: &mut impl Rng) -> TaffyStyle {
35        self.0.clone()
36    }
37    fn create_container_style(&mut self, _rng: &mut impl Rng) -> TaffyStyle {
38        self.0.clone()
39    }
40}
41
42pub trait BuildTree<R: Rng, G: GenStyle<TaffyStyle>> {
43    const NAME: &'static str;
44    type Tree;
45    type Node: Clone;
46
47    fn with_rng(rng: R, style_generator: G) -> Self;
48
49    fn compute_layout_inner(&mut self, available_width: Option<f32>, available_height: Option<f32>);
50    fn random_usize(&mut self, range: impl SampleRange<usize>) -> usize;
51    fn create_leaf_node(&mut self) -> Self::Node;
52    fn create_container_node(&mut self, children: &[Self::Node]) -> Self::Node;
53    fn set_root_children(&mut self, children: &[Self::Node]);
54    fn total_node_count(&mut self) -> usize;
55    fn into_tree_and_root(self) -> (Self::Tree, Self::Node);
56
57    fn build_n_leaf_nodes(&mut self, n: usize) -> Vec<Self::Node> {
58        (0..n).map(|_| self.create_leaf_node()).collect()
59    }
60
61    /// A helper function to recursively construct a deep tree
62    fn build_deep_tree(&mut self, max_nodes: u32, branching_factor: u32) -> Vec<Self::Node> {
63        if max_nodes <= branching_factor {
64            // Build leaf nodes
65            return (0..max_nodes).map(|_| self.create_leaf_node()).collect();
66        }
67
68        // Add another layer to the tree
69        // Each child gets an equal amount of the remaining nodes
70        (0..branching_factor)
71            .map(|_| {
72                let max_nodes = (max_nodes - branching_factor) / branching_factor;
73                let children = self.build_deep_tree(max_nodes, branching_factor);
74                self.create_container_node(&children)
75            })
76            .collect()
77    }
78}
79
80pub trait BuildTreeExt<G: GenStyle<TaffyStyle>>: BuildTree<ChaCha8Rng, G> {
81    fn with_seed(seed: u64, style_generator: G) -> Self
82    where
83        Self: Sized,
84    {
85        let rng = ChaCha8Rng::seed_from_u64(seed);
86        Self::with_rng(rng, style_generator)
87    }
88
89    fn new(style_generator: G) -> Self
90    where
91        Self: Sized,
92    {
93        Self::with_seed(STANDARD_RNG_SEED, style_generator)
94    }
95
96    /// A helper function to recursively construct a deep tree
97    fn build_super_deep_hierarchy(&mut self, depth: u32, nodes_per_level: u32) {
98        let mut children = Vec::with_capacity(nodes_per_level as usize);
99        for _ in 0..depth {
100            let node_with_children = self.create_container_node(&children);
101
102            children.clear();
103            children.push(node_with_children);
104            for _ in 0..(nodes_per_level - 1) {
105                children.push(self.create_leaf_node())
106            }
107        }
108        self.set_root_children(&children);
109    }
110
111    /// A tree with a higher depth for a more realistic scenario
112    fn build_deep_hierarchy(&mut self, node_count: u32, branching_factor: u32) {
113        let children = self.build_deep_tree(node_count, branching_factor);
114        self.set_root_children(&children);
115    }
116
117    /// A tree with many children that have shallow depth
118    fn build_flat_hierarchy(&mut self, target_node_count: u32) {
119        let mut children = Vec::new();
120
121        while self.total_node_count() < target_node_count as usize {
122            let count = self.random_usize(1..=4);
123            let sub_children = self.build_n_leaf_nodes(count);
124            let node = self.create_container_node(&sub_children);
125            children.push(node);
126        }
127
128        self.set_root_children(&children);
129    }
130
131    /// Compute layout given a viewport size
132    fn compute_layout(&mut self, available_width: Option<f32>, available_height: Option<f32>) {
133        self.compute_layout_inner(available_width, available_height);
134    }
135}