diff --git a/Cargo.toml b/Cargo.toml index 97a7e4ee0..d6eba92a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -66,7 +66,7 @@ accesskit_winit = "0.22.0" shipyard = { version = "0.6.2", features = ["proc", "std", "parallel"], default-features = false } smallvec = "1.13.1" -euclid = "0.22.9" +euclid = { version = "0.22.9", default-features = false, features = ["libm"]} uuid = { version = "1.4.1", features = ["v4"]} futures-util = "0.3.30" futures-task = "0.3.30" diff --git a/crates/common/src/layout.rs b/crates/common/src/layout.rs index 449d5cfa8..a75073cfb 100644 --- a/crates/common/src/layout.rs +++ b/crates/common/src/layout.rs @@ -1,9 +1,19 @@ -use std::ops::Div; +use std::{ + ops::{ + Deref, + Div, + }, + sync::Arc, +}; use freya_engine::prelude::Paragraph; -use torin::geometry::{ - Area, - Size2D, +use freya_native_core::SendAnyMap; +use torin::{ + geometry::{ + Area, + Size2D, + }, + prelude::NodeData, }; /// Layout info of a certain Node, used by `use_node`. @@ -36,3 +46,16 @@ pub struct CachedParagraph(pub Paragraph, pub f32); /// In the main thread when measuring the layout and painting. unsafe impl Send for CachedParagraph {} unsafe impl Sync for CachedParagraph {} + +#[derive(Clone)] +pub struct LayoutNodeData(pub Arc); + +impl Deref for LayoutNodeData { + type Target = Arc; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl NodeData for LayoutNodeData {} diff --git a/crates/core/src/accessibility/tree.rs b/crates/core/src/accessibility/tree.rs index 1c2f424f4..500149cc1 100644 --- a/crates/core/src/accessibility/tree.rs +++ b/crates/core/src/accessibility/tree.rs @@ -15,7 +15,10 @@ use accesskit::{ Tree, TreeUpdate, }; -use freya_common::AccessibilityDirtyNodes; +use freya_common::{ + AccessibilityDirtyNodes, + LayoutNodeData, +}; use freya_engine::prelude::{ Color, Slant, @@ -81,7 +84,7 @@ impl AccessibilityTree { pub fn init( &self, rdom: &DioxusDOM, - layout: &Torin, + layout: &Torin, dirty_nodes: &mut AccessibilityDirtyNodes, ) -> TreeUpdate { dirty_nodes.clear(); @@ -130,7 +133,7 @@ impl AccessibilityTree { pub fn process_updates( &mut self, rdom: &DioxusDOM, - layout: &Torin, + layout: &Torin, dirty_nodes: &mut AccessibilityDirtyNodes, ) -> (TreeUpdate, NodeId) { let requested_focus_id = dirty_nodes.requested_focus.take(); @@ -326,7 +329,7 @@ impl AccessibilityTree { /// Create an accessibility node pub fn create_node( node_ref: &DioxusNode, - layout_node: &LayoutNode, + layout_node: &LayoutNode, node_accessibility: &AccessibilityNodeState, ) -> Node { let font_style_state = &*node_ref.get::().unwrap(); diff --git a/crates/core/src/dom/doms.rs b/crates/core/src/dom/doms.rs index c1e597046..05dd2b96a 100644 --- a/crates/core/src/dom/doms.rs +++ b/crates/core/src/dom/doms.rs @@ -10,6 +10,7 @@ use freya_common::{ AccessibilityGenerator, CompositorDirtyNodes, Layers, + LayoutNodeData, ParagraphElements, }; use freya_native_core::{ @@ -122,7 +123,7 @@ impl SafeDOM { pub struct FreyaDOM { rdom: DioxusDOM, dioxus_integration_state: DioxusState, - torin: Arc>>, + torin: Arc>>, paragraphs: Arc>, layers: Arc>, compositor_dirty_nodes: Arc>, @@ -162,7 +163,7 @@ impl Default for FreyaDOM { } impl FreyaDOM { - pub fn layout(&self) -> MutexGuard> { + pub fn layout(&self) -> MutexGuard> { self.torin.lock().unwrap() } diff --git a/crates/core/src/dom/mutations_writer.rs b/crates/core/src/dom/mutations_writer.rs index e682fb1ce..b9d383731 100644 --- a/crates/core/src/dom/mutations_writer.rs +++ b/crates/core/src/dom/mutations_writer.rs @@ -6,6 +6,7 @@ use freya_common::{ AccessibilityDirtyNodes, CompositorDirtyNodes, Layers, + LayoutNodeData, ParagraphElements, }; use freya_native_core::{ @@ -36,7 +37,7 @@ use crate::prelude::{ pub struct MutationsWriter<'a> { pub native_writer: DioxusNativeCoreMutationWriter<'a, CustomAttributeValues>, - pub layout: &'a mut Torin, + pub layout: &'a mut Torin, pub layers: &'a mut Layers, pub paragraphs: &'a mut ParagraphElements, pub scale_factor: f32, diff --git a/crates/core/src/elements/image.rs b/crates/core/src/elements/image.rs index bbc49c111..4d74c3ecc 100644 --- a/crates/core/src/elements/image.rs +++ b/crates/core/src/elements/image.rs @@ -1,3 +1,4 @@ +use freya_common::LayoutNodeData; use freya_engine::prelude::*; use freya_native_core::real_dom::NodeImmutable; use freya_node_state::{ @@ -13,7 +14,7 @@ pub struct ImageElement; impl ElementUtils for ImageElement { fn render( self, - layout_node: &torin::prelude::LayoutNode, + layout_node: &torin::prelude::LayoutNode, node_ref: &DioxusNode, canvas: &Canvas, _font_collection: &mut FontCollection, diff --git a/crates/core/src/elements/label.rs b/crates/core/src/elements/label.rs index 186cf107d..025055f07 100644 --- a/crates/core/src/elements/label.rs +++ b/crates/core/src/elements/label.rs @@ -1,4 +1,7 @@ -use freya_common::CachedParagraph; +use freya_common::{ + CachedParagraph, + LayoutNodeData, +}; use freya_engine::prelude::*; use freya_native_core::prelude::NodeImmutable; use freya_node_state::FontStyleState; @@ -21,7 +24,7 @@ pub struct LabelElement; impl ElementUtils for LabelElement { fn render( self, - layout_node: &torin::prelude::LayoutNode, + layout_node: &torin::prelude::LayoutNode, node_ref: &DioxusNode, canvas: &Canvas, _font_collection: &mut FontCollection, @@ -53,7 +56,7 @@ impl ElementUtils for LabelElement { fn element_drawing_area( &self, - layout_node: &LayoutNode, + layout_node: &LayoutNode, node_ref: &DioxusNode, scale_factor: f32, ) -> Area { diff --git a/crates/core/src/elements/paragraph.rs b/crates/core/src/elements/paragraph.rs index a637dad03..c37773671 100644 --- a/crates/core/src/elements/paragraph.rs +++ b/crates/core/src/elements/paragraph.rs @@ -3,6 +3,7 @@ use std::ops::Mul; use freya_common::{ CachedParagraph, CursorLayoutResponse, + LayoutNodeData, }; use freya_engine::prelude::*; use freya_native_core::{ @@ -47,7 +48,7 @@ impl ParagraphElement { /// Merasure the cursor positio and text selection and notify the subscribed component of the element. pub fn measure_paragraph( node: &DioxusNode, - layout_node: &LayoutNode, + layout_node: &LayoutNode, text_measurement: &TextGroupMeasurement, scale_factor: f64, ) { @@ -115,7 +116,7 @@ impl ParagraphElement { impl ElementUtils for ParagraphElement { fn render( self, - layout_node: &torin::prelude::LayoutNode, + layout_node: &torin::prelude::LayoutNode, node_ref: &DioxusNode, canvas: &Canvas, font_collection: &mut FontCollection, @@ -180,7 +181,7 @@ impl ElementUtils for ParagraphElement { fn element_drawing_area( &self, - layout_node: &LayoutNode, + layout_node: &LayoutNode, node_ref: &DioxusNode, scale_factor: f32, ) -> Area { diff --git a/crates/core/src/elements/rect.rs b/crates/core/src/elements/rect.rs index b033ee415..597126e57 100644 --- a/crates/core/src/elements/rect.rs +++ b/crates/core/src/elements/rect.rs @@ -1,3 +1,4 @@ +use freya_common::LayoutNodeData; use freya_engine::prelude::*; use freya_native_core::real_dom::NodeImmutable; use freya_node_state::{ @@ -34,7 +35,7 @@ pub struct RectElement; impl RectElement { fn get_rounded_rect( &self, - layout_node: &LayoutNode, + layout_node: &LayoutNode, node_ref: &DioxusNode, scale_factor: f32, ) -> RRect { @@ -60,7 +61,7 @@ impl ElementUtils for RectElement { &self, point: &CursorPoint, node_ref: &DioxusNode, - layout_node: &LayoutNode, + layout_node: &LayoutNode, scale_factor: f32, ) -> bool { let rounded_rect = self.get_rounded_rect(layout_node, node_ref, scale_factor); @@ -70,7 +71,7 @@ impl ElementUtils for RectElement { fn clip( &self, - layout_node: &LayoutNode, + layout_node: &LayoutNode, node_ref: &DioxusNode, canvas: &Canvas, scale_factor: f32, @@ -82,7 +83,7 @@ impl ElementUtils for RectElement { fn render( self, - layout_node: &LayoutNode, + layout_node: &LayoutNode, node_ref: &DioxusNode, canvas: &Canvas, font_collection: &mut FontCollection, @@ -172,7 +173,7 @@ impl ElementUtils for RectElement { fn element_drawing_area( &self, - layout_node: &LayoutNode, + layout_node: &LayoutNode, node_ref: &DioxusNode, scale_factor: f32, ) -> Area { diff --git a/crates/core/src/elements/svg.rs b/crates/core/src/elements/svg.rs index 8d6b1c5d7..5578bef46 100644 --- a/crates/core/src/elements/svg.rs +++ b/crates/core/src/elements/svg.rs @@ -1,3 +1,4 @@ +use freya_common::LayoutNodeData; use freya_engine::prelude::*; use freya_native_core::real_dom::NodeImmutable; use freya_node_state::{ @@ -14,7 +15,7 @@ pub struct SvgElement; impl ElementUtils for SvgElement { fn render( self, - layout_node: &LayoutNode, + layout_node: &LayoutNode, node_ref: &DioxusNode, canvas: &Canvas, _font_collection: &mut FontCollection, diff --git a/crates/core/src/elements/utils.rs b/crates/core/src/elements/utils.rs index 1848223fb..ac9be670a 100644 --- a/crates/core/src/elements/utils.rs +++ b/crates/core/src/elements/utils.rs @@ -1,3 +1,4 @@ +use freya_common::LayoutNodeData; use freya_engine::prelude::{ Canvas, FontCollection, @@ -30,7 +31,7 @@ pub trait ElementUtils { &self, point: &CursorPoint, _node_ref: &DioxusNode, - layout_node: &LayoutNode, + layout_node: &LayoutNode, _scale_factor: f32, ) -> bool { layout_node.area.contains(point.to_f32()) @@ -38,7 +39,7 @@ pub trait ElementUtils { fn clip( &self, - _layout_node: &LayoutNode, + _layout_node: &LayoutNode, _node_ref: &DioxusNode, _canvas: &Canvas, _scale_factor: f32, @@ -48,7 +49,7 @@ pub trait ElementUtils { #[allow(clippy::too_many_arguments)] fn render( self, - layout_node: &LayoutNode, + layout_node: &LayoutNode, node_ref: &DioxusNode, canvas: &Canvas, font_collection: &mut FontCollection, @@ -59,7 +60,7 @@ pub trait ElementUtils { fn element_drawing_area( &self, - layout_node: &LayoutNode, + layout_node: &LayoutNode, _node_ref: &DioxusNode, _scale_factor: f32, ) -> Area { @@ -69,9 +70,9 @@ pub trait ElementUtils { fn drawing_area_with_viewports( &self, - layout_node: &LayoutNode, + layout_node: &LayoutNode, node_ref: &DioxusNode, - layout: &Torin, + layout: &Torin, scale_factor: f32, ) -> Option { let mut drawing_area = self.drawing_area(layout_node, node_ref, scale_factor); @@ -93,7 +94,7 @@ pub trait ElementUtils { /// factors like shadows or borders, which are not part of the layout. fn drawing_area( &self, - layout_node: &LayoutNode, + layout_node: &LayoutNode, node_ref: &DioxusNode, scale_factor: f32, ) -> Area { @@ -157,7 +158,7 @@ pub enum ElementWithUtils { impl ElementUtils for ElementWithUtils { fn clip( &self, - layout_node: &LayoutNode, + layout_node: &LayoutNode, node_ref: &DioxusNode, canvas: &Canvas, scale_factor: f32, @@ -175,7 +176,7 @@ impl ElementUtils for ElementWithUtils { &self, point: &CursorPoint, node_ref: &DioxusNode, - layout_node: &LayoutNode, + layout_node: &LayoutNode, scale_factor: f32, ) -> bool { match self { @@ -191,7 +192,7 @@ impl ElementUtils for ElementWithUtils { fn render( self, - layout_node: &LayoutNode, + layout_node: &LayoutNode, node_ref: &DioxusNode, canvas: &Canvas, font_collection: &mut FontCollection, @@ -250,7 +251,7 @@ impl ElementUtils for ElementWithUtils { fn drawing_area( &self, - layout_node: &LayoutNode, + layout_node: &LayoutNode, node_ref: &DioxusNode, scale_factor: f32, ) -> Area { diff --git a/crates/core/src/plugins.rs b/crates/core/src/plugins.rs index b5c36898d..89587dcc6 100644 --- a/crates/core/src/plugins.rs +++ b/crates/core/src/plugins.rs @@ -1,3 +1,4 @@ +use freya_common::LayoutNodeData; use freya_engine::prelude::{ Canvas, FontCollection, @@ -80,10 +81,10 @@ pub enum PluginEvent<'a> { }, /// Before starting to measure the layout. - StartedLayout(&'a Torin), + StartedLayout(&'a Torin), /// After measuring the layout. - FinishedLayout(&'a Torin), + FinishedLayout(&'a Torin), StartedUpdatingDOM, diff --git a/crates/core/src/render/compositor.rs b/crates/core/src/render/compositor.rs index a94535baf..256d76685 100644 --- a/crates/core/src/render/compositor.rs +++ b/crates/core/src/render/compositor.rs @@ -6,6 +6,7 @@ use std::ops::{ use freya_common::{ CompositorDirtyNodes, Layers, + LayoutNodeData, }; use freya_native_core::{ prelude::NodeImmutable, @@ -109,7 +110,7 @@ impl Compositor { #[inline] pub fn get_drawing_area( node_id: NodeId, - layout: &Torin, + layout: &Torin, rdom: &DioxusDOM, scale_factor: f32, ) -> Option { @@ -123,9 +124,9 @@ impl Compositor { #[inline] pub fn with_utils( node_id: NodeId, - layout: &Torin, + layout: &Torin, rdom: &DioxusDOM, - run: impl FnOnce(DioxusNode, ElementWithUtils, &LayoutNode) -> T, + run: impl FnOnce(DioxusNode, ElementWithUtils, &LayoutNode) -> T, ) -> Option { let layout_node = layout.get(node_id)?; let node = rdom.get(node_id)?; @@ -149,7 +150,7 @@ impl Compositor { cache: &mut CompositorCache, layers: &'a Layers, dirty_layers: &'a mut Layers, - layout: &Torin, + layout: &Torin, rdom: &DioxusDOM, scale_factor: f32, ) -> &'a Layers { diff --git a/crates/core/src/render/pipeline.rs b/crates/core/src/render/pipeline.rs index a477aaabb..007088c21 100644 --- a/crates/core/src/render/pipeline.rs +++ b/crates/core/src/render/pipeline.rs @@ -1,6 +1,7 @@ use freya_common::{ CompositorDirtyNodes, Layers, + LayoutNodeData, }; use freya_engine::prelude::{ ClipOp, @@ -54,7 +55,7 @@ use crate::{ pub struct RenderPipeline<'a> { pub rdom: &'a DioxusDOM, pub layers: &'a Layers, - pub layout: &'a Torin, + pub layout: &'a Torin, pub compositor_dirty_nodes: &'a mut CompositorDirtyNodes, pub compositor_dirty_area: &'a mut CompositorDirtyArea, pub compositor_cache: &'a mut CompositorCache, @@ -188,7 +189,7 @@ impl RenderPipeline<'_> { pub fn render( &mut self, node_ref: DioxusNode, - layout_node: &LayoutNode, + layout_node: &LayoutNode, render_wireframe: bool, ) { let dirty_canvas = self.dirty_surface.canvas(); diff --git a/crates/core/src/render/skia_measurer.rs b/crates/core/src/render/skia_measurer.rs index 7dba7df4f..3b5192d90 100644 --- a/crates/core/src/render/skia_measurer.rs +++ b/crates/core/src/render/skia_measurer.rs @@ -2,6 +2,7 @@ use std::sync::Arc; use freya_common::{ CachedParagraph, + LayoutNodeData, NodeReferenceLayout, }; use freya_engine::prelude::*; @@ -13,13 +14,13 @@ use freya_native_core::{ real_dom::NodeImmutable, tags::TagName, NodeId, + SendAnyMap, }; use freya_node_state::LayoutState; use torin::prelude::{ Area, LayoutMeasurer, Node, - SendAnyMap, Size2D, }; @@ -56,13 +57,13 @@ impl<'a> SkiaMeasurer<'a> { } } -impl<'a> LayoutMeasurer for SkiaMeasurer<'a> { +impl<'a> LayoutMeasurer for SkiaMeasurer<'a> { fn measure( &mut self, node_id: NodeId, _node: &Node, area_size: &Size2D, - ) -> Option<(Size2D, Arc)> { + ) -> Option<(Size2D, LayoutNodeData)> { let node = self.rdom.get(node_id).unwrap(); let node_type = node.node_type(); @@ -77,7 +78,7 @@ impl<'a> LayoutMeasurer for SkiaMeasurer<'a> { ); let mut map = SendAnyMap::new(); map.insert(CachedParagraph(paragraph, size.height)); - Some((size, Arc::new(map))) + Some((size, LayoutNodeData(Arc::new(map)))) } NodeType::Element(ElementNode { tag, .. }) if tag == &TagName::Paragraph => { let ParagraphData { paragraph, size } = create_paragraph( @@ -90,7 +91,7 @@ impl<'a> LayoutMeasurer for SkiaMeasurer<'a> { ); let mut map = SendAnyMap::new(); map.insert(CachedParagraph(paragraph, size.height)); - Some((size, Arc::new(map))) + Some((size, LayoutNodeData(Arc::new(map)))) } _ => None, } diff --git a/crates/renderer/src/accessibility.rs b/crates/renderer/src/accessibility.rs index 644b4c26e..0e474a7b7 100644 --- a/crates/renderer/src/accessibility.rs +++ b/crates/renderer/src/accessibility.rs @@ -4,7 +4,10 @@ use std::sync::{ }; use accesskit_winit::Adapter; -use freya_common::AccessibilityDirtyNodes; +use freya_common::{ + AccessibilityDirtyNodes, + LayoutNodeData, +}; use freya_core::{ dom::DioxusDOM, prelude::{ @@ -63,7 +66,7 @@ impl AccessKitManager { pub fn init_accessibility( &mut self, rdom: &DioxusDOM, - layout: &Torin, + layout: &Torin, dirty_nodes: &mut AccessibilityDirtyNodes, ) { let tree = self @@ -81,7 +84,7 @@ impl AccessKitManager { pub fn process_updates( &mut self, rdom: &DioxusDOM, - layout: &Torin, + layout: &Torin, platform_sender: &NativePlatformSender, window: &Window, dirty_nodes: &mut AccessibilityDirtyNodes, @@ -113,7 +116,7 @@ impl AccessKitManager { direction: AccessibilityFocusStrategy, platform_sender: &NativePlatformSender, window: &Window, - layout: &Torin, + layout: &Torin, ) { let (tree, node_id) = self .accessibility_tree @@ -141,7 +144,7 @@ impl AccessKitManager { id: AccessibilityId, platform_sender: &NativePlatformSender, window: &Window, - layout: &Torin, + layout: &Torin, ) { let res = self .accessibility_tree @@ -166,7 +169,12 @@ impl AccessKitManager { } /// Update the Window IME Position with the bounds of the currently focused accessibility node - fn update_ime_position(&self, node_id: NodeId, window: &Window, layout: &Torin) { + fn update_ime_position( + &self, + node_id: NodeId, + window: &Window, + layout: &Torin, + ) { let layout_node = layout.get(node_id); if let Some(layout_node) = layout_node { let area = layout_node.visible_area(); diff --git a/crates/renderer/src/devtools.rs b/crates/renderer/src/devtools.rs index 23c8f5641..945357256 100644 --- a/crates/renderer/src/devtools.rs +++ b/crates/renderer/src/devtools.rs @@ -1,3 +1,4 @@ +use freya_common::LayoutNodeData; use freya_core::prelude::{ get_node_state, FreyaDOM, @@ -81,5 +82,5 @@ pub struct NodeInfo { pub tag: TagName, pub height: u16, pub state: NodeState, - pub layout_node: LayoutNode, + pub layout_node: LayoutNode, } diff --git a/crates/state/src/font_style.rs b/crates/state/src/font_style.rs index 18c033488..8b54a967b 100644 --- a/crates/state/src/font_style.rs +++ b/crates/state/src/font_style.rs @@ -3,7 +3,10 @@ use std::sync::{ Mutex, }; -use freya_common::CompositorDirtyNodes; +use freya_common::{ + CompositorDirtyNodes, + LayoutNodeData, +}; use freya_engine::prelude::*; use freya_native_core::{ attributes::AttributeName, @@ -300,7 +303,9 @@ impl State for FontStyleState { context: &SendAnyMap, ) -> bool { let root_id = context.get::().unwrap(); - let torin_layout = context.get::>>>().unwrap(); + let torin_layout = context + .get::>>>() + .unwrap(); let compositor_dirty_nodes = context.get::>>().unwrap(); let mut font_style = parent.map(|(v,)| v.clone()).unwrap_or_default(); diff --git a/crates/state/src/layout.rs b/crates/state/src/layout.rs index 753123534..28d06c083 100644 --- a/crates/state/src/layout.rs +++ b/crates/state/src/layout.rs @@ -3,7 +3,10 @@ use std::sync::{ Mutex, }; -use freya_common::CompositorDirtyNodes; +use freya_common::{ + CompositorDirtyNodes, + LayoutNodeData, +}; use freya_native_core::{ attributes::AttributeName, exports::shipyard::Component, @@ -222,7 +225,9 @@ impl State for LayoutState { context: &SendAnyMap, ) -> bool { let root_id = context.get::().unwrap(); - let torin_layout = context.get::>>>().unwrap(); + let torin_layout = context + .get::>>>() + .unwrap(); let compositor_dirty_nodes = context.get::>>().unwrap(); let mut layout = LayoutState { diff --git a/crates/testing/src/test_node.rs b/crates/testing/src/test_node.rs index 70eb4e292..2c49fd892 100644 --- a/crates/testing/src/test_node.rs +++ b/crates/testing/src/test_node.rs @@ -1,3 +1,4 @@ +use freya_common::LayoutNodeData; use freya_core::node::NodeState; use freya_native_core::{ node::NodeType, @@ -53,7 +54,7 @@ impl TestNode { } /// Get the Node layout - pub fn layout(&self) -> Option { + pub fn layout(&self) -> Option> { self.utils() .sdom() .get() diff --git a/crates/torin/Cargo.toml b/crates/torin/Cargo.toml index e61a9b972..c5a8ed630 100644 --- a/crates/torin/Cargo.toml +++ b/crates/torin/Cargo.toml @@ -12,14 +12,17 @@ keywords = ["gui", "ui", "desktop", "skia", "dioxus"] categories = ["gui", "caching"] [features] +std = ["euclid/std", "dep:tracing", "dep:rustc-hash"] +no_std = ["dep:hashbrown"] dioxus = ["dep:freya-native-core"] -default = ["dioxus"] +default = ["dioxus", "std"] [dependencies] -tracing = { workspace = true } +tracing = { workspace = true, optional = true } euclid = { workspace = true } -rustc-hash = { workspace = true } +rustc-hash = { workspace = true, optional = true } freya-native-core = { workspace = true, optional = true } +hashbrown = { version = "0.15.2", optional = true } [dev-dependencies] criterion = "0.5.1" diff --git a/crates/torin/benches/bench.rs b/crates/torin/benches/bench.rs index 399af25f7..b7f422535 100644 --- a/crates/torin/benches/bench.rs +++ b/crates/torin/benches/bench.rs @@ -11,23 +11,6 @@ use criterion::{ }; use torin::prelude::*; -struct TestingMeasurer; - -impl LayoutMeasurer for TestingMeasurer { - fn measure( - &mut self, - _node_id: usize, - _node: &Node, - _size: &Size2D, - ) -> Option<(Size2D, Arc)> { - None - } - - fn should_measure_inner_children(&mut self, _node_id: usize) -> bool { - true - } -} - #[derive(Default)] struct TestingDOM { mapper: HashMap, Vec, u16, Node)>, @@ -272,7 +255,6 @@ fn criterion_benchmark(c: &mut Criterion) { let root_area = Rect::new(Point2D::new(0.0, 0.0), Size2D::new(1000.0, 1000.0)); b.iter_batched( || { - let mut measurer = Some(TestingMeasurer); let mut mocked_dom = TestingDOM::default(); mocked_dom.add( @@ -340,11 +322,11 @@ fn criterion_benchmark(c: &mut Criterion) { &mut invalidate_node, ); - let mut layout = Torin::::new(); + let mut layout = Torin::::new(); if mode == BenchmarkMode::InvalidatedCache { layout.find_best_root(&mut mocked_dom); - layout.measure(0, root_area, &mut measurer, &mut mocked_dom); + layout.measure(0, root_area, &mut None::, &mut mocked_dom); mocked_dom.set_node( invalidate_node, Node::from_size_and_direction( @@ -356,11 +338,11 @@ fn criterion_benchmark(c: &mut Criterion) { layout.invalidate(invalidate_node); } - (mocked_dom, measurer, layout) + (mocked_dom, layout) }, - |(mut mocked_dom, mut measurer, mut layout)| { + |(mut mocked_dom, mut layout)| { layout.find_best_root(&mut mocked_dom); - layout.measure(0, root_area, &mut measurer, &mut mocked_dom) + layout.measure(0, root_area, &mut None::, &mut mocked_dom) }, criterion::BatchSize::SmallInput, ) diff --git a/crates/torin/examples/demo.rs b/crates/torin/examples/demo.rs index f19854848..b8f0c4ef1 100644 --- a/crates/torin/examples/demo.rs +++ b/crates/torin/examples/demo.rs @@ -89,7 +89,7 @@ impl DOMAdapter for DemoDOM { } fn main() { - let mut layout = Torin::::new(); + let mut layout = Torin::::new(); let mut demo_dom = DemoDOM::default(); diff --git a/crates/torin/src/custom_measurer.rs b/crates/torin/src/custom_measurer.rs index 445078f12..4deea1657 100644 --- a/crates/torin/src/custom_measurer.rs +++ b/crates/torin/src/custom_measurer.rs @@ -1,4 +1,14 @@ -use std::sync::Arc; +use core::{ + cmp::Eq, + default::Default, + option::{ + Option, + Option::{ + None, + Some, + }, + }, +}; use crate::{ dom_adapter::NodeKey, @@ -6,17 +16,12 @@ use crate::{ node::Node, prelude::{ Area, - SendAnyMap, + NodeData, }, }; -pub trait LayoutMeasurer { - fn measure( - &mut self, - node_id: Key, - node: &Node, - size: &Size2D, - ) -> Option<(Size2D, Arc)>; +pub trait LayoutMeasurer { + fn measure(&mut self, node_id: Key, node: &Node, size: &Size2D) -> Option<(Size2D, Data)>; fn should_measure_inner_children(&mut self, node_id: Key) -> bool; @@ -26,13 +31,8 @@ pub trait LayoutMeasurer { // No-op measurer, use it when you don't need one. pub struct NoopMeasurer; -impl LayoutMeasurer for NoopMeasurer { - fn measure( - &mut self, - _node_id: usize, - _node: &Node, - _size: &Size2D, - ) -> Option<(Size2D, Arc)> { +impl LayoutMeasurer for NoopMeasurer { + fn measure(&mut self, _node_id: usize, _node: &Node, _size: &Size2D) -> Option<(Size2D, ())> { None } diff --git a/crates/torin/src/dom_adapter.rs b/crates/torin/src/dom_adapter.rs index 9810f5312..6c0587006 100644 --- a/crates/torin/src/dom_adapter.rs +++ b/crates/torin/src/dom_adapter.rs @@ -1,4 +1,22 @@ -use std::sync::Arc; +use core::{ + clone::Clone, + cmp::{ + Eq, + PartialEq, + }, + default::Default, + marker::{ + Copy, + Sized, + }, + option::{ + Option, + Option::{ + None, + Some, + }, + }, +}; pub use euclid::Rect; @@ -8,13 +26,14 @@ use crate::{ prelude::{ AreaModel, Gaps, - SendAnyMap, }, }; +extern crate alloc; +use alloc::vec::Vec; /// Cached layout results of a Node #[derive(Debug, Default, Clone)] -pub struct LayoutNode { +pub struct LayoutNode { /// Area that ocuppies this node pub area: Area, @@ -25,10 +44,10 @@ pub struct LayoutNode { pub margin: Gaps, /// Associated data - pub data: Option>, + pub data: Option, } -impl PartialEq for LayoutNode { +impl PartialEq for LayoutNode { fn eq(&self, other: &Self) -> bool { self.area == other.area && self.inner_area == other.inner_area @@ -36,16 +55,19 @@ impl PartialEq for LayoutNode { } } -impl LayoutNode { +impl LayoutNode { // The area without any margin pub fn visible_area(&self) -> Area { self.area.without_gaps(&self.margin) } } -pub trait NodeKey: Clone + PartialEq + Eq + std::hash::Hash + Copy + std::fmt::Debug {} +pub trait NodeKey: Clone + PartialEq + Eq + core::hash::Hash + Copy + core::fmt::Debug {} + +pub trait NodeData: Clone {} impl NodeKey for usize {} +impl NodeData for () {} #[cfg(feature = "dioxus")] impl NodeKey for freya_native_core::NodeId {} @@ -74,12 +96,12 @@ pub trait DOMAdapter { let height_b = self.height(node_b)?; let (node_a, node_b) = match height_a.cmp(&height_b) { - std::cmp::Ordering::Less => ( + core::cmp::Ordering::Less => ( *node_a, balance_heights(self, *node_b, *node_a).unwrap_or(*node_b), ), - std::cmp::Ordering::Equal => (*node_a, *node_b), - std::cmp::Ordering::Greater => ( + core::cmp::Ordering::Equal => (*node_a, *node_b), + core::cmp::Ordering::Greater => ( balance_heights(self, *node_a, *node_b).unwrap_or(*node_a), *node_b, ), diff --git a/crates/torin/src/geometry.rs b/crates/torin/src/geometry.rs index 717ba8a49..0d66e4cc8 100644 --- a/crates/torin/src/geometry.rs +++ b/crates/torin/src/geometry.rs @@ -1,4 +1,17 @@ -use std::f32::consts::PI; +use core::f32::consts::PI; +extern crate alloc; +use alloc::vec::Vec; +use core::{ + cmp::Eq, + default::Default, + option::{ + Option, + Option::{ + None, + Some, + }, + }, +}; use crate::{ node::Node, diff --git a/crates/torin/src/lib.rs b/crates/torin/src/lib.rs index 63633a6f3..58a060efc 100644 --- a/crates/torin/src/lib.rs +++ b/crates/torin/src/lib.rs @@ -4,7 +4,6 @@ pub mod geometry; mod measure; pub mod node; pub mod scaled; -pub mod sendanymap; pub mod torin; pub mod values; @@ -18,10 +17,10 @@ pub mod prelude { geometry::*, node::*, scaled::*, - sendanymap::*, torin::*, values::prelude::*, }; } +#[cfg(feature = "std")] pub mod test_utils; diff --git a/crates/torin/src/measure.rs b/crates/torin/src/measure.rs index 1a64cbc86..4fed243a4 100644 --- a/crates/torin/src/measure.rs +++ b/crates/torin/src/measure.rs @@ -1,5 +1,20 @@ +use core::{ + cmp::Eq, + default::Default, + option::{ + Option, + Option::{ + None, + Some, + }, + }, +}; + pub use euclid::Rect; -use rustc_hash::FxHashMap; +#[cfg(not(feature = "std"))] +use hashbrown::HashMap; +#[cfg(feature = "std")] +use rustc_hash::FxHashMap as HashMap; use crate::{ custom_measurer::LayoutMeasurer, @@ -21,6 +36,7 @@ use crate::{ DirectionMode, LayoutMetadata, Length, + NodeData, Torin, }, }; @@ -33,22 +49,24 @@ pub enum Phase { Final, } -pub struct MeasureContext<'a, Key, L, D> +pub struct MeasureContext<'a, Key, Data, L, D> where Key: NodeKey, - L: LayoutMeasurer, + Data: NodeData, + L: LayoutMeasurer, D: DOMAdapter, { - pub layout: &'a mut Torin, + pub layout: &'a mut Torin, pub measurer: &'a mut Option, pub dom_adapter: &'a mut D, pub layout_metadata: LayoutMetadata, } -impl MeasureContext<'_, Key, L, D> +impl MeasureContext<'_, Key, Data, L, D> where Key: NodeKey, - L: LayoutMeasurer, + Data: NodeData, + L: LayoutMeasurer, D: DOMAdapter, { /// Measure a Node. @@ -70,7 +88,7 @@ where parent_is_dirty: bool, // Current phase of measurement phase: Phase, - ) -> (bool, LayoutNode) { + ) -> (bool, LayoutNode) { // 1. If parent is dirty // 2. If this Node has been marked as dirty // 3. If there is no know cached data about this Node. @@ -312,8 +330,8 @@ where ) { let children = self.dom_adapter.children_of(parent_node_id); - let mut initial_phase_flex_grows = FxHashMap::default(); - let mut initial_phase_sizes = FxHashMap::default(); + let mut initial_phase_flex_grows = HashMap::::default(); + let mut initial_phase_sizes = HashMap::::default(); let mut initial_phase_inner_sizes = Size2D::default(); // Used to calculate the spacing and some alignments diff --git a/crates/torin/src/node.rs b/crates/torin/src/node.rs index 832afcc52..d00154bc9 100644 --- a/crates/torin/src/node.rs +++ b/crates/torin/src/node.rs @@ -1,3 +1,15 @@ +use core::{ + cmp::Eq, + default::Default, + option::{ + Option, + Option::{ + None, + Some, + }, + }, +}; + pub use euclid::Rect; use crate::{ diff --git a/crates/torin/src/sendanymap.rs b/crates/torin/src/sendanymap.rs deleted file mode 100644 index 875805940..000000000 --- a/crates/torin/src/sendanymap.rs +++ /dev/null @@ -1,36 +0,0 @@ -use std::any::{ - Any, - TypeId, -}; - -use rustc_hash::FxHashMap; - -/// A map of types that can be sent between threads -#[derive(Debug)] -pub struct SendAnyMap { - map: FxHashMap>, -} - -impl Default for SendAnyMap { - fn default() -> Self { - Self::new() - } -} - -impl SendAnyMap { - pub fn new() -> Self { - Self { - map: FxHashMap::default(), - } - } - - pub fn get(&self) -> Option<&T> { - self.map - .get(&TypeId::of::()) - .and_then(|any| any.downcast_ref::()) - } - - pub fn insert(&mut self, value: T) { - self.map.insert(TypeId::of::(), Box::new(value)); - } -} diff --git a/crates/torin/src/test_utils.rs b/crates/torin/src/test_utils.rs index 2902982b6..6be563f96 100644 --- a/crates/torin/src/test_utils.rs +++ b/crates/torin/src/test_utils.rs @@ -59,8 +59,8 @@ impl DOMAdapter for TestingDOM { } } -pub fn test_utils() -> (Torin, Option) { - let layout = Torin::::new(); +pub fn test_utils() -> (Torin, Option) { + let layout = Torin::::new(); let measurer = None::; (layout, measurer) diff --git a/crates/torin/src/torin.rs b/crates/torin/src/torin.rs index be15576db..cac2a3495 100644 --- a/crates/torin/src/torin.rs +++ b/crates/torin/src/torin.rs @@ -1,10 +1,20 @@ -use std::{ - collections::HashMap, +use core::{ + default::Default, mem, + option::{ + Option, + Option::{ + None, + Some, + }, + }, }; pub use euclid::Rect; -use rustc_hash::FxHashMap; +#[cfg(not(feature = "std"))] +use hashbrown::HashMap; +#[cfg(feature = "std")] +use rustc_hash::FxHashMap as HashMap; use crate::{ custom_measurer::LayoutMeasurer, @@ -21,6 +31,7 @@ use crate::{ prelude::{ AreaModel, Gaps, + NodeData, }, }; @@ -71,29 +82,29 @@ pub enum DirtyReason { Reorder, } -pub struct Torin { +pub struct Torin { /// Layout results of the registered Nodes - pub results: FxHashMap, + pub results: HashMap>, /// Invalid registered nodes since previous layout measurement - pub dirty: FxHashMap, + pub dirty: HashMap, /// Best Root node candidate from where to start measuring pub root_node_candidate: RootNodeCandidate, } -impl Default for Torin { +impl Default for Torin { fn default() -> Self { Self::new() } } -impl Torin { +impl Torin { /// Create a new Layout pub fn new() -> Self { Self { results: HashMap::default(), - dirty: FxHashMap::default(), + dirty: HashMap::default(), root_node_candidate: RootNodeCandidate::None, } } @@ -109,8 +120,8 @@ impl Torin { self.dirty.clear(); } - /// Read the HashSet of dirty nodes - pub fn get_dirty_nodes(&self) -> &FxHashMap { + /// Read the dirty nodes + pub fn get_dirty_nodes(&self) -> &HashMap { &self.dirty } @@ -239,7 +250,7 @@ impl Torin { &mut self, suggested_root_id: Key, root_area: Area, - measurer: &mut Option>, + measurer: &mut Option>, dom_adapter: &mut impl DOMAdapter, ) { // If there are previosuly cached results @@ -266,7 +277,7 @@ impl Torin { }); let root = dom_adapter.get_node(&root_id).unwrap(); - #[cfg(debug_assertions)] + #[cfg(all(debug_assertions, feature = "std"))] { let root_height = dom_adapter.height(&root_id).unwrap(); tracing::info!( @@ -315,12 +326,12 @@ impl Torin { } /// Get the layout_node of a Node - pub fn get(&self, node_id: Key) -> Option<&LayoutNode> { + pub fn get(&self, node_id: Key) -> Option<&LayoutNode> { self.results.get(&node_id) } /// Cache a Node's layout_node - pub fn cache_node(&mut self, node_id: Key, layout_node: LayoutNode) { + pub(crate) fn cache_node(&mut self, node_id: Key, layout_node: LayoutNode) { self.results.insert(node_id, layout_node); } } diff --git a/crates/torin/src/values/alignment.rs b/crates/torin/src/values/alignment.rs index 6ee467e4e..4ddff50bb 100644 --- a/crates/torin/src/values/alignment.rs +++ b/crates/torin/src/values/alignment.rs @@ -1,3 +1,6 @@ +extern crate alloc; +use alloc::string::String; + #[derive(PartialEq, Clone, Debug, Default)] pub enum Alignment { #[default] diff --git a/crates/torin/src/values/content.rs b/crates/torin/src/values/content.rs index c96b38afb..bb498eab5 100644 --- a/crates/torin/src/values/content.rs +++ b/crates/torin/src/values/content.rs @@ -1,3 +1,6 @@ +extern crate alloc; +use alloc::string::String; + #[derive(PartialEq, Clone, Debug, Default)] pub enum Content { #[default] diff --git a/crates/torin/src/values/direction.rs b/crates/torin/src/values/direction.rs index b219e1433..7e601a37e 100644 --- a/crates/torin/src/values/direction.rs +++ b/crates/torin/src/values/direction.rs @@ -1,3 +1,6 @@ +extern crate alloc; +use alloc::string::String; + #[derive(PartialEq, Clone, Debug, Default)] pub enum DirectionMode { #[default] diff --git a/crates/torin/src/values/gaps.rs b/crates/torin/src/values/gaps.rs index b2c8a33cd..b85bb25fc 100644 --- a/crates/torin/src/values/gaps.rs +++ b/crates/torin/src/values/gaps.rs @@ -1,3 +1,7 @@ +extern crate alloc; + +use alloc::string::String; + pub use euclid::Rect; use crate::{ diff --git a/crates/torin/src/values/position.rs b/crates/torin/src/values/position.rs index b5ae6e86b..d1a9ad733 100644 --- a/crates/torin/src/values/position.rs +++ b/crates/torin/src/values/position.rs @@ -1,4 +1,7 @@ -use std::ops::Deref; +use core::{ + default::Default, + ops::Deref, +}; use crate::{ prelude::{ @@ -8,6 +11,18 @@ use crate::{ }, scaled::Scaled, }; +extern crate alloc; +use alloc::{ + boxed::Box, + string::String, +}; +use core::option::{ + Option, + Option::{ + None, + Some, + }, +}; #[derive(Default, PartialEq, Clone, Debug)] pub struct PositionSides { diff --git a/crates/torin/src/values/size.rs b/crates/torin/src/values/size.rs index 9afce5792..1899c92db 100644 --- a/crates/torin/src/values/size.rs +++ b/crates/torin/src/values/size.rs @@ -1,6 +1,23 @@ -use std::{ +extern crate alloc; +use alloc::{ + boxed::Box, + string::String, + vec::Vec, +}; +use core::{ + cmp::Eq, + default::Default, + matches, ops::Deref, + option::{ + Option, + Option::{ + None, + Some, + }, + }, slice::Iter, + unreachable, }; pub use euclid::Rect; @@ -194,8 +211,8 @@ impl Scaled for DynamicCalculation { } } -impl std::fmt::Display for DynamicCalculation { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for DynamicCalculation { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { DynamicCalculation::Sub => f.write_str("-"), DynamicCalculation::Mul => f.write_str("*"),