Separate Window::build_scene
into layout
and paint
This commit is contained in:
parent
3f037e5128
commit
7f345f8bf5
30 changed files with 289 additions and 136 deletions
|
@ -1361,9 +1361,9 @@ impl AppContext {
|
|||
}));
|
||||
|
||||
let mut window = Window::new(window_id, platform_window, self, build_root_view);
|
||||
let scene = WindowContext::mutable(self, &mut window, window_id)
|
||||
.build_scene()
|
||||
.expect("initial scene should not error");
|
||||
let mut cx = WindowContext::mutable(self, &mut window, window_id);
|
||||
cx.layout(false).expect("initial layout should not error");
|
||||
let scene = cx.paint().expect("initial paint should not error");
|
||||
window.platform_window.present_scene(scene);
|
||||
window
|
||||
}
|
||||
|
@ -1486,6 +1486,7 @@ impl AppContext {
|
|||
self.flushing_effects = true;
|
||||
|
||||
let mut refreshing = false;
|
||||
let mut updated_windows = HashSet::default();
|
||||
loop {
|
||||
if let Some(effect) = self.pending_effects.pop_front() {
|
||||
match effect {
|
||||
|
@ -1664,10 +1665,27 @@ impl AppContext {
|
|||
} else {
|
||||
self.remove_dropped_entities();
|
||||
|
||||
if refreshing {
|
||||
self.perform_window_refresh();
|
||||
} else {
|
||||
self.update_windows();
|
||||
for window_id in self.windows.keys().cloned().collect::<Vec<_>>() {
|
||||
self.update_window(window_id, |cx| {
|
||||
let invalidation = if refreshing {
|
||||
let mut invalidation =
|
||||
cx.window.invalidation.take().unwrap_or_default();
|
||||
invalidation
|
||||
.updated
|
||||
.extend(cx.window.rendered_views.keys().copied());
|
||||
Some(invalidation)
|
||||
} else {
|
||||
cx.window.invalidation.take()
|
||||
};
|
||||
|
||||
if let Some(invalidation) = invalidation {
|
||||
let appearance = cx.window.platform_window.appearance();
|
||||
cx.invalidate(invalidation, appearance);
|
||||
if cx.layout(refreshing).log_err().is_some() {
|
||||
updated_windows.insert(window_id);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if self.pending_effects.is_empty() {
|
||||
|
@ -1675,6 +1693,14 @@ impl AppContext {
|
|||
callback(self);
|
||||
}
|
||||
|
||||
for window_id in updated_windows.drain() {
|
||||
self.update_window(window_id, |cx| {
|
||||
if let Some(scene) = cx.paint().log_err() {
|
||||
cx.window.platform_window.present_scene(scene);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if self.pending_effects.is_empty() {
|
||||
self.flushing_effects = false;
|
||||
self.pending_notifications.clear();
|
||||
|
@ -1689,21 +1715,6 @@ impl AppContext {
|
|||
}
|
||||
}
|
||||
|
||||
fn update_windows(&mut self) {
|
||||
let window_ids = self.windows.keys().cloned().collect::<Vec<_>>();
|
||||
for window_id in window_ids {
|
||||
self.update_window(window_id, |cx| {
|
||||
if let Some(mut invalidation) = cx.window.invalidation.take() {
|
||||
let appearance = cx.window.platform_window.appearance();
|
||||
cx.invalidate(&mut invalidation, appearance);
|
||||
if let Some(scene) = cx.build_scene().log_err() {
|
||||
cx.window.platform_window.present_scene(scene);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn window_was_resized(&mut self, window_id: usize) {
|
||||
self.pending_effects
|
||||
.push_back(Effect::ResizeWindow { window_id });
|
||||
|
@ -1747,23 +1758,6 @@ impl AppContext {
|
|||
self.pending_effects.push_back(Effect::RefreshWindows);
|
||||
}
|
||||
|
||||
fn perform_window_refresh(&mut self) {
|
||||
let window_ids = self.windows.keys().cloned().collect::<Vec<_>>();
|
||||
for window_id in window_ids {
|
||||
self.update_window(window_id, |cx| {
|
||||
let mut invalidation = cx.window.invalidation.take().unwrap_or_default();
|
||||
invalidation
|
||||
.updated
|
||||
.extend(cx.window.rendered_views.keys().copied());
|
||||
cx.invalidate(&mut invalidation, cx.window.platform_window.appearance());
|
||||
cx.refreshing = true;
|
||||
if let Some(scene) = cx.build_scene().log_err() {
|
||||
cx.window.platform_window.present_scene(scene);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_global_event(&mut self, payload: Box<dyn Any>) {
|
||||
let type_id = (&*payload).type_id();
|
||||
|
||||
|
@ -3255,6 +3249,67 @@ 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>,
|
||||
pub refreshing: bool,
|
||||
}
|
||||
|
||||
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>,
|
||||
refreshing: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
view_context,
|
||||
new_parents,
|
||||
views_to_notify_if_ancestors_change,
|
||||
refreshing,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn view_context(&mut self) -> &mut ViewContext<'a, 'b, V> {
|
||||
self.view_context
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'c, V: View> Deref for LayoutContext<'a, 'b, 'c, V> {
|
||||
type Target = ViewContext<'a, 'b, V>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.view_context
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: View> DerefMut for LayoutContext<'_, '_, '_, V> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.view_context
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: View> BorrowAppContext for LayoutContext<'_, '_, '_, V> {
|
||||
fn read_with<T, F: FnOnce(&AppContext) -> T>(&self, f: F) -> T {
|
||||
BorrowAppContext::read_with(&*self.view_context, f)
|
||||
}
|
||||
|
||||
fn update<T, F: FnOnce(&mut AppContext) -> T>(&mut self, f: F) -> T {
|
||||
BorrowAppContext::update(&mut *self.view_context, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: View> BorrowWindowContext for LayoutContext<'_, '_, '_, V> {
|
||||
fn read_with<T, F: FnOnce(&WindowContext) -> T>(&self, window_id: usize, f: F) -> T {
|
||||
BorrowWindowContext::read_with(&*self.view_context, window_id, f)
|
||||
}
|
||||
|
||||
fn update<T, F: FnOnce(&mut WindowContext) -> T>(&mut self, window_id: usize, f: F) -> T {
|
||||
BorrowWindowContext::update(&mut *self.view_context, window_id, f)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EventContext<'a, 'b, 'c, V: View> {
|
||||
view_context: &'c mut ViewContext<'a, 'b, V>,
|
||||
pub(crate) handled: bool,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue