Fix outstanding errors in gpui2

Antonio Scandurra created

Change summary

crates/gpui2/src/app.rs               | 28 ++++++++++----------
crates/gpui2/src/app/async_context.rs | 37 ++++++++++++----------------
crates/gpui2/src/app/model_context.rs |  4 +-
crates/gpui2/src/app/test_context.rs  |  4 +-
crates/gpui2/src/window.rs            | 26 ++++++++++----------
5 files changed, 47 insertions(+), 52 deletions(-)

Detailed changes

crates/gpui2/src/app.rs 🔗

@@ -16,9 +16,9 @@ use crate::{
     current_platform, image_cache::ImageCache, Action, AnyBox, AnyView, AnyWindowHandle,
     AppMetadata, AssetSource, BackgroundExecutor, ClipboardItem, Context, DispatchPhase, DisplayId,
     Entity, FocusEvent, FocusHandle, FocusId, ForegroundExecutor, KeyBinding, Keymap, LayoutId,
-    Pixels, Platform, PlatformDisplay, Point, Render, SharedString, SubscriberSet, Subscription,
-    SvgRenderer, Task, TextStyle, TextStyleRefinement, TextSystem, View, Window, WindowContext,
-    WindowHandle, WindowId,
+    Pixels, Platform, Point, Render, SharedString, SubscriberSet, Subscription, SvgRenderer, Task,
+    TextStyle, TextStyleRefinement, TextSystem, View, Window, WindowContext, WindowHandle,
+    WindowId,
 };
 use anyhow::{anyhow, Result};
 use collections::{HashMap, HashSet, VecDeque};
@@ -115,8 +115,8 @@ type ActionBuilder = fn(json: Option<serde_json::Value>) -> anyhow::Result<Box<d
 type FrameCallback = Box<dyn FnOnce(&mut WindowContext)>;
 type Handler = Box<dyn FnMut(&mut AppContext) -> bool + 'static>;
 type Listener = Box<dyn FnMut(&dyn Any, &mut AppContext) -> bool + 'static>;
