Lift Send and Sync restriction for measurements

This commit is contained in:
Antonio Scandurra 2023-11-30 16:03:22 +01:00
parent 74a5ae5633
commit d9b8c07b1e
4 changed files with 23 additions and 20 deletions

View file

@ -152,15 +152,13 @@ impl TextState {
.to_pixels(font_size.into(), cx.rem_size()); .to_pixels(font_size.into(), cx.rem_size());
let text = SharedString::from(text); let text = SharedString::from(text);
let rem_size = cx.rem_size();
let runs = if let Some(runs) = runs { let runs = if let Some(runs) = runs {
runs runs
} else { } else {
vec![text_style.to_run(text.len())] vec![text_style.to_run(text.len())]
}; };
let layout_id = cx.request_measured_layout(Default::default(), rem_size, { let layout_id = cx.request_measured_layout(Default::default(), {
let element_state = self.clone(); let element_state = self.clone();
move |known_dimensions, available_space| { move |known_dimensions, available_space| {

View file

@ -109,7 +109,6 @@ impl Element for UniformList {
cx: &mut WindowContext, cx: &mut WindowContext,
) -> (LayoutId, Self::State) { ) -> (LayoutId, Self::State) {
let max_items = self.item_count; let max_items = self.item_count;
let rem_size = cx.rem_size();
let item_size = state let item_size = state
.as_ref() .as_ref()
.map(|s| s.item_size) .map(|s| s.item_size)
@ -120,7 +119,6 @@ impl Element for UniformList {
.layout(state.map(|s| s.interactive), cx, |style, cx| { .layout(state.map(|s| s.interactive), cx, |style, cx| {
cx.request_measured_layout( cx.request_measured_layout(
style, style,
rem_size,
move |known_dimensions: Size<Option<Pixels>>, move |known_dimensions: Size<Option<Pixels>>,
available_space: Size<AvailableSpace>| { available_space: Size<AvailableSpace>| {
let desired_height = item_size.height * max_items; let desired_height = item_size.height * max_items;

View file

@ -9,13 +9,15 @@ use taffy::{
Taffy, Taffy,
}; };
type Measureable = dyn Fn(Size<Option<Pixels>>, Size<AvailableSpace>) -> Size<Pixels> + Send + Sync;
pub struct TaffyLayoutEngine { pub struct TaffyLayoutEngine {
taffy: Taffy<Box<Measureable>>, taffy: Taffy,
children_to_parents: HashMap<LayoutId, LayoutId>, children_to_parents: HashMap<LayoutId, LayoutId>,
absolute_layout_bounds: HashMap<LayoutId, Bounds<Pixels>>, absolute_layout_bounds: HashMap<LayoutId, Bounds<Pixels>>,
computed_layouts: HashSet<LayoutId>, computed_layouts: HashSet<LayoutId>,
nodes_to_measure: HashMap<
LayoutId,
Box<dyn FnMut(Size<Option<Pixels>>, Size<AvailableSpace>) -> Size<Pixels>>,
>,
} }
static EXPECT_MESSAGE: &'static str = static EXPECT_MESSAGE: &'static str =
@ -28,6 +30,7 @@ impl TaffyLayoutEngine {
children_to_parents: HashMap::default(), children_to_parents: HashMap::default(),
absolute_layout_bounds: HashMap::default(), absolute_layout_bounds: HashMap::default(),
computed_layouts: HashSet::default(), computed_layouts: HashSet::default(),
nodes_to_measure: HashMap::default(),
} }
} }
@ -36,6 +39,7 @@ impl TaffyLayoutEngine {
self.children_to_parents.clear(); self.children_to_parents.clear();
self.absolute_layout_bounds.clear(); self.absolute_layout_bounds.clear();
self.computed_layouts.clear(); self.computed_layouts.clear();
self.nodes_to_measure.clear();
} }
pub fn request_layout( pub fn request_layout(
@ -65,18 +69,17 @@ impl TaffyLayoutEngine {
&mut self, &mut self,
style: Style, style: Style,
rem_size: Pixels, rem_size: Pixels,
measure: impl Fn(Size<Option<Pixels>>, Size<AvailableSpace>) -> Size<Pixels> measure: impl FnMut(Size<Option<Pixels>>, Size<AvailableSpace>) -> Size<Pixels> + 'static,
+ Send
+ Sync
+ 'static,
) -> LayoutId { ) -> LayoutId {
let style = style.to_taffy(rem_size); let style = style.to_taffy(rem_size);
let measurable = Box::new(measure); let layout_id = self
self.taffy .taffy
.new_leaf_with_context(style, measurable) .new_leaf_with_context(style, ())
.expect(EXPECT_MESSAGE) .expect(EXPECT_MESSAGE)
.into() .into();
self.nodes_to_measure.insert(layout_id, Box::new(measure));
layout_id
} }
// Used to understand performance // Used to understand performance
@ -155,12 +158,14 @@ impl TaffyLayoutEngine {
} }
// let started_at = std::time::Instant::now(); // let started_at = std::time::Instant::now();
dbg!(">>>>>>>>>>>>>");
self.taffy self.taffy
.compute_layout_with_measure( .compute_layout_with_measure(
id.into(), id.into(),
available_space.into(), available_space.into(),
|known_dimensions, available_space, _node_id, context| { |known_dimensions, available_space, node_id, _context| {
let Some(measure) = context else { let Some(measure) = self.nodes_to_measure.get_mut(&node_id.into()) else {
return taffy::geometry::Size::default(); return taffy::geometry::Size::default();
}; };
@ -173,6 +178,8 @@ impl TaffyLayoutEngine {
}, },
) )
.expect(EXPECT_MESSAGE); .expect(EXPECT_MESSAGE);
dbg!("<<<<<<");
// println!("compute_layout took {:?}", started_at.elapsed()); // println!("compute_layout took {:?}", started_at.elapsed());
} }

View file

@ -618,13 +618,13 @@ impl<'a> WindowContext<'a> {
/// The given closure is invoked at layout time with the known dimensions and available space and /// The given closure is invoked at layout time with the known dimensions and available space and
/// returns a `Size`. /// returns a `Size`.
pub fn request_measured_layout< pub fn request_measured_layout<
F: Fn(Size<Option<Pixels>>, Size<AvailableSpace>) -> Size<Pixels> + Send + Sync + 'static, F: FnMut(Size<Option<Pixels>>, Size<AvailableSpace>) -> Size<Pixels> + 'static,
>( >(
&mut self, &mut self,
style: Style, style: Style,
rem_size: Pixels,
measure: F, measure: F,
) -> LayoutId { ) -> LayoutId {
let rem_size = self.rem_size();
self.window self.window
.layout_engine .layout_engine
.request_measured_layout(style, rem_size, measure) .request_measured_layout(style, rem_size, measure)