From 67edb42fbe972c013fc33a70f43d3a600e2b6068 Mon Sep 17 00:00:00 2001 From: Marc Espin Date: Thu, 28 Mar 2024 21:56:55 +0100 Subject: [PATCH 01/23] feat: Incremental viewport creation (#542) * feat: Make viewports a Node state * clean up * fix * clean up --- crates/core/src/events/events_measurer.rs | 24 +++-- crates/core/src/layout/layout_measurer.rs | 7 +- crates/core/src/layout/mod.rs | 2 - crates/core/src/layout/viewports.rs | 89 ------------------- crates/core/src/plugins.rs | 4 - crates/core/src/render.rs | 29 +++--- crates/dom/src/dom.rs | 3 +- .../freya/src/plugins/performance_overlay.rs | 8 -- crates/native-core/src/dioxus.rs | 5 +- crates/native-core/src/tags.rs | 4 - crates/renderer/src/app.rs | 16 +--- crates/renderer/src/renderer.rs | 36 ++++---- crates/state/src/lib.rs | 2 + crates/state/src/viewport.rs | 78 ++++++++++++++++ crates/testing/src/launch.rs | 7 +- crates/testing/src/test_handler.rs | 4 +- crates/testing/src/test_node.rs | 24 ++--- crates/testing/src/test_utils.rs | 6 -- 18 files changed, 147 insertions(+), 201 deletions(-) delete mode 100644 crates/core/src/layout/viewports.rs create mode 100644 crates/state/src/viewport.rs diff --git a/crates/core/src/events/events_measurer.rs b/crates/core/src/events/events_measurer.rs index c6520988a..2a3b0cbab 100644 --- a/crates/core/src/events/events_measurer.rs +++ b/crates/core/src/events/events_measurer.rs @@ -1,11 +1,11 @@ -use crate::layout::{Layers, Viewports}; +use crate::layout::Layers; use dioxus_native_core::real_dom::NodeImmutable; use dioxus_native_core::NodeId; use dioxus_native_core::{prelude::NodeImmutableDioxusExt, tree::TreeRef}; use freya_dom::{dom::DioxusDOM, prelude::FreyaDOM}; use freya_engine::prelude::*; -use freya_node_state::{Fill, Style}; +use freya_node_state::{Fill, Style, ViewportState}; pub use crate::events::{DomEvent, NodesState, PlatformEvent}; @@ -20,14 +20,13 @@ pub fn process_events( events: &mut EventsQueue, event_emitter: &EventEmitter, nodes_state: &mut NodesState, - viewports: &Viewports, scale_factor: f64, ) { // 1. Get global events created from the incoming events let global_events = measure_global_events(events); // 2. Get potential events that could be emitted based on the elements layout and viewports - let potential_events = measure_potential_event_listeners(layers, events, viewports, dom); + let potential_events = measure_potential_event_listeners(layers, events, dom); // 3. Get what events can be actually emitted based on what elements are listening let dom_events = measure_dom_events(potential_events, dom, scale_factor); @@ -74,12 +73,12 @@ pub fn measure_global_events(events: &EventsQueue) -> Vec { pub fn measure_potential_event_listeners( layers: &Layers, events: &EventsQueue, - viewports: &Viewports, fdom: &FreyaDOM, ) -> PotentialEvents { let mut potential_events = PotentialEvents::default(); let layout = fdom.layout(); + let rdom = fdom.rdom(); // Propagate events from the top to the bottom for (layer, layer_nodes) in layers.layers() { @@ -106,17 +105,14 @@ pub fn measure_potential_event_listeners( // Make sure the cursor is inside the node area if cursor_is_inside { - let node_viewports = viewports.get(node_id); + let node = rdom.get(*node_id).unwrap(); + let node_viewports = node.get::().unwrap(); // Make sure the cursor is inside all the applicable viewports from the element - if let Some((_, node_viewports)) = node_viewports { - for viewport_id in node_viewports { - let viewport = viewports.get(viewport_id).unwrap().0; - if let Some(viewport) = viewport { - if !viewport.contains(cursor.to_f32()) { - continue 'events; - } - } + for viewport_id in &node_viewports.viewports { + let viewport = layout.get(*viewport_id).unwrap().visible_area(); + if !viewport.contains(cursor.to_f32()) { + continue 'events; } } diff --git a/crates/core/src/layout/layout_measurer.rs b/crates/core/src/layout/layout_measurer.rs index 8ae0473b4..f6cf0c1e7 100644 --- a/crates/core/src/layout/layout_measurer.rs +++ b/crates/core/src/layout/layout_measurer.rs @@ -9,7 +9,7 @@ pub fn process_layout( area: Area, font_collection: &mut FontCollection, scale_factor: f32, -) -> (Layers, Viewports) { +) -> Layers { let rdom = fdom.rdom(); let mut dom_adapter = DioxusDOMAdapter::new_with_cache(rdom); let skia_measurer = SkiaMeasurer::new(rdom, font_collection); @@ -26,8 +26,5 @@ pub fn process_layout( // Create the layers let layers = Layers::new(rdom, &fdom.layout(), scale_factor); - // Calculate the viewports - let viewports = Viewports::new(&layers, fdom); - - (layers, viewports) + layers } diff --git a/crates/core/src/layout/mod.rs b/crates/core/src/layout/mod.rs index 8aa293399..e9d5eb251 100644 --- a/crates/core/src/layout/mod.rs +++ b/crates/core/src/layout/mod.rs @@ -1,9 +1,7 @@ pub mod layers; pub mod layout_measurer; pub mod skia_measurer; -pub mod viewports; pub use layers::*; pub use layout_measurer::*; pub use skia_measurer::*; -pub use viewports::*; diff --git a/crates/core/src/layout/viewports.rs b/crates/core/src/layout/viewports.rs deleted file mode 100644 index 10b783be9..000000000 --- a/crates/core/src/layout/viewports.rs +++ /dev/null @@ -1,89 +0,0 @@ -use dioxus_native_core::node::ElementNode; -use dioxus_native_core::real_dom::NodeImmutable; -use dioxus_native_core::{node::NodeType, NodeId}; -use torin::prelude::Area; - -use crate::layout::*; -use freya_dom::prelude::FreyaDOM; - -use freya_node_state::{OverflowMode, Style}; -use rustc_hash::FxHashMap; - -/// Viewports of all elegible DOM elements. -#[derive(Default)] -pub struct Viewports { - viewports: FxHashMap, Vec)>, -} - -impl Viewports { - // Calculate all the applicable viewports for the given nodes - pub fn new(layers: &Layers, fdom: &FreyaDOM) -> Self { - let mut viewports = FxHashMap::default(); - let layout = fdom.layout(); - let rdom = fdom.rdom(); - - for (_, layer) in layers.layers() { - for node_id in layer { - let node = rdom.get(*node_id); - let layout_node = layout.get(*node_id); - - if let Some((node, layout_node)) = node.zip(layout_node) { - let node_type = &*node.node_type(); - - if let NodeType::Element(ElementNode { tag, .. }) = node_type { - // No need to consider text spans - if !tag.has_intrinsic_layout() { - continue; - } - - let style = node.get::