From 5dac95c47c13d4993d378a845f09a7881b6b52ea Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 21 Apr 2023 15:03:57 -0600 Subject: [PATCH 1/8] Eliminate ReadView trait --- crates/gpui/src/app.rs | 36 +++++++++-------------------------- crates/gpui/src/app/window.rs | 12 +++--------- 2 files changed, 12 insertions(+), 36 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 8fbf102f38..4f86a23eff 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -158,10 +158,6 @@ pub trait UpgradeViewHandle { fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option; } -pub trait ReadView { - fn read_view(&self, handle: &ViewHandle) -> &T; -} - pub trait ReadViewWith { fn read_view_with( &self, @@ -1444,6 +1440,14 @@ impl AppContext { .unwrap() } + pub fn read_view(&self, handle: &ViewHandle) -> &T { + if let Some(view) = self.views.get(&(handle.window_id, handle.view_id)) { + view.as_any().downcast_ref().expect("downcast is type safe") + } else { + panic!("circular view reference for type {}", type_name::()); + } + } + fn remove_dropped_entities(&mut self) { loop { let (dropped_models, dropped_views, dropped_element_states) = @@ -2172,16 +2176,6 @@ impl UpgradeViewHandle for AppContext { } } -impl ReadView for AppContext { - fn read_view(&self, handle: &ViewHandle) -> &T { - if let Some(view) = self.views.get(&(handle.window_id, handle.view_id)) { - view.as_any().downcast_ref().expect("downcast is type safe") - } else { - panic!("circular view reference for type {}", type_name::()); - } - } -} - #[derive(Debug)] pub enum ParentId { View(usize), @@ -3488,12 +3482,6 @@ impl UpdateModel for ViewContext<'_, '_, V> { } } -impl ReadView for ViewContext<'_, '_, V> { - fn read_view(&self, handle: &ViewHandle) -> &T { - self.window_context.read_view(handle) - } -} - impl UpdateView for ViewContext<'_, '_, V> { type Output = S; @@ -3551,12 +3539,6 @@ impl UpdateModel for EventContext<'_, '_, '_, V> { } } -impl ReadView for EventContext<'_, '_, '_, V> { - fn read_view(&self, handle: &crate::ViewHandle) -> &W { - self.view_context.read_view(handle) - } -} - impl UpdateView for EventContext<'_, '_, '_, V> { type Output = S; @@ -3924,7 +3906,7 @@ impl ViewHandle { self.view_id } - pub fn read<'a, C: ReadView>(&self, cx: &'a C) -> &'a T { + pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T { cx.read_view(self) } diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index 12dc9a60c5..a28507a095 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -15,9 +15,9 @@ use crate::{ util::post_inc, Action, AnyModelHandle, AnyView, AnyViewHandle, AnyWeakModelHandle, AnyWeakViewHandle, AppContext, Effect, Element, Entity, Handle, ModelContext, ModelHandle, MouseRegion, - MouseRegionId, ParentId, ReadModel, ReadView, SceneBuilder, Subscription, UpdateModel, - UpdateView, UpgradeModelHandle, UpgradeViewHandle, View, ViewContext, ViewHandle, - WeakModelHandle, WeakViewHandle, WindowInvalidation, + MouseRegionId, ParentId, ReadModel, SceneBuilder, Subscription, UpdateModel, UpdateView, + UpgradeModelHandle, UpgradeViewHandle, View, ViewContext, ViewHandle, WeakModelHandle, + WeakViewHandle, WindowInvalidation, }; use anyhow::{anyhow, bail, Result}; use collections::{HashMap, HashSet}; @@ -149,12 +149,6 @@ impl UpdateModel for WindowContext<'_> { } } -impl ReadView for WindowContext<'_> { - fn read_view(&self, handle: &crate::ViewHandle) -> &W { - self.app_context.read_view(handle) - } -} - impl UpdateView for WindowContext<'_> { type Output = S; From 55db28e0745aff095691483700f9386a6271ab4f Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 21 Apr 2023 15:05:19 -0600 Subject: [PATCH 2/8] Eliminate ReadModel trait --- crates/gpui/src/app.rs | 42 ++++++++++------------------------- crates/gpui/src/app/window.rs | 8 +------ 2 files changed, 13 insertions(+), 37 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 4f86a23eff..eae798938e 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -121,10 +121,6 @@ pub trait View: Entity + Sized { } } -pub trait ReadModel { - fn read_model(&self, handle: &ModelHandle) -> &T; -} - pub trait ReadModelWith { fn read_model_with( &self, @@ -1285,6 +1281,17 @@ impl AppContext { }) } + pub fn read_model(&self, handle: &ModelHandle) -> &T { + if let Some(model) = self.models.get(&handle.model_id) { + model + .as_any() + .downcast_ref() + .expect("downcast is type safe") + } else { + panic!("circular model reference"); + } + } + pub fn add_window( &mut self, window_options: WindowOptions, @@ -2082,19 +2089,6 @@ impl AppContext { } } -impl ReadModel for AppContext { - fn read_model(&self, handle: &ModelHandle) -> &T { - if let Some(model) = self.models.get(&handle.model_id) { - model - .as_any() - .downcast_ref() - .expect("downcast is type safe") - } else { - panic!("circular model reference"); - } - } -} - impl UpdateModel for AppContext { fn update_model( &mut self, @@ -2861,12 +2855,6 @@ impl AsMut for ModelContext<'_, M> { } } -impl ReadModel for ModelContext<'_, M> { - fn read_model(&self, handle: &ModelHandle) -> &T { - self.app.read_model(handle) - } -} - impl UpdateModel for ModelContext<'_, M> { fn update_model( &mut self, @@ -3466,12 +3454,6 @@ impl UpgradeViewHandle for ViewContext<'_, '_, V> { } } -impl ReadModel for ViewContext<'_, '_, V> { - fn read_model(&self, handle: &ModelHandle) -> &T { - self.window_context.read_model(handle) - } -} - impl UpdateModel for ViewContext<'_, '_, V> { fn update_model( &mut self, @@ -3685,7 +3667,7 @@ impl ModelHandle { self.model_id } - pub fn read<'a, C: ReadModel>(&self, cx: &'a C) -> &'a T { + pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T { cx.read_model(self) } diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index a28507a095..33405e9163 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -15,7 +15,7 @@ use crate::{ util::post_inc, Action, AnyModelHandle, AnyView, AnyViewHandle, AnyWeakModelHandle, AnyWeakViewHandle, AppContext, Effect, Element, Entity, Handle, ModelContext, ModelHandle, MouseRegion, - MouseRegionId, ParentId, ReadModel, SceneBuilder, Subscription, UpdateModel, UpdateView, + MouseRegionId, ParentId, SceneBuilder, Subscription, UpdateModel, UpdateView, UpgradeModelHandle, UpgradeViewHandle, View, ViewContext, ViewHandle, WeakModelHandle, WeakViewHandle, WindowInvalidation, }; @@ -133,12 +133,6 @@ impl DerefMut for WindowContext<'_> { } } -impl ReadModel for WindowContext<'_> { - fn read_model(&self, handle: &ModelHandle) -> &T { - self.app_context.read_model(handle) - } -} - impl UpdateModel for WindowContext<'_> { fn update_model( &mut self, From 83bf3d071d87dde73135cecb9ed2e08090ccc9db Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 21 Apr 2023 15:36:52 -0600 Subject: [PATCH 3/8] WIP --- crates/gpui/src/app.rs | 69 +++++++++++++++++++++++++++++------ crates/gpui/src/app/window.rs | 20 +++++++--- 2 files changed, 73 insertions(+), 16 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index eae798938e..4c197b0d89 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -121,6 +121,11 @@ pub trait View: Entity + Sized { } } +pub trait AccessAppContext { + fn read T>(&self, f: F) -> T; + fn update T>(&mut self, f: F) -> T; +} + pub trait ReadModelWith { fn read_model_with( &self, @@ -148,11 +153,11 @@ pub trait UpgradeModelHandle { fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option; } -pub trait UpgradeViewHandle { - fn upgrade_view_handle(&self, handle: &WeakViewHandle) -> Option>; +// pub trait UpgradeViewHandle { +// fn upgrade_view_handle(&self, handle: &WeakViewHandle) -> Option>; - fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option; -} +// fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option; +// } pub trait ReadViewWith { fn read_view_with( @@ -179,9 +184,6 @@ pub trait UpdateView { #[derive(Clone)] pub struct App(Rc>); -#[derive(Clone)] -pub struct AsyncAppContext(Rc>); - impl App { pub fn new(asset_source: impl AssetSource) -> Result { let platform = platform::current::platform(); @@ -328,6 +330,9 @@ impl App { } } +#[derive(Clone)] +pub struct AsyncAppContext(Rc>); + impl AsyncAppContext { pub fn spawn(&self, f: F) -> Task where @@ -406,6 +411,16 @@ impl AsyncAppContext { } } +impl AccessAppContext for AsyncAppContext { + fn read T>(&self, f: F) -> T { + self.0.borrow().read(f) + } + + fn update T>(&mut self, f: F) -> T { + self.0.borrow_mut().update(f) + } +} + impl UpdateModel for AsyncAppContext { fn update_model( &mut self, @@ -2089,6 +2104,16 @@ impl AppContext { } } +impl AccessAppContext for AppContext { + fn read T>(&self, f: F) -> T { + f(self) + } + + fn update T>(&mut self, f: F) -> T { + f(self) + } +} + impl UpdateModel for AppContext { fn update_model( &mut self, @@ -3427,6 +3452,16 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { } } +impl AccessAppContext for ViewContext<'_, '_, V> { + fn read T>(&self, f: F) -> T { + self.window_context.read(f) + } + + fn update T>(&mut self, f: F) -> T { + self.window_context.update(f) + } +} + impl UpgradeModelHandle for ViewContext<'_, '_, V> { fn upgrade_model_handle( &self, @@ -4223,13 +4258,13 @@ impl WeakHandle for WeakViewHandle { } } -impl WeakViewHandle { +impl WeakViewHandle { fn new(window_id: usize, view_id: usize) -> Self { Self { any_handle: AnyWeakViewHandle { window_id, view_id, - view_type: TypeId::of::(), + view_type: TypeId::of::(), }, view_type: PhantomData, } @@ -4247,8 +4282,20 @@ impl WeakViewHandle { self.any_handle } - pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option> { - cx.upgrade_view_handle(self) + pub fn upgrade(&self, cx: &impl AccessAppContext) -> Option> { + cx.read(|cx| cx.upgrade_view_handle(self)) + } + + pub fn update( + &self, + cx: &mut impl AccessAppContext, + update: impl FnOnce(&mut V, &mut ViewContext) -> T, + ) -> Option { + cx.update(|cx| { + let handle = cx.upgrade_view_handle(self)?; + + cx.update_window(self.window_id, |cx| handle.update(cx, update)) + }) } } diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index 33405e9163..0738797f4b 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -13,11 +13,11 @@ use crate::{ }, text_layout::TextLayoutCache, util::post_inc, - Action, AnyModelHandle, AnyView, AnyViewHandle, AnyWeakModelHandle, AnyWeakViewHandle, - AppContext, Effect, Element, Entity, Handle, ModelContext, ModelHandle, MouseRegion, - MouseRegionId, ParentId, SceneBuilder, Subscription, UpdateModel, UpdateView, - UpgradeModelHandle, UpgradeViewHandle, View, ViewContext, ViewHandle, WeakModelHandle, - WeakViewHandle, WindowInvalidation, + AccessAppContext, Action, AnyModelHandle, AnyView, AnyViewHandle, AnyWeakModelHandle, + AnyWeakViewHandle, AppContext, Effect, Element, Entity, Handle, ModelContext, ModelHandle, + MouseRegion, MouseRegionId, ParentId, SceneBuilder, Subscription, UpdateModel, UpdateView, + UpgradeModelHandle, View, ViewContext, ViewHandle, WeakModelHandle, WeakViewHandle, + WindowInvalidation, }; use anyhow::{anyhow, bail, Result}; use collections::{HashMap, HashSet}; @@ -133,6 +133,16 @@ impl DerefMut for WindowContext<'_> { } } +impl AccessAppContext for WindowContext<'_> { + fn read T>(&self, f: F) -> T { + self.app_context.read(f) + } + + fn update T>(&mut self, f: F) -> T { + self.app_context.update(f) + } +} + impl UpdateModel for WindowContext<'_> { fn update_model( &mut self, From b8fab6fde9b1418247baa7b8c0d115667df5ef1a Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 24 Apr 2023 16:33:27 +0200 Subject: [PATCH 4/8] Remove `UpgradeViewHandle` trait Co-authored-by: Nathan Sobo --- crates/gpui/src/app.rs | 112 ++++++++++++---------------------- crates/gpui/src/app/window.rs | 25 +++----- 2 files changed, 47 insertions(+), 90 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 4c197b0d89..26303e6d79 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -121,8 +121,8 @@ pub trait View: Entity + Sized { } } -pub trait AccessAppContext { - fn read T>(&self, f: F) -> T; +pub trait BorrowAppContext { + fn read_with T>(&self, f: F) -> T; fn update T>(&mut self, f: F) -> T; } @@ -411,9 +411,9 @@ impl AsyncAppContext { } } -impl AccessAppContext for AsyncAppContext { - fn read T>(&self, f: F) -> T { - self.0.borrow().read(f) +impl BorrowAppContext for AsyncAppContext { + fn read_with T>(&self, f: F) -> T { + self.0.borrow().read_with(f) } fn update T>(&mut self, f: F) -> T { @@ -448,16 +448,6 @@ impl UpgradeModelHandle for AsyncAppContext { } } -impl UpgradeViewHandle for AsyncAppContext { - fn upgrade_view_handle(&self, handle: &WeakViewHandle) -> Option> { - self.0.borrow_mut().upgrade_view_handle(handle) - } - - fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option { - self.0.borrow_mut().upgrade_any_view_handle(handle) - } -} - impl ReadModelWith for AsyncAppContext { fn read_model_with( &self, @@ -1470,6 +1460,31 @@ impl AppContext { } } + fn upgrade_view_handle(&self, handle: &WeakViewHandle) -> Option> { + if self.ref_counts.lock().is_entity_alive(handle.view_id) { + Some(ViewHandle::new( + handle.window_id, + handle.view_id, + &self.ref_counts, + )) + } else { + None + } + } + + fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option { + if self.ref_counts.lock().is_entity_alive(handle.view_id) { + Some(AnyViewHandle::new( + handle.window_id, + handle.view_id, + handle.view_type, + self.ref_counts.clone(), + )) + } else { + None + } + } + fn remove_dropped_entities(&mut self) { loop { let (dropped_models, dropped_views, dropped_element_states) = @@ -2104,8 +2119,8 @@ impl AppContext { } } -impl AccessAppContext for AppContext { - fn read T>(&self, f: F) -> T { +impl BorrowAppContext for AppContext { + fn read_with T>(&self, f: F) -> T { f(self) } @@ -2168,33 +2183,6 @@ impl UpgradeModelHandle for AppContext { } } -impl UpgradeViewHandle for AppContext { - fn upgrade_view_handle(&self, handle: &WeakViewHandle) -> Option> { - if self.ref_counts.lock().is_entity_alive(handle.view_id) { - Some(ViewHandle::new( - handle.window_id, - handle.view_id, - &self.ref_counts, - )) - } else { - None - } - } - - fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option { - if self.ref_counts.lock().is_entity_alive(handle.view_id) { - Some(AnyViewHandle::new( - handle.window_id, - handle.view_id, - handle.view_type, - self.ref_counts.clone(), - )) - } else { - None - } - } -} - #[derive(Debug)] pub enum ParentId { View(usize), @@ -3452,9 +3440,9 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { } } -impl AccessAppContext for ViewContext<'_, '_, V> { - fn read T>(&self, f: F) -> T { - self.window_context.read(f) +impl BorrowAppContext for ViewContext<'_, '_, V> { + fn read_with T>(&self, f: F) -> T { + self.window_context.read_with(f) } fn update T>(&mut self, f: F) -> T { @@ -3479,16 +3467,6 @@ impl UpgradeModelHandle for ViewContext<'_, '_, V> { } } -impl UpgradeViewHandle for ViewContext<'_, '_, V> { - fn upgrade_view_handle(&self, handle: &WeakViewHandle) -> Option> { - self.window_context.upgrade_view_handle(handle) - } - - fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option { - self.window_context.upgrade_any_view_handle(handle) - } -} - impl UpdateModel for ViewContext<'_, '_, V> { fn update_model( &mut self, @@ -3588,16 +3566,6 @@ impl UpgradeModelHandle for EventContext<'_, '_, '_, V> { } } -impl UpgradeViewHandle for EventContext<'_, '_, '_, V> { - fn upgrade_view_handle(&self, handle: &WeakViewHandle) -> Option> { - self.view_context.upgrade_view_handle(handle) - } - - fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option { - self.view_context.upgrade_any_view_handle(handle) - } -} - pub(crate) enum Reference<'a, T> { Immutable(&'a T), Mutable(&'a mut T), @@ -4282,13 +4250,13 @@ impl WeakViewHandle { self.any_handle } - pub fn upgrade(&self, cx: &impl AccessAppContext) -> Option> { - cx.read(|cx| cx.upgrade_view_handle(self)) + pub fn upgrade(&self, cx: &impl BorrowAppContext) -> Option> { + cx.read_with(|cx| cx.upgrade_view_handle(self)) } pub fn update( &self, - cx: &mut impl AccessAppContext, + cx: &mut impl BorrowAppContext, update: impl FnOnce(&mut V, &mut ViewContext) -> T, ) -> Option { cx.update(|cx| { @@ -4342,8 +4310,8 @@ impl AnyWeakViewHandle { self.view_id } - pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option { - cx.upgrade_any_view_handle(self) + pub fn upgrade(&self, cx: &impl BorrowAppContext) -> Option { + cx.read_with(|cx| cx.upgrade_any_view_handle(self)) } } diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index 0738797f4b..605a46bf9e 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -13,11 +13,10 @@ use crate::{ }, text_layout::TextLayoutCache, util::post_inc, - AccessAppContext, Action, AnyModelHandle, AnyView, AnyViewHandle, AnyWeakModelHandle, - AnyWeakViewHandle, AppContext, Effect, Element, Entity, Handle, ModelContext, ModelHandle, - MouseRegion, MouseRegionId, ParentId, SceneBuilder, Subscription, UpdateModel, UpdateView, - UpgradeModelHandle, View, ViewContext, ViewHandle, WeakModelHandle, WeakViewHandle, - WindowInvalidation, + Action, AnyModelHandle, AnyView, AnyViewHandle, AnyWeakModelHandle, AppContext, + BorrowAppContext, Effect, Element, Entity, Handle, ModelContext, ModelHandle, MouseRegion, + MouseRegionId, ParentId, SceneBuilder, Subscription, UpdateModel, UpdateView, + UpgradeModelHandle, View, ViewContext, ViewHandle, WeakModelHandle, WindowInvalidation, }; use anyhow::{anyhow, bail, Result}; use collections::{HashMap, HashSet}; @@ -133,9 +132,9 @@ impl DerefMut for WindowContext<'_> { } } -impl AccessAppContext for WindowContext<'_> { - fn read T>(&self, f: F) -> T { - self.app_context.read(f) +impl BorrowAppContext for WindowContext<'_> { + fn read_with T>(&self, f: F) -> T { + self.app_context.read_with(f) } fn update T>(&mut self, f: F) -> T { @@ -194,16 +193,6 @@ impl UpgradeModelHandle for WindowContext<'_> { } } -impl UpgradeViewHandle for WindowContext<'_> { - fn upgrade_view_handle(&self, handle: &WeakViewHandle) -> Option> { - self.app_context.upgrade_view_handle(handle) - } - - fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option { - self.app_context.upgrade_any_view_handle(handle) - } -} - impl<'a> WindowContext<'a> { pub fn mutable( app_context: &'a mut AppContext, From 5f500d34b28fa0ff9dd7cb8a09a9d3f30a4d91f6 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 24 Apr 2023 16:40:30 +0200 Subject: [PATCH 5/8] Remove `UpgradeModelHandle` trait Co-Authored-By: Nathan Sobo --- crates/gpui/src/app.rs | 174 +++++++++++----------------------- crates/gpui/src/app/window.rs | 24 +---- crates/project/src/project.rs | 6 +- 3 files changed, 60 insertions(+), 144 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 26303e6d79..ae71042e54 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -142,23 +142,6 @@ pub trait UpdateModel { ) -> O; } -pub trait UpgradeModelHandle { - fn upgrade_model_handle( - &self, - handle: &WeakModelHandle, - ) -> Option>; - - fn model_handle_is_upgradable(&self, handle: &WeakModelHandle) -> bool; - - fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option; -} - -// pub trait UpgradeViewHandle { -// fn upgrade_view_handle(&self, handle: &WeakViewHandle) -> Option>; - -// fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option; -// } - pub trait ReadViewWith { fn read_view_with( &self, @@ -431,23 +414,6 @@ impl UpdateModel for AsyncAppContext { } } -impl UpgradeModelHandle for AsyncAppContext { - fn upgrade_model_handle( - &self, - handle: &WeakModelHandle, - ) -> Option> { - self.0.borrow().upgrade_model_handle(handle) - } - - fn model_handle_is_upgradable(&self, handle: &WeakModelHandle) -> bool { - self.0.borrow().model_handle_is_upgradable(handle) - } - - fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option { - self.0.borrow().upgrade_any_model_handle(handle) - } -} - impl ReadModelWith for AsyncAppContext { fn read_model_with( &self, @@ -1297,6 +1263,33 @@ impl AppContext { } } + fn upgrade_model_handle( + &self, + handle: &WeakModelHandle, + ) -> Option> { + if self.ref_counts.lock().is_entity_alive(handle.model_id) { + Some(ModelHandle::new(handle.model_id, &self.ref_counts)) + } else { + None + } + } + + fn model_handle_is_upgradable(&self, handle: &WeakModelHandle) -> bool { + self.ref_counts.lock().is_entity_alive(handle.model_id) + } + + fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option { + if self.ref_counts.lock().is_entity_alive(handle.model_id) { + Some(AnyModelHandle::new( + handle.model_id, + handle.model_type, + self.ref_counts.clone(), + )) + } else { + None + } + } + pub fn add_window( &mut self, window_options: WindowOptions, @@ -2154,35 +2147,6 @@ impl UpdateModel for AppContext { } } -impl UpgradeModelHandle for AppContext { - fn upgrade_model_handle( - &self, - handle: &WeakModelHandle, - ) -> Option> { - if self.ref_counts.lock().is_entity_alive(handle.model_id) { - Some(ModelHandle::new(handle.model_id, &self.ref_counts)) - } else { - None - } - } - - fn model_handle_is_upgradable(&self, handle: &WeakModelHandle) -> bool { - self.ref_counts.lock().is_entity_alive(handle.model_id) - } - - fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option { - if self.ref_counts.lock().is_entity_alive(handle.model_id) { - Some(AnyModelHandle::new( - handle.model_id, - handle.model_type, - self.ref_counts.clone(), - )) - } else { - None - } - } -} - #[derive(Debug)] pub enum ParentId { View(usize), @@ -2868,6 +2832,16 @@ impl AsMut for ModelContext<'_, M> { } } +impl BorrowAppContext for ModelContext<'_, M> { + fn read_with T>(&self, f: F) -> T { + self.app.read_with(f) + } + + fn update T>(&mut self, f: F) -> T { + self.app.update(f) + } +} + impl UpdateModel for ModelContext<'_, M> { fn update_model( &mut self, @@ -2878,23 +2852,6 @@ impl UpdateModel for ModelContext<'_, M> { } } -impl UpgradeModelHandle for ModelContext<'_, M> { - fn upgrade_model_handle( - &self, - handle: &WeakModelHandle, - ) -> Option> { - self.app.upgrade_model_handle(handle) - } - - fn model_handle_is_upgradable(&self, handle: &WeakModelHandle) -> bool { - self.app.model_handle_is_upgradable(handle) - } - - fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option { - self.app.upgrade_any_model_handle(handle) - } -} - impl Deref for ModelContext<'_, M> { type Target = AppContext; @@ -3450,23 +3407,6 @@ impl BorrowAppContext for ViewContext<'_, '_, V> { } } -impl UpgradeModelHandle for ViewContext<'_, '_, V> { - fn upgrade_model_handle( - &self, - handle: &WeakModelHandle, - ) -> Option> { - self.window_context.upgrade_model_handle(handle) - } - - fn model_handle_is_upgradable(&self, handle: &WeakModelHandle) -> bool { - self.window_context.model_handle_is_upgradable(handle) - } - - fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option { - self.window_context.upgrade_any_model_handle(handle) - } -} - impl UpdateModel for ViewContext<'_, '_, V> { fn update_model( &mut self, @@ -3524,6 +3464,16 @@ impl DerefMut for EventContext<'_, '_, '_, V> { } } +impl BorrowAppContext for EventContext<'_, '_, '_, V> { + fn read_with T>(&self, f: F) -> T { + self.view_context.read_with(f) + } + + fn update T>(&mut self, f: F) -> T { + self.view_context.update(f) + } +} + impl UpdateModel for EventContext<'_, '_, '_, V> { fn update_model( &mut self, @@ -3549,23 +3499,6 @@ impl UpdateView for EventContext<'_, '_, '_, V> { } } -impl UpgradeModelHandle for EventContext<'_, '_, '_, V> { - fn upgrade_model_handle( - &self, - handle: &WeakModelHandle, - ) -> Option> { - self.view_context.upgrade_model_handle(handle) - } - - fn model_handle_is_upgradable(&self, handle: &WeakModelHandle) -> bool { - self.view_context.model_handle_is_upgradable(handle) - } - - fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option { - self.view_context.upgrade_any_model_handle(handle) - } -} - pub(crate) enum Reference<'a, T> { Immutable(&'a T), Mutable(&'a mut T), @@ -3808,12 +3741,12 @@ impl WeakModelHandle { self.model_id } - pub fn is_upgradable(&self, cx: &impl UpgradeModelHandle) -> bool { - cx.model_handle_is_upgradable(self) + pub fn is_upgradable(&self, cx: &impl BorrowAppContext) -> bool { + cx.read_with(|cx| cx.model_handle_is_upgradable(self)) } - pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option> { - cx.upgrade_model_handle(self) + pub fn upgrade(&self, cx: &impl BorrowAppContext) -> Option> { + cx.read_with(|cx| cx.upgrade_model_handle(self)) } } @@ -4189,9 +4122,10 @@ pub struct AnyWeakModelHandle { } impl AnyWeakModelHandle { - pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option { - cx.upgrade_any_model_handle(self) + pub fn upgrade(&self, cx: &impl BorrowAppContext) -> Option { + cx.read_with(|cx| cx.upgrade_any_model_handle(self)) } + pub fn model_type(&self) -> TypeId { self.model_type } diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index 605a46bf9e..a8af427f7e 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -13,10 +13,9 @@ use crate::{ }, text_layout::TextLayoutCache, util::post_inc, - Action, AnyModelHandle, AnyView, AnyViewHandle, AnyWeakModelHandle, AppContext, - BorrowAppContext, Effect, Element, Entity, Handle, ModelContext, ModelHandle, MouseRegion, - MouseRegionId, ParentId, SceneBuilder, Subscription, UpdateModel, UpdateView, - UpgradeModelHandle, View, ViewContext, ViewHandle, WeakModelHandle, WindowInvalidation, + Action, AnyView, AnyViewHandle, AppContext, BorrowAppContext, Effect, Element, Entity, Handle, + ModelContext, ModelHandle, MouseRegion, MouseRegionId, ParentId, SceneBuilder, Subscription, + UpdateModel, UpdateView, View, ViewContext, ViewHandle, WindowInvalidation, }; use anyhow::{anyhow, bail, Result}; use collections::{HashMap, HashSet}; @@ -176,23 +175,6 @@ impl UpdateView for WindowContext<'_> { } } -impl UpgradeModelHandle for WindowContext<'_> { - fn upgrade_model_handle( - &self, - handle: &WeakModelHandle, - ) -> Option> { - self.app_context.upgrade_model_handle(handle) - } - - fn model_handle_is_upgradable(&self, handle: &WeakModelHandle) -> bool { - self.app_context.model_handle_is_upgradable(handle) - } - - fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option { - self.app_context.upgrade_any_model_handle(handle) - } -} - impl<'a> WindowContext<'a> { pub fn mutable( app_context: &'a mut AppContext, diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index afd0b3bbae..e5fc1e1b3b 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -19,8 +19,8 @@ use futures::{ AsyncWriteExt, Future, FutureExt, StreamExt, TryFutureExt, }; use gpui::{ - AnyModelHandle, AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, Task, - UpgradeModelHandle, WeakModelHandle, + AnyModelHandle, AppContext, AsyncAppContext, BorrowAppContext, Entity, ModelContext, + ModelHandle, Task, WeakModelHandle, }; use language::{ point_to_lsp, @@ -6356,7 +6356,7 @@ impl WorktreeHandle { } impl OpenBuffer { - pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option> { + pub fn upgrade(&self, cx: &impl BorrowAppContext) -> Option> { match self { OpenBuffer::Strong(handle) => Some(handle.clone()), OpenBuffer::Weak(handle) => handle.upgrade(cx), From a9417f3d2e824ae24f001568fa646d27bd2b5fea Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 24 Apr 2023 16:44:54 +0200 Subject: [PATCH 6/8] Remove `ReadModelWith` trait Co-Authored-By: Nathan Sobo --- crates/gpui/src/app.rs | 28 ++----------------------- crates/gpui/src/app/test_app_context.rs | 26 +++++++++++------------ 2 files changed, 14 insertions(+), 40 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index ae71042e54..315c3048a3 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -126,14 +126,6 @@ pub trait BorrowAppContext { fn update T>(&mut self, f: F) -> T; } -pub trait ReadModelWith { - fn read_model_with( - &self, - handle: &ModelHandle, - read: &mut dyn FnMut(&E, &AppContext) -> T, - ) -> T; -} - pub trait UpdateModel { fn update_model( &mut self, @@ -414,18 +406,6 @@ impl UpdateModel for AsyncAppContext { } } -impl ReadModelWith for AsyncAppContext { - fn read_model_with( - &self, - handle: &ModelHandle, - read: &mut dyn FnMut(&E, &AppContext) -> T, - ) -> T { - let cx = self.0.borrow(); - let cx = &*cx; - read(handle.read(cx), cx) - } -} - impl UpdateView for AsyncAppContext { type Output = Result; @@ -3609,14 +3589,10 @@ impl ModelHandle { pub fn read_with(&self, cx: &C, read: F) -> S where - C: ReadModelWith, + C: BorrowAppContext, F: FnOnce(&T, &AppContext) -> S, { - let mut read = Some(read); - cx.read_model_with(self, &mut |model, cx| { - let read = read.take().unwrap(); - read(model, cx) - }) + cx.read_with(|cx| read(self.read(cx), cx)) } pub fn update(&self, cx: &mut C, update: F) -> S diff --git a/crates/gpui/src/app/test_app_context.rs b/crates/gpui/src/app/test_app_context.rs index 5a367b15ba..fdc93319cb 100644 --- a/crates/gpui/src/app/test_app_context.rs +++ b/crates/gpui/src/app/test_app_context.rs @@ -22,8 +22,8 @@ use crate::{ keymap_matcher::Keystroke, platform, platform::{Event, InputHandler, KeyDownEvent, Platform}, - Action, AnyViewHandle, AppContext, Entity, FontCache, Handle, ModelContext, ModelHandle, - ReadModelWith, ReadViewWith, Subscription, Task, UpdateModel, UpdateView, View, ViewContext, + Action, AnyViewHandle, AppContext, BorrowAppContext, Entity, FontCache, Handle, ModelContext, + ModelHandle, ReadViewWith, Subscription, Task, UpdateModel, UpdateView, View, ViewContext, ViewHandle, WeakHandle, WindowContext, }; use collections::BTreeMap; @@ -381,6 +381,16 @@ impl TestAppContext { } } +impl BorrowAppContext for TestAppContext { + fn read_with T>(&self, f: F) -> T { + self.cx.borrow().read_with(f) + } + + fn update T>(&mut self, f: F) -> T { + self.cx.borrow_mut().update(f) + } +} + impl UpdateModel for TestAppContext { fn update_model( &mut self, @@ -391,18 +401,6 @@ impl UpdateModel for TestAppContext { } } -impl ReadModelWith for TestAppContext { - fn read_model_with( - &self, - handle: &ModelHandle, - read: &mut dyn FnMut(&E, &AppContext) -> T, - ) -> T { - let cx = self.cx.borrow(); - let cx = &*cx; - read(handle.read(cx), cx) - } -} - impl UpdateView for TestAppContext { type Output = S; From a6115d93302bf1700b091e026493e5453d6ebc92 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 24 Apr 2023 16:52:09 +0200 Subject: [PATCH 7/8] Remove `UpdateModel` trait Co-Authored-By: Nathan Sobo --- crates/gpui/src/app.rs | 106 +++++++----------------- crates/gpui/src/app/test_app_context.rs | 14 +--- crates/gpui/src/app/window.rs | 14 +--- 3 files changed, 33 insertions(+), 101 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 315c3048a3..34b9b13af9 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -126,14 +126,6 @@ pub trait BorrowAppContext { fn update T>(&mut self, f: F) -> T; } -pub trait UpdateModel { - fn update_model( - &mut self, - handle: &ModelHandle, - update: &mut dyn FnMut(&mut T, &mut ModelContext) -> O, - ) -> O; -} - pub trait ReadViewWith { fn read_view_with( &self, @@ -396,16 +388,6 @@ impl BorrowAppContext for AsyncAppContext { } } -impl UpdateModel for AsyncAppContext { - fn update_model( - &mut self, - handle: &ModelHandle, - update: &mut dyn FnMut(&mut E, &mut ModelContext) -> O, - ) -> O { - self.0.borrow_mut().update_model(handle, update) - } -} - impl UpdateView for AsyncAppContext { type Output = Result; @@ -1243,6 +1225,29 @@ impl AppContext { } } + fn update_model( + &mut self, + handle: &ModelHandle, + update: &mut dyn FnMut(&mut T, &mut ModelContext) -> V, + ) -> V { + if let Some(mut model) = self.models.remove(&handle.model_id) { + self.update(|this| { + let mut cx = ModelContext::new(this, handle.model_id); + let result = update( + model + .as_any_mut() + .downcast_mut() + .expect("downcast is type safe"), + &mut cx, + ); + this.models.insert(handle.model_id, model); + result + }) + } else { + panic!("circular model update"); + } + } + fn upgrade_model_handle( &self, handle: &WeakModelHandle, @@ -2102,31 +2107,6 @@ impl BorrowAppContext for AppContext { } } -impl UpdateModel for AppContext { - fn update_model( - &mut self, - handle: &ModelHandle, - update: &mut dyn FnMut(&mut T, &mut ModelContext) -> V, - ) -> V { - if let Some(mut model) = self.models.remove(&handle.model_id) { - self.update(|this| { - let mut cx = ModelContext::new(this, handle.model_id); - let result = update( - model - .as_any_mut() - .downcast_mut() - .expect("downcast is type safe"), - &mut cx, - ); - this.models.insert(handle.model_id, model); - result - }) - } else { - panic!("circular model update"); - } - } -} - #[derive(Debug)] pub enum ParentId { View(usize), @@ -2822,16 +2802,6 @@ impl BorrowAppContext for ModelContext<'_, M> { } } -impl UpdateModel for ModelContext<'_, M> { - fn update_model( - &mut self, - handle: &ModelHandle, - update: &mut dyn FnMut(&mut T, &mut ModelContext) -> V, - ) -> V { - self.app.update_model(handle, update) - } -} - impl Deref for ModelContext<'_, M> { type Target = AppContext; @@ -3387,16 +3357,6 @@ impl BorrowAppContext for ViewContext<'_, '_, V> { } } -impl UpdateModel for ViewContext<'_, '_, V> { - fn update_model( - &mut self, - handle: &ModelHandle, - update: &mut dyn FnMut(&mut T, &mut ModelContext) -> O, - ) -> O { - self.window_context.update_model(handle, update) - } -} - impl UpdateView for ViewContext<'_, '_, V> { type Output = S; @@ -3454,16 +3414,6 @@ impl BorrowAppContext for EventContext<'_, '_, '_, V> { } } -impl UpdateModel for EventContext<'_, '_, '_, V> { - fn update_model( - &mut self, - handle: &ModelHandle, - update: &mut dyn FnMut(&mut T, &mut ModelContext) -> O, - ) -> O { - self.view_context.update_model(handle, update) - } -} - impl UpdateView for EventContext<'_, '_, '_, V> { type Output = S; @@ -3597,13 +3547,15 @@ impl ModelHandle { pub fn update(&self, cx: &mut C, update: F) -> S where - C: UpdateModel, + C: BorrowAppContext, F: FnOnce(&mut T, &mut ModelContext) -> S, { let mut update = Some(update); - cx.update_model(self, &mut |model, cx| { - let update = update.take().unwrap(); - update(model, cx) + cx.update(|cx| { + cx.update_model(self, &mut |model, cx| { + let update = update.take().unwrap(); + update(model, cx) + }) }) } } diff --git a/crates/gpui/src/app/test_app_context.rs b/crates/gpui/src/app/test_app_context.rs index fdc93319cb..1f18d28164 100644 --- a/crates/gpui/src/app/test_app_context.rs +++ b/crates/gpui/src/app/test_app_context.rs @@ -23,8 +23,8 @@ use crate::{ platform, platform::{Event, InputHandler, KeyDownEvent, Platform}, Action, AnyViewHandle, AppContext, BorrowAppContext, Entity, FontCache, Handle, ModelContext, - ModelHandle, ReadViewWith, Subscription, Task, UpdateModel, UpdateView, View, ViewContext, - ViewHandle, WeakHandle, WindowContext, + ModelHandle, ReadViewWith, Subscription, Task, UpdateView, View, ViewContext, ViewHandle, + WeakHandle, WindowContext, }; use collections::BTreeMap; @@ -391,16 +391,6 @@ impl BorrowAppContext for TestAppContext { } } -impl UpdateModel for TestAppContext { - fn update_model( - &mut self, - handle: &ModelHandle, - update: &mut dyn FnMut(&mut T, &mut ModelContext) -> O, - ) -> O { - self.cx.borrow_mut().update_model(handle, update) - } -} - impl UpdateView for TestAppContext { type Output = S; diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index a8af427f7e..c2ce119d88 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -14,8 +14,8 @@ use crate::{ text_layout::TextLayoutCache, util::post_inc, Action, AnyView, AnyViewHandle, AppContext, BorrowAppContext, Effect, Element, Entity, Handle, - ModelContext, ModelHandle, MouseRegion, MouseRegionId, ParentId, SceneBuilder, Subscription, - UpdateModel, UpdateView, View, ViewContext, ViewHandle, WindowInvalidation, + MouseRegion, MouseRegionId, ParentId, SceneBuilder, Subscription, UpdateView, View, + ViewContext, ViewHandle, WindowInvalidation, }; use anyhow::{anyhow, bail, Result}; use collections::{HashMap, HashSet}; @@ -141,16 +141,6 @@ impl BorrowAppContext for WindowContext<'_> { } } -impl UpdateModel for WindowContext<'_> { - fn update_model( - &mut self, - handle: &ModelHandle, - update: &mut dyn FnMut(&mut T, &mut ModelContext) -> R, - ) -> R { - self.app_context.update_model(handle, update) - } -} - impl UpdateView for WindowContext<'_> { type Output = S; From c165fb9be57e70e67a00d1cfb344d7a3e5079a36 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 24 Apr 2023 17:36:14 +0200 Subject: [PATCH 8/8] Remove `ReadView` and `UpdateView` traits Co-Authored-By: Nathan Sobo --- crates/editor/src/editor.rs | 6 +- crates/editor/src/editor_tests.rs | 12 +- crates/editor/src/items.rs | 2 +- crates/editor/src/test/editor_test_context.rs | 2 +- crates/gpui/src/app.rs | 140 ++++++++---------- crates/gpui/src/app/test_app_context.rs | 71 ++++----- crates/gpui/src/app/window.rs | 62 +++++--- crates/vim/src/test/vim_test_context.rs | 4 +- crates/workspace/src/dock.rs | 23 ++- crates/workspace/src/pane.rs | 4 +- crates/workspace/src/persistence/model.rs | 5 +- crates/workspace/src/workspace.rs | 12 +- 12 files changed, 160 insertions(+), 183 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 54ba2c1a9c..41f9a3fd3f 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -2715,7 +2715,7 @@ impl Editor { title: String, mut cx: AsyncAppContext, ) -> Result<()> { - let replica_id = this.read_with(&cx, |this, cx| this.replica_id(cx)); + let replica_id = this.read_with(&cx, |this, cx| this.replica_id(cx))?; let mut entries = transaction.0.into_iter().collect::>(); entries.sort_unstable_by_key(|(buffer, _)| { @@ -2732,7 +2732,7 @@ impl Editor { .buffer() .read(cx) .excerpt_containing(editor.selections.newest_anchor().head(), cx) - }); + })?; if let Some((_, excerpted_buffer, excerpt_range)) = excerpt { if excerpted_buffer == *buffer { let all_edits_within_excerpt = buffer.read_with(&cx, |buffer, _| { @@ -5814,7 +5814,7 @@ impl Editor { buffer_highlights .next() .map(|highlight| highlight.start.text_anchor..highlight.end.text_anchor) - }) + })? }; if let Some(rename_range) = rename_range { let rename_buffer_range = rename_range.to_offset(&snapshot); diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 0b8a05ace6..e71ab8ae4b 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -5673,8 +5673,8 @@ async fn test_following_with_multiple_excerpts(cx: &mut gpui::TestAppContext) { .await .unwrap(); assert_eq!( - follower_1.read_with(cx, Editor::text), - leader.read_with(cx, Editor::text) + follower_1.read_with(cx, |editor, cx| editor.text(cx)), + leader.read_with(cx, |editor, cx| editor.text(cx)) ); update_message.borrow_mut().take(); @@ -5697,8 +5697,8 @@ async fn test_following_with_multiple_excerpts(cx: &mut gpui::TestAppContext) { .await .unwrap(); assert_eq!( - follower_2.read_with(cx, Editor::text), - leader.read_with(cx, Editor::text) + follower_2.read_with(cx, |editor, cx| editor.text(cx)), + leader.read_with(cx, |editor, cx| editor.text(cx)) ); // Remove some excerpts. @@ -5725,8 +5725,8 @@ async fn test_following_with_multiple_excerpts(cx: &mut gpui::TestAppContext) { .unwrap(); update_message.borrow_mut().take(); assert_eq!( - follower_1.read_with(cx, Editor::text), - leader.read_with(cx, Editor::text) + follower_1.read_with(cx, |editor, cx| editor.text(cx)), + leader.read_with(cx, |editor, cx| editor.text(cx)) ); } diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index a1316b8179..01db7de724 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -78,7 +78,7 @@ impl FollowableItem for Editor { == editor.read(cx).buffer.read(cx).as_singleton().as_ref(); ids_match || singleton_buffer_matches }) - }); + })?; let editor = if let Some(editor) = editor { editor diff --git a/crates/editor/src/test/editor_test_context.rs b/crates/editor/src/test/editor_test_context.rs index 65ff11b77a..269a2f4f3c 100644 --- a/crates/editor/src/test/editor_test_context.rs +++ b/crates/editor/src/test/editor_test_context.rs @@ -57,7 +57,7 @@ impl<'a> EditorTestContext<'a> { pub fn editor(&self, read: F) -> T where - F: FnOnce(&Editor, &AppContext) -> T, + F: FnOnce(&Editor, &ViewContext) -> T, { self.editor.read_with(self.cx, read) } diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 34b9b13af9..a1f9002fba 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -126,26 +126,19 @@ pub trait BorrowAppContext { fn update T>(&mut self, f: F) -> T; } -pub trait ReadViewWith { - fn read_view_with( +pub trait BorrowWindowContext { + type ReturnValue; + + fn read_with T>( &self, - handle: &ViewHandle, - read: &mut dyn FnMut(&V, &AppContext) -> T, - ) -> T - where - V: View; -} - -pub trait UpdateView { - type Output; - - fn update_view( + window_id: usize, + f: F, + ) -> Self::ReturnValue; + fn update T>( &mut self, - handle: &ViewHandle, - update: &mut dyn FnMut(&mut T, &mut ViewContext) -> S, - ) -> Self::Output - where - T: View; + window_id: usize, + f: F, + ) -> Self::ReturnValue; } #[derive(Clone)] @@ -388,36 +381,25 @@ impl BorrowAppContext for AsyncAppContext { } } -impl UpdateView for AsyncAppContext { - type Output = Result; +impl BorrowWindowContext for AsyncAppContext { + type ReturnValue = Result; - fn update_view( - &mut self, - handle: &ViewHandle, - update: &mut dyn FnMut(&mut T, &mut ViewContext) -> S, - ) -> Result - where - T: View, - { + fn read_with T>(&self, window_id: usize, f: F) -> Result { self.0 - .borrow_mut() - .update_window(handle.window_id, |cx| cx.update_view(handle, update)) + .borrow() + .read_window(window_id, f) .ok_or_else(|| anyhow!("window was closed")) } -} -impl ReadViewWith for AsyncAppContext { - fn read_view_with( - &self, - handle: &ViewHandle, - read: &mut dyn FnMut(&V, &AppContext) -> T, - ) -> T - where - V: View, - { - let cx = self.0.borrow(); - let cx = &*cx; - read(handle.read(cx), cx) + fn update T>( + &mut self, + window_id: usize, + f: F, + ) -> Result { + self.0 + .borrow_mut() + .update_window(window_id, f) + .ok_or_else(|| anyhow!("window was closed")) } } @@ -3349,26 +3331,23 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { impl BorrowAppContext for ViewContext<'_, '_, V> { fn read_with T>(&self, f: F) -> T { - self.window_context.read_with(f) + BorrowAppContext::read_with(&*self.window_context, f) } fn update T>(&mut self, f: F) -> T { - self.window_context.update(f) + BorrowAppContext::update(&mut *self.window_context, f) } } -impl UpdateView for ViewContext<'_, '_, V> { - type Output = S; +impl BorrowWindowContext for ViewContext<'_, '_, V> { + type ReturnValue = T; - fn update_view( - &mut self, - handle: &ViewHandle, - update: &mut dyn FnMut(&mut T, &mut ViewContext) -> S, - ) -> S - where - T: View, - { - self.window_context.update_view(handle, update) + fn read_with T>(&self, window_id: usize, f: F) -> T { + BorrowWindowContext::read_with(&*self.window_context, window_id, f) + } + + fn update T>(&mut self, window_id: usize, f: F) -> T { + BorrowWindowContext::update(&mut *self.window_context, window_id, f) } } @@ -3406,26 +3385,23 @@ impl DerefMut for EventContext<'_, '_, '_, V> { impl BorrowAppContext for EventContext<'_, '_, '_, V> { fn read_with T>(&self, f: F) -> T { - self.view_context.read_with(f) + BorrowAppContext::read_with(&*self.view_context, f) } fn update T>(&mut self, f: F) -> T { - self.view_context.update(f) + BorrowAppContext::update(&mut *self.view_context, f) } } -impl UpdateView for EventContext<'_, '_, '_, V> { - type Output = S; +impl BorrowWindowContext for EventContext<'_, '_, '_, V> { + type ReturnValue = T; - fn update_view( - &mut self, - handle: &ViewHandle, - update: &mut dyn FnMut(&mut T, &mut ViewContext) -> S, - ) -> S - where - T: View, - { - self.view_context.update_view(handle, update) + fn read_with T>(&self, window_id: usize, f: F) -> T { + BorrowWindowContext::read_with(&*self.view_context, window_id, f) + } + + fn update T>(&mut self, window_id: usize, f: F) -> T { + BorrowWindowContext::update(&mut *self.view_context, window_id, f) } } @@ -3756,27 +3732,29 @@ impl ViewHandle { cx.read_view(self) } - pub fn read_with(&self, cx: &C, read: F) -> S + pub fn read_with(&self, cx: &C, read: F) -> C::ReturnValue where - C: ReadViewWith, - F: FnOnce(&T, &AppContext) -> S, + C: BorrowWindowContext, + F: FnOnce(&T, &ViewContext) -> S, { - let mut read = Some(read); - cx.read_view_with(self, &mut |view, cx| { - let read = read.take().unwrap(); - read(view, cx) + cx.read_with(self.window_id, |cx| { + let cx = ViewContext::immutable(cx, self.view_id); + read(cx.read_view(self), &cx) }) } - pub fn update(&self, cx: &mut C, update: F) -> C::Output + pub fn update(&self, cx: &mut C, update: F) -> C::ReturnValue where - C: UpdateView, + C: BorrowWindowContext, F: FnOnce(&mut T, &mut ViewContext) -> S, { let mut update = Some(update); - cx.update_view(self, &mut |view, cx| { - let update = update.take().unwrap(); - update(view, cx) + + cx.update(self.window_id, |cx| { + cx.update_view(self, &mut |view, cx| { + let update = update.take().unwrap(); + update(view, cx) + }) }) } diff --git a/crates/gpui/src/app/test_app_context.rs b/crates/gpui/src/app/test_app_context.rs index 1f18d28164..9aa6eb3393 100644 --- a/crates/gpui/src/app/test_app_context.rs +++ b/crates/gpui/src/app/test_app_context.rs @@ -1,3 +1,18 @@ +use crate::{ + executor, + geometry::vector::Vector2F, + keymap_matcher::Keystroke, + platform, + platform::{Event, InputHandler, KeyDownEvent, Platform}, + Action, AnyViewHandle, AppContext, BorrowAppContext, BorrowWindowContext, Entity, FontCache, + Handle, ModelContext, ModelHandle, Subscription, Task, View, ViewContext, ViewHandle, + WeakHandle, WindowContext, +}; +use collections::BTreeMap; +use futures::Future; +use itertools::Itertools; +use parking_lot::{Mutex, RwLock}; +use smol::stream::StreamExt; use std::{ any::Any, cell::RefCell, @@ -11,23 +26,6 @@ use std::{ time::Duration, }; -use futures::Future; -use itertools::Itertools; -use parking_lot::{Mutex, RwLock}; -use smol::stream::StreamExt; - -use crate::{ - executor, - geometry::vector::Vector2F, - keymap_matcher::Keystroke, - platform, - platform::{Event, InputHandler, KeyDownEvent, Platform}, - Action, AnyViewHandle, AppContext, BorrowAppContext, Entity, FontCache, Handle, ModelContext, - ModelHandle, ReadViewWith, Subscription, Task, UpdateView, View, ViewContext, ViewHandle, - WeakHandle, WindowContext, -}; -use collections::BTreeMap; - use super::{ ref_counts::LeakDetector, window_input_handler::WindowInputHandler, AsyncAppContext, RefCounts, }; @@ -391,36 +389,21 @@ impl BorrowAppContext for TestAppContext { } } -impl UpdateView for TestAppContext { - type Output = S; +impl BorrowWindowContext for TestAppContext { + type ReturnValue = T; - fn update_view( - &mut self, - handle: &ViewHandle, - update: &mut dyn FnMut(&mut T, &mut ViewContext) -> S, - ) -> S - where - T: View, - { + fn read_with T>(&self, window_id: usize, f: F) -> T { + self.cx + .borrow() + .read_window(window_id, f) + .expect("window was closed") + } + + fn update T>(&mut self, window_id: usize, f: F) -> T { self.cx .borrow_mut() - .update_window(handle.window_id, |cx| cx.update_view(handle, update)) - .unwrap() - } -} - -impl ReadViewWith for TestAppContext { - fn read_view_with( - &self, - handle: &ViewHandle, - read: &mut dyn FnMut(&V, &AppContext) -> T, - ) -> T - where - V: View, - { - let cx = self.cx.borrow(); - let cx = &*cx; - read(handle.read(cx), cx) + .update_window(window_id, f) + .expect("window was closed") } } diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index c2ce119d88..3c5ab96a86 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -13,9 +13,9 @@ use crate::{ }, text_layout::TextLayoutCache, util::post_inc, - Action, AnyView, AnyViewHandle, AppContext, BorrowAppContext, Effect, Element, Entity, Handle, - MouseRegion, MouseRegionId, ParentId, SceneBuilder, Subscription, UpdateView, View, - ViewContext, ViewHandle, WindowInvalidation, + Action, AnyView, AnyViewHandle, AppContext, BorrowAppContext, BorrowWindowContext, Effect, + Element, Entity, Handle, MouseRegion, MouseRegionId, ParentId, SceneBuilder, Subscription, + View, ViewContext, ViewHandle, WindowInvalidation, }; use anyhow::{anyhow, bail, Result}; use collections::{HashMap, HashSet}; @@ -141,27 +141,23 @@ impl BorrowAppContext for WindowContext<'_> { } } -impl UpdateView for WindowContext<'_> { - type Output = S; +impl BorrowWindowContext for WindowContext<'_> { + type ReturnValue = T; - fn update_view( - &mut self, - handle: &ViewHandle, - update: &mut dyn FnMut(&mut T, &mut ViewContext) -> S, - ) -> S - where - T: View, - { - self.update_any_view(handle.view_id, |view, cx| { - let mut cx = ViewContext::mutable(cx, handle.view_id); - update( - view.as_any_mut() - .downcast_mut() - .expect("downcast is type safe"), - &mut cx, - ) - }) - .expect("view is already on the stack") + fn read_with T>(&self, window_id: usize, f: F) -> T { + if self.window_id == window_id { + f(self) + } else { + panic!("read_with called with id of window that does not belong to this context") + } + } + + fn update T>(&mut self, window_id: usize, f: F) -> T { + if self.window_id == window_id { + f(self) + } else { + panic!("update called with id of window that does not belong to this context") + } } } @@ -225,6 +221,26 @@ impl<'a> WindowContext<'a> { Some(result) } + pub(crate) fn update_view( + &mut self, + handle: &ViewHandle, + update: &mut dyn FnMut(&mut T, &mut ViewContext) -> S, + ) -> S + where + T: View, + { + self.update_any_view(handle.view_id, |view, cx| { + let mut cx = ViewContext::mutable(cx, handle.view_id); + update( + view.as_any_mut() + .downcast_mut() + .expect("downcast is type safe"), + &mut cx, + ) + }) + .expect("view is already on the stack") + } + pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut WindowContext)) { let window_id = self.window_id; self.app_context.defer(move |cx| { diff --git a/crates/vim/src/test/vim_test_context.rs b/crates/vim/src/test/vim_test_context.rs index 577f8c8bd4..69227a0e45 100644 --- a/crates/vim/src/test/vim_test_context.rs +++ b/crates/vim/src/test/vim_test_context.rs @@ -3,7 +3,7 @@ use std::ops::{Deref, DerefMut}; use editor::test::{ editor_lsp_test_context::EditorLspTestContext, editor_test_context::EditorTestContext, }; -use gpui::{AppContext, ContextHandle}; +use gpui::ContextHandle; use search::{BufferSearchBar, ProjectSearchBar}; use crate::{state::Operator, *}; @@ -45,7 +45,7 @@ impl<'a> VimTestContext<'a> { pub fn workspace(&mut self, read: F) -> T where - F: FnOnce(&Workspace, &AppContext) -> T, + F: FnOnce(&Workspace, &ViewContext) -> T, { self.cx.workspace.read_with(self.cx.cx.cx, read) } diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index e4cd7ed14d..c80f71c422 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -428,7 +428,7 @@ mod tests { path::PathBuf, }; - use gpui::{AppContext, TestAppContext, UpdateView, View, ViewContext}; + use gpui::{AppContext, BorrowWindowContext, TestAppContext, ViewContext, WindowContext}; use project::{FakeFs, Project}; use settings::Settings; @@ -660,7 +660,7 @@ mod tests { pub fn workspace(&self, read: F) -> T where - F: FnOnce(&Workspace, &AppContext) -> T, + F: FnOnce(&Workspace, &ViewContext) -> T, { self.workspace.read_with(self.cx, read) } @@ -810,18 +810,15 @@ mod tests { } } - impl<'a> UpdateView for DockTestContext<'a> { - type Output = S; + impl BorrowWindowContext for DockTestContext<'_> { + type ReturnValue = T; - fn update_view( - &mut self, - handle: &ViewHandle, - update: &mut dyn FnMut(&mut T, &mut ViewContext) -> S, - ) -> S - where - T: View, - { - handle.update(self.cx, update) + fn read_with T>(&self, window_id: usize, f: F) -> T { + BorrowWindowContext::read_with(self.cx, window_id, f) + } + + fn update T>(&mut self, window_id: usize, f: F) -> T { + BorrowWindowContext::update(self.cx, window_id, f) } } } diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index c15fa1f724..43bfaed1ad 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -981,7 +981,7 @@ impl Pane { // was started. let (item_ix, mut project_item_ids) = pane.read_with(&cx, |pane, cx| { (pane.index_for_item(&*item), item.project_item_model_ids(cx)) - }); + })?; let item_ix = if let Some(ix) = item_ix { ix } else { @@ -1001,7 +1001,7 @@ impl Pane { project_item_ids.retain(|id| !other_project_item_ids.contains(id)); } } - }); + })?; let should_save = project_item_ids .iter() .any(|id| saved_project_items_ids.insert(*id)); diff --git a/crates/workspace/src/persistence/model.rs b/crates/workspace/src/persistence/model.rs index 1520b7f6a0..523a80af7c 100644 --- a/crates/workspace/src/persistence/model.rs +++ b/crates/workspace/src/persistence/model.rs @@ -140,7 +140,10 @@ impl SerializedPaneGroup { .await .log_err()?; - if pane.read_with(cx, |pane, _| pane.items_len() != 0) { + if pane + .read_with(cx, |pane, _| pane.items_len() != 0) + .log_err()? + { Some((Member::Pane(pane.clone()), active.then(|| pane))) } else { workspace diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 68f8555393..bc493f9aba 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -1226,7 +1226,7 @@ impl Workspace { cx.read(|cx| (item.is_singleton(cx), item.project_entry_ids(cx))); if singleton || !project_entry_ids.is_empty() { if let Some(ix) = - pane.read_with(&cx, |pane, _| pane.index_for_item(item.as_ref())) + pane.read_with(&cx, |pane, _| pane.index_for_item(item.as_ref()))? { if !Pane::save_item( project.clone(), @@ -2298,7 +2298,7 @@ impl Workspace { this.read_with(&cx, |this, _| { this.leader_updates_tx .unbounded_send((leader_id, envelope.payload)) - })?; + })??; Ok(()) } @@ -2354,7 +2354,7 @@ impl Workspace { .flat_map(|states_by_pane| states_by_pane.keys()) .cloned() .collect() - }); + })?; Self::add_views_from_leader(this.clone(), leader_id, panes, vec![view], cx).await?; } } @@ -2369,7 +2369,7 @@ impl Workspace { views: Vec, cx: &mut AsyncAppContext, ) -> Result<()> { - let project = this.read_with(cx, |this, _| this.project.clone()); + let project = this.read_with(cx, |this, _| this.project.clone())?; let replica_id = project .read_with(cx, |project, _| { project @@ -2699,7 +2699,7 @@ impl Workspace { workspace.dock_pane().clone(), workspace.last_active_center_pane.clone(), ) - }); + })?; serialized_workspace .dock_pane @@ -2765,7 +2765,7 @@ impl Workspace { })?; // Serialize ourself to make sure our timestamps and any pane / item changes are replicated - workspace.read_with(&cx, |workspace, cx| workspace.serialize_workspace(cx)) + workspace.read_with(&cx, |workspace, cx| workspace.serialize_workspace(cx))? } anyhow::Ok(()) })