Allow notifying views when the ancestry of another view is outdated

This commit is contained in:
Antonio Scandurra 2023-05-03 19:25:00 +02:00
parent 7250754f8e
commit 040cc4d4c3
3 changed files with 27 additions and 6 deletions

View File

@ -25,6 +25,7 @@ use std::{
use anyhow::{anyhow, Context, Result};
use parking_lot::Mutex;
use postage::oneshot;
use smallvec::SmallVec;
use smol::prelude::*;
use util::ResultExt;
use uuid::Uuid;
@ -3198,7 +3199,7 @@ impl<V> BorrowWindowContext for ViewContext<'_, '_, V> {
pub struct LayoutContext<'a, 'b, 'c, V: View> {
view_context: &'c mut ViewContext<'a, 'b, V>,
new_parents: &'c mut HashMap<usize, usize>,
views_to_notify_if_ancestors_change: &'c mut HashSet<usize>,
views_to_notify_if_ancestors_change: &'c mut HashMap<usize, SmallVec<[usize; 2]>>,
pub refreshing: bool,
}
@ -3206,7 +3207,7 @@ impl<'a, 'b, 'c, V: View> LayoutContext<'a, 'b, 'c, V> {
pub fn new(
view_context: &'c mut ViewContext<'a, 'b, V>,
new_parents: &'c mut HashMap<usize, usize>,
views_to_notify_if_ancestors_change: &'c mut HashSet<usize>,
views_to_notify_if_ancestors_change: &'c mut HashMap<usize, SmallVec<[usize; 2]>>,
refreshing: bool,
) -> Self {
Self {

View File

@ -933,7 +933,7 @@ impl<'a> WindowContext<'a> {
let root_view_id = self.window.root_view().id();
let mut rendered_root = self.window.rendered_views.remove(&root_view_id).unwrap();
let mut new_parents = HashMap::default();
let mut views_to_notify_if_ancestors_change = HashSet::default();
let mut views_to_notify_if_ancestors_change = HashMap::default();
rendered_root.layout(
SizeConstraint::strict(window_size),
&mut new_parents,
@ -942,6 +942,25 @@ impl<'a> WindowContext<'a> {
self,
)?;
for (view_id, view_ids_to_notify) in views_to_notify_if_ancestors_change {
let mut current_view_id = view_id;
loop {
let old_parent_id = self.window.parents.get(&current_view_id);
let new_parent_id = new_parents.get(&current_view_id);
if old_parent_id.is_none() && new_parent_id.is_none() {
break;
} else if old_parent_id == new_parent_id {
current_view_id = *old_parent_id.unwrap();
} else {
let window_id = self.window_id;
for view_id_to_notify in view_ids_to_notify {
self.notify_view(window_id, view_id_to_notify);
}
break;
}
}
}
self.window.parents = new_parents;
self.window
.rendered_views

View File

@ -37,9 +37,10 @@ use crate::{
WindowContext,
};
use anyhow::{anyhow, Result};
use collections::{HashMap, HashSet};
use collections::HashMap;
use core::panic;
use json::ToJson;
use smallvec::SmallVec;
use std::{
any::Any,
borrow::Cow,
@ -648,7 +649,7 @@ pub trait AnyRootElement {
&mut self,
constraint: SizeConstraint,
new_parents: &mut HashMap<usize, usize>,
views_to_notify_if_ancestors_change: &mut HashSet<usize>,
views_to_notify_if_ancestors_change: &mut HashMap<usize, SmallVec<[usize; 2]>>,
refreshing: bool,
cx: &mut WindowContext,
) -> Result<Vector2F>;
@ -673,7 +674,7 @@ impl<V: View> AnyRootElement for RootElement<V> {
&mut self,
constraint: SizeConstraint,
new_parents: &mut HashMap<usize, usize>,
views_to_notify_if_ancestors_change: &mut HashSet<usize>,
views_to_notify_if_ancestors_change: &mut HashMap<usize, SmallVec<[usize; 2]>>,
refreshing: bool,
cx: &mut WindowContext,
) -> Result<Vector2F> {