diff --git a/crates/gpui2/src/app.rs b/crates/gpui2/src/app.rs index 97002a8304d560ca138057d48795176a7ca18f1a..f71619bc015de2db2eb5a43951f0d33a782246f9 100644 --- a/crates/gpui2/src/app.rs +++ b/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) -> anyhow::Result; type Handler = Box bool + 'static>; type Listener = Box bool + 'static>; -type QuitHandler = Box LocalBoxFuture<'static, ()> + 'static>; -type ReleaseListener = Box; +type QuitHandler = Box LocalBoxFuture<'static, ()> + 'static>; +type ReleaseListener = Box; pub struct AppContext { this: Weak>, @@ -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( &mut self, - id: WindowId, - update: impl FnOnce(&mut WindowContext) -> R, + handle: AnyWindowHandle, + update: impl FnOnce(AnyView, &mut WindowContext) -> R, ) -> Result { 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); } } diff --git a/crates/gpui2/src/app/async_context.rs b/crates/gpui2/src/app/async_context.rs index ef7108584e2afe4ec8a80c1ba8626f6125242236..08ae307d1b1ad8dc969dd5425b936b50686c13e1 100644 --- a/crates/gpui2/src/app/async_context.rs +++ b/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( &self, handle: AnyWindowHandle, - update: impl FnOnce(&mut WindowContext) -> R, + update: impl FnOnce(AnyView, &mut WindowContext) -> R, ) -> Result { 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(&self, f: impl FnOnce(AsyncAppContext) -> Fut) -> Task @@ -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( &mut self, read: impl FnOnce(&G, &WindowContext) -> R, ) -> Result { - self.app - .update_window(self.window, |cx| read(cx.global(), cx)) + self.window.update(self, |_, cx| read(cx.global(), cx)) } pub fn update_global( @@ -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( @@ -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( @@ -226,8 +221,8 @@ impl Context for AsyncWindowContext { handle: &Model, update: impl FnOnce(&mut T, &mut Self::ModelContext<'_, T>) -> R, ) -> Result { - 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(&mut self, window: AnyWindowHandle, update: F) -> Result @@ -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( @@ -257,8 +252,8 @@ impl VisualContext for AsyncWindowContext { view: &View, update: impl FnOnce(&mut V, &mut Self::ViewContext<'_, V>) -> R, ) -> Self::Result { - 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( @@ -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)) } } diff --git a/crates/gpui2/src/app/model_context.rs b/crates/gpui2/src/app/model_context.rs index a764cd73661d16247b12bd731b496f80c7ead86f..d72b03913925300cb1d915e61174d40ed1326532 100644 --- a/crates/gpui2/src/app/model_context.rs +++ b/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( &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, diff --git a/crates/gpui2/src/app/test_context.rs b/crates/gpui2/src/app/test_context.rs index 9f6fb4d75a72ac82b081a994da4831ddc010e2e9..ee1da50136e26fc121b2d0e805a0d047836497fe 100644 --- a/crates/gpui2/src/app/test_context.rs +++ b/crates/gpui2/src/app/test_context.rs @@ -92,10 +92,10 @@ impl TestAppContext { pub fn update_window( &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(&self, f: impl FnOnce(AsyncAppContext) -> Fut) -> Task diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index ab12f08a1ce6b54f680562af345c96229fdaa20a..f059e02a335a6a199fdbbebc6607c4e184d1c419 100644 --- a/crates/gpui2/src/window.rs +++ b/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 WindowHandle { } pub fn update( - &self, + self, cx: &mut C, update: impl FnOnce(&mut V, &mut as UpdateView>::ViewContext<'_, V>) -> R, ) -> Result @@ -2052,14 +2052,14 @@ impl AnyWindowHandle { } pub fn update( - &self, + self, cx: &mut C, update: impl FnOnce(AnyView, &mut C::WindowContext<'_>) -> R, ) -> Result where C: Context, { - cx.update_window(*self, update) + cx.update_window(self, update) } }