mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-12 21:37:01 +00:00

SmolStr has an Arc internally for large strings. This allows cheap copies of large strings, but we lose that ability when we convert the SmolStr to a &str and then reconstruct a SmolStr from that slice. I was hoping for some larger gains here, considering the impact of this code change, but it only removes ~50k allocations, while the impact on the runtime is not noticeable at all. Still, I believe this is the right thing to do. Before: ``` allocations: 2338981 Time (mean ± σ): 988.3 ms ± 17.9 ms [User: 690.2 ms, System: 206.4 ms] Range (min … max): 956.4 ms … 1016.3 ms 10 runs ``` After: ``` allocations: 2287723 Time (mean ± σ): 989.8 ms ± 23.2 ms [User: 699.2 ms, System: 197.6 ms] Range (min … max): 945.3 ms … 1021.4 ms 10 runs ```
82 lines
3.1 KiB
Rust
82 lines
3.1 KiB
Rust
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
|
|
|
//! This pass creates bindings to "absolute-y" and "absolute-y" properties
|
|
//! that can be used to compute the window-absolute coordinates of elements.
|
|
|
|
use smol_str::SmolStr;
|
|
use std::cell::RefCell;
|
|
use std::rc::Rc;
|
|
|
|
use crate::expression_tree::{BuiltinFunction, Expression};
|
|
use crate::namedreference::NamedReference;
|
|
use crate::object_tree::{
|
|
recurse_elem_including_sub_components_no_borrow, visit_all_named_references_in_element,
|
|
Component,
|
|
};
|
|
|
|
pub fn lower_absolute_coordinates(component: &Rc<Component>) {
|
|
let mut to_materialize = std::collections::HashSet::new();
|
|
|
|
recurse_elem_including_sub_components_no_borrow(component, &(), &mut |elem, _| {
|
|
visit_all_named_references_in_element(elem, |nr| {
|
|
if nr.name() == "absolute-position" {
|
|
to_materialize.insert(nr.clone());
|
|
}
|
|
});
|
|
});
|
|
|
|
let point_type = BuiltinFunction::ItemAbsolutePosition.ty().return_type.clone();
|
|
|
|
for nr in to_materialize {
|
|
let elem = nr.element();
|
|
|
|
// Create a binding for the `absolute-position` property. The
|
|
// materialize properties pass is going to create the actual property later.
|
|
|
|
let parent_position_var = Box::new(Expression::ReadLocalVariable {
|
|
name: "parent_position".into(),
|
|
ty: point_type.clone(),
|
|
});
|
|
|
|
let binding = Expression::CodeBlock(vec![
|
|
Expression::StoreLocalVariable {
|
|
name: "parent_position".into(),
|
|
value: Expression::FunctionCall {
|
|
function: Box::new(Expression::BuiltinFunctionReference(
|
|
BuiltinFunction::ItemAbsolutePosition,
|
|
None,
|
|
)),
|
|
arguments: vec![Expression::ElementReference(Rc::downgrade(&elem))],
|
|
source_location: None,
|
|
}
|
|
.into(),
|
|
},
|
|
Expression::Struct {
|
|
ty: point_type.clone(),
|
|
values: IntoIterator::into_iter(["x", "y"])
|
|
.map(|coord| {
|
|
(
|
|
coord.into(),
|
|
Expression::BinaryExpression {
|
|
lhs: Expression::StructFieldAccess {
|
|
base: parent_position_var.clone(),
|
|
name: coord.into(),
|
|
}
|
|
.into(),
|
|
rhs: Expression::PropertyReference(NamedReference::new(
|
|
&elem,
|
|
SmolStr::new_static(coord),
|
|
))
|
|
.into(),
|
|
op: '+',
|
|
},
|
|
)
|
|
})
|
|
.collect(),
|
|
},
|
|
]);
|
|
|
|
elem.borrow_mut().bindings.insert(nr.name().clone(), RefCell::new(binding.into()));
|
|
}
|
|
}
|