Move `dispatch_action_any_action_at` to `AsyncAppContext`

Antonio Scandurra created

Change summary

crates/command_palette/src/command_palette.rs |  8 ++-
crates/context_menu/src/context_menu.rs       | 27 +++++++----
crates/gpui/src/app.rs                        | 51 ++++++--------------
3 files changed, 37 insertions(+), 49 deletions(-)

Detailed changes

crates/command_palette/src/command_palette.rs 🔗

@@ -167,9 +167,11 @@ impl PickerDelegate for CommandPaletteDelegate {
             let focused_view_id = self.focused_view_id;
             let action_ix = self.matches[self.selected_ix].candidate_id;
             let action = self.actions.remove(action_ix).action;
-            cx.defer(move |_, cx| {
-                cx.dispatch_any_action_at(window_id, focused_view_id, action);
-            });
+            cx.app_context()
+                .spawn(move |mut cx| async move {
+                    cx.dispatch_action(window_id, focused_view_id, action.as_ref())
+                })
+                .detach_and_log_err(cx);
         }
         cx.emit(PickerEvent::Dismiss);
     }

crates/context_menu/src/context_menu.rs 🔗

@@ -227,11 +227,13 @@ impl ContextMenu {
                 match action {
                     ContextMenuItemAction::Action(action) => {
                         let window_id = cx.window_id();
-                        cx.dispatch_any_action_at(
-                            window_id,
-                            self.parent_view_id,
-                            action.boxed_clone(),
-                        );
+                        let view_id = self.parent_view_id;
+                        let action = action.boxed_clone();
+                        cx.app_context()
+                            .spawn(|mut cx| async move {
+                                cx.dispatch_action(window_id, view_id, action.as_ref())
+                            })
+                            .detach_and_log_err(cx);
                     }
                     ContextMenuItemAction::Handler(handler) => handler(cx),
                 }
@@ -459,11 +461,16 @@ impl ContextMenu {
                                 let window_id = cx.window_id();
                                 match &action {
                                     ContextMenuItemAction::Action(action) => {
-                                        cx.dispatch_any_action_at(
-                                            window_id,
-                                            view_id,
-                                            action.boxed_clone(),
-                                        );
+                                        let action = action.boxed_clone();
+                                        cx.app_context()
+                                            .spawn(|mut cx| async move {
+                                                cx.dispatch_action(
+                                                    window_id,
+                                                    view_id,
+                                                    action.as_ref(),
+                                                )
+                                            })
+                                            .detach_and_log_err(cx);
                                     }
                                     ContextMenuItemAction::Handler(handler) => handler(cx),
                                 }

crates/gpui/src/app.rs 🔗

@@ -309,6 +309,20 @@ impl AsyncAppContext {
         self.0.borrow_mut().update_window(window_id, callback)
     }
 
+    pub fn dispatch_action(
+        &mut self,
+        window_id: usize,
+        view_id: usize,
+        action: &dyn Action,
+    ) -> Result<()> {
+        self.0
+            .borrow_mut()
+            .update_window(window_id, |window| {
+                window.handle_dispatch_action_from_effect(Some(view_id), action);
+            })
+            .ok_or_else(|| anyhow!("window not found"))
+    }
+
     pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
     where
         T: Entity,
@@ -1619,17 +1633,7 @@ impl AppContext {
                         Effect::RefreshWindows => {
                             refreshing = true;
                         }
-                        Effect::DispatchActionFrom {
-                            window_id,
-                            view_id,
-                            action,
-                        } => {
-                            self.handle_dispatch_action_from_effect(
-                                window_id,
-                                Some(view_id),
-                                action.as_ref(),
-                            );
-                        }
+
                         Effect::ActionDispatchNotification { action_id } => {
                             self.handle_action_dispatch_notification_effect(action_id)
                         }
@@ -1745,19 +1749,6 @@ impl AppContext {
         self.pending_effects.push_back(Effect::RefreshWindows);
     }
 
-    pub fn dispatch_any_action_at(
-        &mut self,
-        window_id: usize,
-        view_id: usize,
-        action: Box<dyn Action>,
-    ) {
-        self.pending_effects.push_back(Effect::DispatchActionFrom {
-            window_id,
-            view_id,
-            action,
-        });
-    }
-
     fn perform_window_refresh(&mut self) {
         let window_ids = self.windows.keys().cloned().collect::<Vec<_>>();
         for window_id in window_ids {
@@ -2155,11 +2146,6 @@ pub enum Effect {
         result: MatchResult,
     },
     RefreshWindows,
-    DispatchActionFrom {
-        window_id: usize,
-        view_id: usize,
-        action: Box<dyn Action>,
-    },
     ActionDispatchNotification {
         action_id: TypeId,
     },
@@ -2248,13 +2234,6 @@ impl Debug for Effect {
                 .field("view_id", view_id)
                 .field("subscription_id", subscription_id)
                 .finish(),
-            Effect::DispatchActionFrom {
-                window_id, view_id, ..
-            } => f
-                .debug_struct("Effect::DispatchActionFrom")
-                .field("window_id", window_id)
-                .field("view_id", view_id)
-                .finish(),
             Effect::ActionDispatchNotification { action_id, .. } => f
                 .debug_struct("Effect::ActionDispatchNotification")
                 .field("action_id", action_id)