1use crate::{
2 AnyView, AnyWindowHandle, AppContext, AsyncApp, DispatchPhase, Effect, EntityId, EventEmitter,
3 FocusHandle, FocusOutEvent, Focusable, Global, KeystrokeObserver, Priority, Reservation,
4 SubscriberSet, Subscription, Task, WeakEntity, WeakFocusHandle, Window, WindowHandle,
5 WindowVisibility,
6};
7use anyhow::Result;
8use futures::FutureExt;
9use gpui_util::Deferred;
10use std::{
11 any::{Any, TypeId},
12 borrow::{Borrow, BorrowMut},
13 future::Future,
14 ops,
15 sync::Arc,
16};
17
18use super::{App, AsyncWindowContext, Entity, KeystrokeEvent};
19
20pub struct Context<'a, T> {
22 app: &'a mut App,
23 entity_state: WeakEntity<T>,
24}
25
26impl<'a, T> ops::Deref for Context<'a, T> {
27 type Target = App;
28
29 fn deref(&self) -> &Self::Target {
30 self.app
31 }
32}
33
34impl<'a, T> ops::DerefMut for Context<'a, T> {
35 fn deref_mut(&mut self) -> &mut Self::Target {
36 self.app
37 }
38}
39
40impl<'a, T: 'static> Context<'a, T> {
41 pub(crate) fn new_context(app: &'a mut App, entity_state: WeakEntity<T>) -> Self {
42 Self { app, entity_state }
43 }
44
45 pub fn entity_id(&self) -> EntityId {
47 self.entity_state.entity_id
48 }
49
50 pub fn entity(&self) -> Entity<T> {
52 self.weak_entity()
53 .upgrade()
54 .expect("The entity must be alive if we have a entity context")
55 }
56
57 pub fn weak_entity(&self) -> WeakEntity<T> {
59 self.entity_state.clone()
60 }
61
62 pub fn observe<W>(
65 &mut self,
66 entity: &Entity<W>,
67 mut on_notify: impl FnMut(&mut T, Entity<W>, &mut Context<T>) + 'static,
68 ) -> Subscription
69 where
70 T: 'static,
71 W: 'static,
72 {
73 let observer = self.weak_entity();
74 self.app.observe_internal(entity, move |entity, cx| {
75 invoke_observer(&observer, entity, cx, &mut on_notify)
76 })
77 }
78
79 pub fn observe_self(
81 &mut self,
82 mut on_event: impl FnMut(&mut T, &mut Context<T>) + 'static,
83 ) -> Subscription
84 where
85 T: 'static,
86 {
87 let this = self.entity();
88 self.app.observe(&this, move |this, cx| {
89 this.update(cx, |this, cx| on_event(this, cx))
90 })
91 }
92
93 pub fn subscribe<T2, Evt>(
95 &mut self,
96 entity: &Entity<T2>,
97 mut on_event: impl FnMut(&mut T, Entity<T2>, &Evt, &mut Context<T>) + 'static,
98 ) -> Subscription
99 where
100 T: 'static,
101 T2: 'static + EventEmitter<Evt>,
102 Evt: 'static,
103 {
104 let subscriber = self.weak_entity();
105 self.app
106 .subscribe_internal(entity, move |entity, event, cx| {
107 invoke_subscriber(&subscriber, entity, event, cx, &mut on_event)
108 })
109 }
110
111 pub fn subscribe_self<Evt>(
113 &mut self,
114 mut on_event: impl FnMut(&mut T, &Evt, &mut Context<T>) + 'static,
115 ) -> Subscription
116 where
117 T: 'static + EventEmitter<Evt>,
118 Evt: 'static,
119 {
120 let this = self.entity();
121 self.app.subscribe(&this, move |this, evt, cx| {
122 this.update(cx, |this, cx| on_event(this, evt, cx))
123 })
124 }
125
126 pub fn on_release(&self, on_release: impl FnOnce(&mut T, &mut App) + 'static) -> Subscription
128 where
129 T: 'static,
130 {
131 let (subscription, activate) = self.app.release_listeners.insert(
132 self.entity_state.entity_id,
133 Box::new(move |this, cx| {
134 let this = this.downcast_mut().expect("invalid entity type");
135 on_release(this, cx);
136 }),
137 );
138 activate();
139 subscription
140 }
141
142 pub fn observe_release<T2>(
144 &self,
145 entity: &Entity<T2>,
146 on_release: impl FnOnce(&mut T, &mut T2, &mut Context<T>) + 'static,
147 ) -> Subscription
148 where
149 T: Any,
150 T2: 'static,
151 {
152 let entity_id = entity.entity_id();
153 let this = self.weak_entity();
154 let (subscription, activate) = self.app.release_listeners.insert(
155 entity_id,
156 Box::new(move |entity, cx| {
157 let entity = entity.downcast_mut().expect("invalid entity type");
158 if let Some(this) = this.upgrade() {
159 this.update(cx, |this, cx| on_release(this, entity, cx));
160 }
161 }),
162 );
163 activate();
164 subscription
165 }
166
167 pub fn observe_global<G: 'static>(
169 &mut self,
170 mut f: impl FnMut(&mut T, &mut Context<T>) + 'static,
171 ) -> Subscription
172 where
173 T: 'static,
174 {
175 let handle = self.weak_entity();
176 let (subscription, activate) = self.global_observers.insert(
177 TypeId::of::<G>(),
178 Box::new(move |cx| handle.update(cx, |view, cx| f(view, cx)).is_ok()),
179 );
180 self.defer(move |_| activate());
181 subscription
182 }
183
184 pub fn on_app_restart(
186 &self,
187 mut on_restart: impl FnMut(&mut T, &mut App) + 'static,
188 ) -> Subscription
189 where
190 T: 'static,
191 {
192 let handle = self.weak_entity();
193 self.app.on_app_restart(move |cx| {
194 handle.update(cx, |entity, cx| on_restart(entity, cx)).ok();
195 })
196 }
197
198 pub fn on_app_quit<Fut>(
201 &self,
202 mut on_quit: impl FnMut(&mut T, &mut Context<T>) -> Fut + 'static,
203 ) -> Subscription
204 where
205 Fut: 'static + Future<Output = ()>,
206 T: 'static,
207 {
208 let handle = self.weak_entity();
209 self.app.on_app_quit(move |cx| {
210 let future = handle.update(cx, |entity, cx| on_quit(entity, cx)).ok();
211 async move {
212 if let Some(future) = future {
213 future.await;
214 }
215 }
216 .boxed_local()
217 })
218 }
219
220 pub fn notify(&mut self) {
222 self.app.notify(self.entity_state.entity_id);
223 }
224
225 #[track_caller]
229 #[inline(always)]
230 pub fn spawn<AsyncFn, R>(&self, f: AsyncFn) -> Task<R>
231 where
232 T: 'static,
233 AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncApp) -> R + 'static,
234 R: 'static,
235 {
236 let this = self.weak_entity();
237 self.app.spawn(async move |cx| f(this, cx).await)
238 }
239
240 #[inline(always)]
246 pub fn listener<E: ?Sized>(
247 &self,
248 listener: impl Fn(&mut T, &E, &mut Window, &mut Context<T>) + 'static,
249 ) -> impl Fn(&E, &mut Window, &mut App) + 'static {
250 let view = self.entity().downgrade();
251 move |event: &E, window: &mut Window, cx: &mut App| {
252 invoke_listener(&view, window, cx, &|view, window, cx| {
253 listener(view, event, window, cx);
254 });
255 }
256 }
257
258 pub fn processor<E, R>(
261 &self,
262 f: impl Fn(&mut T, E, &mut Window, &mut Context<T>) -> R + 'static,
263 ) -> impl Fn(E, &mut Window, &mut App) -> R + 'static {
264 let view = self.entity();
265 move |e: E, window: &mut Window, cx: &mut App| {
266 view.update(cx, |view, cx| f(view, e, window, cx))
267 }
268 }
269
270 pub fn on_drop(
272 &self,
273 f: impl FnOnce(&mut T, &mut Context<T>) + 'static,
274 ) -> Deferred<impl FnOnce()> {
275 let this = self.weak_entity();
276 let mut cx = self.to_async();
277 gpui_util::defer(move || {
278 this.update(&mut cx, f).ok();
279 })
280 }
281
282 pub fn focus_view<W: Focusable>(&mut self, view: &Entity<W>, window: &mut Window) {
284 window.focus(&view.focus_handle(self), self);
285 }
286
287 pub fn on_next_frame(
289 &self,
290 window: &mut Window,
291 f: impl FnOnce(&mut T, &mut Window, &mut Context<T>) + 'static,
292 ) where
293 T: 'static,
294 {
295 let view = self.entity();
296 window.on_next_frame(move |window, cx| view.update(cx, |view, cx| f(view, window, cx)));
297 }
298
299 pub fn defer_in(
302 &mut self,
303 window: &Window,
304 f: impl FnOnce(&mut T, &mut Window, &mut Context<T>) + 'static,
305 ) {
306 let view = self.weak_entity();
307 let entity_id = self.entity_id();
308 self.ensure_window(entity_id, window.handle.id);
309 self.app.defer(move |cx| {
310 cx.with_window(entity_id, |window, cx| {
311 view.update(cx, |view, cx| f(view, window, cx)).ok();
312 });
313 });
314 }
315
316 pub fn observe_in<V2>(
318 &mut self,
319 observed: &Entity<V2>,
320 window: &mut Window,
321 mut on_notify: impl FnMut(&mut T, Entity<V2>, &mut Window, &mut Context<T>) + 'static,
322 ) -> Subscription
323 where
324 V2: 'static,
325 T: 'static,
326 {
327 let observed_id = observed.entity_id();
328 let observed = observed.downgrade();
329 let observer = self.weak_entity();
330 let observer_id = self.entity_id();
331 self.ensure_window(observer_id, window.handle.id);
332 self.new_observer(
333 observed_id,
334 Box::new(move |cx| invoke_observer_in(&observer, &observed, cx, &mut on_notify)),
335 )
336 }
337
338 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 subscriber = self.weak_entity();
353 let subscriber_id = self.entity_id();
354 self.ensure_window(subscriber_id, window.handle.id);
355 self.new_subscription(
356 emitter.entity_id(),
357 (
358 TypeId::of::<Evt>(),
359 Box::new(move |event, cx| {
360 invoke_subscriber_in(&subscriber, &emitter, event, cx, &mut on_event)
361 }),
362 ),
363 )
364 }
365
366 pub fn on_release_in(
371 &mut self,
372 window: &Window,
373 on_release: impl FnOnce(&mut T, &mut Window, &mut App) + 'static,
374 ) -> Subscription {
375 let entity = self.entity();
376 self.app.observe_release_in(&entity, window, on_release)
377 }
378
379 pub fn observe_release_in<T2>(
381 &self,
382 observed: &Entity<T2>,
383 window: &Window,
384 mut on_release: impl FnMut(&mut T, &mut T2, &mut Window, &mut Context<T>) + 'static,
385 ) -> Subscription
386 where
387 T: 'static,
388 T2: 'static,
389 {
390 let observer = self.weak_entity();
391 self.app
392 .observe_release_in(observed, window, move |observed, window, cx| {
393 observer
394 .update(cx, |observer, cx| {
395 on_release(observer, observed, window, cx)
396 })
397 .ok();
398 })
399 }
400
401 pub fn observe_window_bounds(
403 &self,
404 window: &mut Window,
405 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
406 ) -> Subscription {
407 let view = self.weak_entity();
408 let (subscription, activate) = window.bounds_observers.insert(
409 (),
410 Box::new(move |window, cx| {
411 view.update(cx, |view, cx| callback(view, window, cx))
412 .is_ok()
413 }),
414 );
415 activate();
416 subscription
417 }
418
419 pub fn observe_window_activation(
421 &self,
422 window: &mut Window,
423 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
424 ) -> Subscription {
425 let view = self.weak_entity();
426 let (subscription, activate) = window.activation_observers.insert(
427 (),
428 Box::new(move |window, cx| {
429 view.update(cx, |view, cx| callback(view, window, cx))
430 .is_ok()
431 }),
432 );
433 activate();
434 subscription
435 }
436
437 pub fn observe_window_visibility(
440 &self,
441 window: &mut Window,
442 mut callback: impl FnMut(&mut T, WindowVisibility, &mut Window, &mut Context<T>) + 'static,
443 ) -> Subscription {
444 let view = self.weak_entity();
445 let (subscription, activate) = window.visibility_observers.insert(
446 (),
447 Box::new(move |visibility, window, cx| {
448 view.update(cx, |view, cx| callback(view, visibility, window, cx))
449 .is_ok()
450 }),
451 );
452 activate();
453 subscription
454 }
455
456 pub fn observe_window_appearance(
458 &self,
459 window: &mut Window,
460 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
461 ) -> Subscription {
462 let view = self.weak_entity();
463 let (subscription, activate) = window.appearance_observers.insert(
464 (),
465 Box::new(move |window, cx| {
466 view.update(cx, |view, cx| callback(view, window, cx))
467 .is_ok()
468 }),
469 );
470 activate();
471 subscription
472 }
473
474 pub fn observe_window_display(
478 &self,
479 window: &mut Window,
480 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
481 ) -> Subscription {
482 let view = self.weak_entity();
483 let (subscription, activate) = window.display_observers.insert(
484 (),
485 Box::new(move |window, cx| {
486 view.update(cx, |view, cx| callback(view, window, cx))
487 .is_ok()
488 }),
489 );
490 activate();
491 subscription
492 }
493
494 pub fn observe_button_layout_changed(
496 &self,
497 window: &mut Window,
498 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
499 ) -> Subscription {
500 let view = self.weak_entity();
501 let (subscription, activate) = window.button_layout_observers.insert(
502 (),
503 Box::new(move |window, cx| {
504 view.update(cx, |view, cx| callback(view, window, cx))
505 .is_ok()
506 }),
507 );
508 activate();
509 subscription
510 }
511
512 pub fn observe_keystrokes(
514 &mut self,
515 mut f: impl FnMut(&mut T, &KeystrokeEvent, &mut Window, &mut Context<T>) + 'static,
516 ) -> Subscription {
517 fn inner(
518 keystroke_observers: &SubscriberSet<(), KeystrokeObserver>,
519 handler: KeystrokeObserver,
520 ) -> Subscription {
521 let (subscription, activate) = keystroke_observers.insert((), handler);
522 activate();
523 subscription
524 }
525
526 let view = self.weak_entity();
527 inner(
528 &self.keystroke_observers,
529 Box::new(move |event, window, cx| {
530 if let Some(view) = view.upgrade() {
531 view.update(cx, |view, cx| f(view, event, window, cx));
532 true
533 } else {
534 false
535 }
536 }),
537 )
538 }
539
540 pub fn observe_pending_input(
542 &self,
543 window: &mut Window,
544 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
545 ) -> Subscription {
546 let view = self.weak_entity();
547 let (subscription, activate) = window.pending_input_observers.insert(
548 (),
549 Box::new(move |window, cx| {
550 view.update(cx, |view, cx| callback(view, window, cx))
551 .is_ok()
552 }),
553 );
554 activate();
555 subscription
556 }
557
558 pub fn on_focus(
561 &mut self,
562 handle: &FocusHandle,
563 window: &mut Window,
564 mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
565 ) -> Subscription {
566 let view = self.weak_entity();
567 let focus_id = handle.id;
568 let (subscription, activate) =
569 window.new_focus_listener(Box::new(move |event, window, cx| {
570 view.update(cx, |view, cx| {
571 if event.previous_focus_path.last() != Some(&focus_id)
572 && event.current_focus_path.last() == Some(&focus_id)
573 {
574 listener(view, window, cx)
575 }
576 })
577 .is_ok()
578 }));
579 self.defer(|_| activate());
580 subscription
581 }
582
583 pub fn on_focus_in(
587 &mut self,
588 handle: &FocusHandle,
589 window: &mut Window,
590 mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
591 ) -> Subscription {
592 let view = self.weak_entity();
593 let focus_id = handle.id;
594 let (subscription, activate) =
595 window.new_focus_listener(Box::new(move |event, window, cx| {
596 view.update(cx, |view, cx| {
597 if event.is_focus_in(focus_id) {
598 listener(view, window, cx)
599 }
600 })
601 .is_ok()
602 }));
603 self.defer(|_| activate());
604 subscription
605 }
606
607 pub fn on_blur(
610 &mut self,
611 handle: &FocusHandle,
612 window: &mut Window,
613 mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
614 ) -> Subscription {
615 let view = self.weak_entity();
616 let focus_id = handle.id;
617 let (subscription, activate) =
618 window.new_focus_listener(Box::new(move |event, window, cx| {
619 view.update(cx, |view, cx| {
620 if event.previous_focus_path.last() == Some(&focus_id)
621 && event.current_focus_path.last() != Some(&focus_id)
622 {
623 listener(view, window, cx)
624 }
625 })
626 .is_ok()
627 }));
628 self.defer(|_| activate());
629 subscription
630 }
631
632 pub fn on_focus_lost(
637 &mut self,
638 window: &mut Window,
639 mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
640 ) -> Subscription {
641 let view = self.weak_entity();
642 let (subscription, activate) = window.focus_lost_listeners.insert(
643 (),
644 Box::new(move |window, cx| {
645 view.update(cx, |view, cx| listener(view, window, cx))
646 .is_ok()
647 }),
648 );
649 self.defer(|_| activate());
650 subscription
651 }
652
653 pub fn on_focus_out(
656 &mut self,
657 handle: &FocusHandle,
658 window: &mut Window,
659 mut listener: impl FnMut(&mut T, FocusOutEvent, &mut Window, &mut Context<T>) + 'static,
660 ) -> Subscription {
661 let view = self.weak_entity();
662 let focus_id = handle.id;
663 let (subscription, activate) =
664 window.new_focus_listener(Box::new(move |event, window, cx| {
665 view.update(cx, |view, cx| {
666 if let Some(blurred_id) = event.previous_focus_path.last().copied()
667 && event.is_focus_out(focus_id)
668 {
669 let event = FocusOutEvent {
670 blurred: WeakFocusHandle {
671 id: blurred_id,
672 handles: Arc::downgrade(&cx.focus_handles),
673 },
674 };
675 listener(view, event, window, cx)
676 }
677 })
678 .is_ok()
679 }));
680 self.defer(|_| activate());
681 subscription
682 }
683
684 #[track_caller]
689 #[inline(always)]
690 pub fn spawn_in<AsyncFn, R>(&self, window: &Window, f: AsyncFn) -> Task<R>
691 where
692 R: 'static,
693 AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncWindowContext) -> R + 'static,
694 {
695 let view = self.weak_entity();
696 window.spawn(self, async move |cx| f(view, cx).await)
697 }
698
699 #[track_caller]
704 #[inline(always)]
705 pub fn spawn_in_with_priority<AsyncFn, R>(
706 &self,
707 priority: Priority,
708 window: &Window,
709 f: AsyncFn,
710 ) -> Task<R>
711 where
712 R: 'static,
713 AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncWindowContext) -> R + 'static,
714 {
715 let view = self.weak_entity();
716 window.spawn_with_priority(priority, self, async move |cx| f(view, cx).await)
717 }
718
719 pub fn observe_global_in<G: Global>(
721 &mut self,
722 window: &Window,
723 mut f: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
724 ) -> Subscription {
725 let window_handle = window.handle;
726 let view = self.weak_entity();
727 let (subscription, activate) = self.global_observers.insert(
728 TypeId::of::<G>(),
729 Box::new(move |cx| {
730 if view.upgrade().is_none() {
732 return false;
733 }
734 let Ok(entity_alive) = window_handle.update(cx, |_, window, cx| {
738 view.update(cx, |view, cx| f(view, window, cx)).is_ok()
739 }) else {
740 return true;
741 };
742 entity_alive
743 }),
744 );
745 self.defer(move |_| activate());
746 subscription
747 }
748
749 pub fn on_action(
751 &mut self,
752 action_type: TypeId,
753 window: &mut Window,
754 listener: impl Fn(&mut T, &dyn Any, DispatchPhase, &mut Window, &mut Context<T>) + 'static,
755 ) {
756 let handle = self.weak_entity();
757 window.on_action(action_type, move |action, phase, window, cx| {
758 handle
759 .update(cx, |view, cx| {
760 listener(view, action, phase, window, cx);
761 })
762 .ok();
763 });
764 }
765
766 pub fn focus_self(&mut self, window: &mut Window)
768 where
769 T: Focusable,
770 {
771 let view = self.entity();
772 window.defer(self, move |window, cx| {
773 view.read(cx).focus_handle(cx).focus(window, cx)
774 })
775 }
776}
777
778impl<T> Context<'_, T> {
779 pub fn emit<Evt>(&mut self, event: Evt)
781 where
782 T: EventEmitter<Evt>,
783 Evt: 'static,
784 {
785 let event = self
786 .event_arena
787 .alloc(|| event)
788 .map(|it| it as &mut dyn Any);
789 self.app.pending_effects.push_back(Effect::Emit {
790 emitter: self.entity_state.entity_id,
791 event_type: TypeId::of::<Evt>(),
792 event,
793 });
794 }
795}
796
797impl<T> AppContext for Context<'_, T> {
798 #[inline]
799 fn new<U: 'static>(&mut self, build_entity: impl FnOnce(&mut Context<U>) -> U) -> Entity<U> {
800 self.app.new(build_entity)
801 }
802
803 #[inline]
804 fn reserve_entity<U: 'static>(&mut self) -> Reservation<U> {
805 self.app.reserve_entity()
806 }
807
808 #[inline]
809 fn insert_entity<U: 'static>(
810 &mut self,
811 reservation: Reservation<U>,
812 build_entity: impl FnOnce(&mut Context<U>) -> U,
813 ) -> Entity<U> {
814 self.app.insert_entity(reservation, build_entity)
815 }
816
817 #[inline]
818 fn update_entity<U: 'static, R>(
819 &mut self,
820 handle: &Entity<U>,
821 update: impl FnOnce(&mut U, &mut Context<U>) -> R,
822 ) -> R {
823 self.app.update_entity(handle, update)
824 }
825
826 #[inline]
827 fn as_mut<'a, E>(&'a mut self, handle: &Entity<E>) -> super::GpuiBorrow<'a, E>
828 where
829 E: 'static,
830 {
831 self.app.as_mut(handle)
832 }
833
834 #[inline]
835 fn read_entity<U, R>(&self, handle: &Entity<U>, read: impl FnOnce(&U, &App) -> R) -> R
836 where
837 U: 'static,
838 {
839 self.app.read_entity(handle, read)
840 }
841
842 #[inline]
843 fn update_window<R, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<R>
844 where
845 F: FnOnce(AnyView, &mut Window, &mut App) -> R,
846 {
847 self.app.update_window(window, update)
848 }
849
850 #[inline]
851 fn with_window<R>(
852 &mut self,
853 entity_id: EntityId,
854 f: impl FnOnce(&mut Window, &mut App) -> R,
855 ) -> Option<R> {
856 self.app.with_window(entity_id, f)
857 }
858
859 #[inline]
860 fn read_window<U, R>(
861 &self,
862 window: &WindowHandle<U>,
863 read: impl FnOnce(Entity<U>, &App) -> R,
864 ) -> Result<R>
865 where
866 U: 'static,
867 {
868 self.app.read_window(window, read)
869 }
870
871 #[inline]
872 fn background_spawn<R>(&self, future: impl Future<Output = R> + Send + 'static) -> Task<R>
873 where
874 R: Send + 'static,
875 {
876 self.app.background_executor.spawn(future)
877 }
878
879 #[inline]
880 fn read_global<G, R>(&self, callback: impl FnOnce(&G, &App) -> R) -> R
881 where
882 G: Global,
883 {
884 self.app.read_global(callback)
885 }
886}
887
888impl<T> Borrow<App> for Context<'_, T> {
889 fn borrow(&self) -> &App {
890 self.app
891 }
892}
893
894impl<T> BorrowMut<App> for Context<'_, T> {
895 fn borrow_mut(&mut self) -> &mut App {
896 self.app
897 }
898}
899
900#[inline(never)]
901fn invoke_observer<T: 'static, W: 'static>(
902 observer: &WeakEntity<T>,
903 observed: Entity<W>,
904 cx: &mut App,
905 on_notify: &mut dyn FnMut(&mut T, Entity<W>, &mut Context<T>),
906) -> bool {
907 if let Some(observer) = observer.upgrade() {
908 observer.update(cx, |observer, cx| on_notify(observer, observed, cx));
909 true
910 } else {
911 false
912 }
913}
914
915#[inline(never)]
916fn invoke_subscriber<T: 'static, Emitter: 'static, Event: 'static>(
917 subscriber: &WeakEntity<T>,
918 emitter: Entity<Emitter>,
919 event: &Event,
920 cx: &mut App,
921 on_event: &mut dyn FnMut(&mut T, Entity<Emitter>, &Event, &mut Context<T>),
922) -> bool {
923 if let Some(subscriber) = subscriber.upgrade() {
924 subscriber.update(cx, |subscriber, cx| {
925 on_event(subscriber, emitter, event, cx)
926 });
927 true
928 } else {
929 false
930 }
931}
932
933#[inline(never)]
934fn invoke_observer_in<T: 'static, W: 'static>(
935 observer: &WeakEntity<T>,
936 observed: &WeakEntity<W>,
937 cx: &mut App,
938 on_notify: &mut dyn FnMut(&mut T, Entity<W>, &mut Window, &mut Context<T>),
939) -> bool {
940 let Some((observer, observed)) = observer.upgrade().zip(observed.upgrade()) else {
941 return false;
942 };
943 cx.with_window(observer.entity_id(), |window, cx| {
944 observer.update(cx, |observer, cx| {
945 on_notify(observer, observed, window, cx);
946 });
947 });
948 true
949}
950
951#[inline(never)]
952fn invoke_subscriber_in<T: 'static, Emitter: 'static, Event: 'static>(
953 subscriber: &WeakEntity<T>,
954 emitter: &WeakEntity<Emitter>,
955 event: &dyn Any,
956 cx: &mut App,
957 on_event: &mut dyn FnMut(&mut T, &Entity<Emitter>, &Event, &mut Window, &mut Context<T>),
958) -> bool {
959 let Some((subscriber, emitter)) = subscriber.upgrade().zip(emitter.upgrade()) else {
960 return false;
961 };
962 let event = event.downcast_ref().expect("invalid event type");
963 cx.with_window(subscriber.entity_id(), |window, cx| {
964 subscriber.update(cx, |subscriber, cx| {
965 on_event(subscriber, &emitter, event, window, cx);
966 });
967 });
968 true
969}
970
971#[inline(never)]
972fn invoke_listener<T: 'static>(
973 view: &WeakEntity<T>,
974 window: &mut Window,
975 cx: &mut App,
976 listener: &dyn Fn(&mut T, &mut Window, &mut Context<T>),
977) {
978 view.update(cx, |view, cx| listener(view, window, cx)).ok();
979}