diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 2d268e9466..bd56da59af 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -413,16 +413,17 @@ impl AppContext { self.pending_effects.push_back(Effect::Refresh); } - pub(crate) fn update(&mut self, update: impl FnOnce(&mut Self) -> R) -> R { - self.pending_updates += 1; - let result = update(self); - if !self.flushing_effects && self.pending_updates == 1 { - self.flushing_effects = true; - self.flush_effects(); - self.flushing_effects = false; - } - self.pending_updates -= 1; - result + pub(crate) fn update<'a, R>(&'a mut self, update: impl FnOnce(&'a mut Self) -> R) -> R { + todo!() + // self.pending_updates += 1; + // let result = update(self); + // if !self.flushing_effects && self.pending_updates == 1 { + // self.flushing_effects = true; + // self.flush_effects(); + // self.flushing_effects = false; + // } + // self.pending_updates -= 1; + // result } /// Arrange a callback to be invoked when the given model or view calls `notify` on its respective context. @@ -1413,11 +1414,23 @@ impl AppContext { pub fn get_name(&self) -> &'static str { self.name.as_ref().unwrap() } + + fn insert_model2<'a, T: 'static>( + &'a mut self, + reservation: Reservation, + build_model: impl FnOnce(&mut ModelContext<'a, 'b, T>) -> T, + ) -> Model { + self.update(|cx| { + let slot = reservation.0; + let entity = build_model(&mut ModelContext::new(cx, &slot)); + cx.entities.insert(slot, entity) + }) + } } impl Context for AppContext { type Result = T; - type EntityContext<'a, 'b, T: 'static> = ModelContext<'a, T>; + type EntityContext<'a, 'b, T: 'static> = ModelContext<'a, 'b, T>; /// Build an entity that is owned by the application. The given function will be invoked with /// a `ModelContext` and must return an object representing the entity. A `Model` handle will be returned, diff --git a/crates/gpui/src/app/async_context.rs b/crates/gpui/src/app/async_context.rs index f38b358f6d..f818d90988 100644 --- a/crates/gpui/src/app/async_context.rs +++ b/crates/gpui/src/app/async_context.rs @@ -20,7 +20,7 @@ pub struct AsyncAppContext { impl Context for AsyncAppContext { type Result = Result; - type EntityContext<'a, 'b, T: 'static> = ModelContext<'a, T>; + type EntityContext<'a, 'b, T: 'static> = ModelContext<'a, 'b, T>; fn new_model( &mut self, diff --git a/crates/gpui/src/app/model_context.rs b/crates/gpui/src/app/model_context.rs index 7b0149a0ab..a4bd7459e6 100644 --- a/crates/gpui/src/app/model_context.rs +++ b/crates/gpui/src/app/model_context.rs @@ -13,15 +13,15 @@ use std::{ /// The app context, with specialized behavior for the given model. #[derive(Deref, DerefMut)] -pub struct ModelContext<'a, T> { +pub struct ModelContext<'a, 'b, T> { #[deref] #[deref_mut] pub(crate) app: &'a mut AppContext, - pub(crate) entity: &'a Model, + pub(crate) entity: &'b Model, } -impl<'a, T: 'static> ModelContext<'a, T> { - pub(crate) fn new(app: &'a mut AppContext, model_state: &'a Model) -> Self { +impl<'a, 'b, T: 'static> ModelContext<'a, 'b, T> { + pub(crate) fn new(app: &'a mut AppContext, model_state: &'b Model) -> Self { Self { app, entity: model_state, @@ -48,7 +48,7 @@ impl<'a, T: 'static> ModelContext<'a, T> { pub fn observe( &mut self, entity: &E, - mut on_notify: impl FnMut(&mut T, E, &mut ModelContext<'_, T>) + 'static, + mut on_notify: impl FnMut(&mut T, E, &mut ModelContext<'_, '_, T>) + 'static, ) -> Subscription where T: 'static, @@ -70,7 +70,7 @@ impl<'a, T: 'static> ModelContext<'a, T> { pub fn subscribe( &mut self, entity: &E, - mut on_event: impl FnMut(&mut T, E, &Evt, &mut ModelContext<'_, T>) + 'static, + mut on_event: impl FnMut(&mut T, E, &Evt, &mut ModelContext<'_, '_, T>) + 'static, ) -> Subscription where T: 'static, @@ -112,7 +112,7 @@ impl<'a, T: 'static> ModelContext<'a, T> { pub fn observe_release( &self, entity: &E, - on_release: impl FnOnce(&mut T, &mut T2, &mut ModelContext<'_, T>) + 'static, + on_release: impl FnOnce(&mut T, &mut T2, &mut ModelContext<'_, '_, T>) + 'static, ) -> Subscription where T: Any, @@ -137,7 +137,7 @@ impl<'a, T: 'static> ModelContext<'a, T> { /// Register a callback to for updates to the given global pub fn observe_global( &mut self, - mut f: impl FnMut(&mut T, &mut ModelContext<'_, T>) + 'static, + mut f: impl FnMut(&mut T, &mut ModelContext<'_, '_, T>) + 'static, ) -> Subscription where T: 'static, @@ -210,7 +210,7 @@ impl<'a, T: 'static> ModelContext<'a, T> { } } -impl<'a, T> ModelContext<'a, T> { +impl<'a, 'b, T> ModelContext<'a, 'b, T> { /// Emit an event of the specified type, which can be handled by other entities that have subscribed via `subscribe` methods on their respective contexts. pub fn emit(&mut self, event: Evt) where @@ -225,13 +225,13 @@ impl<'a, T> ModelContext<'a, T> { } } -impl<'a, T> Context for ModelContext<'a, T> { +impl<'a, 'b, T> Context for ModelContext<'a, 'b, T> { type Result = U; - type EntityContext<'b, 'c, U: 'static> = ModelContext<'b, U>; + type EntityContext<'c, 'd, U: 'static> = ModelContext<'c, 'd, U>; fn new_model( &mut self, - build_model: impl FnOnce(&mut ModelContext<'_, U>) -> U, + build_model: impl FnOnce(&mut Self::EntityContext<'_, '_, U>) -> U, ) -> Model { self.app.new_model(build_model) } @@ -243,7 +243,7 @@ impl<'a, T> Context for ModelContext<'a, T> { fn insert_model( &mut self, reservation: Reservation, - build_model: impl FnOnce(&mut ModelContext<'_, U>) -> U, + build_model: impl FnOnce(&mut ModelContext<'_, '_, U>) -> U, ) -> Self::Result> { self.app.insert_model(reservation, build_model) } @@ -251,7 +251,7 @@ impl<'a, T> Context for ModelContext<'a, T> { fn update_model( &mut self, handle: &Model, - update: impl FnOnce(&mut U, &mut ModelContext<'_, U>) -> R, + update: impl FnOnce(&mut U, &mut ModelContext<'_, '_, U>) -> R, ) -> R { self.app.update_model(handle, update) } @@ -286,13 +286,13 @@ impl<'a, T> Context for ModelContext<'a, T> { } } -impl Borrow for ModelContext<'_, T> { +impl Borrow for ModelContext<'_, '_, T> { fn borrow(&self) -> &AppContext { self.app } } -impl BorrowMut for ModelContext<'_, T> { +impl BorrowMut for ModelContext<'_, '_, T> { fn borrow_mut(&mut self) -> &mut AppContext { self.app } diff --git a/crates/gpui/src/app/test_context.rs b/crates/gpui/src/app/test_context.rs index dd31426190..33f1f7346c 100644 --- a/crates/gpui/src/app/test_context.rs +++ b/crates/gpui/src/app/test_context.rs @@ -31,7 +31,7 @@ pub struct TestAppContext { impl Context for TestAppContext { type Result = T; - type EntityContext<'a, 'b, T: 'static> = ModelContext<'a, T>; + type EntityContext<'a, 'b, T: 'static> = ModelContext<'a, 'b, T>; fn new_model( &mut self, diff --git a/crates/gpui/src/gpui.rs b/crates/gpui/src/gpui.rs index eb9ccbf7ae..4eaaa9c623 100644 --- a/crates/gpui/src/gpui.rs +++ b/crates/gpui/src/gpui.rs @@ -165,12 +165,12 @@ pub trait Context { /// Defines the context type used when updating an entity within this context. /// This associated type specifies the appropriate context for entity updates, /// allowing for context-specific operations and ensuring type safety. - type EntityContext<'a, 'b, T: 'static>; + type EntityContext<'a, 'b, 'c, T: 'static>; /// Create a new model in the app context. fn new_model( &mut self, - build_model: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T, + build_model: impl FnOnce(&mut Self::EntityContext<'_, '_, '_, T>) -> T, ) -> Self::Result>; /// Reserve a slot for a model to be inserted later. @@ -183,14 +183,14 @@ pub trait Context { fn insert_model( &mut self, reservation: Reservation, - build_model: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T, + build_model: impl FnOnce(&mut Self::EntityContext<'_, '_, '_, T>) -> T, ) -> Self::Result>; /// Update a model in the app context. fn update_model( &mut self, handle: &Model, - update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R, + update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, '_, T>) -> R, ) -> Self::Result where T: 'static; diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index 3e3d722dce..d51ed04b7e 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -6615,11 +6615,13 @@ impl Context for WindowContext<'_> { reservation: crate::Reservation, build_model: impl FnOnce(&mut ViewContext<'_, '_, T>) -> T, ) -> Self::Result> { - self.app.update(|cx| { - let slot = reservation.0; - let entity = build_model(&mut ViewContext::new(cx, &slot)); - cx.entities.insert(slot, entity) - }) + self.app + .insert_model(reservation, |cx: &mut ModelContext<'_, T>| { + // let window = &mut self.window; + ViewContext::new(cx, &mut self.window); + // build_model(&mut cx) + todo!() + }) } fn update_model( @@ -6686,7 +6688,7 @@ impl Context for WindowContext<'_> { impl VisualContext for WindowContext<'_> { fn new_view( &mut self, - build_view_state: impl FnOnce(&mut ViewContext<'_, '_, V>) -> V, + build_view_state: impl FnOnce(&mut ViewContext<'_, '_, '_, V>) -> V, ) -> Self::Result> where V: 'static + Render, @@ -6723,7 +6725,7 @@ impl VisualContext for WindowContext<'_> { fn replace_root_view( &mut self, - build_view: impl FnOnce(&mut ViewContext<'_, '_, V>) -> V, + build_view: impl FnOnce(&mut ViewContext<'_, '_, '_, V>) -> V, ) -> Self::Result> where V: 'static + Render, @@ -6815,37 +6817,37 @@ impl BorrowWindow for T where T: BorrowMut + BorrowMut {} /// Allows you to interact with focus, emit events, etc. /// ViewContext also derefs to [`WindowContext`], giving you access to all of its methods as well. /// When you call [`View::update`], you're passed a `&mut V` and an `&mut ViewContext`. -pub struct ViewContext<'a, 'b, V> { - cx: &'a mut ModelContext<'a, V>, - window: &'b mut Window, +pub struct ViewContext<'a, 'b, 'c, V> { + cx: &'a mut ModelContext<'a, 'b, V>, + window: &'c mut Window, } -impl Borrow for ViewContext<'_, '_, V> { +impl Borrow for ViewContext<'_, '_, '_, V> { fn borrow(&self) -> &AppContext { &*self.cx } } -impl BorrowMut for ViewContext<'_, '_, V> { +impl BorrowMut for ViewContext<'_, '_, '_, V> { fn borrow_mut(&mut self) -> &mut AppContext { &mut *self.cx } } -impl Borrow for ViewContext<'_, '_, V> { +impl Borrow for ViewContext<'_, '_, '_, V> { fn borrow(&self) -> &Window { &*self.window } } -impl BorrowMut for ViewContext<'_, '_, V> { +impl BorrowMut for ViewContext<'_, '_, '_, V> { fn borrow_mut(&mut self) -> &mut Window { &mut *self.window } } -impl<'a, 'b, V: 'static> ViewContext<'a, 'b, V> { - pub(crate) fn new(cx: &'a mut ModelContext<'a, V>, window: &'b mut Window) -> Self { +impl<'a, 'b, 'c, V: 'static> ViewContext<'a, 'b, 'c, V> { + pub(crate) fn new(cx: &'a mut ModelContext<'a, 'b, V>, window: &'c mut Window) -> Self { Self { cx, window } } @@ -6893,7 +6895,7 @@ impl<'a, 'b, V: 'static> ViewContext<'a, 'b, V> { pub fn observe( &mut self, entity: &E, - mut on_notify: impl FnMut(&mut V, E, &mut ViewContext<'_, '_, V>) + 'static, + mut on_notify: impl FnMut(&mut V, E, &mut ViewContext<'_, '_, '_, V>) + 'static, ) -> Subscription where V2: 'static, @@ -6927,7 +6929,7 @@ impl<'a, 'b, V: 'static> ViewContext<'a, 'b, V> { pub fn subscribe( &mut self, entity: &E, - mut on_event: impl FnMut(&mut V, E, &Evt, &mut ViewContext<'_, '_, V>) + 'static, + mut on_event: impl FnMut(&mut V, E, &Evt, &mut ViewContext<'_, '_, '_, V>) + 'static, ) -> Subscription where V2: EventEmitter, @@ -6983,7 +6985,7 @@ impl<'a, 'b, V: 'static> ViewContext<'a, 'b, V> { pub fn observe_release( &self, entity: &E, - mut on_release: impl FnMut(&mut V, &mut V2, &mut ViewContext<'_, '_, V>) + 'static, + mut on_release: impl FnMut(&mut V, &mut V2, &mut ViewContext<'_, '_, '_, V>) + 'static, ) -> Subscription where V: 'static, @@ -7232,7 +7234,7 @@ impl<'a, 'b, V: 'static> ViewContext<'a, 'b, V> { /// Register a callback to be invoked when the given global state changes. pub fn observe_global( &mut self, - mut f: impl FnMut(&mut V, &mut ViewContext<'_, '_, V>) + 'static, + mut f: impl FnMut(&mut V, &mut ViewContext<'_, '_, '_, V>) + 'static, ) -> Subscription { let window_handle = self.window.handle; let view = self.view().downgrade(); @@ -7305,7 +7307,7 @@ impl<'a, 'b, V: 'static> ViewContext<'a, 'b, V> { } } -impl Context for ViewContext<'_, '_, V> { +impl Context for ViewContext<'_, '_, '_, V> { type Result = U; type EntityContext<'a, 'b, T: 'static> = ViewContext<'a, T>; @@ -7366,7 +7368,7 @@ impl Context for ViewContext<'_, '_, V> { } } -impl VisualContext for ViewContext<'_, '_, V> { +impl VisualContext for ViewContext<'_, '_, '_, V> { fn new_view( &mut self, build_view_state: impl FnOnce(&mut ViewContext<'_, '_, W>) -> W, @@ -7401,15 +7403,15 @@ impl VisualContext for ViewContext<'_, '_, V> { } } -impl<'a, V> std::ops::Deref for ViewContext<'a, '_, V> { - type Target = ModelContext<'a, V>; +impl<'a, 'b, V> std::ops::Deref for ViewContext<'a, 'b, '_, V> { + type Target = ModelContext<'a, 'b, V>; fn deref(&self) -> &Self::Target { &self.cx } } -impl<'a, V> std::ops::DerefMut for ViewContext<'a, '_, V> { +impl std::ops::DerefMut for ViewContext<'_, '_, '_, V> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.cx } @@ -7477,7 +7479,7 @@ impl WindowHandle { pub fn update( &self, cx: &mut C, - update: impl FnOnce(&mut V, &mut ViewContext<'_, '_, V>) -> R, + update: impl FnOnce(&mut V, &mut ViewContext<'_, '_, '_, V>) -> R, ) -> Result where C: Context,