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