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