diff --git a/gpui/src/app.rs b/gpui/src/app.rs index 1156ec40d4..0cf1069738 100644 --- a/gpui/src/app.rs +++ b/gpui/src/app.rs @@ -57,18 +57,19 @@ pub trait ReadModel { } pub trait ReadModelWith { - fn read_model_with T, T>( + fn read_model_with( &self, handle: &ModelHandle, - read: F, + read: &mut dyn FnMut(&E, &AppContext) -> T, ) -> T; } pub trait UpdateModel { - fn update_model(&mut self, handle: &ModelHandle, update: F) -> S - where - T: Entity, - F: FnOnce(&mut T, &mut ModelContext) -> S; + fn update_model( + &mut self, + handle: &ModelHandle, + update: &mut dyn FnMut(&mut T, &mut ModelContext) -> O, + ) -> O; } pub trait UpgradeModelHandle { @@ -81,17 +82,23 @@ pub trait ReadView { } pub trait ReadViewWith { - fn read_view_with(&self, handle: &ViewHandle, read: F) -> T + fn read_view_with( + &self, + handle: &ViewHandle, + read: &mut dyn FnMut(&V, &AppContext) -> T, + ) -> T where - V: View, - F: FnOnce(&V, &AppContext) -> T; + V: View; } pub trait UpdateView { - fn update_view(&mut self, handle: &ViewHandle, update: F) -> S + fn update_view( + &mut self, + handle: &ViewHandle, + update: &mut dyn FnMut(&mut T, &mut ViewContext) -> S, + ) -> S where - T: View, - F: FnOnce(&mut T, &mut ViewContext) -> S; + T: View; } pub trait Action: 'static + AnyAction { @@ -531,11 +538,11 @@ impl AsyncAppContext { } impl UpdateModel for AsyncAppContext { - fn update_model(&mut self, handle: &ModelHandle, update: F) -> S - where - T: Entity, - F: FnOnce(&mut T, &mut ModelContext) -> S, - { + fn update_model( + &mut self, + handle: &ModelHandle, + update: &mut dyn FnMut(&mut E, &mut ModelContext) -> O, + ) -> O { let mut state = self.0.borrow_mut(); state.pending_flushes += 1; let result = state.update_model(handle, update); @@ -554,10 +561,10 @@ impl UpgradeModelHandle for AsyncAppContext { } impl ReadModelWith for AsyncAppContext { - fn read_model_with T, T>( + fn read_model_with( &self, handle: &ModelHandle, - read: F, + read: &mut dyn FnMut(&E, &AppContext) -> T, ) -> T { let cx = self.0.borrow(); let cx = cx.as_ref(); @@ -566,10 +573,13 @@ impl ReadModelWith for AsyncAppContext { } impl UpdateView for AsyncAppContext { - fn update_view(&mut self, handle: &ViewHandle, update: F) -> S + fn update_view( + &mut self, + handle: &ViewHandle, + update: &mut dyn FnMut(&mut T, &mut ViewContext) -> S, + ) -> S where T: View, - F: FnOnce(&mut T, &mut ViewContext) -> S, { let mut state = self.0.borrow_mut(); state.pending_flushes += 1; @@ -580,10 +590,13 @@ impl UpdateView for AsyncAppContext { } impl ReadViewWith for AsyncAppContext { - fn read_view_with(&self, handle: &ViewHandle, read: F) -> T + fn read_view_with( + &self, + handle: &ViewHandle, + read: &mut dyn FnMut(&V, &AppContext) -> T, + ) -> T where V: View, - F: FnOnce(&V, &AppContext) -> T, { let cx = self.0.borrow(); let cx = cx.as_ref(); @@ -592,11 +605,11 @@ impl ReadViewWith for AsyncAppContext { } impl UpdateModel for TestAppContext { - fn update_model(&mut self, handle: &ModelHandle, update: F) -> S - where - T: Entity, - F: FnOnce(&mut T, &mut ModelContext) -> S, - { + fn update_model( + &mut self, + handle: &ModelHandle, + update: &mut dyn FnMut(&mut T, &mut ModelContext) -> O, + ) -> O { let mut state = self.cx.borrow_mut(); state.pending_flushes += 1; let result = state.update_model(handle, update); @@ -606,10 +619,10 @@ impl UpdateModel for TestAppContext { } impl ReadModelWith for TestAppContext { - fn read_model_with T, T>( + fn read_model_with( &self, handle: &ModelHandle, - read: F, + read: &mut dyn FnMut(&E, &AppContext) -> T, ) -> T { let cx = self.cx.borrow(); let cx = cx.as_ref(); @@ -618,10 +631,13 @@ impl ReadModelWith for TestAppContext { } impl UpdateView for TestAppContext { - fn update_view(&mut self, handle: &ViewHandle, update: F) -> S + fn update_view( + &mut self, + handle: &ViewHandle, + update: &mut dyn FnMut(&mut T, &mut ViewContext) -> S, + ) -> S where T: View, - F: FnOnce(&mut T, &mut ViewContext) -> S, { let mut state = self.cx.borrow_mut(); state.pending_flushes += 1; @@ -632,10 +648,13 @@ impl UpdateView for TestAppContext { } impl ReadViewWith for TestAppContext { - fn read_view_with(&self, handle: &ViewHandle, read: F) -> T + fn read_view_with( + &self, + handle: &ViewHandle, + read: &mut dyn FnMut(&V, &AppContext) -> T, + ) -> T where V: View, - F: FnOnce(&V, &AppContext) -> T, { let cx = self.cx.borrow(); let cx = cx.as_ref(); @@ -1629,11 +1648,11 @@ impl ReadModel for MutableAppContext { } impl UpdateModel for MutableAppContext { - fn update_model(&mut self, handle: &ModelHandle, update: F) -> S - where - T: Entity, - F: FnOnce(&mut T, &mut ModelContext) -> S, - { + fn update_model( + &mut self, + handle: &ModelHandle, + update: &mut dyn FnMut(&mut T, &mut ModelContext) -> V, + ) -> V { if let Some(mut model) = self.cx.models.remove(&handle.model_id) { self.pending_flushes += 1; let mut cx = ModelContext::new(self, handle.model_id); @@ -1673,10 +1692,13 @@ impl ReadView for MutableAppContext { } impl UpdateView for MutableAppContext { - fn update_view(&mut self, handle: &ViewHandle, update: F) -> S + fn update_view( + &mut self, + handle: &ViewHandle, + update: &mut dyn FnMut(&mut T, &mut ViewContext) -> S, + ) -> S where T: View, - F: FnOnce(&mut T, &mut ViewContext) -> S, { self.pending_flushes += 1; let mut view = self @@ -2083,11 +2105,11 @@ impl ReadModel for ModelContext<'_, M> { } impl UpdateModel for ModelContext<'_, M> { - fn update_model(&mut self, handle: &ModelHandle, update: F) -> S - where - T: Entity, - F: FnOnce(&mut T, &mut ModelContext) -> S, - { + fn update_model( + &mut self, + handle: &ModelHandle, + update: &mut dyn FnMut(&mut T, &mut ModelContext) -> V, + ) -> V { self.app.update_model(handle, update) } } @@ -2344,11 +2366,11 @@ impl ReadModel for RenderContext<'_, V> { } impl UpdateModel for RenderContext<'_, V> { - fn update_model(&mut self, handle: &ModelHandle, update: F) -> S - where - T: Entity, - F: FnOnce(&mut T, &mut ModelContext) -> S, - { + fn update_model( + &mut self, + handle: &ModelHandle, + update: &mut dyn FnMut(&mut T, &mut ModelContext) -> O, + ) -> O { self.app.update_model(handle, update) } } @@ -2395,11 +2417,11 @@ impl UpgradeModelHandle for ViewContext<'_, V> { } impl UpdateModel for ViewContext<'_, V> { - fn update_model(&mut self, handle: &ModelHandle, update: F) -> S - where - T: Entity, - F: FnOnce(&mut T, &mut ModelContext) -> S, - { + fn update_model( + &mut self, + handle: &ModelHandle, + update: &mut dyn FnMut(&mut T, &mut ModelContext) -> O, + ) -> O { self.app.update_model(handle, update) } } @@ -2411,10 +2433,13 @@ impl ReadView for ViewContext<'_, V> { } impl UpdateView for ViewContext<'_, V> { - fn update_view(&mut self, handle: &ViewHandle, update: F) -> S + fn update_view( + &mut self, + handle: &ViewHandle, + update: &mut dyn FnMut(&mut T, &mut ViewContext) -> S, + ) -> S where T: View, - F: FnOnce(&mut T, &mut ViewContext) -> S, { self.app.update_view(handle, update) } @@ -2469,7 +2494,11 @@ impl ModelHandle { C: ReadModelWith, F: FnOnce(&T, &AppContext) -> S, { - cx.read_model_with(self, read) + let mut read = Some(read); + cx.read_model_with(self, &mut |model, cx| { + let read = read.take().unwrap(); + read(model, cx) + }) } pub fn update(&self, cx: &mut C, update: F) -> S @@ -2477,7 +2506,11 @@ impl ModelHandle { C: UpdateModel, F: FnOnce(&mut T, &mut ModelContext) -> S, { - cx.update_model(self, update) + let mut update = Some(update); + cx.update_model(self, &mut |model, cx| { + let update = update.take().unwrap(); + update(model, cx) + }) } pub fn next_notification(&self, cx: &TestAppContext) -> impl Future { @@ -2743,7 +2776,11 @@ impl ViewHandle { C: ReadViewWith, F: FnOnce(&T, &AppContext) -> S, { - cx.read_view_with(self, read) + let mut read = Some(read); + cx.read_view_with(self, &mut |view, cx| { + let read = read.take().unwrap(); + read(view, cx) + }) } pub fn update(&self, cx: &mut C, update: F) -> S @@ -2751,7 +2788,11 @@ impl ViewHandle { C: UpdateView, F: FnOnce(&mut T, &mut ViewContext) -> S, { - cx.update_view(self, update) + let mut update = Some(update); + cx.update_view(self, &mut |view, cx| { + let update = update.take().unwrap(); + update(view, cx) + }) } pub fn is_focused(&self, cx: &AppContext) -> bool { diff --git a/gpui/src/presenter.rs b/gpui/src/presenter.rs index 8bcdd08aad..354f0a0f82 100644 --- a/gpui/src/presenter.rs +++ b/gpui/src/presenter.rs @@ -7,7 +7,7 @@ use crate::{ platform::Event, text_layout::TextLayoutCache, Action, AnyAction, AssetCache, ElementBox, Entity, FontSystem, ModelHandle, ReadModel, - ReadView, Scene, UpdateView, View, ViewHandle, + ReadView, Scene, View, ViewHandle, }; use pathfinder_geometry::vector::{vec2f, Vector2F}; use serde_json::json; @@ -264,16 +264,6 @@ impl<'a> ReadView for LayoutContext<'a> { } } -impl<'a> UpdateView for LayoutContext<'a> { - fn update_view(&mut self, handle: &ViewHandle, update: F) -> S - where - T: View, - F: FnOnce(&mut T, &mut crate::ViewContext) -> S, - { - self.app.update_view(handle, update) - } -} - impl<'a> ReadModel for LayoutContext<'a> { fn read_model(&self, handle: &ModelHandle) -> &T { self.app.read_model(handle)