diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index c99ee073b85d86c5971f3274a4d149895c821b4e..dc0bc36443672a2374c847ce9345b98aa84d4d6d 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -2215,8 +2215,6 @@ impl App { } impl AppContext for App { - type Result = T; - /// Builds an entity that is owned by the application. /// /// The given function will be invoked with a [`Context`] and must return an object representing the entity. An @@ -2238,7 +2236,7 @@ impl AppContext for App { }) } - fn reserve_entity(&mut self) -> Self::Result> { + fn reserve_entity(&mut self) -> Reservation { Reservation(self.entities.reserve()) } @@ -2246,7 +2244,7 @@ impl AppContext for App { &mut self, reservation: Reservation, build_entity: impl FnOnce(&mut Context) -> T, - ) -> Self::Result> { + ) -> Entity { self.update(|cx| { let slot = reservation.0; let entity = build_entity(&mut Context::new_context(cx, slot.downgrade())); @@ -2279,11 +2277,7 @@ impl AppContext for App { GpuiBorrow::new(handle.clone(), self) } - fn read_entity( - &self, - handle: &Entity, - read: impl FnOnce(&T, &App) -> R, - ) -> Self::Result + fn read_entity(&self, handle: &Entity, read: impl FnOnce(&T, &App) -> R) -> R where T: 'static, { @@ -2328,7 +2322,7 @@ impl AppContext for App { self.background_executor.spawn(future) } - fn read_global(&self, callback: impl FnOnce(&G, &App) -> R) -> Self::Result + fn read_global(&self, callback: impl FnOnce(&G, &App) -> R) -> R where G: Global, { diff --git a/crates/gpui/src/app/async_context.rs b/crates/gpui/src/app/async_context.rs index 3f9d21ef65ab16350c8d16fa3197ac507e5d503e..0c592f90697b19527af8b08e87ae4e7935316c78 100644 --- a/crates/gpui/src/app/async_context.rs +++ b/crates/gpui/src/app/async_context.rs @@ -1,9 +1,10 @@ use crate::{ AnyView, AnyWindowHandle, App, AppCell, AppContext, BackgroundExecutor, BorrowAppContext, - Entity, EventEmitter, Focusable, ForegroundExecutor, Global, PromptButton, PromptLevel, Render, - Reservation, Result, Subscription, Task, VisualContext, Window, WindowHandle, + Entity, EventEmitter, Focusable, ForegroundExecutor, Global, GpuiBorrow, PromptButton, + PromptLevel, Render, Reservation, Result, Subscription, Task, VisualContext, Window, + WindowHandle, }; -use anyhow::{Context as _, anyhow}; +use anyhow::Context as _; use derive_more::{Deref, DerefMut}; use futures::channel::oneshot; use std::{future::Future, rc::Weak}; @@ -12,7 +13,10 @@ use super::{Context, WeakEntity}; /// An async-friendly version of [App] with a static lifetime so it can be held across `await` points in async code. /// You're provided with an instance when calling [App::spawn], and you can also create one with [App::to_async]. -/// Internally, this holds a weak reference to an `App`, so its methods are fallible to protect against cases where the [App] is dropped. +/// +/// Internally, this holds a weak reference to an `App`. Methods will panic if the app has been dropped, +/// but this should not happen in practice when using foreground tasks spawned via `cx.spawn()`, +/// as the executor checks if the app is alive before running each task. #[derive(Clone)] pub struct AsyncApp { pub(crate) app: Weak, @@ -21,64 +25,61 @@ pub struct AsyncApp { pub(crate) foreground_executor: ForegroundExecutor, } -impl AppContext for AsyncApp { - type Result = Result; +impl AsyncApp { + fn app(&self) -> std::rc::Rc { + self.app + .upgrade() + .expect("app was released before async operation completed") + } +} - fn new( - &mut self, - build_entity: impl FnOnce(&mut Context) -> T, - ) -> Self::Result> { - let app = self.app.upgrade().context("app was released")?; +impl AppContext for AsyncApp { + fn new(&mut self, build_entity: impl FnOnce(&mut Context) -> T) -> Entity { + let app = self.app(); let mut app = app.borrow_mut(); - Ok(app.new(build_entity)) + app.new(build_entity) } - fn reserve_entity(&mut self) -> Result> { - let app = self.app.upgrade().context("app was released")?; + fn reserve_entity(&mut self) -> Reservation { + let app = self.app(); let mut app = app.borrow_mut(); - Ok(app.reserve_entity()) + app.reserve_entity() } fn insert_entity( &mut self, reservation: Reservation, build_entity: impl FnOnce(&mut Context) -> T, - ) -> Result> { - let app = self.app.upgrade().context("app was released")?; + ) -> Entity { + let app = self.app(); let mut app = app.borrow_mut(); - Ok(app.insert_entity(reservation, build_entity)) + app.insert_entity(reservation, build_entity) } fn update_entity( &mut self, handle: &Entity, update: impl FnOnce(&mut T, &mut Context) -> R, - ) -> Self::Result { - let app = self.app.upgrade().context("app was released")?; + ) -> R { + let app = self.app(); let mut app = app.borrow_mut(); - Ok(app.update_entity(handle, update)) + app.update_entity(handle, update) } - fn as_mut<'a, T>(&'a mut self, _handle: &Entity) -> Self::Result> + fn as_mut<'a, T>(&'a mut self, _handle: &Entity) -> GpuiBorrow<'a, T> where T: 'static, { - Err(anyhow!( - "Cannot as_mut with an async context. Try calling update() first" - )) + panic!("Cannot as_mut with an async context. Try calling update() first") } - fn read_entity( - &self, - handle: &Entity, - callback: impl FnOnce(&T, &App) -> R, - ) -> Self::Result + fn read_entity(&self, handle: &Entity, callback: impl FnOnce(&T, &App) -> R) -> R where T: 'static, { - let app = self.app.upgrade().context("app was released")?; + let app = self.app(); let lock = app.borrow(); - Ok(lock.read_entity(handle, callback)) + lock.read_entity(handle, callback) } fn update_window(&mut self, window: AnyWindowHandle, f: F) -> Result @@ -110,23 +111,22 @@ impl AppContext for AsyncApp { self.background_executor.spawn(future) } - fn read_global(&self, callback: impl FnOnce(&G, &App) -> R) -> Self::Result + fn read_global(&self, callback: impl FnOnce(&G, &App) -> R) -> R where G: Global, { - let app = self.app.upgrade().context("app was released")?; + let app = self.app(); let mut lock = app.borrow_mut(); - Ok(lock.update(|this| this.read_global(callback))) + lock.update(|this| this.read_global(callback)) } } impl AsyncApp { /// Schedules all windows in the application to be redrawn. - pub fn refresh(&self) -> Result<()> { - let app = self.app.upgrade().context("app was released")?; + pub fn refresh(&self) { + let app = self.app(); let mut lock = app.borrow_mut(); lock.refresh_windows(); - Ok(()) } /// Get an executor which can be used to spawn futures in the background. @@ -140,10 +140,10 @@ impl AsyncApp { } /// Invoke the given function in the context of the app, then flush any effects produced during its invocation. - pub fn update(&self, f: impl FnOnce(&mut App) -> R) -> Result { - let app = self.app.upgrade().context("app was released")?; + pub fn update(&self, f: impl FnOnce(&mut App) -> R) -> R { + let app = self.app(); let mut lock = app.borrow_mut(); - Ok(lock.update(f)) + lock.update(f) } /// Arrange for the given callback to be invoked whenever the given entity emits an event of a given type. @@ -151,16 +151,15 @@ impl AsyncApp { pub fn subscribe( &mut self, entity: &Entity, - mut on_event: impl FnMut(Entity, &Event, &mut App) + 'static, - ) -> Result + on_event: impl FnMut(Entity, &Event, &mut App) + 'static, + ) -> Subscription where T: 'static + EventEmitter, Event: 'static, { - let app = self.app.upgrade().context("app was released")?; + let app = self.app(); let mut lock = app.borrow_mut(); - let subscription = lock.subscribe(entity, on_event); - Ok(subscription) + lock.subscribe(entity, on_event) } /// Open a window with the given options based on the root view returned by the given function. @@ -172,7 +171,7 @@ impl AsyncApp { where V: 'static + Render, { - let app = self.app.upgrade().context("app was released")?; + let app = self.app(); let mut lock = app.borrow_mut(); lock.open_window(options, build_root_view) } @@ -190,61 +189,50 @@ impl AsyncApp { } /// Determine whether global state of the specified type has been assigned. - /// Returns an error if the `App` has been dropped. - pub fn has_global(&self) -> Result { - let app = self.app.upgrade().context("app was released")?; + pub fn has_global(&self) -> bool { + let app = self.app(); let app = app.borrow_mut(); - Ok(app.has_global::()) + app.has_global::() } /// Reads the global state of the specified type, passing it to the given callback. /// /// Panics if no global state of the specified type has been assigned. - /// Returns an error if the `App` has been dropped. - pub fn read_global(&self, read: impl FnOnce(&G, &App) -> R) -> Result { - let app = self.app.upgrade().context("app was released")?; + pub fn read_global(&self, read: impl FnOnce(&G, &App) -> R) -> R { + let app = self.app(); let app = app.borrow_mut(); - Ok(read(app.global(), &app)) + read(app.global(), &app) } /// Reads the global state of the specified type, passing it to the given callback. /// /// Similar to [`AsyncApp::read_global`], but returns an error instead of panicking - /// if no state of the specified type has been assigned. - /// - /// Returns an error if no state of the specified type has been assigned the `App` has been dropped. pub fn try_read_global(&self, read: impl FnOnce(&G, &App) -> R) -> Option { - let app = self.app.upgrade()?; + let app = self.app(); let app = app.borrow_mut(); Some(read(app.try_global()?, &app)) } /// Reads the global state of the specified type, passing it to the given callback. /// A default value is assigned if a global of this type has not yet been assigned. - /// - /// # Errors - /// If the app has ben dropped this returns an error. - pub fn try_read_default_global( + pub fn read_default_global( &self, read: impl FnOnce(&G, &App) -> R, - ) -> Result { - let app = self.app.upgrade().context("app was released")?; + ) -> R { + let app = self.app(); let mut app = app.borrow_mut(); app.update(|cx| { cx.default_global::(); }); - Ok(read(app.try_global().context("app was released")?, &app)) + read(app.global(), &app) } /// A convenience method for [`App::update_global`](BorrowAppContext::update_global) /// for updating the global state of the specified type. - pub fn update_global( - &self, - update: impl FnOnce(&mut G, &mut App) -> R, - ) -> Result { - let app = self.app.upgrade().context("app was released")?; + pub fn update_global(&self, update: impl FnOnce(&mut G, &mut App) -> R) -> R { + let app = self.app(); let mut app = app.borrow_mut(); - Ok(app.update(|cx| cx.update_global(update))) + app.update(|cx| cx.update_global(update)) } /// Run something using this entity and cx, when the returned struct is dropped @@ -363,54 +351,41 @@ impl AsyncWindowContext { } impl AppContext for AsyncWindowContext { - type Result = Result; - - fn new(&mut self, build_entity: impl FnOnce(&mut Context) -> T) -> Result> + fn new(&mut self, build_entity: impl FnOnce(&mut Context) -> T) -> Entity where T: 'static, { - self.app - .update_window(self.window, |_, _, cx| cx.new(build_entity)) + self.app.new(build_entity) } - fn reserve_entity(&mut self) -> Result> { - self.app - .update_window(self.window, |_, _, cx| cx.reserve_entity()) + fn reserve_entity(&mut self) -> Reservation { + self.app.reserve_entity() } fn insert_entity( &mut self, reservation: Reservation, build_entity: impl FnOnce(&mut Context) -> T, - ) -> Self::Result> { - self.app.update_window(self.window, |_, _, cx| { - cx.insert_entity(reservation, build_entity) - }) + ) -> Entity { + self.app.insert_entity(reservation, build_entity) } fn update_entity( &mut self, handle: &Entity, update: impl FnOnce(&mut T, &mut Context) -> R, - ) -> Result { - self.app - .update_window(self.window, |_, _, cx| cx.update_entity(handle, update)) + ) -> R { + self.app.update_entity(handle, update) } - fn as_mut<'a, T>(&'a mut self, _: &Entity) -> Self::Result> + fn as_mut<'a, T>(&'a mut self, _: &Entity) -> GpuiBorrow<'a, T> where T: 'static, { - Err(anyhow!( - "Cannot use as_mut() from an async context, call `update`" - )) + panic!("Cannot use as_mut() from an async context, call `update`") } - fn read_entity( - &self, - handle: &Entity, - read: impl FnOnce(&T, &App) -> R, - ) -> Self::Result + fn read_entity(&self, handle: &Entity, read: impl FnOnce(&T, &App) -> R) -> R where T: 'static, { @@ -442,7 +417,7 @@ impl AppContext for AsyncWindowContext { self.app.background_executor.spawn(future) } - fn read_global(&self, callback: impl FnOnce(&G, &App) -> R) -> Result + fn read_global(&self, callback: impl FnOnce(&G, &App) -> R) -> R where G: Global, { @@ -458,7 +433,7 @@ impl VisualContext for AsyncWindowContext { fn new_window_entity( &mut self, build_entity: impl FnOnce(&mut Window, &mut Context) -> T, - ) -> Self::Result> { + ) -> Result> { self.app.update_window(self.window, |_, window, cx| { cx.new(|cx| build_entity(window, cx)) }) @@ -468,7 +443,7 @@ impl VisualContext for AsyncWindowContext { &mut self, view: &Entity, update: impl FnOnce(&mut T, &mut Window, &mut Context) -> R, - ) -> Self::Result { + ) -> Result { self.app.update_window(self.window, |_, window, cx| { view.update(cx, |entity, cx| update(entity, window, cx)) }) @@ -477,7 +452,7 @@ impl VisualContext for AsyncWindowContext { fn replace_root_view( &mut self, build_view: impl FnOnce(&mut Window, &mut Context) -> V, - ) -> Self::Result> + ) -> Result> where V: 'static + Render, { @@ -486,7 +461,7 @@ impl VisualContext for AsyncWindowContext { }) } - fn focus(&mut self, view: &Entity) -> Self::Result<()> + fn focus(&mut self, view: &Entity) -> Result<()> where V: Focusable, { diff --git a/crates/gpui/src/app/context.rs b/crates/gpui/src/app/context.rs index b780ca426c15c99030f24ee48bde978ad38526e7..aa482ccd07136f2823b364292dcf0d4a18e98039 100644 --- a/crates/gpui/src/app/context.rs +++ b/crates/gpui/src/app/context.rs @@ -753,8 +753,6 @@ impl Context<'_, T> { } impl AppContext for Context<'_, T> { - type Result = U; - #[inline] fn new(&mut self, build_entity: impl FnOnce(&mut Context) -> U) -> Entity { self.app.new(build_entity) @@ -770,7 +768,7 @@ impl AppContext for Context<'_, T> { &mut self, reservation: Reservation, build_entity: impl FnOnce(&mut Context) -> U, - ) -> Self::Result> { + ) -> Entity { self.app.insert_entity(reservation, build_entity) } @@ -784,7 +782,7 @@ impl AppContext for Context<'_, T> { } #[inline] - fn as_mut<'a, E>(&'a mut self, handle: &Entity) -> Self::Result> + fn as_mut<'a, E>(&'a mut self, handle: &Entity) -> super::GpuiBorrow<'a, E> where E: 'static, { @@ -792,11 +790,7 @@ impl AppContext for Context<'_, T> { } #[inline] - fn read_entity( - &self, - handle: &Entity, - read: impl FnOnce(&U, &App) -> R, - ) -> Self::Result + fn read_entity(&self, handle: &Entity, read: impl FnOnce(&U, &App) -> R) -> R where U: 'static, { @@ -832,7 +826,7 @@ impl AppContext for Context<'_, T> { } #[inline] - fn read_global(&self, callback: impl FnOnce(&G, &App) -> R) -> Self::Result + fn read_global(&self, callback: impl FnOnce(&G, &App) -> R) -> R where G: Global, { diff --git a/crates/gpui/src/app/entity_map.rs b/crates/gpui/src/app/entity_map.rs index 8c1bdfa1cee509dcbc061200cb651ce5d3bf4fcd..a3604f5de65f7b763db32c7cc64b35664abbbda7 100644 --- a/crates/gpui/src/app/entity_map.rs +++ b/crates/gpui/src/app/entity_map.rs @@ -431,11 +431,7 @@ impl Entity { /// Read the entity referenced by this handle with the given function. #[inline] - pub fn read_with( - &self, - cx: &C, - f: impl FnOnce(&T, &App) -> R, - ) -> C::Result { + pub fn read_with(&self, cx: &C, f: impl FnOnce(&T, &App) -> R) -> R { cx.read_entity(self, f) } @@ -445,18 +441,18 @@ impl Entity { &self, cx: &mut C, update: impl FnOnce(&mut T, &mut Context) -> R, - ) -> C::Result { + ) -> R { cx.update_entity(self, update) } /// Updates the entity referenced by this handle with the given function. #[inline] - pub fn as_mut<'a, C: AppContext>(&self, cx: &'a mut C) -> C::Result> { + pub fn as_mut<'a, C: AppContext>(&self, cx: &'a mut C) -> GpuiBorrow<'a, T> { cx.as_mut(self) } /// Updates the entity referenced by this handle with the given function. - pub fn write(&self, cx: &mut C, value: T) -> C::Result<()> { + pub fn write(&self, cx: &mut C, value: T) { self.update(cx, |entity, cx| { *entity = value; cx.notify(); @@ -465,13 +461,13 @@ impl Entity { /// Updates the entity referenced by this handle with the given function if /// the referenced entity still exists, within a visual context that has a window. - /// Returns an error if the entity has been released. + /// Returns an error if the window has been closed. #[inline] pub fn update_in( &self, cx: &mut C, update: impl FnOnce(&mut T, &mut Window, &mut Context) -> R, - ) -> C::Result { + ) -> Result { cx.update_window_entity(self, update) } } @@ -749,13 +745,9 @@ impl WeakEntity { ) -> Result where C: AppContext, - Result>: crate::Flatten, { - crate::Flatten::flatten( - self.upgrade() - .context("entity released") - .map(|this| cx.update_entity(&this, update)), - ) + let entity = self.upgrade().context("entity released")?; + Ok(cx.update_entity(&entity, update)) } /// Updates the entity referenced by this handle with the given function if @@ -768,14 +760,13 @@ impl WeakEntity { ) -> Result where C: VisualContext, - Result>: crate::Flatten, { let window = cx.window_handle(); - let this = self.upgrade().context("entity released")?; + let entity = self.upgrade().context("entity released")?; - crate::Flatten::flatten(window.update(cx, |_, window, cx| { - this.update(cx, |entity, cx| update(entity, window, cx)) - })) + window.update(cx, |_, window, cx| { + entity.update(cx, |entity, cx| update(entity, window, cx)) + }) } /// Reads the entity referenced by this handle with the given function if @@ -784,13 +775,9 @@ impl WeakEntity { pub fn read_with(&self, cx: &C, read: impl FnOnce(&T, &App) -> R) -> Result where C: AppContext, - Result>: crate::Flatten, { - crate::Flatten::flatten( - self.upgrade() - .context("entity released") - .map(|this| cx.read_entity(&this, read)), - ) + let entity = self.upgrade().context("entity released")?; + Ok(cx.read_entity(&entity, read)) } /// Create a new weak entity that can never be upgraded. diff --git a/crates/gpui/src/app/test_context.rs b/crates/gpui/src/app/test_context.rs index d7a1e4704584595d769989b421ccd767fba58985..fe4b7cfc47914df5a6fe0bd88b36061c5c999b8a 100644 --- a/crates/gpui/src/app/test_context.rs +++ b/crates/gpui/src/app/test_context.rs @@ -33,17 +33,12 @@ pub struct TestAppContext { } impl AppContext for TestAppContext { - type Result = T; - - fn new( - &mut self, - build_entity: impl FnOnce(&mut Context) -> T, - ) -> Self::Result> { + fn new(&mut self, build_entity: impl FnOnce(&mut Context) -> T) -> Entity { let mut app = self.app.borrow_mut(); app.new(build_entity) } - fn reserve_entity(&mut self) -> Self::Result> { + fn reserve_entity(&mut self) -> crate::Reservation { let mut app = self.app.borrow_mut(); app.reserve_entity() } @@ -52,7 +47,7 @@ impl AppContext for TestAppContext { &mut self, reservation: crate::Reservation, build_entity: impl FnOnce(&mut Context) -> T, - ) -> Self::Result> { + ) -> Entity { let mut app = self.app.borrow_mut(); app.insert_entity(reservation, build_entity) } @@ -61,23 +56,19 @@ impl AppContext for TestAppContext { &mut self, handle: &Entity, update: impl FnOnce(&mut T, &mut Context) -> R, - ) -> Self::Result { + ) -> R { let mut app = self.app.borrow_mut(); app.update_entity(handle, update) } - fn as_mut<'a, T>(&'a mut self, _: &Entity) -> Self::Result> + fn as_mut<'a, T>(&'a mut self, _: &Entity) -> super::GpuiBorrow<'a, T> where T: 'static, { panic!("Cannot use as_mut with a test app context. Try calling update() first") } - fn read_entity( - &self, - handle: &Entity, - read: impl FnOnce(&T, &App) -> R, - ) -> Self::Result + fn read_entity(&self, handle: &Entity, read: impl FnOnce(&T, &App) -> R) -> R where T: 'static, { @@ -112,7 +103,7 @@ impl AppContext for TestAppContext { self.background_executor.spawn(future) } - fn read_global(&self, callback: impl FnOnce(&G, &App) -> R) -> Self::Result + fn read_global(&self, callback: impl FnOnce(&G, &App) -> R) -> R where G: Global, { @@ -917,16 +908,11 @@ impl VisualTestContext { } impl AppContext for VisualTestContext { - type Result = ::Result; - - fn new( - &mut self, - build_entity: impl FnOnce(&mut Context) -> T, - ) -> Self::Result> { + fn new(&mut self, build_entity: impl FnOnce(&mut Context) -> T) -> Entity { self.cx.new(build_entity) } - fn reserve_entity(&mut self) -> Self::Result> { + fn reserve_entity(&mut self) -> crate::Reservation { self.cx.reserve_entity() } @@ -934,7 +920,7 @@ impl AppContext for VisualTestContext { &mut self, reservation: crate::Reservation, build_entity: impl FnOnce(&mut Context) -> T, - ) -> Self::Result> { + ) -> Entity { self.cx.insert_entity(reservation, build_entity) } @@ -942,25 +928,21 @@ impl AppContext for VisualTestContext { &mut self, handle: &Entity, update: impl FnOnce(&mut T, &mut Context) -> R, - ) -> Self::Result + ) -> R where T: 'static, { self.cx.update_entity(handle, update) } - fn as_mut<'a, T>(&'a mut self, handle: &Entity) -> Self::Result> + fn as_mut<'a, T>(&'a mut self, handle: &Entity) -> super::GpuiBorrow<'a, T> where T: 'static, { self.cx.as_mut(handle) } - fn read_entity( - &self, - handle: &Entity, - read: impl FnOnce(&T, &App) -> R, - ) -> Self::Result + fn read_entity(&self, handle: &Entity, read: impl FnOnce(&T, &App) -> R) -> R where T: 'static, { @@ -992,7 +974,7 @@ impl AppContext for VisualTestContext { self.cx.background_spawn(future) } - fn read_global(&self, callback: impl FnOnce(&G, &App) -> R) -> Self::Result + fn read_global(&self, callback: impl FnOnce(&G, &App) -> R) -> R where G: Global, { @@ -1009,46 +991,38 @@ impl VisualContext for VisualTestContext { fn new_window_entity( &mut self, build_entity: impl FnOnce(&mut Window, &mut Context) -> T, - ) -> Self::Result> { - self.window - .update(&mut self.cx, |_, window, cx| { - cx.new(|cx| build_entity(window, cx)) - }) - .unwrap() + ) -> Result> { + self.window.update(&mut self.cx, |_, window, cx| { + cx.new(|cx| build_entity(window, cx)) + }) } fn update_window_entity( &mut self, view: &Entity, update: impl FnOnce(&mut V, &mut Window, &mut Context) -> R, - ) -> Self::Result { - self.window - .update(&mut self.cx, |_, window, cx| { - view.update(cx, |v, cx| update(v, window, cx)) - }) - .unwrap() + ) -> Result { + self.window.update(&mut self.cx, |_, window, cx| { + view.update(cx, |v, cx| update(v, window, cx)) + }) } fn replace_root_view( &mut self, build_view: impl FnOnce(&mut Window, &mut Context) -> V, - ) -> Self::Result> + ) -> Result> where V: 'static + Render, { - self.window - .update(&mut self.cx, |_, window, cx| { - window.replace_root(cx, build_view) - }) - .unwrap() + self.window.update(&mut self.cx, |_, window, cx| { + window.replace_root(cx, build_view) + }) } - fn focus(&mut self, view: &Entity) -> Self::Result<()> { - self.window - .update(&mut self.cx, |_, window, cx| { - view.read(cx).focus_handle(cx).focus(window, cx) - }) - .unwrap() + fn focus(&mut self, view: &Entity) -> Result<()> { + self.window.update(&mut self.cx, |_, window, cx| { + view.read(cx).focus_handle(cx).focus(window, cx) + }) } } diff --git a/crates/gpui/src/gpui.rs b/crates/gpui/src/gpui.rs index 76a61e286d3fe6c1acae8e4e628d4c9130f1305f..9935cc29a5b0ed45184c062b6a190c92cadf3460 100644 --- a/crates/gpui/src/gpui.rs +++ b/crates/gpui/src/gpui.rs @@ -118,23 +118,16 @@ pub use window::*; /// The context trait, allows the different contexts in GPUI to be used /// interchangeably for certain operations. pub trait AppContext { - /// The result type for this context, used for async contexts that - /// can't hold a direct reference to the application context. - type Result; - /// Create a new entity in the app context. #[expect( clippy::wrong_self_convention, reason = "`App::new` is an ubiquitous function for creating entities" )] - fn new( - &mut self, - build_entity: impl FnOnce(&mut Context) -> T, - ) -> Self::Result>; + fn new(&mut self, build_entity: impl FnOnce(&mut Context) -> T) -> Entity; /// Reserve a slot for a entity to be inserted later. /// The returned [Reservation] allows you to obtain the [EntityId] for the future entity. - fn reserve_entity(&mut self) -> Self::Result>; + fn reserve_entity(&mut self) -> Reservation; /// Insert a new entity in the app context based on a [Reservation] previously obtained from [`reserve_entity`]. /// @@ -143,28 +136,24 @@ pub trait AppContext { &mut self, reservation: Reservation, build_entity: impl FnOnce(&mut Context) -> T, - ) -> Self::Result>; + ) -> Entity; /// Update a entity in the app context. fn update_entity( &mut self, handle: &Entity, update: impl FnOnce(&mut T, &mut Context) -> R, - ) -> Self::Result + ) -> R where T: 'static; /// Update a entity in the app context. - fn as_mut<'a, T>(&'a mut self, handle: &Entity) -> Self::Result> + fn as_mut<'a, T>(&'a mut self, handle: &Entity) -> GpuiBorrow<'a, T> where T: 'static; /// Read a entity from the app context. - fn read_entity( - &self, - handle: &Entity, - read: impl FnOnce(&T, &App) -> R, - ) -> Self::Result + fn read_entity(&self, handle: &Entity, read: impl FnOnce(&T, &App) -> R) -> R where T: 'static; @@ -188,7 +177,7 @@ pub trait AppContext { R: Send + 'static; /// Read a global from this app context - fn read_global(&self, callback: impl FnOnce(&G, &App) -> R) -> Self::Result + fn read_global(&self, callback: impl FnOnce(&G, &App) -> R) -> R where G: Global; } @@ -215,24 +204,24 @@ pub trait VisualContext: AppContext { &mut self, entity: &Entity, update: impl FnOnce(&mut T, &mut Window, &mut Context) -> R, - ) -> Self::Result; + ) -> Result; /// Create a new entity, with access to `Window`. fn new_window_entity( &mut self, build_entity: impl FnOnce(&mut Window, &mut Context) -> T, - ) -> Self::Result>; + ) -> Result>; /// Replace the root view of a window with a new view. fn replace_root_view( &mut self, build_view: impl FnOnce(&mut Window, &mut Context) -> V, - ) -> Self::Result> + ) -> Result> where V: 'static + Render; /// Focus a entity in the window, if it implements the [`Focusable`] trait. - fn focus(&mut self, entity: &Entity) -> Self::Result<()> + fn focus(&mut self, entity: &Entity) -> Result<()> where V: Focusable; } @@ -284,24 +273,6 @@ where } } -/// A flatten equivalent for anyhow `Result`s. -pub trait Flatten { - /// Convert this type into a simple `Result`. - fn flatten(self) -> Result; -} - -impl Flatten for Result> { - fn flatten(self) -> Result { - self? - } -} - -impl Flatten for Result { - fn flatten(self) -> Result { - self - } -} - /// Information about the GPU GPUI is running on. #[derive(Default, Debug, serde::Serialize, serde::Deserialize, Clone)] pub struct GpuSpecs { diff --git a/crates/gpui/src/platform/app_menu.rs b/crates/gpui/src/platform/app_menu.rs index 39e7556b2d210f85fb9fda573244c9f031a92e2c..b1e0d82bb9f6d4ee265d047f562e088a8e48c1db 100644 --- a/crates/gpui/src/platform/app_menu.rs +++ b/crates/gpui/src/platform/app_menu.rs @@ -1,5 +1,4 @@ use crate::{Action, App, Platform, SharedString}; -use util::ResultExt; /// A menu of the application, either a main menu or a submenu pub struct Menu { @@ -263,14 +262,18 @@ pub(crate) fn init_app_menus(platform: &dyn Platform, cx: &App) { platform.on_will_open_app_menu(Box::new({ let cx = cx.to_async(); move || { - cx.update(|cx| cx.clear_pending_keystrokes()).ok(); + if let Some(app) = cx.app.upgrade() { + app.borrow_mut().update(|cx| cx.clear_pending_keystrokes()); + } } })); platform.on_validate_app_menu_command(Box::new({ let cx = cx.to_async(); move |action| { - cx.update(|cx| cx.is_action_available(action)) + cx.app + .upgrade() + .map(|app| app.borrow_mut().update(|cx| cx.is_action_available(action))) .unwrap_or(false) } })); @@ -278,7 +281,9 @@ pub(crate) fn init_app_menus(platform: &dyn Platform, cx: &App) { platform.on_app_menu_action(Box::new({ let cx = cx.to_async(); move |action| { - cx.update(|cx| cx.dispatch_action(action)).log_err(); + if let Some(app) = cx.app.upgrade() { + app.borrow_mut().update(|cx| cx.dispatch_action(action)); + } } })); } diff --git a/crates/gpui/src/platform/mac/platform.rs b/crates/gpui/src/platform/mac/platform.rs index 9b32c6735bf6215fecc0455defc4237fd25e8cb0..bf1a177d22ff2c2c998eacdbb1b75216dcce8791 100644 --- a/crates/gpui/src/platform/mac/platform.rs +++ b/crates/gpui/src/platform/mac/platform.rs @@ -687,7 +687,7 @@ impl Platform for MacPlatform { } self.background_executor() - .spawn(async { crate::Flatten::flatten(done_rx.await.map_err(|e| anyhow!(e))) }) + .spawn(async { done_rx.await.map_err(|e| anyhow!(e))? }) } fn on_open_urls(&self, callback: Box)>) { diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index 8df421feb968677be0abbb642a7127871881bcf3..78c68ebd80759fcb47cf05b6537751eefaedd8f4 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -4909,11 +4909,11 @@ impl WindowHandle { where C: AppContext, { - crate::Flatten::flatten(cx.update_window(self.any_handle, |root_view, _, _| { + cx.update_window(self.any_handle, |root_view, _, _| { root_view .downcast::() .map_err(|_| anyhow!("the type of the window's root view has changed")) - })) + })? } /// Updates the root view of this window.