Skip to content

Commit

Permalink
Merge branch 'main' into feat/table-component
Browse files Browse the repository at this point in the history
  • Loading branch information
marc2332 authored Sep 24, 2023
2 parents a81960c + 724e4e8 commit 005bb00
Show file tree
Hide file tree
Showing 14 changed files with 564 additions and 421 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/benchmarks.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
on:
push:
pull_request:
paths:
- 'crates/torin/**/*'
- '.github/workflows/benchmarks.yml'
Expand All @@ -14,5 +14,5 @@ jobs:
- uses: boa-dev/criterion-compare-action@59f4d964c5f19d7f13d36f5c0944b18ce6652cb0
with:
package: torin
branchName: feat/torin-benchmarks-TEST-COMPARE
branchName: ${{ github.base_ref }}
token: ${{ secrets.GITHUB_TOKEN }}
7 changes: 7 additions & 0 deletions book/src/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ Install these packages:
sudo apt install build-essential libssl-dev pkg-config cmake libgtk-3-dev libclang-dev
```

#### Arch Linux

Install these packages:
```sh
sudo pacman -S base-devel openssl cmake gtk3 clang
```

Don't hesitate to contribute so other distros can be added here.

### MacOS
Expand Down
2 changes: 1 addition & 1 deletion crates/components/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "freya-components"
description = "Components library desgined for Freya."
version = "0.1.4"
version = "0.1.5"
edition = "2021"
license = "MIT"
authors = ["Marc Espín <[email protected]>"]
Expand Down
6 changes: 3 additions & 3 deletions crates/core/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ pub fn process_layout(
scale_factor: f32,
) -> (Layers, ViewportsCollection) {
let rdom = fdom.rdom();
let dom_adapter = DioxusDOMAdapter::new(rdom);
let mut dom_adapter = DioxusDOMAdapter::new_with_cache(rdom);
let skia_measurer = SkiaMeasurer::new(rdom, font_collection);

// Finds the best Node from where to start measuring
fdom.layout().find_best_root(&dom_adapter);
fdom.layout().find_best_root(&mut dom_adapter);

let root_id = fdom.rdom().root_id();

// Measure the layout
fdom.layout()
.measure(root_id, area, &mut Some(skia_measurer), &dom_adapter);
.measure(root_id, area, &mut Some(skia_measurer), &mut dom_adapter);

// Create the layers
let mut layers = Layers::default();
Expand Down
19 changes: 11 additions & 8 deletions crates/core/src/viewports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ pub fn calculate_viewports(
let node_areas = layout.get(*node_id);

if let Some((node, node_areas)) = node.zip(node_areas) {
let style = node.get::<Style>().unwrap();
let node_type = &*node.node_type();

if let NodeType::Element(..) = node_type {
let style = node.get::<Style>().unwrap();

// Clip any overflow from it's children
if style.overflow == OverflowMode::Clip {
viewports_collection
Expand All @@ -38,14 +39,16 @@ pub fn calculate_viewports(
.0 = Some(node_areas.area);
}

for child in node.children() {
if viewports_collection.contains_key(node_id) {
let mut inherited_viewports =
viewports_collection.get(node_id).unwrap().1.clone();

inherited_viewports.push(*node_id);
// Pass viewports to the children
if let Some((_, mut inherited_viewports)) =
viewports_collection.get(node_id).cloned()
{
// Add the itself
inherited_viewports.push(*node_id);

viewports_collection.insert(child.id(), (None, inherited_viewports));
for child in node.children() {
viewports_collection
.insert(child.id(), (None, inherited_viewports.clone()));
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion crates/dom/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "freya-dom"
description = "Internal DOM abstractions for Freya."
version = "0.1.1"
version = "0.1.2"
edition = "2021"
license = "MIT"
authors = ["Marc Espín <[email protected]>"]
Expand All @@ -11,12 +11,17 @@ repository = "https://github.com/marc2332/freya"
keywords = ["gui", "ui", "desktop", "skia", "dioxus"]
categories = ["gui", "asynchronous"]

[package.metadata.docs.rs]
features = ["freya-engine/mocked-engine"]

[features]
shared = []
skia-engine = ["freya-engine/skia-engine"]

[dependencies]
freya-node-state = { workspace = true }
freya-common = { workspace = true }
freya-engine = { workspace = true }
torin = { workspace = true }

dioxus-rsx = { workspace = true }
Expand Down
4 changes: 2 additions & 2 deletions crates/dom/src/dom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,10 @@ impl FreyaDOM {

/// Process the given mutations from the [`VirtualDOM`](dioxus_core::VirtualDom).
pub fn apply_mutations(&mut self, mutations: Mutations, scale_factor: f32) -> (bool, bool) {
let dom_adapter = DioxusDOMAdapter::new(self.rdom());
let mut dom_adapter = DioxusDOMAdapter::new_with_cache(self.rdom());
// Apply the mutations to the layout
self.layout()
.apply_mutations(&mutations, &self.dioxus_integration_state, &dom_adapter);
.apply_mutations(&mutations, &self.dioxus_integration_state, &mut dom_adapter);

// Apply the mutations the integration state
self.dioxus_integration_state
Expand Down
91 changes: 62 additions & 29 deletions crates/dom/src/dom_adapter.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
use dioxus_native_core::{prelude::NodeType, real_dom::NodeImmutable, tree::TreeRef, NodeId};
use freya_node_state::LayoutState;
use rustc_hash::FxHashMap;
use torin::prelude::*;

use crate::dom::DioxusDOM;

/// RealDOM adapter for Torin.
pub struct DioxusDOMAdapter<'a> {
pub rdom: &'a DioxusDOM,

valid_nodes_cache: Option<FxHashMap<NodeId, bool>>,
}

impl<'a> DioxusDOMAdapter<'a> {
pub fn new(rdom: &'a DioxusDOM) -> Self {
Self { rdom }
Self {
rdom,
valid_nodes_cache: None,
}
}

pub fn new_with_cache(rdom: &'a DioxusDOM) -> Self {
Self {
rdom,
valid_nodes_cache: Some(FxHashMap::default()),
}
}
}

Expand Down Expand Up @@ -51,17 +64,17 @@ impl DOMAdapter<NodeId> for DioxusDOMAdapter<'_> {
self.rdom.tree_ref().parent_id(*node_id)
}

fn children_of(&self, node_id: &NodeId) -> Vec<NodeId> {
fn children_of(&mut self, node_id: &NodeId) -> Vec<NodeId> {
self.rdom
.tree_ref()
.children_ids(*node_id)
.into_iter()
.filter(|id| is_node_valid(self.rdom, id))
.filter(|id| is_node_valid(self.rdom, &mut self.valid_nodes_cache, id))
.collect::<Vec<NodeId>>()
}

fn is_node_valid(&self, node_id: &NodeId) -> bool {
is_node_valid(self.rdom, node_id)
fn is_node_valid(&mut self, node_id: &NodeId) -> bool {
is_node_valid(self.rdom, &mut self.valid_nodes_cache, node_id)
}

fn closest_common_parent(&self, node_id_a: &NodeId, node_id_b: &NodeId) -> Option<NodeId> {
Expand Down Expand Up @@ -134,38 +147,58 @@ fn find_common_parent(rdom: &DioxusDOM, node_a: NodeId, node_b: NodeId) -> Optio
}

/// Check is the given Node is valid or not, this means not being a placeholder or an unconnected Node.
fn is_node_valid(rdom: &DioxusDOM, node_id: &NodeId) -> bool {
fn is_node_valid(
rdom: &DioxusDOM,
valid_nodes_cache: &mut Option<FxHashMap<NodeId, bool>>,
node_id: &NodeId,
) -> bool {
// Check if Node was valid from cache
if let Some(valid_nodes_cache) = valid_nodes_cache {
if let Some(is_valid) = valid_nodes_cache.get(node_id) {
return *is_valid;
}
}

let node = rdom.get(*node_id);

if let Some(node) = node {
let is_placeholder = matches!(*node.node_type(), NodeType::Placeholder);
let is_valid = 'validation: {
if let Some(node) = node {
let is_placeholder = matches!(*node.node_type(), NodeType::Placeholder);

// Placeholders can't be measured
if is_placeholder {
return false;
}
// Placeholders can't be measured
if is_placeholder {
break 'validation false;
}

// Make sure this Node isn't part of an unconnected Node
// This walkes up to the ancestor that has a height of 0 and checks if it has the same ID as the root Node
// If it has the same ID, it means that is not an unconnected ID, otherwise, it is and should be skipped.
let tree = rdom.tree_ref();
let mut current = *node_id;
loop {
let height = tree.height(current);
if let Some(height) = height {
if height == 0 {
break;
// Make sure this Node isn't part of an unconnected Node
// This walkes up to the ancestor that has a height of 0 and checks if it has the same ID as the root Node
// If it has the same ID, it means that is not an unconnected ID, otherwise, it is and should be skipped.
let tree = rdom.tree_ref();
let mut current = *node_id;
loop {
let height = tree.height(current);
if let Some(height) = height {
if height == 0 {
break;
}
}
}

let parent_current = tree.parent_id(current);
if let Some(parent_current) = parent_current {
current = parent_current;
let parent_current = tree.parent_id(current);
if let Some(parent_current) = parent_current {
current = parent_current;
}
}

current == rdom.root_id()
} else {
false
}
};

current == rdom.root_id()
} else {
false
// Save the validation result in the cache
if let Some(valid_nodes_cache) = valid_nodes_cache {
valid_nodes_cache.insert(*node_id, is_valid);
}

is_valid
}
2 changes: 1 addition & 1 deletion crates/renderer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "freya-renderer"
description = "Internal renderer powered by Skia for Freya."
version = "0.1.5"
version = "0.1.6"
edition = "2021"
license = "MIT"
authors = ["Marc Espín <[email protected]>"]
Expand Down
Loading

0 comments on commit 005bb00

Please sign in to comment.