-type QuitHandler = Box<dyn FnMut(&mut AppContext) -> LocalBoxFuture<'static, ()> + 'static>;
-type ReleaseListener = Box<dyn FnMut(&mut dyn Any, &mut AppContext) + 'static>;
+type QuitHandler = Box<dyn FnOnce(&mut AppContext) -> LocalBoxFuture<'static, ()> + 'static>;
+type ReleaseListener = Box<dyn FnOnce(&mut dyn Any, &mut AppContext) + 'static>;
 
 pub struct AppContext {
     this: Weak<RefCell<AppContext>>,
@@ -215,10 +215,9 @@ impl AppContext {
     pub fn quit(&mut self) {
         let mut futures = Vec::new();
 
-        self.quit_observers.clone().retain(&(), |observer| {
+        for observer in self.quit_observers.remove(&()) {
             futures.push(observer(self));
-            true
-        });
+        }
 
         self.windows.clear();
         self.flush_effects();
@@ -265,21 +264,22 @@ impl AppContext {
 
     pub(crate) fn update_window<R>(
         &mut self,
-        id: WindowId,
-        update: impl FnOnce(&mut WindowContext) -> R,
+        handle: AnyWindowHandle,
+        update: impl FnOnce(AnyView, &mut WindowContext) -> R,
     ) -> Result<R> {
         self.update(|cx| {
             let mut window = cx
                 .windows
-                .get_mut(id)
+                .get_mut(handle.id)
                 .ok_or_else(|| anyhow!("window not found"))?
                 .take()
                 .unwrap();
 
-            let result = update(&mut WindowContext::new(cx, &mut window));
+            let root_view = window.root_view.clone().unwrap();
+            let result = update(root_view, &mut WindowContext::new(cx, &mut window));
 
             cx.windows
-                .get_mut(id)
+                .get_mut(handle.id)
                 .ok_or_else(|| anyhow!("window not found"))?
                 .replace(window);
 
@@ -432,7 +432,7 @@ impl AppContext {
             for (entity_id, mut entity) in dropped {
                 self.observers.remove(&entity_id);
                 self.event_listeners.remove(&entity_id);
-                for mut release_callback in self.release_listeners.remove(&entity_id) {
+                for release_callback in self.release_listeners.remove(&entity_id) {
                     release_callback(entity.as_mut(), self);
                 }
             }

crates/gpui2/src/app/async_context.rs 🔗

@@ -1,11 +1,10 @@
 use crate::{
     AnyView, AnyWindowHandle, AppContext, BackgroundExecutor, Context, ForegroundExecutor, Model,
     ModelContext, Render, Result, Task, View, ViewContext, VisualContext, WindowContext,
-    WindowHandle,
 };
 use anyhow::{anyhow, Context as _};
 use derive_more::{Deref, DerefMut};
-use std::{cell::RefCell, future::Future, mem, rc::Weak};
+use std::{cell::RefCell, future::Future, rc::Weak};
 
 #[derive(Clone)]
 pub struct AsyncAppContext {
@@ -88,14 +87,14 @@ impl AsyncAppContext {
     pub fn update_window<R>(
         &self,
         handle: AnyWindowHandle,
-        update: impl FnOnce(&mut WindowContext) -> R,
+        update: impl FnOnce(AnyView, &mut WindowContext) -> R,
     ) -> Result<R> {
         let app = self
             .app
             .upgrade()
             .ok_or_else(|| anyhow!("app was released"))?;
         let mut app_context = app.borrow_mut();
-        app_context.update_window(handle.id, update)
+        app_context.update_window(handle, update)
     }
 
     pub fn spawn<Fut, R>(&self, f: impl FnOnce(AsyncAppContext) -> Fut) -> Task<R>
@@ -167,17 +166,14 @@ impl AsyncWindowContext {
     }
 
     pub fn on_next_frame(&mut self, f: impl FnOnce(&mut WindowContext) + Send + 'static) {
-        self.app
-            .update_window(self.window, |cx| cx.on_next_frame(f))
-            .ok();
+        self.window.update(self, |_, cx| cx.on_next_frame(f)).ok();
     }
 
     pub fn read_global<G: 'static, R>(
         &mut self,
         read: impl FnOnce(&G, &WindowContext) -> R,
     ) -> Result<R> {
-        self.app
-            .update_window(self.window, |cx| read(cx.global(), cx))
+        self.window.update(self, |_, cx| read(cx.global(), cx))
     }
 
     pub fn update_global<G, R>(
@@ -187,8 +183,7 @@ impl AsyncWindowContext {
     where
         G: 'static,
     {
-        self.app
-            .update_window(self.window, |cx| cx.update_global(update))
+        self.window.update(self, |_, cx| cx.update_global(update))
     }
 
     pub fn spawn<Fut, R>(
@@ -217,8 +212,8 @@ impl Context for AsyncWindowContext {
     where
         T: 'static,
     {
-        self.app
-            .update_window(self.window, |cx| cx.build_model(build_model))
+        self.window
+            .update(self, |_, cx| cx.build_model(build_model))
     }
 
     fn update_model<T: 'static, R>(
@@ -226,8 +221,8 @@ impl Context for AsyncWindowContext {
         handle: &Model<T>,
         update: impl FnOnce(&mut T, &mut Self::ModelContext<'_, T>) -> R,
     ) -> Result<R> {
-        self.app
-            .update_window(self.window, |cx| cx.update_model(handle, update))
+        self.window
+            .update(self, |_, cx| cx.update_model(handle, update))
     }
 
     fn update_window<T, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<T>
@@ -248,8 +243,8 @@ impl VisualContext for AsyncWindowContext {
     where
         V: 'static,
     {
-        self.app
-            .update_window(self.window, |cx| cx.build_view(build_view_state))
+        self.window
+            .update(self, |_, cx| cx.build_view(build_view_state))
     }
 
     fn update_view<V: 'static, R>(
@@ -257,8 +252,8 @@ impl VisualContext for AsyncWindowContext {
         view: &View<V>,
         update: impl FnOnce(&mut V, &mut Self::ViewContext<'_, V>) -> R,
     ) -> Self::Result<R> {
-        self.app
-            .update_window(self.window, |cx| cx.update_view(view, update))
+        self.window
+            .update(self, |_, cx| cx.update_view(view, update))
     }
 
     fn replace_root_view<V>(
@@ -268,7 +263,7 @@ impl VisualContext for AsyncWindowContext {
     where
         V: 'static + Send + Render,
     {
-        self.app
-            .update_window(self.window, |cx| cx.replace_root_view(build_view))
+        self.window
+            .update(self, |_, cx| cx.replace_root_view(build_view))
     }
 }

crates/gpui2/src/app/model_context.rs 🔗

@@ -93,7 +93,7 @@ impl<'a, T: 'static> ModelContext<'a, T> {
 
     pub fn on_release(
         &mut self,
-        mut on_release: impl FnMut(&mut T, &mut AppContext) + 'static,
+        on_release: impl FnOnce(&mut T, &mut AppContext) + 'static,
     ) -> Subscription
     where
         T: 'static,
@@ -110,7 +110,7 @@ impl<'a, T: 'static> ModelContext<'a, T> {
     pub fn observe_release<T2, E>(
         &mut self,
         entity: &E,
-        mut on_release: impl FnMut(&mut T, &mut T2, &mut ModelContext<'_, T>) + 'static,
+        on_release: impl FnOnce(&mut T, &mut T2, &mut ModelContext<'_, T>) + 'static,
     ) -> Subscription
     where
         T: Any,

crates/gpui2/src/app/test_context.rs 🔗

@@ -92,10 +92,10 @@ impl TestAppContext {
     pub fn update_window<R>(
         &self,
         handle: AnyWindowHandle,
-        update: impl FnOnce(&mut WindowContext) -> R,
+        update: impl FnOnce(AnyView, &mut WindowContext) -> R,
     ) -> R {
         let mut app = self.app.borrow_mut();
-        app.update_window(handle.id, update).unwrap()
+        app.update_window(handle, update).unwrap()
     }
 
     pub fn spawn<Fut, R>(&self, f: impl FnOnce(AsyncAppContext) -> Fut) -> Task<R>

crates/gpui2/src/window.rs 🔗

@@ -204,14 +204,15 @@ impl Window {
         platform_window.on_resize(Box::new({
             let mut cx = cx.to_async();
             move |content_size, scale_factor| {
-                cx.update_window(handle, |cx| {
-                    cx.window.scale_factor = scale_factor;
-                    cx.window.scene_builder = SceneBuilder::new();
-                    cx.window.content_size = content_size;
-                    cx.window.display_id = cx.window.platform_window.display().id();
-                    cx.window.dirty = true;
-                })
-                .log_err();
+                handle
+                    .update(&mut cx, |_, cx| {
+                        cx.window.scale_factor = scale_factor;
+                        cx.window.scene_builder = SceneBuilder::new();
+                        cx.window.content_size = content_size;
+                        cx.window.display_id = cx.window.platform_window.display().id();
+                        cx.window.dirty = true;
+                    })
+                    .log_err();
             }
         }));
 
@@ -416,7 +417,7 @@ impl<'a> WindowContext<'a> {
                 return;
             }
         } else {
-            let async_cx = self.to_async();
+            let mut async_cx = self.to_async();
             self.next_frame_callbacks.insert(display_id, vec![f]);
             self.platform().set_display_link_output_callback(
                 display_id,
@@ -1681,7 +1682,6 @@ impl<'a, V: 'static> ViewContext<'a, V> {
             self.view.model.entity_id,
             Box::new(move |this, cx| {
                 let this = this.downcast_mut().expect("invalid entity type");
-                // todo!("are we okay with silently swallowing the error?")
                 let _ = window_handle.update(cx, |_, cx| on_release(this, cx));
             }),
         )
@@ -1981,7 +1981,7 @@ impl<V: 'static + Render> WindowHandle<V> {
     }
 
     pub fn update<C, R>(
-        &self,
+        self,
         cx: &mut C,
         update: impl FnOnce(&mut V, &mut <C::WindowContext<'_> as UpdateView>::ViewContext<'_, V>) -> R,
     ) -> Result<R>
@@ -2052,14 +2052,14 @@ impl AnyWindowHandle {
     }
 
     pub fn update<C, R>(
-        &self,
+        self,
         cx: &mut C,
         update: impl FnOnce(AnyView, &mut C::WindowContext<'_>) -> R,
     ) -> Result<R>
     where
         C: Context,
     {
-        cx.update_window(*self, update)
+        cx.update_window(self, update)
     }
 }