context.rs

  1use crate::{
  2    AnyView, AnyWindowHandle, AppContext, AsyncApp, DispatchPhase, Effect, EntityId, EventEmitter,
  3    FocusHandle, FocusOutEvent, Focusable, Global, KeystrokeObserver, Reservation, SubscriberSet,
  4    Subscription, Task, WeakEntity, WeakFocusHandle, Window, WindowHandle,
  5};
  6use anyhow::Result;
  7use futures::FutureExt;
  8use std::{
  9    any::{Any, TypeId},
 10    borrow::{Borrow, BorrowMut},
 11    future::Future,
 12    ops,
 13    sync::Arc,
 14};
 15use util::Deferred;
 16
 17use super::{App, AsyncWindowContext, Entity, KeystrokeEvent};
 18
 19/// The app context, with specialized behavior for the given entity.
 20pub struct Context<'a, T> {
 21    app: &'a mut App,
 22    entity_state: WeakEntity<T>,
 23}
 24
 25impl<'a, T> ops::Deref for Context<'a, T> {
 26    type Target = App;
 27
 28    fn deref(&self) -> &Self::Target {
 29        self.app
 30    }
 31}
 32
 33impl<'a, T> ops::DerefMut for Context<'a, T> {
 34    fn deref_mut(&mut self) -> &mut Self::Target {
 35        self.app
 36    }
 37}
 38
 39impl<'a, T: 'static> Context<'a, T> {
 40    pub(crate) fn new_context(app: &'a mut App, entity_state: WeakEntity<T>) -> Self {
 41        Self { app, entity_state }
 42    }
 43
 44    /// The entity id of the entity backing this context.
 45    pub fn entity_id(&self) -> EntityId {
 46        self.entity_state.entity_id
 47    }
 48
 49    /// Returns a handle to the entity belonging to this context.
 50    pub fn entity(&self) -> Entity<T> {
 51        self.weak_entity()
 52            .upgrade()
 53            .expect("The entity must be alive if we have a entity context")
 54    }
 55
 56    /// Returns a weak handle to the entity belonging to this context.
 57    pub fn weak_entity(&self) -> WeakEntity<T> {
 58        self.entity_state.clone()
 59    }
 60
 61    /// Arranges for the given function to be called whenever [`Context::notify`] is
 62    /// called with the given entity.
 63    pub fn observe<W>(
 64        &mut self,
 65        entity: &Entity<W>,
 66        mut on_notify: impl FnMut(&mut T, Entity<W>, &mut Context<T>) + 'static,
 67    ) -> Subscription
 68    where
 69        T: 'static,
 70        W: 'static,
 71    {
 72        let this = self.weak_entity();
 73        self.app.observe_internal(entity, move |e, cx| {
 74            if let Some(this) = this.upgrade() {
 75                this.update(cx, |this, cx| on_notify(this, e, cx));
 76                true
 77            } else {
 78                false
 79            }
 80        })
 81    }
 82
 83    /// Subscribe to an event type from another entity
 84    pub fn subscribe<T2, Evt>(
 85        &mut self,
 86        entity: &Entity<T2>,
 87        mut on_event: impl FnMut(&mut T, Entity<T2>, &Evt, &mut Context<T>) + 'static,
 88    ) -> Subscription
 89    where
 90        T: 'static,
 91        T2: 'static + EventEmitter<Evt>,
 92        Evt: 'static,
 93    {
 94        let this = self.weak_entity();
 95        self.app.subscribe_internal(entity, move |e, event, cx| {
 96            if let Some(this) = this.upgrade() {
 97                this.update(cx, |this, cx| on_event(this, e, event, cx));
 98                true
 99            } else {
100                false
101            }
102        })
103    }
104
105    /// Subscribe to an event type from ourself
106    pub fn subscribe_self<Evt>(
107        &mut self,
108        mut on_event: impl FnMut(&mut T, &Evt, &mut Context<T>) + 'static,
109    ) -> Subscription
110    where
111        T: 'static + EventEmitter<Evt>,
112        Evt: 'static,
113    {
114        let this = self.entity();
115        self.app.subscribe(&this, move |this, evt, cx| {
116            this.update(cx, |this, cx| on_event(this, evt, cx))
117        })
118    }
119
120    /// Register a callback to be invoked when GPUI releases this entity.
121    pub fn on_release(&self, on_release: impl FnOnce(&mut T, &mut App) + 'static) -> Subscription
122    where
123        T: 'static,
124    {
125        let (subscription, activate) = self.app.release_listeners.insert(
126            self.entity_state.entity_id,
127            Box::new(move |this, cx| {
128                let this = this.downcast_mut().expect("invalid entity type");
129                on_release(this, cx);
130            }),
131        );
132        activate();
133        subscription
134    }
135
136    /// Register a callback to be run on the release of another entity
137    pub fn observe_release<T2>(
138        &self,
139        entity: &Entity<T2>,
140        on_release: impl FnOnce(&mut T, &mut T2, &mut Context<T>) + 'static,
141    ) -> Subscription
142    where
143        T: Any,
144        T2: 'static,
145    {
146        let entity_id = entity.entity_id();
147        let this = self.weak_entity();
148        let (subscription, activate) = self.app.release_listeners.insert(
149            entity_id,
150            Box::new(move |entity, cx| {
151                let entity = entity.downcast_mut().expect("invalid entity type");
152                if let Some(this) = this.upgrade() {
153                    this.update(cx, |this, cx| on_release(this, entity, cx));
154                }
155            }),
156        );
157        activate();
158        subscription
159    }
160
161    /// Register a callback to for updates to the given global
162    pub fn observe_global<G: 'static>(
163        &mut self,
164        mut f: impl FnMut(&mut T, &mut Context<T>) + 'static,
165    ) -> Subscription
166    where
167        T: 'static,
168    {
169        let handle = self.weak_entity();
170        let (subscription, activate) = self.global_observers.insert(
171            TypeId::of::<G>(),
172            Box::new(move |cx| handle.update(cx, |view, cx| f(view, cx)).is_ok()),
173        );
174        self.defer(move |_| activate());
175        subscription
176    }
177
178    /// Register a callback to be invoked when the application is about to restart.
179    pub fn on_app_restart(
180        &self,
181        mut on_restart: impl FnMut(&mut T, &mut App) + 'static,
182    ) -> Subscription
183    where
184        T: 'static,
185    {
186        let handle = self.weak_entity();
187        self.app.on_app_restart(move |cx| {
188            handle.update(cx, |entity, cx| on_restart(entity, cx)).ok();
189        })
190    }
191
192    /// Arrange for the given function to be invoked whenever the application is quit.
193    /// The future returned from this callback will be polled for up to [crate::SHUTDOWN_TIMEOUT] until the app fully quits.
194    pub fn on_app_quit<Fut>(
195        &self,
196        mut on_quit: impl FnMut(&mut T, &mut Context<T>) -> Fut + 'static,
197    ) -> Subscription
198    where
199        Fut: 'static + Future<Output = ()>,
200        T: 'static,
201    {
202        let handle = self.weak_entity();
203        self.app.on_app_quit(move |cx| {
204            let future = handle.update(cx, |entity, cx| on_quit(entity, cx)).ok();
205            async move {
206                if let Some(future) = future {
207                    future.await;
208                }
209            }
210            .boxed_local()
211        })
212    }
213
214    /// Tell GPUI that this entity has changed and observers of it should be notified.
215    pub fn notify(&mut self) {
216        self.app.notify(self.entity_state.entity_id);
217    }
218
219    /// Spawn the future returned by the given function.
220    /// The function is provided a weak handle to the entity owned by this context and a context that can be held across await points.
221    /// The returned task must be held or detached.
222    #[track_caller]
223    pub fn spawn<AsyncFn, R>(&self, f: AsyncFn) -> Task<R>
224    where
225        T: 'static,
226        AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncApp) -> R + 'static,
227        R: 'static,
228    {
229        let this = self.weak_entity();
230        self.app.spawn(async move |cx| f(this, cx).await)
231    }
232
233    /// Convenience method for accessing view state in an event callback.
234    ///
235    /// Many GPUI callbacks take the form of `Fn(&E, &mut Window, &mut App)`,
236    /// but it's often useful to be able to access view state in these
237    /// callbacks. This method provides a convenient way to do so.
238    pub fn listener<E: ?Sized>(
239        &self,
240        f: impl Fn(&mut T, &E, &mut Window, &mut Context<T>) + 'static,
241    ) -> impl Fn(&E, &mut Window, &mut App) + 'static {
242        let view = self.entity().downgrade();
243        move |e: &E, window: &mut Window, cx: &mut App| {
244            view.update(cx, |view, cx| f(view, e, window, cx)).ok();
245        }
246    }
247
248    /// Convenience method for producing view state in a closure.
249    /// See `listener` for more details.
250    pub fn processor<E, R>(
251        &self,
252        f: impl Fn(&mut T, E, &mut Window, &mut Context<T>) -> R + 'static,
253    ) -> impl Fn(E, &mut Window, &mut App) -> R + 'static {
254        let view = self.entity();
255        move |e: E, window: &mut Window, cx: &mut App| {
256            view.update(cx, |view, cx| f(view, e, window, cx))
257        }
258    }
259
260    /// Run something using this entity and cx, when the returned struct is dropped
261    pub fn on_drop(
262        &self,
263        f: impl FnOnce(&mut T, &mut Context<T>) + 'static,
264    ) -> Deferred<impl FnOnce()> {
265        let this = self.weak_entity();
266        let mut cx = self.to_async();
267        util::defer(move || {
268            this.update(&mut cx, f).ok();
269        })
270    }
271
272    /// Focus the given view in the given window. View type is required to implement Focusable.
273    pub fn focus_view<W: Focusable>(&mut self, view: &Entity<W>, window: &mut Window) {
274        window.focus(&view.focus_handle(self));
275    }
276
277    /// Sets a given callback to be run on the next frame.
278    pub fn on_next_frame(
279        &self,
280        window: &mut Window,
281        f: impl FnOnce(&mut T, &mut Window, &mut Context<T>) + 'static,
282    ) where
283        T: 'static,
284    {
285        let view = self.entity();
286        window.on_next_frame(move |window, cx| view.update(cx, |view, cx| f(view, window, cx)));
287    }
288
289    /// Schedules the given function to be run at the end of the current effect cycle, allowing entities
290    /// that are currently on the stack to be returned to the app.
291    pub fn defer_in(
292        &mut self,
293        window: &Window,
294        f: impl FnOnce(&mut T, &mut Window, &mut Context<T>) + 'static,
295    ) {
296        let view = self.entity();
297        window.defer(self, move |window, cx| {
298            view.update(cx, |view, cx| f(view, window, cx))
299        });
300    }
301
302    /// Observe another entity for changes to its state, as tracked by [`Context::notify`].
303    pub fn observe_in<V2>(
304        &mut self,
305        observed: &Entity<V2>,
306        window: &mut Window,
307        mut on_notify: impl FnMut(&mut T, Entity<V2>, &mut Window, &mut Context<T>) + 'static,
308    ) -> Subscription
309    where
310        V2: 'static,
311        T: 'static,
312    {
313        let observed_id = observed.entity_id();
314        let observed = observed.downgrade();
315        let window_handle = window.handle;
316        let observer = self.weak_entity();
317        self.new_observer(
318            observed_id,
319            Box::new(move |cx| {
320                window_handle
321                    .update(cx, |_, window, cx| {
322                        if let Some((observer, observed)) =
323                            observer.upgrade().zip(observed.upgrade())
324                        {
325                            observer.update(cx, |observer, cx| {
326                                on_notify(observer, observed, window, cx);
327                            });
328                            true
329                        } else {
330                            false
331                        }
332                    })
333                    .unwrap_or(false)
334            }),
335        )
336    }
337
338    /// Subscribe to events emitted by another entity.
339    /// The entity to which you're subscribing must implement the [`EventEmitter`] trait.
340    /// The callback will be invoked with a reference to the current view, a handle to the emitting `Entity`, the event, a mutable reference to the `Window`, and the context for the entity.
341    pub fn subscribe_in<Emitter, Evt>(
342        &mut self,
343        emitter: &Entity<Emitter>,
344        window: &Window,
345        mut on_event: impl FnMut(&mut T, &Entity<Emitter>, &Evt, &mut Window, &mut Context<T>) + 'static,
346    ) -> Subscription
347    where
348        Emitter: EventEmitter<Evt>,
349        Evt: 'static,
350    {
351        let emitter = emitter.downgrade();
352        let window_handle = window.handle;
353        let subscriber = self.weak_entity();
354        self.new_subscription(
355            emitter.entity_id(),
356            (
357                TypeId::of::<Evt>(),
358                Box::new(move |event, cx| {
359                    window_handle
360                        .update(cx, |_, window, cx| {
361                            if let Some((subscriber, emitter)) =
362                                subscriber.upgrade().zip(emitter.upgrade())
363                            {
364                                let event = event.downcast_ref().expect("invalid event type");
365                                subscriber.update(cx, |subscriber, cx| {
366                                    on_event(subscriber, &emitter, event, window, cx);
367                                });
368                                true
369                            } else {
370                                false
371                            }
372                        })
373                        .unwrap_or(false)
374                }),
375            ),
376        )
377    }
378
379    /// Register a callback to be invoked when the view is released.
380    ///
381    /// The callback receives a handle to the view's window. This handle may be
382    /// invalid, if the window was closed before the view was released.
383    pub fn on_release_in(
384        &mut self,
385        window: &Window,
386        on_release: impl FnOnce(&mut T, &mut Window, &mut App) + 'static,
387    ) -> Subscription {
388        let entity = self.entity();
389        self.app.observe_release_in(&entity, window, on_release)
390    }
391
392    /// Register a callback to be invoked when the given Entity is released.
393    pub fn observe_release_in<T2>(
394        &self,
395        observed: &Entity<T2>,
396        window: &Window,
397        mut on_release: impl FnMut(&mut T, &mut T2, &mut Window, &mut Context<T>) + 'static,
398    ) -> Subscription
399    where
400        T: 'static,
401        T2: 'static,
402    {
403        let observer = self.weak_entity();
404        self.app
405            .observe_release_in(observed, window, move |observed, window, cx| {
406                observer
407                    .update(cx, |observer, cx| {
408                        on_release(observer, observed, window, cx)
409                    })
410                    .ok();
411            })
412    }
413
414    /// Register a callback to be invoked when the window is resized.
415    pub fn observe_window_bounds(
416        &self,
417        window: &mut Window,
418        mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
419    ) -> Subscription {
420        let view = self.weak_entity();
421        let (subscription, activate) = window.bounds_observers.insert(
422            (),
423            Box::new(move |window, cx| {
424                view.update(cx, |view, cx| callback(view, window, cx))
425                    .is_ok()
426            }),
427        );
428        activate();
429        subscription
430    }
431
432    /// Register a callback to be invoked when the window is activated or deactivated.
433    pub fn observe_window_activation(
434        &self,
435        window: &mut Window,
436        mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
437    ) -> Subscription {
438        let view = self.weak_entity();
439        let (subscription, activate) = window.activation_observers.insert(
440            (),
441            Box::new(move |window, cx| {
442                view.update(cx, |view, cx| callback(view, window, cx))
443                    .is_ok()
444            }),
445        );
446        activate();
447        subscription
448    }
449
450    /// Registers a callback to be invoked when the window appearance changes.
451    pub fn observe_window_appearance(
452        &self,
453        window: &mut Window,
454        mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
455    ) -> Subscription {
456        let view = self.weak_entity();
457        let (subscription, activate) = window.appearance_observers.insert(
458            (),
459            Box::new(move |window, cx| {
460                view.update(cx, |view, cx| callback(view, window, cx))
461                    .is_ok()
462            }),
463        );
464        activate();
465        subscription
466    }
467
468    /// Register a callback to be invoked when a keystroke is received by the application
469    /// in any window. Note that this fires after all other action and event mechanisms have resolved
470    /// and that this API will not be invoked if the event's propagation is stopped.
471    pub fn observe_keystrokes(
472        &mut self,
473        mut f: impl FnMut(&mut T, &KeystrokeEvent, &mut Window, &mut Context<T>) + 'static,
474    ) -> Subscription {
475        fn inner(
476            keystroke_observers: &SubscriberSet<(), KeystrokeObserver>,
477            handler: KeystrokeObserver,
478        ) -> Subscription {
479            let (subscription, activate) = keystroke_observers.insert((), handler);
480            activate();
481            subscription
482        }
483
484        let view = self.weak_entity();
485        inner(
486            &self.keystroke_observers,
487            Box::new(move |event, window, cx| {
488                if let Some(view) = view.upgrade() {
489                    view.update(cx, |view, cx| f(view, event, window, cx));
490                    true
491                } else {
492                    false
493                }
494            }),
495        )
496    }
497
498    /// Register a callback to be invoked when the window's pending input changes.
499    pub fn observe_pending_input(
500        &self,
501        window: &mut Window,
502        mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
503    ) -> Subscription {
504        let view = self.weak_entity();
505        let (subscription, activate) = window.pending_input_observers.insert(
506            (),
507            Box::new(move |window, cx| {
508                view.update(cx, |view, cx| callback(view, window, cx))
509                    .is_ok()
510            }),
511        );
512        activate();
513        subscription
514    }
515
516    /// Register a listener to be called when the given focus handle receives focus.
517    /// Returns a subscription and persists until the subscription is dropped.
518    pub fn on_focus(
519        &mut self,
520        handle: &FocusHandle,
521        window: &mut Window,
522        mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
523    ) -> Subscription {
524        let view = self.weak_entity();
525        let focus_id = handle.id;
526        let (subscription, activate) =
527            window.new_focus_listener(Box::new(move |event, window, cx| {
528                view.update(cx, |view, cx| {
529                    if event.previous_focus_path.last() != Some(&focus_id)
530                        && event.current_focus_path.last() == Some(&focus_id)
531                    {
532                        listener(view, window, cx)
533                    }
534                })
535                .is_ok()
536            }));
537        self.defer(|_| activate());
538        subscription
539    }
540
541    /// Register a listener to be called when the given focus handle or one of its descendants receives focus.
542    /// This does not fire if the given focus handle - or one of its descendants - was previously focused.
543    /// Returns a subscription and persists until the subscription is dropped.
544    pub fn on_focus_in(
545        &mut self,
546        handle: &FocusHandle,
547        window: &mut Window,
548        mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
549    ) -> Subscription {
550        let view = self.weak_entity();
551        let focus_id = handle.id;
552        let (subscription, activate) =
553            window.new_focus_listener(Box::new(move |event, window, cx| {
554                view.update(cx, |view, cx| {
555                    if event.is_focus_in(focus_id) {
556                        listener(view, window, cx)
557                    }
558                })
559                .is_ok()
560            }));
561        self.defer(|_| activate());
562        subscription
563    }
564
565    /// Register a listener to be called when the given focus handle loses focus.
566    /// Returns a subscription and persists until the subscription is dropped.
567    pub fn on_blur(
568        &mut self,
569        handle: &FocusHandle,
570        window: &mut Window,
571        mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
572    ) -> Subscription {
573        let view = self.weak_entity();
574        let focus_id = handle.id;
575        let (subscription, activate) =
576            window.new_focus_listener(Box::new(move |event, window, cx| {
577                view.update(cx, |view, cx| {
578                    if event.previous_focus_path.last() == Some(&focus_id)
579                        && event.current_focus_path.last() != Some(&focus_id)
580                    {
581                        listener(view, window, cx)
582                    }
583                })
584                .is_ok()
585            }));
586        self.defer(|_| activate());
587        subscription
588    }
589
590    /// Register a listener to be called when nothing in the window has focus.
591    /// This typically happens when the node that was focused is removed from the tree,
592    /// and this callback lets you chose a default place to restore the users focus.
593    /// Returns a subscription and persists until the subscription is dropped.
594    pub fn on_focus_lost(
595        &mut self,
596        window: &mut Window,
597        mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
598    ) -> Subscription {
599        let view = self.weak_entity();
600        let (subscription, activate) = window.focus_lost_listeners.insert(
601            (),
602            Box::new(move |window, cx| {
603                view.update(cx, |view, cx| listener(view, window, cx))
604                    .is_ok()
605            }),
606        );
607        self.defer(|_| activate());
608        subscription
609    }
610
611    /// Register a listener to be called when the given focus handle or one of its descendants loses focus.
612    /// Returns a subscription and persists until the subscription is dropped.
613    pub fn on_focus_out(
614        &mut self,
615        handle: &FocusHandle,
616        window: &mut Window,
617        mut listener: impl FnMut(&mut T, FocusOutEvent, &mut Window, &mut Context<T>) + 'static,
618    ) -> Subscription {
619        let view = self.weak_entity();
620        let focus_id = handle.id;
621        let (subscription, activate) =
622            window.new_focus_listener(Box::new(move |event, window, cx| {
623                view.update(cx, |view, cx| {
624                    if let Some(blurred_id) = event.previous_focus_path.last().copied()
625                        && event.is_focus_out(focus_id)
626                    {
627                        let event = FocusOutEvent {
628                            blurred: WeakFocusHandle {
629                                id: blurred_id,
630                                handles: Arc::downgrade(&cx.focus_handles),
631                            },
632                        };
633                        listener(view, event, window, cx)
634                    }
635                })
636                .is_ok()
637            }));
638        self.defer(|_| activate());
639        subscription
640    }
641
642    /// Schedule a future to be run asynchronously.
643    /// The given callback is invoked with a [`WeakEntity<V>`] to avoid leaking the entity for a long-running process.
644    /// It's also given an [`AsyncWindowContext`], which can be used to access the state of the entity across await points.
645    /// The returned future will be polled on the main thread.
646    #[track_caller]
647    pub fn spawn_in<AsyncFn, R>(&self, window: &Window, f: AsyncFn) -> Task<R>
648    where
649        R: 'static,
650        AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncWindowContext) -> R + 'static,
651    {
652        let view = self.weak_entity();
653        window.spawn(self, async move |cx| f(view, cx).await)
654    }
655
656    /// Register a callback to be invoked when the given global state changes.
657    pub fn observe_global_in<G: Global>(
658        &mut self,
659        window: &Window,
660        mut f: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
661    ) -> Subscription {
662        let window_handle = window.handle;
663        let view = self.weak_entity();
664        let (subscription, activate) = self.global_observers.insert(
665            TypeId::of::<G>(),
666            Box::new(move |cx| {
667                window_handle
668                    .update(cx, |_, window, cx| {
669                        view.update(cx, |view, cx| f(view, window, cx)).is_ok()
670                    })
671                    .unwrap_or(false)
672            }),
673        );
674        self.defer(move |_| activate());
675        subscription
676    }
677
678    /// Register a callback to be invoked when the given Action type is dispatched to the window.
679    pub fn on_action(
680        &mut self,
681        action_type: TypeId,
682        window: &mut Window,
683        listener: impl Fn(&mut T, &dyn Any, DispatchPhase, &mut Window, &mut Context<T>) + 'static,
684    ) {
685        let handle = self.weak_entity();
686        window.on_action(action_type, move |action, phase, window, cx| {
687            handle
688                .update(cx, |view, cx| {
689                    listener(view, action, phase, window, cx);
690                })
691                .ok();
692        });
693    }
694
695    /// Move focus to the current view, assuming it implements [`Focusable`].
696    pub fn focus_self(&mut self, window: &mut Window)
697    where
698        T: Focusable,
699    {
700        let view = self.entity();
701        window.defer(self, move |window, cx| {
702            view.read(cx).focus_handle(cx).focus(window)
703        })
704    }
705}
706
707impl<T> Context<'_, T> {
708    /// Emit an event of the specified type, which can be handled by other entities that have subscribed via `subscribe` methods on their respective contexts.
709    pub fn emit<Evt>(&mut self, event: Evt)
710    where
711        T: EventEmitter<Evt>,
712        Evt: 'static,
713    {
714        self.app.pending_effects.push_back(Effect::Emit {
715            emitter: self.entity_state.entity_id,
716            event_type: TypeId::of::<Evt>(),
717            event: Box::new(event),
718        });
719    }
720}
721
722impl<T> AppContext for Context<'_, T> {
723    type Result<U> = U;
724
725    fn new<U: 'static>(&mut self, build_entity: impl FnOnce(&mut Context<U>) -> U) -> Entity<U> {
726        self.app.new(build_entity)
727    }
728
729    fn reserve_entity<U: 'static>(&mut self) -> Reservation<U> {
730        self.app.reserve_entity()
731    }
732
733    fn insert_entity<U: 'static>(
734        &mut self,
735        reservation: Reservation<U>,
736        build_entity: impl FnOnce(&mut Context<U>) -> U,
737    ) -> Self::Result<Entity<U>> {
738        self.app.insert_entity(reservation, build_entity)
739    }
740
741    fn update_entity<U: 'static, R>(
742        &mut self,
743        handle: &Entity<U>,
744        update: impl FnOnce(&mut U, &mut Context<U>) -> R,
745    ) -> R {
746        self.app.update_entity(handle, update)
747    }
748
749    fn as_mut<'a, E>(&'a mut self, handle: &Entity<E>) -> Self::Result<super::GpuiBorrow<'a, E>>
750    where
751        E: 'static,
752    {
753        self.app.as_mut(handle)
754    }
755
756    fn read_entity<U, R>(
757        &self,
758        handle: &Entity<U>,
759        read: impl FnOnce(&U, &App) -> R,
760    ) -> Self::Result<R>
761    where
762        U: 'static,
763    {
764        self.app.read_entity(handle, read)
765    }
766
767    fn update_window<R, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<R>
768    where
769        F: FnOnce(AnyView, &mut Window, &mut App) -> R,
770    {
771        self.app.update_window(window, update)
772    }
773
774    fn read_window<U, R>(
775        &self,
776        window: &WindowHandle<U>,
777        read: impl FnOnce(Entity<U>, &App) -> R,
778    ) -> Result<R>
779    where
780        U: 'static,
781    {
782        self.app.read_window(window, read)
783    }
784
785    fn background_spawn<R>(&self, future: impl Future<Output = R> + Send + 'static) -> Task<R>
786    where
787        R: Send + 'static,
788    {
789        self.app.background_executor.spawn(future)
790    }
791
792    fn read_global<G, R>(&self, callback: impl FnOnce(&G, &App) -> R) -> Self::Result<R>
793    where
794        G: Global,
795    {
796        self.app.read_global(callback)
797    }
798}
799
800impl<T> Borrow<App> for Context<'_, T> {
801    fn borrow(&self) -> &App {
802        self.app
803    }
804}
805
806impl<T> BorrowMut<App> for Context<'_, T> {
807    fn borrow_mut(&mut self) -> &mut App {
808        self.app
809    }
810}