Remove `UpdateModel` trait

Antonio Scandurra and Nathan Sobo created

Co-Authored-By: Nathan Sobo <nathan@zed.dev>

Change summary

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(-)

Detailed changes

crates/gpui/src/app.rs 🔗

@@ -126,14 +126,6 @@ pub trait BorrowAppContext {
     fn update<T, F: FnOnce(&mut AppContext) -> T>(&mut self, f: F) -> T;
 }
 
-pub trait UpdateModel {
-    fn update_model<T: Entity, O>(
-        &mut self,
-        handle: &ModelHandle<T>,
-        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
-    ) -> O;
-}
-
 pub trait ReadViewWith {
     fn read_view_with<V, T>(
         &self,
@@ -396,16 +388,6 @@ impl BorrowAppContext for AsyncAppContext {
     }
 }
 
-impl UpdateModel for AsyncAppContext {
-    fn update_model<E: Entity, O>(
-        &mut self,
-        handle: &ModelHandle<E>,
-        update: &mut dyn FnMut(&mut E, &mut ModelContext<E>) -> O,
-    ) -> O {
-        self.0.borrow_mut().update_model(handle, update)
-    }
-}
-
 impl UpdateView for AsyncAppContext {
     type Output<S> = Result<S>;
 
@@ -1243,6 +1225,29 @@ impl AppContext {
         }
     }
 
+    fn update_model<T: Entity, V>(
+        &mut self,
+        handle: &ModelHandle<T>,
+        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> 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<T: Entity>(
         &self,
         handle: &WeakModelHandle<T>,
@@ -2102,31 +2107,6 @@ impl BorrowAppContext for AppContext {
     }
 }
 
-impl UpdateModel for AppContext {
-    fn update_model<T: Entity, V>(
-        &mut self,
-        handle: &ModelHandle<T>,
-        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> 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<M> BorrowAppContext for ModelContext<'_, M> {
     }
 }
 
-impl<M> UpdateModel for ModelContext<'_, M> {
-    fn update_model<T: Entity, V>(
-        &mut self,
-        handle: &ModelHandle<T>,
-        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
-    ) -> V {
-        self.app.update_model(handle, update)
-    }
-}
-
 impl<M> Deref for ModelContext<'_, M> {
     type Target = AppContext;
 
@@ -3387,16 +3357,6 @@ impl<V> BorrowAppContext for ViewContext<'_, '_, V> {
     }
 }
 
-impl<V: View> UpdateModel for ViewContext<'_, '_, V> {
-    fn update_model<T: Entity, O>(
-        &mut self,
-        handle: &ModelHandle<T>,
-        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
-    ) -> O {
-        self.window_context.update_model(handle, update)
-    }
-}
-
 impl<V: View> UpdateView for ViewContext<'_, '_, V> {
     type Output<S> = S;
 
@@ -3454,16 +3414,6 @@ impl<V: View> BorrowAppContext for EventContext<'_, '_, '_, V> {
     }
 }
 
-impl<V: View> UpdateModel for EventContext<'_, '_, '_, V> {
-    fn update_model<T: Entity, O>(
-        &mut self,
-        handle: &ModelHandle<T>,
-        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
-    ) -> O {
-        self.view_context.update_model(handle, update)
-    }
-}
-
 impl<V: View> UpdateView for EventContext<'_, '_, '_, V> {
     type Output<S> = S;
 
@@ -3597,13 +3547,15 @@ impl<T: Entity> ModelHandle<T> {
 
     pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
     where
-        C: UpdateModel,
+        C: BorrowAppContext,
         F: FnOnce(&mut T, &mut ModelContext<T>) -> 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)
+            })
         })
     }
 }

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<T: Entity, O>(
-        &mut self,
-        handle: &ModelHandle<T>,
-        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
-    ) -> O {
-        self.cx.borrow_mut().update_model(handle, update)
-    }
-}
-
 impl UpdateView for TestAppContext {
     type Output<S> = S;
 

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<T: Entity, R>(
-        &mut self,
-        handle: &ModelHandle<T>,
-        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> R,
-    ) -> R {
-        self.app_context.update_model(handle, update)
-    }
-}
-
 impl UpdateView for WindowContext<'_> {
     type Output<S> = S;