Fix infinite loop

Nathan Sobo created

Change summary

crates/gpui3/src/app.rs    |  4 -
crates/gpui3/src/view.rs   |  6 +--
crates/gpui3/src/window.rs | 68 +++++++++++++++++++++------------------
3 files changed, 40 insertions(+), 38 deletions(-)

Detailed changes

crates/gpui3/src/app.rs 🔗

@@ -21,7 +21,6 @@ use smallvec::SmallVec;
 use std::{
     any::{type_name, Any, TypeId},
     marker::PhantomData,
-    ops::{Deref, DerefMut},
     sync::{Arc, Weak},
 };
 use util::ResultExt;
@@ -220,7 +219,6 @@ impl<Thread: 'static + Send + Sync> AppContext<Thread> {
                 .unwrap();
 
             let result = update(&mut WindowContext::mutable(cx.downcast_mut(), &mut window));
-            window.dirty = true;
 
             cx.windows
                 .get_mut(id)
@@ -266,7 +264,7 @@ impl<Thread: 'static + Send + Sync> AppContext<Thread> {
 
         for dirty_window_id in dirty_window_ids {
             self.update_window(dirty_window_id, |cx| cx.draw())
-                .unwrap() // We know we have the window.
+                .unwrap()
                 .log_err();
         }
     }

crates/gpui3/src/view.rs 🔗

@@ -102,9 +102,7 @@ impl<S: Send + Sync + 'static, P: Send + 'static> ViewObject for View<S, P> {
 
     fn paint(&mut self, _: Layout, element: &mut dyn Any, cx: &mut WindowContext) -> Result<()> {
         self.state.update(cx, |state, cx| {
-            let boxed_element = element.downcast_mut::<Box<dyn Any>>().unwrap();
-            let element = boxed_element.downcast_mut::<AnyElement<S>>().unwrap();
-
+            let element = element.downcast_mut::<AnyElement<S>>().unwrap();
             element.paint(state, None, cx)
         })
     }
@@ -135,7 +133,7 @@ impl<S: 'static> Element for AnyView<S> {
         cx: &mut ViewContext<Self::State>,
     ) -> Result<()> {
         dbg!("Element.paint for AnyView");
-        self.view.lock().paint(layout, element, cx)
+        self.view.lock().paint(layout, element.as_mut(), cx)
     }
 }
 

crates/gpui3/src/window.rs 🔗

@@ -80,33 +80,8 @@ impl<'a, 'w> WindowContext<'a, 'w> {
         }
     }
 
-    pub(crate) fn draw(&mut self) -> Result<()> {
-        dbg!("Draw");
-        let unit_entity = self.unit_entity.clone();
-        self.update_entity(&unit_entity, |_, cx| {
-            let mut root_view = cx.window.root_view.take().unwrap();
-            let (root_layout_id, mut frame_state) = root_view.layout(&mut (), cx)?;
-            let available_space = cx.window.content_size.map(Into::into);
-            cx.window
-                .layout_engine
-                .compute_layout(root_layout_id, available_space)?;
-            let layout = cx.window.layout_engine.layout(root_layout_id)?;
-            dbg!("Paint root view");
-            root_view.paint(layout, &mut (), &mut frame_state, cx)?;
-            cx.window.root_view = Some(root_view);
-            let scene = cx.window.scene.take();
-            dbg!(&scene);
-
-            // todo!
-            // self.run_on_main(|cx| {
-            //     cx.window
-            //         .platform_window
-            //         .borrow_on_main_thread()
-            //         .draw(scene);
-            // });
-
-            Ok(())
-        })
+    pub fn notify(&mut self) {
+        self.window.dirty = true;
     }
 
     pub fn request_layout(
@@ -151,6 +126,37 @@ impl<'a, 'w> WindowContext<'a, 'w> {
     pub fn mouse_position(&self) -> Point<Pixels> {
         self.window.mouse_position
     }
+
+    pub(crate) fn draw(&mut self) -> Result<()> {
+        dbg!("Draw");
+        let unit_entity = self.unit_entity.clone();
+        self.update_entity(&unit_entity, |_, cx| {
+            let mut root_view = cx.window.root_view.take().unwrap();
+            let (root_layout_id, mut frame_state) = root_view.layout(&mut (), cx)?;
+            let available_space = cx.window.content_size.map(Into::into);
+            cx.window
+                .layout_engine
+                .compute_layout(root_layout_id, available_space)?;
+            let layout = cx.window.layout_engine.layout(root_layout_id)?;
+            dbg!("Paint root view");
+            root_view.paint(layout, &mut (), &mut frame_state, cx)?;
+            cx.window.root_view = Some(root_view);
+            let scene = cx.window.scene.take();
+
+            dbg!(&scene);
+
+            // todo!
+            // self.run_on_main(|cx| {
+            //     cx.window
+            //         .platform_window
+            //         .borrow_on_main_thread()
+            //         .draw(scene);
+            // });
+
+            cx.window.dirty = false;
+            Ok(())
+        })
+    }
 }
 
 impl WindowContext<'_, '_, MainThread> {
@@ -268,11 +274,11 @@ impl<'a, 'w, S: Send + Sync + 'static> ViewContext<'a, 'w, S> {
     }
 
     pub fn notify(&mut self) {
-        let entity_id = self.entity_id;
-        self.app
+        self.window_cx.notify();
+        self.window_cx
+            .app
             .pending_effects
-            .push_back(Effect::Notify(entity_id));
-        self.window.dirty = true;
+            .push_back(Effect::Notify(self.entity_id));
     }
 
     pub(crate) fn erase_state<R>(&mut self, f: impl FnOnce(&mut ViewContext<()>) -> R) -> R {