Skip to main content

gpui/app/
async_context.rs

1use crate::{
2    AnyView, AnyWindowHandle, App, AppCell, AppContext, BackgroundExecutor, BorrowAppContext,
3    Entity, EntityId, EventEmitter, Focusable, ForegroundExecutor, Global, GpuiBorrow,
4    PromptButton, PromptLevel, Render, Reservation, Result, Subscription, Task, VisualContext,
5    Window, WindowHandle,
6};
7use anyhow::{Context as _, bail};
8use derive_more::{Deref, DerefMut};
9use futures::channel::oneshot;
10use futures::future::FutureExt;
11use std::{future::Future, rc::Weak};
12
13use super::{Context, WeakEntity};
14
15/// A handle to the app that you can hold across `.await` points.
16///
17/// [`App`] can't be borrowed across an `.await`, because the rest of the application
18/// needs it while your future waits. `AsyncApp` is the alternative: you get one as
19/// the argument of a future started with [`App::spawn`], or from [`App::to_async`].
20/// Each method borrows the app for the length of one call, runs a complete update,
21/// and releases the borrow. Entity methods are on the [`AppContext`] trait, which
22/// `AsyncApp` implements, so helpers written against that trait work here too.
23///
24/// `AsyncApp` holds a weak reference to the app, so it doesn't keep the app alive.
25/// Most methods panic if the app has been released. The `AppContext` methods that return a
26/// `Result` or `Option`, such as `update_window` and `with_window`, report it as an error or
27/// `None` instead. Keep an `AsyncApp` only inside the futures that use it. One stored
28/// somewhere else can outlive the app.
29///
30/// See [contexts](crate::_documentation::concepts::contexts#async-contexts) for how
31/// async contexts fit with the other contexts.
32///
33/// # Examples
34///
35/// ```
36/// use gpui::{AppContext, TestApp};
37///
38/// let mut app = TestApp::new();
39/// let count = app.update(|cx| cx.new(|_| 0_usize));
40///
41/// let task = app.to_async().spawn({
42///     let count = count.clone();
43///     async move |cx| {
44///         cx.update(|cx| {
45///             count.update(cx, |count, cx| {
46///                 *count += 1;
47///                 cx.notify();
48///             })
49///         });
50///     }
51/// });
52/// task.detach();
53///
54/// app.run_until_parked();
55/// app.read(|cx| assert_eq!(*count.read(cx), 1));
56/// ```
57#[derive(Clone)]
58pub struct AsyncApp {
59    pub(crate) app: Weak<AppCell>,
60    pub(crate) background_executor: BackgroundExecutor,
61    pub(crate) foreground_executor: ForegroundExecutor,
62}
63
64impl AsyncApp {
65    fn app(&self) -> std::rc::Rc<AppCell> {
66        self.app
67            .upgrade()
68            .expect("app was released before async operation completed")
69    }
70}
71
72impl AppContext for AsyncApp {
73    fn new<T: 'static>(&mut self, build_entity: impl FnOnce(&mut Context<T>) -> T) -> Entity<T> {
74        let app = self.app();
75        let mut app = app.borrow_mut();
76        app.new(build_entity)
77    }
78
79    fn reserve_entity<T: 'static>(&mut self) -> Reservation<T> {
80        let app = self.app();
81        let mut app = app.borrow_mut();
82        app.reserve_entity()
83    }
84
85    fn insert_entity<T: 'static>(
86        &mut self,
87        reservation: Reservation<T>,
88        build_entity: impl FnOnce(&mut Context<T>) -> T,
89    ) -> Entity<T> {
90        let app = self.app();
91        let mut app = app.borrow_mut();
92        app.insert_entity(reservation, build_entity)
93    }
94
95    #[inline(always)]
96    fn update_entity<T: 'static, R>(
97        &mut self,
98        handle: &Entity<T>,
99        update: impl FnOnce(&mut T, &mut Context<T>) -> R,
100    ) -> R {
101        let app = self.app();
102        let mut app = app.borrow_mut();
103        app.update_entity(handle, update)
104    }
105
106    fn as_mut<'a, T>(&'a mut self, _handle: &Entity<T>) -> GpuiBorrow<'a, T>
107    where
108        T: 'static,
109    {
110        panic!("Cannot as_mut with an async context. Try calling update() first")
111    }
112
113    #[inline(always)]
114    fn read_entity<T, R>(&self, handle: &Entity<T>, callback: impl FnOnce(&T, &App) -> R) -> R
115    where
116        T: 'static,
117    {
118        let app = self.app();
119        let lock = app.borrow();
120        lock.read_entity(handle, callback)
121    }
122
123    fn notify(&mut self, entity_id: EntityId) {
124        let app = self.app();
125        let mut lock = app.borrow_mut();
126        lock.notify(entity_id);
127    }
128
129    fn emit<EntityType, EventType>(&mut self, entity: &Entity<EntityType>, event: EventType)
130    where
131        EntityType: EventEmitter<EventType>,
132        EventType: 'static,
133    {
134        let app = self.app();
135        let mut lock = app.borrow_mut();
136        lock.emit(entity, event)
137    }
138
139    #[inline(always)]
140    fn update_window<T, F>(&mut self, window: AnyWindowHandle, f: F) -> Result<T>
141    where
142        F: FnOnce(AnyView, &mut Window, &mut App) -> T,
143    {
144        let app = self.app.upgrade().context("app was released")?;
145        let mut lock = app.try_borrow_mut()?;
146        if lock.quitting {
147            bail!("app is quitting");
148        }
149        lock.update_window(window, f)
150    }
151
152    #[inline(always)]
153    fn with_window<R>(
154        &mut self,
155        entity_id: EntityId,
156        f: impl FnOnce(&mut Window, &mut App) -> R,
157    ) -> Option<R> {
158        let app = self.app.upgrade()?;
159        let mut lock = app.try_borrow_mut().ok()?;
160        if lock.quitting {
161            return None;
162        }
163        lock.with_window(entity_id, f)
164    }
165
166    fn read_window<T, R>(
167        &self,
168        window: &WindowHandle<T>,
169        read: impl FnOnce(Entity<T>, &App) -> R,
170    ) -> Result<R>
171    where
172        T: 'static,
173    {
174        let app = self.app.upgrade().context("app was released")?;
175        let lock = app.borrow();
176        if lock.quitting {
177            bail!("app is quitting");
178        }
179        lock.read_window(window, read)
180    }
181
182    #[track_caller]
183    fn background_spawn<R>(&self, future: impl Future<Output = R> + Send + 'static) -> Task<R>
184    where
185        R: Send + 'static,
186    {
187        self.background_executor.spawn(future)
188    }
189
190    fn read_global<G, R>(&self, callback: impl FnOnce(&G, &App) -> R) -> R
191    where
192        G: Global,
193    {
194        let app = self.app();
195        let mut lock = app.borrow_mut();
196        lock.update(|this| this.read_global(callback))
197    }
198
199    fn insert_global_entity<T: 'static>(&mut self, entity: Entity<T>) {
200        let app = self.app();
201        let mut lock = app.borrow_mut();
202        lock.insert_global_entity(entity)
203    }
204
205    fn remove_global_entity<T: 'static>(&mut self, entity: &Entity<T>) {
206        let app = self.app();
207        let mut lock = app.borrow_mut();
208        lock.remove_global_entity(entity)
209    }
210
211    fn global_entities<T: 'static>(&self) -> impl Iterator<Item = Entity<T>> {
212        let app = self.app();
213        let mut lock = app.borrow_mut();
214        let iter = lock.global_entities();
215        // Cloning the iterator here so that lock can be released when function is going out of scope
216        iter.collect::<Vec<_>>().into_iter()
217    }
218}
219
220impl AsyncApp {
221    /// Schedules a redraw of every window.
222    ///
223    /// The windows draw on the next frame. This doesn't draw anything itself.
224    pub fn refresh(&self) {
225        let app = self.app();
226        let mut lock = app.borrow_mut();
227        // A direct call would leave the refresh effect queued, which cannot wake
228        // a platform render loop that has already parked.
229        lock.update(|cx| cx.refresh_windows());
230    }
231
232    /// Returns the [`BackgroundExecutor`], for running work on other threads.
233    pub fn background_executor(&self) -> &BackgroundExecutor {
234        &self.background_executor
235    }
236
237    /// Whether this app runs on the deterministic test scheduler. See
238    /// [`BackgroundExecutor::is_test`].
239    pub fn is_test(&self) -> bool {
240        self.background_executor.is_test()
241    }
242
243    /// Returns the [`ForegroundExecutor`], for running futures on the main thread.
244    pub fn foreground_executor(&self) -> &ForegroundExecutor {
245        &self.foreground_executor
246    }
247
248    /// Runs `f` with the app and returns its result.
249    ///
250    /// Effects queued by `f`, such as notifications, are flushed before this returns.
251    ///
252    /// # Panics
253    ///
254    /// Panics if the app has been released, or if it is already borrowed, such as when
255    /// called from inside another update.
256    #[inline(always)]
257    pub fn update<R>(&self, f: impl FnOnce(&mut App) -> R) -> R {
258        let app = self.app();
259        let mut lock = app.borrow_mut();
260        lock.update(f)
261    }
262
263    /// Calls `on_event` each time `entity` emits an `Event`.
264    ///
265    /// The callback receives the emitting entity, the event and the app. The
266    /// subscription stays active while you hold it. Dropping it unsubscribes, and
267    /// [`Subscription::detach`] keeps the subscription for as long as the entity lives.
268    /// Inside an entity's own context, [`Context::subscribe`] is the usual choice.
269    pub fn subscribe<T, Event>(
270        &mut self,
271        entity: &Entity<T>,
272        on_event: impl FnMut(Entity<T>, &Event, &mut App) + 'static,
273    ) -> Subscription
274    where
275        T: 'static + EventEmitter<Event>,
276        Event: 'static,
277    {
278        let app = self.app();
279        let mut lock = app.borrow_mut();
280        lock.subscribe(entity, on_event)
281    }
282
283    /// Opens a window with `options` and returns a handle to it.
284    ///
285    /// `build_root_view` creates the window's root view. The method returns an error if the app is
286    /// quitting.
287    ///
288    /// # Panics
289    ///
290    /// Panics if the app has been released, or if it is already borrowed.
291    pub fn open_window<V>(
292        &self,
293        options: crate::WindowOptions,
294        build_root_view: impl FnOnce(&mut Window, &mut App) -> Entity<V>,
295    ) -> Result<WindowHandle<V>>
296    where
297        V: 'static + Render,
298    {
299        let app = self.app();
300        let mut lock = app.borrow_mut();
301        if lock.quitting {
302            bail!("app is quitting");
303        }
304        lock.open_window(options, build_root_view)
305    }
306
307    /// Runs the future returned by `f` on the main thread, and returns a task for its
308    /// result.
309    ///
310    /// `f` receives an `&mut AsyncApp`. Dropping the returned [`Task`] cancels the
311    /// future, so store it, await it or call [`Task::detach`].
312    #[track_caller]
313    #[inline(always)]
314    pub fn spawn<AsyncFn, R>(&self, f: AsyncFn) -> Task<R>
315    where
316        AsyncFn: AsyncFnOnce(&mut AsyncApp) -> R + 'static,
317        R: 'static,
318    {
319        let mut cx = self.clone();
320        self.foreground_executor
321            .spawn(async move { f(&mut cx).await }.boxed_local())
322    }
323
324    /// Returns whether a global of type `G` has been set.
325    pub fn has_global<G: Global>(&self) -> bool {
326        let app = self.app();
327        let app = app.borrow_mut();
328        app.has_global::<G>()
329    }
330
331    /// Calls `read` with the global of type `G` and the app, and returns its result.
332    ///
333    /// Use [`AsyncApp::try_read_global`] if the global may not be set.
334    ///
335    /// # Panics
336    ///
337    /// Panics if no global of type `G` has been set, or if the app has been released.
338    #[inline(always)]
339    pub fn read_global<G: Global, R>(&self, read: impl FnOnce(&G, &App) -> R) -> R {
340        let app = self.app();
341        let app = app.borrow_mut();
342        read(app.global(), &app)
343    }
344
345    /// Like [`AsyncApp::read_global`], but returns `None` instead of panicking when no
346    /// global of type `G` is set, or when the app is quitting.
347    pub fn try_read_global<G: Global, R>(&self, read: impl FnOnce(&G, &App) -> R) -> Option<R> {
348        let app = self.app();
349        let app = app.borrow_mut();
350        if app.quitting {
351            return None;
352        }
353        Some(read(app.try_global()?, &app))
354    }
355
356    /// Like [`AsyncApp::read_global`], but first sets a `G::default()` if no global of
357    /// type `G` has been set.
358    pub fn read_default_global<G: Global + Default, R>(
359        &self,
360        read: impl FnOnce(&G, &App) -> R,
361    ) -> R {
362        let app = self.app();
363        let mut app = app.borrow_mut();
364        app.update(|cx| {
365            cx.default_global::<G>();
366        });
367        read(app.global(), &app)
368    }
369
370    /// Updates the global of type `G` with `update`, and returns its result.
371    ///
372    /// While `update` runs, the global is taken out of the app. Reading it through the
373    /// app from inside `update` panics, so change the global through the `&mut G` that
374    /// `update` receives.
375    ///
376    /// # Panics
377    ///
378    /// Panics if no global of type `G` has been set, or if the app has been released.
379    pub fn update_global<G: Global, R>(&self, update: impl FnOnce(&mut G, &mut App) -> R) -> R {
380        let app = self.app();
381        let mut app = app.borrow_mut();
382        app.update(|cx| cx.update_global(update))
383    }
384
385    /// Returns a guard that calls `f` with `entity` when the guard is dropped.
386    ///
387    /// `f` doesn't run if the entity has been released by then. Hold the guard in a
388    /// variable. A guard that is dropped at once runs `f` immediately.
389    ///
390    /// # Examples
391    ///
392    /// ```
393    /// use gpui::{AppContext, TestApp};
394    ///
395    /// let mut app = TestApp::new();
396    /// let log = app.update(|cx| cx.new(|_| Vec::<&'static str>::new()));
397    /// let guard = app.update(|cx| {
398    ///     cx.to_async().on_drop(&log.downgrade(), |log, cx| {
399    ///         log.push("finished");
400    ///         cx.notify();
401    ///     })
402    /// });
403    /// drop(guard);
404    /// app.read(|cx| assert_eq!(*log.read(cx), vec!["finished"]));
405    /// ```
406    pub fn on_drop<T: 'static, Callback: FnOnce(&mut T, &mut Context<T>) + 'static>(
407        &self,
408        entity: &WeakEntity<T>,
409        f: Callback,
410    ) -> gpui_util::Deferred<impl FnOnce() + use<T, Callback>> {
411        let entity = entity.clone();
412        let mut cx = self.clone();
413        gpui_util::defer(move || {
414            entity.update(&mut cx, f).ok();
415        })
416    }
417}
418
419/// A handle to the app and one window, for use across `.await` points.
420///
421/// Get one from [`Context::spawn_in`] or [`Window::spawn`]. It derefs to
422/// [`AsyncApp`], so the methods of `AsyncApp` are available on it too. The window
423/// methods on this type return an error once the window has closed.
424///
425/// Use it inside a future when you need the window and not only the app. See
426/// [contexts](crate::_documentation::concepts::contexts#async-contexts).
427///
428/// # Examples
429///
430/// ```
431/// use gpui::{Context, Render, TestApp, Window, div, prelude::*};
432///
433/// struct Panel {
434///     updates: usize,
435/// }
436///
437/// impl Render for Panel {
438///     fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
439///         div()
440///     }
441/// }
442///
443/// let mut app = TestApp::new();
444/// let mut window = app.open_window(|_window, _cx| Panel { updates: 0 });
445///
446/// window.update(|panel, window, cx| {
447///     cx.spawn_in(window, async move |panel, cx| {
448///         panel
449///             .update(cx, |panel, cx| {
450///                 panel.updates += 1;
451///                 cx.notify();
452///             })
453///             .ok();
454///     })
455///     .detach();
456/// });
457///
458/// app.run_until_parked();
459/// window.read(|panel, _cx| assert_eq!(panel.updates, 1));
460/// ```
461#[derive(Clone, Deref, DerefMut)]
462pub struct AsyncWindowContext {
463    #[deref]
464    #[deref_mut]
465    app: AsyncApp,
466    window: AnyWindowHandle,
467}
468
469impl AsyncWindowContext {
470    pub(crate) fn new_context(app: AsyncApp, window: AnyWindowHandle) -> Self {
471        Self { app, window }
472    }
473
474    /// Returns the handle of the window this context is for.
475    pub fn window_handle(&self) -> AnyWindowHandle {
476        self.window
477    }
478
479    /// Runs `update` with the window and the app, and returns its result.
480    ///
481    /// Effects queued by `update` are flushed before this returns.
482    ///
483    /// # Errors
484    ///
485    /// Returns an error if the window has closed, or if the app is quitting or already
486    /// borrowed.
487    #[inline(always)]
488    pub fn update<R>(&mut self, update: impl FnOnce(&mut Window, &mut App) -> R) -> Result<R> {
489        self.app
490            .update_window(self.window, |_, window, cx| update(window, cx))
491    }
492
493    /// Like [`AsyncWindowContext::update`], but also passes the window's root view.
494    ///
495    /// # Errors
496    ///
497    /// Returns an error under the same conditions as [`AsyncWindowContext::update`].
498    #[inline(always)]
499    pub fn update_root<R>(
500        &mut self,
501        update: impl FnOnce(AnyView, &mut Window, &mut App) -> R,
502    ) -> Result<R> {
503        self.app.update_window(self.window, update)
504    }
505
506    /// Runs `f` before the window draws its next frame. Does nothing if the window has
507    /// closed.
508    ///
509    /// Schedules the callback like [`Window::on_next_frame`], but tolerates a window that has
510    /// already been closed.
511    pub fn on_next_frame(&mut self, f: impl FnOnce(&mut Window, &mut App) + 'static) {
512        self.app
513            .update_window(self.window, |_, window, _| window.on_next_frame(f))
514            .ok();
515    }
516
517    /// Calls `read` with the global of type `G`, the window and the app, and returns its
518    /// result.
519    ///
520    /// # Errors
521    ///
522    /// Returns an error if the window has closed.
523    ///
524    /// # Panics
525    ///
526    /// Panics if no global of type `G` has been set.
527    pub fn read_global<G: Global, R>(
528        &mut self,
529        read: impl FnOnce(&G, &Window, &App) -> R,
530    ) -> Result<R> {
531        self.app
532            .update_window(self.window, |_, window, cx| read(cx.global(), window, cx))
533    }
534
535    /// Updates the global of type `G` with `update`, and returns its result.
536    ///
537    /// The global is taken out of the app while `update` runs, as with
538    /// [`AsyncApp::update_global`].
539    ///
540    /// # Errors
541    ///
542    /// Returns an error if the window has closed.
543    ///
544    /// # Panics
545    ///
546    /// Panics if no global of type `G` has been set.
547    pub fn update_global<G, R>(
548        &mut self,
549        update: impl FnOnce(&mut G, &mut Window, &mut App) -> R,
550    ) -> Result<R>
551    where
552        G: Global,
553    {
554        self.app.update_window(self.window, |_, window, cx| {
555            cx.update_global(|global, cx| update(global, window, cx))
556        })
557    }
558
559    /// Runs the future returned by `f` on the main thread, with an
560    /// `AsyncWindowContext` for this window, and returns a task for its result.
561    ///
562    /// Dropping the returned [`Task`] cancels the future. Store it, await it or call
563    /// [`Task::detach`].
564    #[track_caller]
565    #[inline(always)]
566    pub fn spawn<AsyncFn, R>(&self, f: AsyncFn) -> Task<R>
567    where
568        AsyncFn: AsyncFnOnce(&mut AsyncWindowContext) -> R + 'static,
569        R: 'static,
570    {
571        let mut cx = self.clone();
572        self.foreground_executor
573            .spawn(async move { f(&mut cx).await }.boxed_local())
574    }
575
576    /// Shows a platform alert with one button for each entry in `answers`.
577    ///
578    /// The receiver resolves to the index of the button the user clicked. If the window
579    /// has closed, the receiver is canceled, so awaiting it returns an error. See
580    /// [`Window::prompt`] for `level` and `detail`.
581    pub fn prompt<T>(
582        &mut self,
583        level: PromptLevel,
584        message: &str,
585        detail: Option<&str>,
586        answers: &[T],
587    ) -> oneshot::Receiver<usize>
588    where
589        T: Clone + Into<PromptButton>,
590    {
591        self.app
592            .update_window(self.window, |_, window, cx| {
593                window.prompt(level, message, detail, answers, cx)
594            })
595            .unwrap_or_else(|_| oneshot::channel().1)
596    }
597}
598
599impl AppContext for AsyncWindowContext {
600    fn new<T>(&mut self, build_entity: impl FnOnce(&mut Context<T>) -> T) -> Entity<T>
601    where
602        T: 'static,
603    {
604        let mut build_entity = Some(build_entity);
605        match self.app.update_window(self.window, |_, _, cx| {
606            cx.new(
607                build_entity
608                    .take()
609                    .expect("build_entity is taken exactly once"),
610            )
611        }) {
612            Ok(entity) => entity,
613            Err(_) => self.app.new(
614                build_entity
615                    .take()
616                    .expect("update_window returned Err without invoking the closure"),
617            ),
618        }
619    }
620
621    fn reserve_entity<T: 'static>(&mut self) -> Reservation<T> {
622        self.app.reserve_entity()
623    }
624
625    fn insert_entity<T: 'static>(
626        &mut self,
627        reservation: Reservation<T>,
628        build_entity: impl FnOnce(&mut Context<T>) -> T,
629    ) -> Entity<T> {
630        let mut args = Some((reservation, build_entity));
631        match self.app.update_window(self.window, |_, _, cx| {
632            let (reservation, build_entity) = args.take().expect("args are taken exactly once");
633            cx.insert_entity(reservation, build_entity)
634        }) {
635            Ok(entity) => entity,
636            Err(_) => {
637                let (reservation, build_entity) = args
638                    .take()
639                    .expect("update_window returned Err without invoking the closure");
640                self.app.insert_entity(reservation, build_entity)
641            }
642        }
643    }
644
645    #[inline(always)]
646    fn update_entity<T: 'static, R>(
647        &mut self,
648        handle: &Entity<T>,
649        update: impl FnOnce(&mut T, &mut Context<T>) -> R,
650    ) -> R {
651        self.app.update_entity(handle, update)
652    }
653
654    fn as_mut<'a, T>(&'a mut self, _: &Entity<T>) -> GpuiBorrow<'a, T>
655    where
656        T: 'static,
657    {
658        panic!("Cannot use as_mut() from an async context, call `update`")
659    }
660
661    #[inline(always)]
662    fn read_entity<T, R>(&self, handle: &Entity<T>, read: impl FnOnce(&T, &App) -> R) -> R
663    where
664        T: 'static,
665    {
666        self.app.read_entity(handle, read)
667    }
668
669    fn notify(&mut self, entity_id: EntityId) {
670        self.app.notify(entity_id);
671    }
672
673    fn emit<EntityType, EventType>(&mut self, entity: &Entity<EntityType>, event: EventType)
674    where
675        EntityType: EventEmitter<EventType>,
676        EventType: 'static,
677    {
678        self.app.emit(entity, event)
679    }
680
681    #[inline(always)]
682    fn update_window<T, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<T>
683    where
684        F: FnOnce(AnyView, &mut Window, &mut App) -> T,
685    {
686        self.app.update_window(window, update)
687    }
688
689    #[inline(always)]
690    fn with_window<R>(
691        &mut self,
692        entity_id: EntityId,
693        f: impl FnOnce(&mut Window, &mut App) -> R,
694    ) -> Option<R> {
695        self.app.with_window(entity_id, f)
696    }
697
698    fn read_window<T, R>(
699        &self,
700        window: &WindowHandle<T>,
701        read: impl FnOnce(Entity<T>, &App) -> R,
702    ) -> Result<R>
703    where
704        T: 'static,
705    {
706        self.app.read_window(window, read)
707    }
708
709    #[track_caller]
710    fn background_spawn<R>(&self, future: impl Future<Output = R> + Send + 'static) -> Task<R>
711    where
712        R: Send + 'static,
713    {
714        self.app.background_executor.spawn(future)
715    }
716
717    fn read_global<G, R>(&self, callback: impl FnOnce(&G, &App) -> R) -> R
718    where
719        G: Global,
720    {
721        self.app.read_global(callback)
722    }
723
724    fn insert_global_entity<T: 'static>(&mut self, entity: Entity<T>) {
725        self.app.insert_global_entity(entity)
726    }
727
728    fn remove_global_entity<T: 'static>(&mut self, entity: &Entity<T>) {
729        self.app.remove_global_entity(entity)
730    }
731
732    fn global_entities<T: 'static>(&self) -> impl Iterator<Item = Entity<T>> {
733        self.app.global_entities()
734    }
735}
736
737impl VisualContext for AsyncWindowContext {
738    type Result<T> = Result<T>;
739
740    fn window_handle(&self) -> AnyWindowHandle {
741        self.window
742    }
743
744    fn new_window_entity<T: 'static>(
745        &mut self,
746        build_entity: impl FnOnce(&mut Window, &mut Context<T>) -> T,
747    ) -> Result<Entity<T>> {
748        self.app.update_window(self.window, |_, window, cx| {
749            cx.new(|cx| build_entity(window, cx))
750        })
751    }
752
753    fn update_window_entity<T: 'static, R>(
754        &mut self,
755        view: &Entity<T>,
756        update: impl FnOnce(&mut T, &mut Window, &mut Context<T>) -> R,
757    ) -> Result<R> {
758        let view = view.clone();
759        self.app
760            .with_window(view.entity_id(), |window, app| {
761                view.update(app, |entity, cx| update(entity, window, cx))
762            })
763            .context("entity has no current window")
764    }
765
766    fn replace_root_view<V>(
767        &mut self,
768        build_view: impl FnOnce(&mut Window, &mut Context<V>) -> V,
769    ) -> Result<Entity<V>>
770    where
771        V: 'static + Render,
772    {
773        self.app.update_window(self.window, |_, window, cx| {
774            window.replace_root(cx, build_view)
775        })
776    }
777
778    fn focus<V>(&mut self, view: &Entity<V>) -> Result<()>
779    where
780        V: Focusable,
781    {
782        self.app.update_window(self.window, |_, window, cx| {
783            view.read(cx).focus_handle(cx).focus(window, cx);
784        })
785    }
786}