1pub mod action;
2mod callback_collection;
3mod menu;
4pub(crate) mod ref_counts;
5#[cfg(any(test, feature = "test-support"))]
6pub mod test_app_context;
7pub(crate) mod window;
8mod window_input_handler;
9
10use std::{
11 any::{type_name, Any, TypeId},
12 cell::RefCell,
13 fmt::{self, Debug},
14 hash::{Hash, Hasher},
15 marker::PhantomData,
16 mem,
17 ops::{Deref, DerefMut, Range},
18 path::{Path, PathBuf},
19 pin::Pin,
20 rc::{self, Rc},
21 sync::{Arc, Weak},
22 time::Duration,
23};
24
25use anyhow::{anyhow, Context, Result};
26use parking_lot::Mutex;
27use postage::oneshot;
28use smol::prelude::*;
29use util::ResultExt;
30use uuid::Uuid;
31
32pub use action::*;
33use callback_collection::CallbackCollection;
34use collections::{hash_map::Entry, BTreeMap, HashMap, HashSet, VecDeque};
35pub use menu::*;
36use platform::Event;
37#[cfg(any(test, feature = "test-support"))]
38use ref_counts::LeakDetector;
39#[cfg(any(test, feature = "test-support"))]
40pub use test_app_context::{ContextHandle, TestAppContext};
41use window_input_handler::WindowInputHandler;
42
43use crate::{
44 elements::{AnyRootElement, Element, RootElement},
45 executor::{self, Task},
46 keymap_matcher::{self, Binding, KeymapContext, KeymapMatcher, Keystroke, MatchResult},
47 platform::{
48 self, FontSystem, KeyDownEvent, KeyUpEvent, ModifiersChangedEvent, MouseButton,
49 PathPromptOptions, Platform, PromptLevel, WindowBounds, WindowOptions,
50 },
51 util::post_inc,
52 window::{Window, WindowContext},
53 AssetCache, AssetSource, ClipboardItem, FontCache, MouseRegionId,
54};
55
56use self::ref_counts::RefCounts;
57
58pub trait Entity: 'static {
59 type Event;
60
61 fn release(&mut self, _: &mut AppContext) {}
62 fn app_will_quit(
63 &mut self,
64 _: &mut AppContext,
65 ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
66 None
67 }
68}
69
70pub trait View: Entity + Sized {
71 fn ui_name() -> &'static str;
72 fn render(&mut self, cx: &mut ViewContext<'_, '_, '_, Self>) -> Element<Self>;
73 fn focus_in(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {}
74 fn focus_out(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {}
75 fn key_down(&mut self, _: &KeyDownEvent, _: &mut ViewContext<Self>) -> bool {
76 false
77 }
78 fn key_up(&mut self, _: &KeyUpEvent, _: &mut ViewContext<Self>) -> bool {
79 false
80 }
81 fn modifiers_changed(&mut self, _: &ModifiersChangedEvent, _: &mut ViewContext<Self>) -> bool {
82 false
83 }
84
85 fn keymap_context(&self, _: &AppContext) -> keymap_matcher::KeymapContext {
86 Self::default_keymap_context()
87 }
88 fn default_keymap_context() -> keymap_matcher::KeymapContext {
89 let mut cx = keymap_matcher::KeymapContext::default();
90 cx.add_identifier(Self::ui_name());
91 cx
92 }
93 fn debug_json(&self, _: &AppContext) -> serde_json::Value {
94 serde_json::Value::Null
95 }
96
97 fn text_for_range(&self, _: Range<usize>, _: &AppContext) -> Option<String> {
98 None
99 }
100 fn selected_text_range(&self, _: &AppContext) -> Option<Range<usize>> {
101 None
102 }
103 fn marked_text_range(&self, _: &AppContext) -> Option<Range<usize>> {
104 None
105 }
106 fn unmark_text(&mut self, _: &mut ViewContext<Self>) {}
107 fn replace_text_in_range(
108 &mut self,
109 _: Option<Range<usize>>,
110 _: &str,
111 _: &mut ViewContext<Self>,
112 ) {
113 }
114 fn replace_and_mark_text_in_range(
115 &mut self,
116 _: Option<Range<usize>>,
117 _: &str,
118 _: Option<Range<usize>>,
119 _: &mut ViewContext<Self>,
120 ) {
121 }
122}
123
124pub trait ReadModel {
125 fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T;
126}
127
128pub trait ReadModelWith {
129 fn read_model_with<E: Entity, T>(
130 &self,
131 handle: &ModelHandle<E>,
132 read: &mut dyn FnMut(&E, &AppContext) -> T,
133 ) -> T;
134}
135
136pub trait UpdateModel {
137 fn update_model<T: Entity, O>(
138 &mut self,
139 handle: &ModelHandle<T>,
140 update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
141 ) -> O;
142}
143
144pub trait UpgradeModelHandle {
145 fn upgrade_model_handle<T: Entity>(
146 &self,
147 handle: &WeakModelHandle<T>,
148 ) -> Option<ModelHandle<T>>;
149
150 fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool;
151
152 fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle>;
153}
154
155pub trait UpgradeViewHandle {
156 fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>>;
157
158 fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle>;
159}
160
161pub trait ReadView {
162 fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T;
163}
164
165pub trait ReadViewWith {
166 fn read_view_with<V, T>(
167 &self,
168 handle: &ViewHandle<V>,
169 read: &mut dyn FnMut(&V, &AppContext) -> T,
170 ) -> T
171 where
172 V: View;
173}
174
175pub trait UpdateView {
176 type Output<S>;
177
178 fn update_view<T, S>(
179 &mut self,
180 handle: &ViewHandle<T>,
181 update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
182 ) -> Self::Output<S>
183 where
184 T: View;
185}
186
187#[derive(Clone)]
188pub struct App(Rc<RefCell<AppContext>>);
189
190#[derive(Clone)]
191pub struct AsyncAppContext(Rc<RefCell<AppContext>>);
192
193impl App {
194 pub fn new(asset_source: impl AssetSource) -> Result<Self> {
195 let platform = platform::current::platform();
196 let foreground = Rc::new(executor::Foreground::platform(platform.dispatcher())?);
197 let foreground_platform = platform::current::foreground_platform(foreground.clone());
198 let app = Self(Rc::new(RefCell::new(AppContext::new(
199 foreground,
200 Arc::new(executor::Background::new()),
201 platform.clone(),
202 foreground_platform.clone(),
203 Arc::new(FontCache::new(platform.fonts())),
204 Default::default(),
205 asset_source,
206 ))));
207
208 foreground_platform.on_quit(Box::new({
209 let cx = app.0.clone();
210 move || {
211 cx.borrow_mut().quit();
212 }
213 }));
214 setup_menu_handlers(foreground_platform.as_ref(), &app);
215
216 app.0.borrow_mut().weak_self = Some(Rc::downgrade(&app.0));
217 Ok(app)
218 }
219
220 pub fn background(&self) -> Arc<executor::Background> {
221 self.0.borrow().background().clone()
222 }
223
224 pub fn on_become_active<F>(self, mut callback: F) -> Self
225 where
226 F: 'static + FnMut(&mut AppContext),
227 {
228 let cx = self.0.clone();
229 self.0
230 .borrow_mut()
231 .foreground_platform
232 .on_become_active(Box::new(move || callback(&mut *cx.borrow_mut())));
233 self
234 }
235
236 pub fn on_resign_active<F>(self, mut callback: F) -> Self
237 where
238 F: 'static + FnMut(&mut AppContext),
239 {
240 let cx = self.0.clone();
241 self.0
242 .borrow_mut()
243 .foreground_platform
244 .on_resign_active(Box::new(move || callback(&mut *cx.borrow_mut())));
245 self
246 }
247
248 pub fn on_quit<F>(&mut self, mut callback: F) -> &mut Self
249 where
250 F: 'static + FnMut(&mut AppContext),
251 {
252 let cx = self.0.clone();
253 self.0
254 .borrow_mut()
255 .foreground_platform
256 .on_quit(Box::new(move || callback(&mut *cx.borrow_mut())));
257 self
258 }
259
260 /// Handle the application being re-activated when no windows are open.
261 pub fn on_reopen<F>(&mut self, mut callback: F) -> &mut Self
262 where
263 F: 'static + FnMut(&mut AppContext),
264 {
265 let cx = self.0.clone();
266 self.0
267 .borrow_mut()
268 .foreground_platform
269 .on_reopen(Box::new(move || callback(&mut *cx.borrow_mut())));
270 self
271 }
272
273 pub fn on_event<F>(&mut self, mut callback: F) -> &mut Self
274 where
275 F: 'static + FnMut(Event, &mut AppContext) -> bool,
276 {
277 let cx = self.0.clone();
278 self.0
279 .borrow_mut()
280 .foreground_platform
281 .on_event(Box::new(move |event| {
282 callback(event, &mut *cx.borrow_mut())
283 }));
284 self
285 }
286
287 pub fn on_open_urls<F>(&mut self, mut callback: F) -> &mut Self
288 where
289 F: 'static + FnMut(Vec<String>, &mut AppContext),
290 {
291 let cx = self.0.clone();
292 self.0
293 .borrow_mut()
294 .foreground_platform
295 .on_open_urls(Box::new(move |urls| callback(urls, &mut *cx.borrow_mut())));
296 self
297 }
298
299 pub fn run<F>(self, on_finish_launching: F)
300 where
301 F: 'static + FnOnce(&mut AppContext),
302 {
303 let platform = self.0.borrow().foreground_platform.clone();
304 platform.run(Box::new(move || {
305 let mut cx = self.0.borrow_mut();
306 let cx = &mut *cx;
307 crate::views::init(cx);
308 on_finish_launching(cx);
309 }))
310 }
311
312 pub fn platform(&self) -> Arc<dyn Platform> {
313 self.0.borrow().platform.clone()
314 }
315
316 pub fn font_cache(&self) -> Arc<FontCache> {
317 self.0.borrow().font_cache.clone()
318 }
319
320 fn update<T, F: FnOnce(&mut AppContext) -> T>(&mut self, callback: F) -> T {
321 let mut state = self.0.borrow_mut();
322 let result = state.update(callback);
323 state.pending_notifications.clear();
324 result
325 }
326
327 fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
328 &mut self,
329 window_id: usize,
330 callback: F,
331 ) -> Option<T> {
332 let mut state = self.0.borrow_mut();
333 let result = state.update_window(window_id, callback);
334 state.pending_notifications.clear();
335 result
336 }
337}
338
339impl AsyncAppContext {
340 pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
341 where
342 F: FnOnce(AsyncAppContext) -> Fut,
343 Fut: 'static + Future<Output = T>,
344 T: 'static,
345 {
346 self.0.borrow().foreground.spawn(f(self.clone()))
347 }
348
349 pub fn read<T, F: FnOnce(&AppContext) -> T>(&self, callback: F) -> T {
350 callback(&*self.0.borrow())
351 }
352
353 pub fn update<T, F: FnOnce(&mut AppContext) -> T>(&mut self, callback: F) -> T {
354 self.0.borrow_mut().update(callback)
355 }
356
357 pub fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
358 &mut self,
359 window_id: usize,
360 callback: F,
361 ) -> Option<T> {
362 self.0.borrow_mut().update_window(window_id, callback)
363 }
364
365 pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
366 where
367 T: Entity,
368 F: FnOnce(&mut ModelContext<T>) -> T,
369 {
370 self.update(|cx| cx.add_model(build_model))
371 }
372
373 pub fn add_window<T, F>(
374 &mut self,
375 window_options: WindowOptions,
376 build_root_view: F,
377 ) -> (usize, ViewHandle<T>)
378 where
379 T: View,
380 F: FnOnce(&mut ViewContext<T>) -> T,
381 {
382 self.update(|cx| cx.add_window(window_options, build_root_view))
383 }
384
385 pub fn remove_window(&mut self, window_id: usize) {
386 self.update(|cx| cx.remove_window(window_id))
387 }
388
389 pub fn activate_window(&mut self, window_id: usize) {
390 self.update_window(window_id, |cx| cx.activate_window());
391 }
392
393 // TODO: Can we eliminate this method and move it to WindowContext then call it with update_window?s
394 pub fn prompt(
395 &mut self,
396 window_id: usize,
397 level: PromptLevel,
398 msg: &str,
399 answers: &[&str],
400 ) -> Option<oneshot::Receiver<usize>> {
401 self.update_window(window_id, |cx| cx.prompt(level, msg, answers))
402 }
403
404 pub fn platform(&self) -> Arc<dyn Platform> {
405 self.0.borrow().platform().clone()
406 }
407
408 pub fn foreground(&self) -> Rc<executor::Foreground> {
409 self.0.borrow().foreground.clone()
410 }
411
412 pub fn background(&self) -> Arc<executor::Background> {
413 self.0.borrow().background.clone()
414 }
415}
416
417impl UpdateModel for AsyncAppContext {
418 fn update_model<E: Entity, O>(
419 &mut self,
420 handle: &ModelHandle<E>,
421 update: &mut dyn FnMut(&mut E, &mut ModelContext<E>) -> O,
422 ) -> O {
423 self.0.borrow_mut().update_model(handle, update)
424 }
425}
426
427impl UpgradeModelHandle for AsyncAppContext {
428 fn upgrade_model_handle<T: Entity>(
429 &self,
430 handle: &WeakModelHandle<T>,
431 ) -> Option<ModelHandle<T>> {
432 self.0.borrow().upgrade_model_handle(handle)
433 }
434
435 fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
436 self.0.borrow().model_handle_is_upgradable(handle)
437 }
438
439 fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
440 self.0.borrow().upgrade_any_model_handle(handle)
441 }
442}
443
444impl UpgradeViewHandle for AsyncAppContext {
445 fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
446 self.0.borrow_mut().upgrade_view_handle(handle)
447 }
448
449 fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
450 self.0.borrow_mut().upgrade_any_view_handle(handle)
451 }
452}
453
454impl ReadModelWith for AsyncAppContext {
455 fn read_model_with<E: Entity, T>(
456 &self,
457 handle: &ModelHandle<E>,
458 read: &mut dyn FnMut(&E, &AppContext) -> T,
459 ) -> T {
460 let cx = self.0.borrow();
461 let cx = &*cx;
462 read(handle.read(cx), cx)
463 }
464}
465
466impl UpdateView for AsyncAppContext {
467 type Output<S> = Result<S>;
468
469 fn update_view<T, S>(
470 &mut self,
471 handle: &ViewHandle<T>,
472 update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
473 ) -> Result<S>
474 where
475 T: View,
476 {
477 self.0
478 .borrow_mut()
479 .update_window(handle.window_id, |cx| cx.update_view(handle, update))
480 .ok_or_else(|| anyhow!("window was closed"))
481 }
482}
483
484impl ReadViewWith for AsyncAppContext {
485 fn read_view_with<V, T>(
486 &self,
487 handle: &ViewHandle<V>,
488 read: &mut dyn FnMut(&V, &AppContext) -> T,
489 ) -> T
490 where
491 V: View,
492 {
493 let cx = self.0.borrow();
494 let cx = &*cx;
495 read(handle.read(cx), cx)
496 }
497}
498
499type ActionCallback = dyn FnMut(&mut dyn AnyView, &dyn Action, &mut WindowContext, usize);
500type GlobalActionCallback = dyn FnMut(&dyn Action, &mut AppContext);
501
502type SubscriptionCallback = Box<dyn FnMut(&dyn Any, &mut AppContext) -> bool>;
503type GlobalSubscriptionCallback = Box<dyn FnMut(&dyn Any, &mut AppContext)>;
504type ObservationCallback = Box<dyn FnMut(&mut AppContext) -> bool>;
505type GlobalObservationCallback = Box<dyn FnMut(&mut AppContext)>;
506type FocusObservationCallback = Box<dyn FnMut(bool, &mut WindowContext) -> bool>;
507type ReleaseObservationCallback = Box<dyn FnMut(&dyn Any, &mut AppContext)>;
508type ActionObservationCallback = Box<dyn FnMut(TypeId, &mut AppContext)>;
509type WindowActivationCallback = Box<dyn FnMut(bool, &mut WindowContext) -> bool>;
510type WindowFullscreenCallback = Box<dyn FnMut(bool, &mut WindowContext) -> bool>;
511type WindowBoundsCallback = Box<dyn FnMut(WindowBounds, Uuid, &mut WindowContext) -> bool>;
512type KeystrokeCallback =
513 Box<dyn FnMut(&Keystroke, &MatchResult, Option<&Box<dyn Action>>, &mut WindowContext) -> bool>;
514type ActiveLabeledTasksCallback = Box<dyn FnMut(&mut AppContext) -> bool>;
515type DeserializeActionCallback = fn(json: &str) -> anyhow::Result<Box<dyn Action>>;
516type WindowShouldCloseSubscriptionCallback = Box<dyn FnMut(&mut AppContext) -> bool>;
517
518pub struct AppContext {
519 models: HashMap<usize, Box<dyn AnyModel>>,
520 views: HashMap<(usize, usize), Box<dyn AnyView>>,
521 pub(crate) parents: HashMap<(usize, usize), ParentId>,
522 windows: HashMap<usize, Window>,
523 globals: HashMap<TypeId, Box<dyn Any>>,
524 element_states: HashMap<ElementStateId, Box<dyn Any>>,
525 background: Arc<executor::Background>,
526 ref_counts: Arc<Mutex<RefCounts>>,
527
528 weak_self: Option<rc::Weak<RefCell<Self>>>,
529 platform: Arc<dyn Platform>,
530 foreground_platform: Rc<dyn platform::ForegroundPlatform>,
531 pub asset_cache: Arc<AssetCache>,
532 font_system: Arc<dyn FontSystem>,
533 pub font_cache: Arc<FontCache>,
534 action_deserializers: HashMap<&'static str, (TypeId, DeserializeActionCallback)>,
535 capture_actions: HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>>,
536 // Entity Types -> { Action Types -> Action Handlers }
537 actions: HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>>,
538 // Action Types -> Action Handlers
539 global_actions: HashMap<TypeId, Box<GlobalActionCallback>>,
540 keystroke_matcher: KeymapMatcher,
541 next_entity_id: usize,
542 next_window_id: usize,
543 next_subscription_id: usize,
544 frame_count: usize,
545
546 subscriptions: CallbackCollection<usize, SubscriptionCallback>,
547 global_subscriptions: CallbackCollection<TypeId, GlobalSubscriptionCallback>,
548 observations: CallbackCollection<usize, ObservationCallback>,
549 global_observations: CallbackCollection<TypeId, GlobalObservationCallback>,
550 focus_observations: CallbackCollection<usize, FocusObservationCallback>,
551 release_observations: CallbackCollection<usize, ReleaseObservationCallback>,
552 action_dispatch_observations: CallbackCollection<(), ActionObservationCallback>,
553 window_activation_observations: CallbackCollection<usize, WindowActivationCallback>,
554 window_fullscreen_observations: CallbackCollection<usize, WindowFullscreenCallback>,
555 window_bounds_observations: CallbackCollection<usize, WindowBoundsCallback>,
556 keystroke_observations: CallbackCollection<usize, KeystrokeCallback>,
557 active_labeled_task_observations: CallbackCollection<(), ActiveLabeledTasksCallback>,
558
559 foreground: Rc<executor::Foreground>,
560 pending_effects: VecDeque<Effect>,
561 pending_notifications: HashSet<usize>,
562 pending_global_notifications: HashSet<TypeId>,
563 pending_flushes: usize,
564 flushing_effects: bool,
565 halt_action_dispatch: bool,
566 next_labeled_task_id: usize,
567 active_labeled_tasks: BTreeMap<usize, &'static str>,
568}
569
570impl AppContext {
571 fn new(
572 foreground: Rc<executor::Foreground>,
573 background: Arc<executor::Background>,
574 platform: Arc<dyn platform::Platform>,
575 foreground_platform: Rc<dyn platform::ForegroundPlatform>,
576 font_cache: Arc<FontCache>,
577 ref_counts: RefCounts,
578 asset_source: impl AssetSource,
579 ) -> Self {
580 Self {
581 models: Default::default(),
582 views: Default::default(),
583 parents: Default::default(),
584 windows: Default::default(),
585 globals: Default::default(),
586 element_states: Default::default(),
587 ref_counts: Arc::new(Mutex::new(ref_counts)),
588 background,
589
590 weak_self: None,
591 font_system: platform.fonts(),
592 platform,
593 foreground_platform,
594 font_cache,
595 asset_cache: Arc::new(AssetCache::new(asset_source)),
596 action_deserializers: Default::default(),
597 capture_actions: Default::default(),
598 actions: Default::default(),
599 global_actions: Default::default(),
600 keystroke_matcher: KeymapMatcher::default(),
601 next_entity_id: 0,
602 next_window_id: 0,
603 next_subscription_id: 0,
604 frame_count: 0,
605 subscriptions: Default::default(),
606 global_subscriptions: Default::default(),
607 observations: Default::default(),
608 focus_observations: Default::default(),
609 release_observations: Default::default(),
610 global_observations: Default::default(),
611 window_activation_observations: Default::default(),
612 window_fullscreen_observations: Default::default(),
613 window_bounds_observations: Default::default(),
614 keystroke_observations: Default::default(),
615 action_dispatch_observations: Default::default(),
616 active_labeled_task_observations: Default::default(),
617 foreground,
618 pending_effects: VecDeque::new(),
619 pending_notifications: Default::default(),
620 pending_global_notifications: Default::default(),
621 pending_flushes: 0,
622 flushing_effects: false,
623 halt_action_dispatch: false,
624 next_labeled_task_id: 0,
625 active_labeled_tasks: Default::default(),
626 }
627 }
628
629 pub fn background(&self) -> &Arc<executor::Background> {
630 &self.background
631 }
632
633 pub fn font_cache(&self) -> &Arc<FontCache> {
634 &self.font_cache
635 }
636
637 pub fn platform(&self) -> &Arc<dyn Platform> {
638 &self.platform
639 }
640
641 pub fn has_global<T: 'static>(&self) -> bool {
642 self.globals.contains_key(&TypeId::of::<T>())
643 }
644
645 pub fn global<T: 'static>(&self) -> &T {
646 if let Some(global) = self.globals.get(&TypeId::of::<T>()) {
647 global.downcast_ref().unwrap()
648 } else {
649 panic!("no global has been added for {}", type_name::<T>());
650 }
651 }
652
653 pub fn upgrade(&self) -> App {
654 App(self.weak_self.as_ref().unwrap().upgrade().unwrap())
655 }
656
657 pub fn quit(&mut self) {
658 let mut futures = Vec::new();
659
660 self.update(|cx| {
661 for model_id in cx.models.keys().copied().collect::<Vec<_>>() {
662 let mut model = cx.models.remove(&model_id).unwrap();
663 futures.extend(model.app_will_quit(cx));
664 cx.models.insert(model_id, model);
665 }
666
667 for view_id in cx.views.keys().copied().collect::<Vec<_>>() {
668 let mut view = cx.views.remove(&view_id).unwrap();
669 futures.extend(view.app_will_quit(cx));
670 cx.views.insert(view_id, view);
671 }
672 });
673
674 self.remove_all_windows();
675
676 let futures = futures::future::join_all(futures);
677 if self
678 .background
679 .block_with_timeout(Duration::from_millis(100), futures)
680 .is_err()
681 {
682 log::error!("timed out waiting on app_will_quit");
683 }
684 }
685
686 pub fn remove_all_windows(&mut self) {
687 self.windows.clear();
688 self.flush_effects();
689 }
690
691 pub fn foreground(&self) -> &Rc<executor::Foreground> {
692 &self.foreground
693 }
694
695 pub fn deserialize_action(
696 &self,
697 name: &str,
698 argument: Option<&str>,
699 ) -> Result<Box<dyn Action>> {
700 let callback = self
701 .action_deserializers
702 .get(name)
703 .ok_or_else(|| anyhow!("unknown action {}", name))?
704 .1;
705 callback(argument.unwrap_or("{}"))
706 .with_context(|| format!("invalid data for action {}", name))
707 }
708
709 pub fn add_action<A, V, F, R>(&mut self, handler: F)
710 where
711 A: Action,
712 V: View,
713 F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>) -> R,
714 {
715 self.add_action_internal(handler, false)
716 }
717
718 pub fn capture_action<A, V, F>(&mut self, handler: F)
719 where
720 A: Action,
721 V: View,
722 F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>),
723 {
724 self.add_action_internal(handler, true)
725 }
726
727 fn add_action_internal<A, V, F, R>(&mut self, mut handler: F, capture: bool)
728 where
729 A: Action,
730 V: View,
731 F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>) -> R,
732 {
733 let handler = Box::new(
734 move |view: &mut dyn AnyView,
735 action: &dyn Action,
736 cx: &mut WindowContext,
737 view_id: usize| {
738 let action = action.as_any().downcast_ref().unwrap();
739 let mut cx = ViewContext::mutable(cx, view_id);
740 handler(
741 view.as_any_mut()
742 .downcast_mut()
743 .expect("downcast is type safe"),
744 action,
745 &mut cx,
746 );
747 },
748 );
749
750 self.action_deserializers
751 .entry(A::qualified_name())
752 .or_insert((TypeId::of::<A>(), A::from_json_str));
753
754 let actions = if capture {
755 &mut self.capture_actions
756 } else {
757 &mut self.actions
758 };
759
760 actions
761 .entry(TypeId::of::<V>())
762 .or_default()
763 .entry(TypeId::of::<A>())
764 .or_default()
765 .push(handler);
766 }
767
768 pub fn add_async_action<A, V, F>(&mut self, mut handler: F)
769 where
770 A: Action,
771 V: View,
772 F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>) -> Option<Task<Result<()>>>,
773 {
774 self.add_action(move |view, action, cx| {
775 if let Some(task) = handler(view, action, cx) {
776 task.detach_and_log_err(cx);
777 }
778 })
779 }
780
781 pub fn add_global_action<A, F>(&mut self, mut handler: F)
782 where
783 A: Action,
784 F: 'static + FnMut(&A, &mut AppContext),
785 {
786 let handler = Box::new(move |action: &dyn Action, cx: &mut AppContext| {
787 let action = action.as_any().downcast_ref().unwrap();
788 handler(action, cx);
789 });
790
791 self.action_deserializers
792 .entry(A::qualified_name())
793 .or_insert((TypeId::of::<A>(), A::from_json_str));
794
795 if self
796 .global_actions
797 .insert(TypeId::of::<A>(), handler)
798 .is_some()
799 {
800 panic!(
801 "registered multiple global handlers for {}",
802 type_name::<A>()
803 );
804 }
805 }
806
807 pub fn has_window(&self, window_id: usize) -> bool {
808 self.window_ids()
809 .find(|window| window == &window_id)
810 .is_some()
811 }
812
813 pub fn window_is_active(&self, window_id: usize) -> bool {
814 self.windows.get(&window_id).map_or(false, |w| w.is_active)
815 }
816
817 pub fn root_view(&self, window_id: usize) -> Option<&AnyViewHandle> {
818 self.windows.get(&window_id).map(|w| w.root_view())
819 }
820
821 pub fn window_ids(&self) -> impl Iterator<Item = usize> + '_ {
822 self.windows.keys().copied()
823 }
824
825 pub fn view_ui_name(&self, window_id: usize, view_id: usize) -> Option<&'static str> {
826 Some(self.views.get(&(window_id, view_id))?.ui_name())
827 }
828
829 pub fn view_type_id(&self, window_id: usize, view_id: usize) -> Option<TypeId> {
830 self.views
831 .get(&(window_id, view_id))
832 .map(|view| view.as_any().type_id())
833 }
834
835 pub fn active_labeled_tasks<'a>(
836 &'a self,
837 ) -> impl DoubleEndedIterator<Item = &'static str> + 'a {
838 self.active_labeled_tasks.values().cloned()
839 }
840
841 pub(crate) fn start_frame(&mut self) {
842 self.frame_count += 1;
843 }
844
845 pub fn update<T, F: FnOnce(&mut Self) -> T>(&mut self, callback: F) -> T {
846 self.pending_flushes += 1;
847 let result = callback(self);
848 self.flush_effects();
849 result
850 }
851
852 pub fn read_window<T, F: FnOnce(&WindowContext) -> T>(
853 &self,
854 window_id: usize,
855 callback: F,
856 ) -> Option<T> {
857 let window = self.windows.get(&window_id)?;
858 let window_context = WindowContext::immutable(self, &window, window_id);
859 Some(callback(&window_context))
860 }
861
862 pub fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
863 &mut self,
864 window_id: usize,
865 callback: F,
866 ) -> Option<T> {
867 self.update(|app_context| {
868 let mut window = app_context.windows.remove(&window_id)?;
869 let mut window_context = WindowContext::mutable(app_context, &mut window, window_id);
870 let result = callback(&mut window_context);
871 app_context.windows.insert(window_id, window);
872 Some(result)
873 })
874 }
875
876 pub fn update_active_window<T, F: FnOnce(&mut WindowContext) -> T>(
877 &mut self,
878 callback: F,
879 ) -> Option<T> {
880 self.platform
881 .main_window_id()
882 .and_then(|id| self.update_window(id, callback))
883 }
884
885 pub fn prompt_for_paths(
886 &self,
887 options: PathPromptOptions,
888 ) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
889 self.foreground_platform.prompt_for_paths(options)
890 }
891
892 pub fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
893 self.foreground_platform.prompt_for_new_path(directory)
894 }
895
896 pub fn reveal_path(&self, path: &Path) {
897 self.foreground_platform.reveal_path(path)
898 }
899
900 pub fn emit_global<E: Any>(&mut self, payload: E) {
901 self.pending_effects.push_back(Effect::GlobalEvent {
902 payload: Box::new(payload),
903 });
904 }
905
906 pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
907 where
908 E: Entity,
909 E::Event: 'static,
910 H: Handle<E>,
911 F: 'static + FnMut(H, &E::Event, &mut Self),
912 {
913 self.subscribe_internal(handle, move |handle, event, cx| {
914 callback(handle, event, cx);
915 true
916 })
917 }
918
919 pub fn subscribe_global<E, F>(&mut self, mut callback: F) -> Subscription
920 where
921 E: Any,
922 F: 'static + FnMut(&E, &mut Self),
923 {
924 let subscription_id = post_inc(&mut self.next_subscription_id);
925 let type_id = TypeId::of::<E>();
926 self.pending_effects.push_back(Effect::GlobalSubscription {
927 type_id,
928 subscription_id,
929 callback: Box::new(move |payload, cx| {
930 let payload = payload.downcast_ref().expect("downcast is type safe");
931 callback(payload, cx)
932 }),
933 });
934 Subscription::GlobalSubscription(
935 self.global_subscriptions
936 .subscribe(type_id, subscription_id),
937 )
938 }
939
940 pub fn observe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
941 where
942 E: Entity,
943 E::Event: 'static,
944 H: Handle<E>,
945 F: 'static + FnMut(H, &mut Self),
946 {
947 self.observe_internal(handle, move |handle, cx| {
948 callback(handle, cx);
949 true
950 })
951 }
952
953 fn subscribe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
954 where
955 E: Entity,
956 E::Event: 'static,
957 H: Handle<E>,
958 F: 'static + FnMut(H, &E::Event, &mut Self) -> bool,
959 {
960 let subscription_id = post_inc(&mut self.next_subscription_id);
961 let emitter = handle.downgrade();
962 self.pending_effects.push_back(Effect::Subscription {
963 entity_id: handle.id(),
964 subscription_id,
965 callback: Box::new(move |payload, cx| {
966 if let Some(emitter) = H::upgrade_from(&emitter, cx) {
967 let payload = payload.downcast_ref().expect("downcast is type safe");
968 callback(emitter, payload, cx)
969 } else {
970 false
971 }
972 }),
973 });
974 Subscription::Subscription(self.subscriptions.subscribe(handle.id(), subscription_id))
975 }
976
977 fn observe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
978 where
979 E: Entity,
980 E::Event: 'static,
981 H: Handle<E>,
982 F: 'static + FnMut(H, &mut Self) -> bool,
983 {
984 let subscription_id = post_inc(&mut self.next_subscription_id);
985 let observed = handle.downgrade();
986 let entity_id = handle.id();
987 self.pending_effects.push_back(Effect::Observation {
988 entity_id,
989 subscription_id,
990 callback: Box::new(move |cx| {
991 if let Some(observed) = H::upgrade_from(&observed, cx) {
992 callback(observed, cx)
993 } else {
994 false
995 }
996 }),
997 });
998 Subscription::Observation(self.observations.subscribe(entity_id, subscription_id))
999 }
1000
1001 fn observe_focus<F, V>(&mut self, handle: &ViewHandle<V>, mut callback: F) -> Subscription
1002 where
1003 F: 'static + FnMut(ViewHandle<V>, bool, &mut WindowContext) -> bool,
1004 V: View,
1005 {
1006 let subscription_id = post_inc(&mut self.next_subscription_id);
1007 let observed = handle.downgrade();
1008 let view_id = handle.id();
1009
1010 self.pending_effects.push_back(Effect::FocusObservation {
1011 view_id,
1012 subscription_id,
1013 callback: Box::new(move |focused, cx| {
1014 if let Some(observed) = observed.upgrade(cx) {
1015 callback(observed, focused, cx)
1016 } else {
1017 false
1018 }
1019 }),
1020 });
1021 Subscription::FocusObservation(self.focus_observations.subscribe(view_id, subscription_id))
1022 }
1023
1024 pub fn observe_global<G, F>(&mut self, mut observe: F) -> Subscription
1025 where
1026 G: Any,
1027 F: 'static + FnMut(&mut AppContext),
1028 {
1029 let type_id = TypeId::of::<G>();
1030 let id = post_inc(&mut self.next_subscription_id);
1031
1032 self.global_observations.add_callback(
1033 type_id,
1034 id,
1035 Box::new(move |cx: &mut AppContext| observe(cx)),
1036 );
1037 Subscription::GlobalObservation(self.global_observations.subscribe(type_id, id))
1038 }
1039
1040 pub fn observe_default_global<G, F>(&mut self, observe: F) -> Subscription
1041 where
1042 G: Any + Default,
1043 F: 'static + FnMut(&mut AppContext),
1044 {
1045 if !self.has_global::<G>() {
1046 self.set_global(G::default());
1047 }
1048 self.observe_global::<G, F>(observe)
1049 }
1050
1051 pub fn observe_release<E, H, F>(&mut self, handle: &H, callback: F) -> Subscription
1052 where
1053 E: Entity,
1054 E::Event: 'static,
1055 H: Handle<E>,
1056 F: 'static + FnOnce(&E, &mut Self),
1057 {
1058 let id = post_inc(&mut self.next_subscription_id);
1059 let mut callback = Some(callback);
1060 self.release_observations.add_callback(
1061 handle.id(),
1062 id,
1063 Box::new(move |released, cx| {
1064 let released = released.downcast_ref().unwrap();
1065 if let Some(callback) = callback.take() {
1066 callback(released, cx)
1067 }
1068 }),
1069 );
1070 Subscription::ReleaseObservation(self.release_observations.subscribe(handle.id(), id))
1071 }
1072
1073 pub fn observe_actions<F>(&mut self, callback: F) -> Subscription
1074 where
1075 F: 'static + FnMut(TypeId, &mut AppContext),
1076 {
1077 let subscription_id = post_inc(&mut self.next_subscription_id);
1078 self.action_dispatch_observations
1079 .add_callback((), subscription_id, Box::new(callback));
1080 Subscription::ActionObservation(
1081 self.action_dispatch_observations
1082 .subscribe((), subscription_id),
1083 )
1084 }
1085
1086 fn observe_active_labeled_tasks<F>(&mut self, callback: F) -> Subscription
1087 where
1088 F: 'static + FnMut(&mut AppContext) -> bool,
1089 {
1090 let subscription_id = post_inc(&mut self.next_subscription_id);
1091 self.active_labeled_task_observations
1092 .add_callback((), subscription_id, Box::new(callback));
1093 Subscription::ActiveLabeledTasksObservation(
1094 self.active_labeled_task_observations
1095 .subscribe((), subscription_id),
1096 )
1097 }
1098
1099 pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut AppContext)) {
1100 self.pending_effects.push_back(Effect::Deferred {
1101 callback: Box::new(callback),
1102 after_window_update: false,
1103 })
1104 }
1105
1106 pub fn after_window_update(&mut self, callback: impl 'static + FnOnce(&mut AppContext)) {
1107 self.pending_effects.push_back(Effect::Deferred {
1108 callback: Box::new(callback),
1109 after_window_update: true,
1110 })
1111 }
1112
1113 pub(crate) fn notify_model(&mut self, model_id: usize) {
1114 if self.pending_notifications.insert(model_id) {
1115 self.pending_effects
1116 .push_back(Effect::ModelNotification { model_id });
1117 }
1118 }
1119
1120 pub(crate) fn notify_view(&mut self, window_id: usize, view_id: usize) {
1121 if self.pending_notifications.insert(view_id) {
1122 self.pending_effects
1123 .push_back(Effect::ViewNotification { window_id, view_id });
1124 }
1125 }
1126
1127 pub(crate) fn notify_global(&mut self, type_id: TypeId) {
1128 if self.pending_global_notifications.insert(type_id) {
1129 self.pending_effects
1130 .push_back(Effect::GlobalNotification { type_id });
1131 }
1132 }
1133
1134 pub fn all_action_names<'a>(&'a self) -> impl Iterator<Item = &'static str> + 'a {
1135 self.action_deserializers.keys().copied()
1136 }
1137
1138 pub fn is_action_available(&self, action: &dyn Action) -> bool {
1139 let mut available_in_window = false;
1140 let action_type = action.as_any().type_id();
1141 if let Some(window_id) = self.platform.main_window_id() {
1142 available_in_window = self
1143 .read_window(window_id, |cx| {
1144 if let Some(focused_view_id) = cx.focused_view_id() {
1145 for view_id in cx.ancestors(focused_view_id) {
1146 if let Some(view) = cx.views.get(&(window_id, view_id)) {
1147 let view_type = view.as_any().type_id();
1148 if let Some(actions) = cx.actions.get(&view_type) {
1149 if actions.contains_key(&action_type) {
1150 return true;
1151 }
1152 }
1153 }
1154 }
1155 }
1156 false
1157 })
1158 .unwrap_or(false);
1159 }
1160 available_in_window || self.global_actions.contains_key(&action_type)
1161 }
1162
1163 fn actions_mut(
1164 &mut self,
1165 capture_phase: bool,
1166 ) -> &mut HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>> {
1167 if capture_phase {
1168 &mut self.capture_actions
1169 } else {
1170 &mut self.actions
1171 }
1172 }
1173
1174 pub fn dispatch_global_action<A: Action>(&mut self, action: A) {
1175 self.dispatch_global_action_any(&action);
1176 }
1177
1178 fn dispatch_global_action_any(&mut self, action: &dyn Action) -> bool {
1179 self.update(|this| {
1180 if let Some((name, mut handler)) = this.global_actions.remove_entry(&action.id()) {
1181 handler(action, this);
1182 this.global_actions.insert(name, handler);
1183 true
1184 } else {
1185 false
1186 }
1187 })
1188 }
1189
1190 pub fn add_bindings<T: IntoIterator<Item = Binding>>(&mut self, bindings: T) {
1191 self.keystroke_matcher.add_bindings(bindings);
1192 }
1193
1194 pub fn clear_bindings(&mut self) {
1195 self.keystroke_matcher.clear_bindings();
1196 }
1197
1198 pub fn default_global<T: 'static + Default>(&mut self) -> &T {
1199 let type_id = TypeId::of::<T>();
1200 self.update(|this| {
1201 if let Entry::Vacant(entry) = this.globals.entry(type_id) {
1202 entry.insert(Box::new(T::default()));
1203 this.notify_global(type_id);
1204 }
1205 });
1206 self.globals.get(&type_id).unwrap().downcast_ref().unwrap()
1207 }
1208
1209 pub fn set_global<T: 'static>(&mut self, state: T) {
1210 self.update(|this| {
1211 let type_id = TypeId::of::<T>();
1212 this.globals.insert(type_id, Box::new(state));
1213 this.notify_global(type_id);
1214 });
1215 }
1216
1217 pub fn update_default_global<T, F, U>(&mut self, update: F) -> U
1218 where
1219 T: 'static + Default,
1220 F: FnOnce(&mut T, &mut AppContext) -> U,
1221 {
1222 self.update(|mut this| {
1223 Self::update_default_global_internal(&mut this, |global, cx| update(global, cx))
1224 })
1225 }
1226
1227 fn update_default_global_internal<C, T, F, U>(this: &mut C, update: F) -> U
1228 where
1229 C: DerefMut<Target = AppContext>,
1230 T: 'static + Default,
1231 F: FnOnce(&mut T, &mut C) -> U,
1232 {
1233 let type_id = TypeId::of::<T>();
1234 let mut state = this
1235 .globals
1236 .remove(&type_id)
1237 .unwrap_or_else(|| Box::new(T::default()));
1238 let result = update(state.downcast_mut().unwrap(), this);
1239 this.globals.insert(type_id, state);
1240 this.notify_global(type_id);
1241 result
1242 }
1243
1244 pub fn update_global<T, F, U>(&mut self, update: F) -> U
1245 where
1246 T: 'static,
1247 F: FnOnce(&mut T, &mut AppContext) -> U,
1248 {
1249 self.update(|mut this| {
1250 Self::update_global_internal(&mut this, |global, cx| update(global, cx))
1251 })
1252 }
1253
1254 fn update_global_internal<C, T, F, U>(this: &mut C, update: F) -> U
1255 where
1256 C: DerefMut<Target = AppContext>,
1257 T: 'static,
1258 F: FnOnce(&mut T, &mut C) -> U,
1259 {
1260 let type_id = TypeId::of::<T>();
1261 if let Some(mut state) = this.globals.remove(&type_id) {
1262 let result = update(state.downcast_mut().unwrap(), this);
1263 this.globals.insert(type_id, state);
1264 this.notify_global(type_id);
1265 result
1266 } else {
1267 panic!("No global added for {}", std::any::type_name::<T>());
1268 }
1269 }
1270
1271 pub fn clear_globals(&mut self) {
1272 self.globals.clear();
1273 }
1274
1275 pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
1276 where
1277 T: Entity,
1278 F: FnOnce(&mut ModelContext<T>) -> T,
1279 {
1280 self.update(|this| {
1281 let model_id = post_inc(&mut this.next_entity_id);
1282 let handle = ModelHandle::new(model_id, &this.ref_counts);
1283 let mut cx = ModelContext::new(this, model_id);
1284 let model = build_model(&mut cx);
1285 this.models.insert(model_id, Box::new(model));
1286 handle
1287 })
1288 }
1289
1290 pub fn add_window<V, F>(
1291 &mut self,
1292 window_options: WindowOptions,
1293 build_root_view: F,
1294 ) -> (usize, ViewHandle<V>)
1295 where
1296 V: View,
1297 F: FnOnce(&mut ViewContext<V>) -> V,
1298 {
1299 self.update(|this| {
1300 let window_id = post_inc(&mut this.next_window_id);
1301 let platform_window =
1302 this.platform
1303 .open_window(window_id, window_options, this.foreground.clone());
1304 let window = this.build_window(window_id, platform_window, build_root_view);
1305 let root_view = window.root_view().clone().downcast::<V>().unwrap();
1306 this.windows.insert(window_id, window);
1307 (window_id, root_view)
1308 })
1309 }
1310
1311 pub fn add_status_bar_item<V, F>(&mut self, build_root_view: F) -> (usize, ViewHandle<V>)
1312 where
1313 V: View,
1314 F: FnOnce(&mut ViewContext<V>) -> V,
1315 {
1316 self.update(|this| {
1317 let window_id = post_inc(&mut this.next_window_id);
1318 let platform_window = this.platform.add_status_item(window_id);
1319 let window = this.build_window(window_id, platform_window, build_root_view);
1320 let root_view = window.root_view().clone().downcast::<V>().unwrap();
1321
1322 this.windows.insert(window_id, window);
1323 this.update_window(window_id, |cx| {
1324 root_view.update(cx, |view, cx| view.focus_in(cx.handle().into_any(), cx))
1325 });
1326
1327 (window_id, root_view)
1328 })
1329 }
1330
1331 pub fn remove_status_bar_item(&mut self, id: usize) {
1332 self.remove_window(id);
1333 }
1334
1335 pub fn remove_window(&mut self, window_id: usize) {
1336 self.windows.remove(&window_id);
1337 self.flush_effects();
1338 }
1339
1340 pub fn build_window<V, F>(
1341 &mut self,
1342 window_id: usize,
1343 mut platform_window: Box<dyn platform::Window>,
1344 build_root_view: F,
1345 ) -> Window
1346 where
1347 V: View,
1348 F: FnOnce(&mut ViewContext<V>) -> V,
1349 {
1350 {
1351 let mut app = self.upgrade();
1352
1353 platform_window.on_event(Box::new(move |event| {
1354 app.update_window(window_id, |cx| {
1355 if let Event::KeyDown(KeyDownEvent { keystroke, .. }) = &event {
1356 if cx.dispatch_keystroke(keystroke) {
1357 return true;
1358 }
1359 }
1360
1361 cx.dispatch_event(event, false)
1362 })
1363 .unwrap_or(false)
1364 }));
1365 }
1366
1367 {
1368 let mut app = self.upgrade();
1369 platform_window.on_active_status_change(Box::new(move |is_active| {
1370 app.update(|cx| cx.window_changed_active_status(window_id, is_active))
1371 }));
1372 }
1373
1374 {
1375 let mut app = self.upgrade();
1376 platform_window.on_resize(Box::new(move || {
1377 app.update(|cx| cx.window_was_resized(window_id))
1378 }));
1379 }
1380
1381 {
1382 let mut app = self.upgrade();
1383 platform_window.on_moved(Box::new(move || {
1384 app.update(|cx| cx.window_was_moved(window_id))
1385 }));
1386 }
1387
1388 {
1389 let mut app = self.upgrade();
1390 platform_window.on_fullscreen(Box::new(move |is_fullscreen| {
1391 app.update(|cx| cx.window_was_fullscreen_changed(window_id, is_fullscreen))
1392 }));
1393 }
1394
1395 {
1396 let mut app = self.upgrade();
1397 platform_window.on_close(Box::new(move || {
1398 app.update(|cx| cx.remove_window(window_id));
1399 }));
1400 }
1401
1402 {
1403 let mut app = self.upgrade();
1404 platform_window
1405 .on_appearance_changed(Box::new(move || app.update(|cx| cx.refresh_windows())));
1406 }
1407
1408 platform_window.set_input_handler(Box::new(WindowInputHandler {
1409 app: self.upgrade().0,
1410 window_id,
1411 }));
1412
1413 let mut window = Window::new(window_id, platform_window, self, build_root_view);
1414 let scene = WindowContext::mutable(self, &mut window, window_id)
1415 .build_scene()
1416 .expect("initial scene should not error");
1417 window.platform_window.present_scene(scene);
1418 window
1419 }
1420
1421 pub fn replace_root_view<V, F>(
1422 &mut self,
1423 window_id: usize,
1424 build_root_view: F,
1425 ) -> Option<ViewHandle<V>>
1426 where
1427 V: View,
1428 F: FnOnce(&mut ViewContext<V>) -> V,
1429 {
1430 self.update_window(window_id, |cx| cx.replace_root_view(build_root_view))
1431 }
1432
1433 pub fn add_view<S, F>(&mut self, parent: &AnyViewHandle, build_view: F) -> ViewHandle<S>
1434 where
1435 S: View,
1436 F: FnOnce(&mut ViewContext<S>) -> S,
1437 {
1438 self.update_window(parent.window_id, |cx| {
1439 cx.build_and_insert_view(ParentId::View(parent.view_id), |cx| Some(build_view(cx)))
1440 .unwrap()
1441 })
1442 .unwrap()
1443 }
1444
1445 fn remove_dropped_entities(&mut self) {
1446 loop {
1447 let (dropped_models, dropped_views, dropped_element_states) =
1448 self.ref_counts.lock().take_dropped();
1449 if dropped_models.is_empty()
1450 && dropped_views.is_empty()
1451 && dropped_element_states.is_empty()
1452 {
1453 break;
1454 }
1455
1456 for model_id in dropped_models {
1457 self.subscriptions.remove(model_id);
1458 self.observations.remove(model_id);
1459 let mut model = self.models.remove(&model_id).unwrap();
1460 model.release(self);
1461 self.pending_effects
1462 .push_back(Effect::ModelRelease { model_id, model });
1463 }
1464
1465 for (window_id, view_id) in dropped_views {
1466 self.subscriptions.remove(view_id);
1467 self.observations.remove(view_id);
1468 let mut view = self.views.remove(&(window_id, view_id)).unwrap();
1469 view.release(self);
1470 let change_focus_to = self.windows.get_mut(&window_id).and_then(|window| {
1471 window
1472 .invalidation
1473 .get_or_insert_with(Default::default)
1474 .removed
1475 .push(view_id);
1476 if window.focused_view_id == Some(view_id) {
1477 Some(window.root_view().id())
1478 } else {
1479 None
1480 }
1481 });
1482 self.parents.remove(&(window_id, view_id));
1483
1484 if let Some(view_id) = change_focus_to {
1485 self.handle_focus_effect(window_id, Some(view_id));
1486 }
1487
1488 self.pending_effects
1489 .push_back(Effect::ViewRelease { view_id, view });
1490 }
1491
1492 for key in dropped_element_states {
1493 self.element_states.remove(&key);
1494 }
1495 }
1496 }
1497
1498 fn flush_effects(&mut self) {
1499 self.pending_flushes = self.pending_flushes.saturating_sub(1);
1500 let mut after_window_update_callbacks = Vec::new();
1501
1502 if !self.flushing_effects && self.pending_flushes == 0 {
1503 self.flushing_effects = true;
1504
1505 let mut refreshing = false;
1506 loop {
1507 if let Some(effect) = self.pending_effects.pop_front() {
1508 match effect {
1509 Effect::Subscription {
1510 entity_id,
1511 subscription_id,
1512 callback,
1513 } => self
1514 .subscriptions
1515 .add_callback(entity_id, subscription_id, callback),
1516
1517 Effect::Event { entity_id, payload } => {
1518 let mut subscriptions = self.subscriptions.clone();
1519 subscriptions
1520 .emit(entity_id, |callback| callback(payload.as_ref(), self))
1521 }
1522
1523 Effect::GlobalSubscription {
1524 type_id,
1525 subscription_id,
1526 callback,
1527 } => self.global_subscriptions.add_callback(
1528 type_id,
1529 subscription_id,
1530 callback,
1531 ),
1532
1533 Effect::GlobalEvent { payload } => self.emit_global_event(payload),
1534
1535 Effect::Observation {
1536 entity_id,
1537 subscription_id,
1538 callback,
1539 } => self
1540 .observations
1541 .add_callback(entity_id, subscription_id, callback),
1542
1543 Effect::ModelNotification { model_id } => {
1544 let mut observations = self.observations.clone();
1545 observations.emit(model_id, |callback| callback(self));
1546 }
1547
1548 Effect::ViewNotification { window_id, view_id } => {
1549 self.handle_view_notification_effect(window_id, view_id)
1550 }
1551
1552 Effect::GlobalNotification { type_id } => {
1553 let mut subscriptions = self.global_observations.clone();
1554 subscriptions.emit(type_id, |callback| {
1555 callback(self);
1556 true
1557 });
1558 }
1559
1560 Effect::Deferred {
1561 callback,
1562 after_window_update,
1563 } => {
1564 if after_window_update {
1565 after_window_update_callbacks.push(callback);
1566 } else {
1567 callback(self)
1568 }
1569 }
1570
1571 Effect::ModelRelease { model_id, model } => {
1572 self.handle_entity_release_effect(model_id, model.as_any())
1573 }
1574
1575 Effect::ViewRelease { view_id, view } => {
1576 self.handle_entity_release_effect(view_id, view.as_any())
1577 }
1578
1579 Effect::Focus { window_id, view_id } => {
1580 self.handle_focus_effect(window_id, view_id);
1581 }
1582
1583 Effect::FocusObservation {
1584 view_id,
1585 subscription_id,
1586 callback,
1587 } => {
1588 self.focus_observations.add_callback(
1589 view_id,
1590 subscription_id,
1591 callback,
1592 );
1593 }
1594
1595 Effect::ResizeWindow { window_id } => {
1596 if let Some(window) = self.windows.get_mut(&window_id) {
1597 window
1598 .invalidation
1599 .get_or_insert(WindowInvalidation::default());
1600 }
1601 self.handle_window_moved(window_id);
1602 }
1603
1604 Effect::MoveWindow { window_id } => {
1605 self.handle_window_moved(window_id);
1606 }
1607
1608 Effect::WindowActivationObservation {
1609 window_id,
1610 subscription_id,
1611 callback,
1612 } => self.window_activation_observations.add_callback(
1613 window_id,
1614 subscription_id,
1615 callback,
1616 ),
1617
1618 Effect::ActivateWindow {
1619 window_id,
1620 is_active,
1621 } => self.handle_window_activation_effect(window_id, is_active),
1622
1623 Effect::WindowFullscreenObservation {
1624 window_id,
1625 subscription_id,
1626 callback,
1627 } => self.window_fullscreen_observations.add_callback(
1628 window_id,
1629 subscription_id,
1630 callback,
1631 ),
1632
1633 Effect::FullscreenWindow {
1634 window_id,
1635 is_fullscreen,
1636 } => self.handle_fullscreen_effect(window_id, is_fullscreen),
1637
1638 Effect::WindowBoundsObservation {
1639 window_id,
1640 subscription_id,
1641 callback,
1642 } => self.window_bounds_observations.add_callback(
1643 window_id,
1644 subscription_id,
1645 callback,
1646 ),
1647
1648 Effect::RefreshWindows => {
1649 refreshing = true;
1650 }
1651 Effect::DispatchActionFrom {
1652 window_id,
1653 view_id,
1654 action,
1655 } => {
1656 self.handle_dispatch_action_from_effect(
1657 window_id,
1658 Some(view_id),
1659 action.as_ref(),
1660 );
1661 }
1662 Effect::ActionDispatchNotification { action_id } => {
1663 self.handle_action_dispatch_notification_effect(action_id)
1664 }
1665 Effect::WindowShouldCloseSubscription {
1666 window_id,
1667 callback,
1668 } => {
1669 self.handle_window_should_close_subscription_effect(window_id, callback)
1670 }
1671 Effect::Keystroke {
1672 window_id,
1673 keystroke,
1674 handled_by,
1675 result,
1676 } => self.handle_keystroke_effect(window_id, keystroke, handled_by, result),
1677 Effect::ActiveLabeledTasksChanged => {
1678 self.handle_active_labeled_tasks_changed_effect()
1679 }
1680 Effect::ActiveLabeledTasksObservation {
1681 subscription_id,
1682 callback,
1683 } => self.active_labeled_task_observations.add_callback(
1684 (),
1685 subscription_id,
1686 callback,
1687 ),
1688 }
1689 self.pending_notifications.clear();
1690 self.remove_dropped_entities();
1691 } else {
1692 self.remove_dropped_entities();
1693
1694 if refreshing {
1695 self.perform_window_refresh();
1696 } else {
1697 self.update_windows();
1698 }
1699
1700 if self.pending_effects.is_empty() {
1701 for callback in after_window_update_callbacks.drain(..) {
1702 callback(self);
1703 }
1704
1705 if self.pending_effects.is_empty() {
1706 self.flushing_effects = false;
1707 self.pending_notifications.clear();
1708 self.pending_global_notifications.clear();
1709 break;
1710 }
1711 }
1712
1713 refreshing = false;
1714 }
1715 }
1716 }
1717 }
1718
1719 fn update_windows(&mut self) {
1720 let window_ids = self.windows.keys().cloned().collect::<Vec<_>>();
1721 for window_id in window_ids {
1722 self.update_window(window_id, |cx| {
1723 if let Some(mut invalidation) = cx.window.invalidation.take() {
1724 let appearance = cx.window.platform_window.appearance();
1725 cx.invalidate(&mut invalidation, appearance);
1726 if let Some(scene) = cx.build_scene().log_err() {
1727 cx.window.platform_window.present_scene(scene);
1728 }
1729 }
1730 });
1731 }
1732 }
1733
1734 fn window_was_resized(&mut self, window_id: usize) {
1735 self.pending_effects
1736 .push_back(Effect::ResizeWindow { window_id });
1737 }
1738
1739 fn window_was_moved(&mut self, window_id: usize) {
1740 self.pending_effects
1741 .push_back(Effect::MoveWindow { window_id });
1742 }
1743
1744 fn window_was_fullscreen_changed(&mut self, window_id: usize, is_fullscreen: bool) {
1745 self.pending_effects.push_back(Effect::FullscreenWindow {
1746 window_id,
1747 is_fullscreen,
1748 });
1749 }
1750
1751 fn window_changed_active_status(&mut self, window_id: usize, is_active: bool) {
1752 self.pending_effects.push_back(Effect::ActivateWindow {
1753 window_id,
1754 is_active,
1755 });
1756 }
1757
1758 fn keystroke(
1759 &mut self,
1760 window_id: usize,
1761 keystroke: Keystroke,
1762 handled_by: Option<Box<dyn Action>>,
1763 result: MatchResult,
1764 ) {
1765 self.pending_effects.push_back(Effect::Keystroke {
1766 window_id,
1767 keystroke,
1768 handled_by,
1769 result,
1770 });
1771 }
1772
1773 pub fn refresh_windows(&mut self) {
1774 self.pending_effects.push_back(Effect::RefreshWindows);
1775 }
1776
1777 pub fn dispatch_action_at(&mut self, window_id: usize, view_id: usize, action: impl Action) {
1778 self.dispatch_any_action_at(window_id, view_id, Box::new(action));
1779 }
1780
1781 pub fn dispatch_any_action_at(
1782 &mut self,
1783 window_id: usize,
1784 view_id: usize,
1785 action: Box<dyn Action>,
1786 ) {
1787 self.pending_effects.push_back(Effect::DispatchActionFrom {
1788 window_id,
1789 view_id,
1790 action,
1791 });
1792 }
1793
1794 fn perform_window_refresh(&mut self) {
1795 let window_ids = self.windows.keys().cloned().collect::<Vec<_>>();
1796 for window_id in window_ids {
1797 self.update_window(window_id, |cx| {
1798 let mut invalidation = cx.window.invalidation.take().unwrap_or_default();
1799 invalidation
1800 .updated
1801 .extend(cx.window.rendered_views.keys().copied());
1802 cx.invalidate(&mut invalidation, cx.window.platform_window.appearance());
1803 cx.refreshing = true;
1804 if let Some(scene) = cx.build_scene().log_err() {
1805 cx.window.platform_window.present_scene(scene);
1806 }
1807 });
1808 }
1809 }
1810
1811 fn emit_global_event(&mut self, payload: Box<dyn Any>) {
1812 let type_id = (&*payload).type_id();
1813
1814 let mut subscriptions = self.global_subscriptions.clone();
1815 subscriptions.emit(type_id, |callback| {
1816 callback(payload.as_ref(), self);
1817 true //Always alive
1818 });
1819 }
1820
1821 fn handle_view_notification_effect(
1822 &mut self,
1823 observed_window_id: usize,
1824 observed_view_id: usize,
1825 ) {
1826 if self
1827 .views
1828 .contains_key(&(observed_window_id, observed_view_id))
1829 {
1830 if let Some(window) = self.windows.get_mut(&observed_window_id) {
1831 window
1832 .invalidation
1833 .get_or_insert_with(Default::default)
1834 .updated
1835 .insert(observed_view_id);
1836 }
1837
1838 let mut observations = self.observations.clone();
1839 observations.emit(observed_view_id, |callback| callback(self));
1840 }
1841 }
1842
1843 fn handle_entity_release_effect(&mut self, entity_id: usize, entity: &dyn Any) {
1844 self.release_observations
1845 .clone()
1846 .emit(entity_id, |callback| {
1847 callback(entity, self);
1848 // Release observations happen one time. So clear the callback by returning false
1849 false
1850 })
1851 }
1852
1853 fn handle_fullscreen_effect(&mut self, window_id: usize, is_fullscreen: bool) {
1854 self.update_window(window_id, |cx| {
1855 cx.window.is_fullscreen = is_fullscreen;
1856
1857 let mut fullscreen_observations = cx.window_fullscreen_observations.clone();
1858 fullscreen_observations.emit(window_id, |callback| callback(is_fullscreen, cx));
1859
1860 if let Some(uuid) = cx.window_display_uuid() {
1861 let bounds = cx.window_bounds();
1862 let mut bounds_observations = cx.window_bounds_observations.clone();
1863 bounds_observations.emit(window_id, |callback| callback(bounds, uuid, cx));
1864 }
1865
1866 Some(())
1867 });
1868 }
1869
1870 fn handle_keystroke_effect(
1871 &mut self,
1872 window_id: usize,
1873 keystroke: Keystroke,
1874 handled_by: Option<Box<dyn Action>>,
1875 result: MatchResult,
1876 ) {
1877 self.update_window(window_id, |cx| {
1878 let mut observations = cx.keystroke_observations.clone();
1879 observations.emit(window_id, move |callback| {
1880 callback(&keystroke, &result, handled_by.as_ref(), cx)
1881 });
1882 });
1883 }
1884
1885 fn handle_window_activation_effect(&mut self, window_id: usize, active: bool) {
1886 self.update_window(window_id, |cx| {
1887 if cx.window.is_active == active {
1888 return;
1889 }
1890 cx.window.is_active = active;
1891
1892 if let Some(focused_id) = cx.window.focused_view_id {
1893 for view_id in cx.ancestors(focused_id).collect::<Vec<_>>() {
1894 cx.update_any_view(view_id, |view, cx| {
1895 if active {
1896 view.focus_in(focused_id, cx, view_id);
1897 } else {
1898 view.focus_out(focused_id, cx, view_id);
1899 }
1900 });
1901 }
1902 }
1903
1904 let mut observations = cx.window_activation_observations.clone();
1905 observations.emit(window_id, |callback| callback(active, cx));
1906 });
1907 }
1908
1909 fn handle_focus_effect(&mut self, window_id: usize, mut focused_id: Option<usize>) {
1910 let mut blurred_id = None;
1911 self.update_window(window_id, |cx| {
1912 if cx.window.focused_view_id == focused_id {
1913 focused_id = None;
1914 return;
1915 }
1916 blurred_id = cx.window.focused_view_id;
1917 cx.window.focused_view_id = focused_id;
1918
1919 let blurred_parents = blurred_id
1920 .map(|blurred_id| cx.ancestors(blurred_id).collect::<Vec<_>>())
1921 .unwrap_or_default();
1922 let focused_parents = focused_id
1923 .map(|focused_id| cx.ancestors(focused_id).collect::<Vec<_>>())
1924 .unwrap_or_default();
1925
1926 if let Some(blurred_id) = blurred_id {
1927 for view_id in blurred_parents.iter().copied() {
1928 if let Some(mut view) = cx.views.remove(&(window_id, view_id)) {
1929 view.focus_out(blurred_id, cx, view_id);
1930 cx.views.insert((window_id, view_id), view);
1931 }
1932 }
1933
1934 let mut subscriptions = cx.focus_observations.clone();
1935 subscriptions.emit(blurred_id, |callback| callback(false, cx));
1936 }
1937
1938 if let Some(focused_id) = focused_id {
1939 for view_id in focused_parents {
1940 if let Some(mut view) = cx.views.remove(&(window_id, view_id)) {
1941 view.focus_in(focused_id, cx, view_id);
1942 cx.views.insert((window_id, view_id), view);
1943 }
1944 }
1945
1946 let mut subscriptions = cx.focus_observations.clone();
1947 subscriptions.emit(focused_id, |callback| callback(true, cx));
1948 }
1949 });
1950 }
1951
1952 fn handle_dispatch_action_from_effect(
1953 &mut self,
1954 window_id: usize,
1955 view_id: Option<usize>,
1956 action: &dyn Action,
1957 ) {
1958 self.update_window(window_id, |cx| {
1959 cx.handle_dispatch_action_from_effect(view_id, action)
1960 });
1961 }
1962
1963 fn handle_action_dispatch_notification_effect(&mut self, action_id: TypeId) {
1964 self.action_dispatch_observations
1965 .clone()
1966 .emit((), |callback| {
1967 callback(action_id, self);
1968 true
1969 });
1970 }
1971
1972 fn handle_window_should_close_subscription_effect(
1973 &mut self,
1974 window_id: usize,
1975 mut callback: WindowShouldCloseSubscriptionCallback,
1976 ) {
1977 let mut app = self.upgrade();
1978 if let Some(window) = self.windows.get_mut(&window_id) {
1979 window
1980 .platform_window
1981 .on_should_close(Box::new(move || app.update(|cx| callback(cx))))
1982 }
1983 }
1984
1985 fn handle_window_moved(&mut self, window_id: usize) {
1986 self.update_window(window_id, |cx| {
1987 if let Some(display) = cx.window_display_uuid() {
1988 let bounds = cx.window_bounds();
1989 cx.window_bounds_observations
1990 .clone()
1991 .emit(window_id, move |callback| {
1992 callback(bounds, display, cx);
1993 true
1994 });
1995 }
1996 });
1997 }
1998
1999 fn handle_active_labeled_tasks_changed_effect(&mut self) {
2000 self.active_labeled_task_observations
2001 .clone()
2002 .emit((), move |callback| {
2003 callback(self);
2004 true
2005 });
2006 }
2007
2008 pub fn focus(&mut self, window_id: usize, view_id: Option<usize>) {
2009 self.pending_effects
2010 .push_back(Effect::Focus { window_id, view_id });
2011 }
2012
2013 fn spawn_internal<F, Fut, T>(&mut self, task_name: Option<&'static str>, f: F) -> Task<T>
2014 where
2015 F: FnOnce(AsyncAppContext) -> Fut,
2016 Fut: 'static + Future<Output = T>,
2017 T: 'static,
2018 {
2019 let label_id = task_name.map(|task_name| {
2020 let id = post_inc(&mut self.next_labeled_task_id);
2021 self.active_labeled_tasks.insert(id, task_name);
2022 self.pending_effects
2023 .push_back(Effect::ActiveLabeledTasksChanged);
2024 id
2025 });
2026
2027 let future = f(self.to_async());
2028 let cx = self.to_async();
2029 self.foreground.spawn(async move {
2030 let result = future.await;
2031 let mut cx = cx.0.borrow_mut();
2032
2033 if let Some(completed_label_id) = label_id {
2034 cx.active_labeled_tasks.remove(&completed_label_id);
2035 cx.pending_effects
2036 .push_back(Effect::ActiveLabeledTasksChanged);
2037 }
2038 cx.flush_effects();
2039 result
2040 })
2041 }
2042
2043 pub fn spawn_labeled<F, Fut, T>(&mut self, task_name: &'static str, f: F) -> Task<T>
2044 where
2045 F: FnOnce(AsyncAppContext) -> Fut,
2046 Fut: 'static + Future<Output = T>,
2047 T: 'static,
2048 {
2049 self.spawn_internal(Some(task_name), f)
2050 }
2051
2052 pub fn spawn<F, Fut, T>(&mut self, f: F) -> Task<T>
2053 where
2054 F: FnOnce(AsyncAppContext) -> Fut,
2055 Fut: 'static + Future<Output = T>,
2056 T: 'static,
2057 {
2058 self.spawn_internal(None, f)
2059 }
2060
2061 pub fn to_async(&self) -> AsyncAppContext {
2062 AsyncAppContext(self.weak_self.as_ref().unwrap().upgrade().unwrap())
2063 }
2064
2065 pub fn write_to_clipboard(&self, item: ClipboardItem) {
2066 self.platform.write_to_clipboard(item);
2067 }
2068
2069 pub fn read_from_clipboard(&self) -> Option<ClipboardItem> {
2070 self.platform.read_from_clipboard()
2071 }
2072
2073 #[cfg(any(test, feature = "test-support"))]
2074 pub fn leak_detector(&self) -> Arc<Mutex<LeakDetector>> {
2075 self.ref_counts.lock().leak_detector.clone()
2076 }
2077}
2078
2079impl ReadModel for AppContext {
2080 fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2081 if let Some(model) = self.models.get(&handle.model_id) {
2082 model
2083 .as_any()
2084 .downcast_ref()
2085 .expect("downcast is type safe")
2086 } else {
2087 panic!("circular model reference");
2088 }
2089 }
2090}
2091
2092impl UpdateModel for AppContext {
2093 fn update_model<T: Entity, V>(
2094 &mut self,
2095 handle: &ModelHandle<T>,
2096 update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
2097 ) -> V {
2098 if let Some(mut model) = self.models.remove(&handle.model_id) {
2099 self.update(|this| {
2100 let mut cx = ModelContext::new(this, handle.model_id);
2101 let result = update(
2102 model
2103 .as_any_mut()
2104 .downcast_mut()
2105 .expect("downcast is type safe"),
2106 &mut cx,
2107 );
2108 this.models.insert(handle.model_id, model);
2109 result
2110 })
2111 } else {
2112 panic!("circular model update");
2113 }
2114 }
2115}
2116
2117impl UpgradeModelHandle for AppContext {
2118 fn upgrade_model_handle<T: Entity>(
2119 &self,
2120 handle: &WeakModelHandle<T>,
2121 ) -> Option<ModelHandle<T>> {
2122 if self.ref_counts.lock().is_entity_alive(handle.model_id) {
2123 Some(ModelHandle::new(handle.model_id, &self.ref_counts))
2124 } else {
2125 None
2126 }
2127 }
2128
2129 fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
2130 self.ref_counts.lock().is_entity_alive(handle.model_id)
2131 }
2132
2133 fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
2134 if self.ref_counts.lock().is_entity_alive(handle.model_id) {
2135 Some(AnyModelHandle::new(
2136 handle.model_id,
2137 handle.model_type,
2138 self.ref_counts.clone(),
2139 ))
2140 } else {
2141 None
2142 }
2143 }
2144}
2145
2146impl UpgradeViewHandle for AppContext {
2147 fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
2148 if self.ref_counts.lock().is_entity_alive(handle.view_id) {
2149 Some(ViewHandle::new(
2150 handle.window_id,
2151 handle.view_id,
2152 &self.ref_counts,
2153 ))
2154 } else {
2155 None
2156 }
2157 }
2158
2159 fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
2160 if self.ref_counts.lock().is_entity_alive(handle.view_id) {
2161 Some(AnyViewHandle::new(
2162 handle.window_id,
2163 handle.view_id,
2164 handle.view_type,
2165 self.ref_counts.clone(),
2166 ))
2167 } else {
2168 None
2169 }
2170 }
2171}
2172
2173impl ReadView for AppContext {
2174 fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
2175 if let Some(view) = self.views.get(&(handle.window_id, handle.view_id)) {
2176 view.as_any().downcast_ref().expect("downcast is type safe")
2177 } else {
2178 panic!("circular view reference for type {}", type_name::<T>());
2179 }
2180 }
2181}
2182
2183#[derive(Debug)]
2184pub enum ParentId {
2185 View(usize),
2186 Root,
2187}
2188
2189#[derive(Default, Clone)]
2190pub struct WindowInvalidation {
2191 pub updated: HashSet<usize>,
2192 pub removed: Vec<usize>,
2193}
2194
2195pub enum Effect {
2196 Subscription {
2197 entity_id: usize,
2198 subscription_id: usize,
2199 callback: SubscriptionCallback,
2200 },
2201 Event {
2202 entity_id: usize,
2203 payload: Box<dyn Any>,
2204 },
2205 GlobalSubscription {
2206 type_id: TypeId,
2207 subscription_id: usize,
2208 callback: GlobalSubscriptionCallback,
2209 },
2210 GlobalEvent {
2211 payload: Box<dyn Any>,
2212 },
2213 Observation {
2214 entity_id: usize,
2215 subscription_id: usize,
2216 callback: ObservationCallback,
2217 },
2218 ModelNotification {
2219 model_id: usize,
2220 },
2221 ViewNotification {
2222 window_id: usize,
2223 view_id: usize,
2224 },
2225 Deferred {
2226 callback: Box<dyn FnOnce(&mut AppContext)>,
2227 after_window_update: bool,
2228 },
2229 GlobalNotification {
2230 type_id: TypeId,
2231 },
2232 ModelRelease {
2233 model_id: usize,
2234 model: Box<dyn AnyModel>,
2235 },
2236 ViewRelease {
2237 view_id: usize,
2238 view: Box<dyn AnyView>,
2239 },
2240 Focus {
2241 window_id: usize,
2242 view_id: Option<usize>,
2243 },
2244 FocusObservation {
2245 view_id: usize,
2246 subscription_id: usize,
2247 callback: FocusObservationCallback,
2248 },
2249 ResizeWindow {
2250 window_id: usize,
2251 },
2252 MoveWindow {
2253 window_id: usize,
2254 },
2255 ActivateWindow {
2256 window_id: usize,
2257 is_active: bool,
2258 },
2259 WindowActivationObservation {
2260 window_id: usize,
2261 subscription_id: usize,
2262 callback: WindowActivationCallback,
2263 },
2264 FullscreenWindow {
2265 window_id: usize,
2266 is_fullscreen: bool,
2267 },
2268 WindowFullscreenObservation {
2269 window_id: usize,
2270 subscription_id: usize,
2271 callback: WindowFullscreenCallback,
2272 },
2273 WindowBoundsObservation {
2274 window_id: usize,
2275 subscription_id: usize,
2276 callback: WindowBoundsCallback,
2277 },
2278 Keystroke {
2279 window_id: usize,
2280 keystroke: Keystroke,
2281 handled_by: Option<Box<dyn Action>>,
2282 result: MatchResult,
2283 },
2284 RefreshWindows,
2285 DispatchActionFrom {
2286 window_id: usize,
2287 view_id: usize,
2288 action: Box<dyn Action>,
2289 },
2290 ActionDispatchNotification {
2291 action_id: TypeId,
2292 },
2293 WindowShouldCloseSubscription {
2294 window_id: usize,
2295 callback: WindowShouldCloseSubscriptionCallback,
2296 },
2297 ActiveLabeledTasksChanged,
2298 ActiveLabeledTasksObservation {
2299 subscription_id: usize,
2300 callback: ActiveLabeledTasksCallback,
2301 },
2302}
2303
2304impl Debug for Effect {
2305 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2306 match self {
2307 Effect::Subscription {
2308 entity_id,
2309 subscription_id,
2310 ..
2311 } => f
2312 .debug_struct("Effect::Subscribe")
2313 .field("entity_id", entity_id)
2314 .field("subscription_id", subscription_id)
2315 .finish(),
2316 Effect::Event { entity_id, .. } => f
2317 .debug_struct("Effect::Event")
2318 .field("entity_id", entity_id)
2319 .finish(),
2320 Effect::GlobalSubscription {
2321 type_id,
2322 subscription_id,
2323 ..
2324 } => f
2325 .debug_struct("Effect::Subscribe")
2326 .field("type_id", type_id)
2327 .field("subscription_id", subscription_id)
2328 .finish(),
2329 Effect::GlobalEvent { payload, .. } => f
2330 .debug_struct("Effect::GlobalEvent")
2331 .field("type_id", &(&*payload).type_id())
2332 .finish(),
2333 Effect::Observation {
2334 entity_id,
2335 subscription_id,
2336 ..
2337 } => f
2338 .debug_struct("Effect::Observation")
2339 .field("entity_id", entity_id)
2340 .field("subscription_id", subscription_id)
2341 .finish(),
2342 Effect::ModelNotification { model_id } => f
2343 .debug_struct("Effect::ModelNotification")
2344 .field("model_id", model_id)
2345 .finish(),
2346 Effect::ViewNotification { window_id, view_id } => f
2347 .debug_struct("Effect::ViewNotification")
2348 .field("window_id", window_id)
2349 .field("view_id", view_id)
2350 .finish(),
2351 Effect::GlobalNotification { type_id } => f
2352 .debug_struct("Effect::GlobalNotification")
2353 .field("type_id", type_id)
2354 .finish(),
2355 Effect::Deferred { .. } => f.debug_struct("Effect::Deferred").finish(),
2356 Effect::ModelRelease { model_id, .. } => f
2357 .debug_struct("Effect::ModelRelease")
2358 .field("model_id", model_id)
2359 .finish(),
2360 Effect::ViewRelease { view_id, .. } => f
2361 .debug_struct("Effect::ViewRelease")
2362 .field("view_id", view_id)
2363 .finish(),
2364 Effect::Focus { window_id, view_id } => f
2365 .debug_struct("Effect::Focus")
2366 .field("window_id", window_id)
2367 .field("view_id", view_id)
2368 .finish(),
2369 Effect::FocusObservation {
2370 view_id,
2371 subscription_id,
2372 ..
2373 } => f
2374 .debug_struct("Effect::FocusObservation")
2375 .field("view_id", view_id)
2376 .field("subscription_id", subscription_id)
2377 .finish(),
2378 Effect::DispatchActionFrom {
2379 window_id, view_id, ..
2380 } => f
2381 .debug_struct("Effect::DispatchActionFrom")
2382 .field("window_id", window_id)
2383 .field("view_id", view_id)
2384 .finish(),
2385 Effect::ActionDispatchNotification { action_id, .. } => f
2386 .debug_struct("Effect::ActionDispatchNotification")
2387 .field("action_id", action_id)
2388 .finish(),
2389 Effect::ResizeWindow { window_id } => f
2390 .debug_struct("Effect::RefreshWindow")
2391 .field("window_id", window_id)
2392 .finish(),
2393 Effect::MoveWindow { window_id } => f
2394 .debug_struct("Effect::MoveWindow")
2395 .field("window_id", window_id)
2396 .finish(),
2397 Effect::WindowActivationObservation {
2398 window_id,
2399 subscription_id,
2400 ..
2401 } => f
2402 .debug_struct("Effect::WindowActivationObservation")
2403 .field("window_id", window_id)
2404 .field("subscription_id", subscription_id)
2405 .finish(),
2406 Effect::ActivateWindow {
2407 window_id,
2408 is_active,
2409 } => f
2410 .debug_struct("Effect::ActivateWindow")
2411 .field("window_id", window_id)
2412 .field("is_active", is_active)
2413 .finish(),
2414 Effect::FullscreenWindow {
2415 window_id,
2416 is_fullscreen,
2417 } => f
2418 .debug_struct("Effect::FullscreenWindow")
2419 .field("window_id", window_id)
2420 .field("is_fullscreen", is_fullscreen)
2421 .finish(),
2422 Effect::WindowFullscreenObservation {
2423 window_id,
2424 subscription_id,
2425 callback: _,
2426 } => f
2427 .debug_struct("Effect::WindowFullscreenObservation")
2428 .field("window_id", window_id)
2429 .field("subscription_id", subscription_id)
2430 .finish(),
2431
2432 Effect::WindowBoundsObservation {
2433 window_id,
2434 subscription_id,
2435 callback: _,
2436 } => f
2437 .debug_struct("Effect::WindowBoundsObservation")
2438 .field("window_id", window_id)
2439 .field("subscription_id", subscription_id)
2440 .finish(),
2441 Effect::RefreshWindows => f.debug_struct("Effect::FullViewRefresh").finish(),
2442 Effect::WindowShouldCloseSubscription { window_id, .. } => f
2443 .debug_struct("Effect::WindowShouldCloseSubscription")
2444 .field("window_id", window_id)
2445 .finish(),
2446 Effect::Keystroke {
2447 window_id,
2448 keystroke,
2449 handled_by,
2450 result,
2451 } => f
2452 .debug_struct("Effect::Keystroke")
2453 .field("window_id", window_id)
2454 .field("keystroke", keystroke)
2455 .field(
2456 "keystroke",
2457 &handled_by.as_ref().map(|handled_by| handled_by.name()),
2458 )
2459 .field("result", result)
2460 .finish(),
2461 Effect::ActiveLabeledTasksChanged => {
2462 f.debug_struct("Effect::ActiveLabeledTasksChanged").finish()
2463 }
2464 Effect::ActiveLabeledTasksObservation {
2465 subscription_id,
2466 callback: _,
2467 } => f
2468 .debug_struct("Effect::ActiveLabeledTasksObservation")
2469 .field("subscription_id", subscription_id)
2470 .finish(),
2471 }
2472 }
2473}
2474
2475pub trait AnyModel {
2476 fn as_any(&self) -> &dyn Any;
2477 fn as_any_mut(&mut self) -> &mut dyn Any;
2478 fn release(&mut self, cx: &mut AppContext);
2479 fn app_will_quit(
2480 &mut self,
2481 cx: &mut AppContext,
2482 ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
2483}
2484
2485impl<T> AnyModel for T
2486where
2487 T: Entity,
2488{
2489 fn as_any(&self) -> &dyn Any {
2490 self
2491 }
2492
2493 fn as_any_mut(&mut self) -> &mut dyn Any {
2494 self
2495 }
2496
2497 fn release(&mut self, cx: &mut AppContext) {
2498 self.release(cx);
2499 }
2500
2501 fn app_will_quit(
2502 &mut self,
2503 cx: &mut AppContext,
2504 ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
2505 self.app_will_quit(cx)
2506 }
2507}
2508
2509pub trait AnyView {
2510 fn as_any(&self) -> &dyn Any;
2511 fn as_any_mut(&mut self) -> &mut dyn Any;
2512 fn release(&mut self, cx: &mut AppContext);
2513 fn app_will_quit(
2514 &mut self,
2515 cx: &mut AppContext,
2516 ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
2517 fn ui_name(&self) -> &'static str;
2518 fn render(&mut self, cx: &mut WindowContext, view_id: usize) -> Box<dyn AnyRootElement>;
2519 fn focus_in<'a, 'b>(
2520 &mut self,
2521 focused_id: usize,
2522 cx: &mut WindowContext<'a, 'b>,
2523 view_id: usize,
2524 );
2525 fn focus_out(&mut self, focused_id: usize, cx: &mut WindowContext, view_id: usize);
2526 fn key_down(&mut self, event: &KeyDownEvent, cx: &mut WindowContext, view_id: usize) -> bool;
2527 fn key_up(&mut self, event: &KeyUpEvent, cx: &mut WindowContext, view_id: usize) -> bool;
2528 fn modifiers_changed(
2529 &mut self,
2530 event: &ModifiersChangedEvent,
2531 cx: &mut WindowContext,
2532 view_id: usize,
2533 ) -> bool;
2534 fn keymap_context(&self, cx: &AppContext) -> KeymapContext;
2535 fn debug_json(&self, cx: &WindowContext) -> serde_json::Value;
2536
2537 fn text_for_range(&self, range: Range<usize>, cx: &WindowContext) -> Option<String>;
2538 fn selected_text_range(&self, cx: &WindowContext) -> Option<Range<usize>>;
2539 fn marked_text_range(&self, cx: &WindowContext) -> Option<Range<usize>>;
2540 fn unmark_text(&mut self, cx: &mut WindowContext, view_id: usize);
2541 fn replace_text_in_range(
2542 &mut self,
2543 range: Option<Range<usize>>,
2544 text: &str,
2545 cx: &mut WindowContext,
2546 view_id: usize,
2547 );
2548 fn replace_and_mark_text_in_range(
2549 &mut self,
2550 range: Option<Range<usize>>,
2551 new_text: &str,
2552 new_selected_range: Option<Range<usize>>,
2553 cx: &mut WindowContext,
2554 view_id: usize,
2555 );
2556 fn any_handle(&self, window_id: usize, view_id: usize, cx: &AppContext) -> AnyViewHandle {
2557 AnyViewHandle::new(
2558 window_id,
2559 view_id,
2560 self.as_any().type_id(),
2561 cx.ref_counts.clone(),
2562 )
2563 }
2564}
2565
2566impl<V> AnyView for V
2567where
2568 V: View,
2569{
2570 fn as_any(&self) -> &dyn Any {
2571 self
2572 }
2573
2574 fn as_any_mut(&mut self) -> &mut dyn Any {
2575 self
2576 }
2577
2578 fn release(&mut self, cx: &mut AppContext) {
2579 self.release(cx);
2580 }
2581
2582 fn app_will_quit(
2583 &mut self,
2584 cx: &mut AppContext,
2585 ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
2586 self.app_will_quit(cx)
2587 }
2588
2589 fn ui_name(&self) -> &'static str {
2590 V::ui_name()
2591 }
2592
2593 fn render(&mut self, cx: &mut WindowContext, view_id: usize) -> Box<dyn AnyRootElement> {
2594 let mut view_context = ViewContext::mutable(cx, view_id);
2595 let element = V::render(self, &mut view_context);
2596 let view = WeakViewHandle::new(cx.window_id, view_id);
2597 Box::new(RootElement::new(element, view))
2598 }
2599
2600 fn focus_in(&mut self, focused_id: usize, cx: &mut WindowContext, view_id: usize) {
2601 let mut cx = ViewContext::mutable(cx, view_id);
2602 let focused_view_handle: AnyViewHandle = if view_id == focused_id {
2603 cx.handle().into_any()
2604 } else {
2605 let focused_type = cx
2606 .views
2607 .get(&(cx.window_id, focused_id))
2608 .unwrap()
2609 .as_any()
2610 .type_id();
2611 AnyViewHandle::new(
2612 cx.window_id,
2613 focused_id,
2614 focused_type,
2615 cx.ref_counts.clone(),
2616 )
2617 };
2618 View::focus_in(self, focused_view_handle, &mut cx);
2619 }
2620
2621 fn focus_out(&mut self, blurred_id: usize, cx: &mut WindowContext, view_id: usize) {
2622 let mut cx = ViewContext::mutable(cx, view_id);
2623 let blurred_view_handle: AnyViewHandle = if view_id == blurred_id {
2624 cx.handle().into_any()
2625 } else {
2626 let blurred_type = cx
2627 .views
2628 .get(&(cx.window_id, blurred_id))
2629 .unwrap()
2630 .as_any()
2631 .type_id();
2632 AnyViewHandle::new(
2633 cx.window_id,
2634 blurred_id,
2635 blurred_type,
2636 cx.ref_counts.clone(),
2637 )
2638 };
2639 View::focus_out(self, blurred_view_handle, &mut cx);
2640 }
2641
2642 fn key_down(&mut self, event: &KeyDownEvent, cx: &mut WindowContext, view_id: usize) -> bool {
2643 let mut cx = ViewContext::mutable(cx, view_id);
2644 View::key_down(self, event, &mut cx)
2645 }
2646
2647 fn key_up(&mut self, event: &KeyUpEvent, cx: &mut WindowContext, view_id: usize) -> bool {
2648 let mut cx = ViewContext::mutable(cx, view_id);
2649 View::key_up(self, event, &mut cx)
2650 }
2651
2652 fn modifiers_changed(
2653 &mut self,
2654 event: &ModifiersChangedEvent,
2655 cx: &mut WindowContext,
2656 view_id: usize,
2657 ) -> bool {
2658 let mut cx = ViewContext::mutable(cx, view_id);
2659 View::modifiers_changed(self, event, &mut cx)
2660 }
2661
2662 fn keymap_context(&self, cx: &AppContext) -> KeymapContext {
2663 View::keymap_context(self, cx)
2664 }
2665
2666 fn debug_json(&self, cx: &WindowContext) -> serde_json::Value {
2667 View::debug_json(self, cx)
2668 }
2669
2670 fn text_for_range(&self, range: Range<usize>, cx: &WindowContext) -> Option<String> {
2671 View::text_for_range(self, range, cx)
2672 }
2673
2674 fn selected_text_range(&self, cx: &WindowContext) -> Option<Range<usize>> {
2675 View::selected_text_range(self, cx)
2676 }
2677
2678 fn marked_text_range(&self, cx: &WindowContext) -> Option<Range<usize>> {
2679 View::marked_text_range(self, cx)
2680 }
2681
2682 fn unmark_text(&mut self, cx: &mut WindowContext, view_id: usize) {
2683 let mut cx = ViewContext::mutable(cx, view_id);
2684 View::unmark_text(self, &mut cx)
2685 }
2686
2687 fn replace_text_in_range(
2688 &mut self,
2689 range: Option<Range<usize>>,
2690 text: &str,
2691 cx: &mut WindowContext,
2692 view_id: usize,
2693 ) {
2694 let mut cx = ViewContext::mutable(cx, view_id);
2695 View::replace_text_in_range(self, range, text, &mut cx)
2696 }
2697
2698 fn replace_and_mark_text_in_range(
2699 &mut self,
2700 range: Option<Range<usize>>,
2701 new_text: &str,
2702 new_selected_range: Option<Range<usize>>,
2703 cx: &mut WindowContext,
2704 view_id: usize,
2705 ) {
2706 let mut cx = ViewContext::mutable(cx, view_id);
2707 View::replace_and_mark_text_in_range(self, range, new_text, new_selected_range, &mut cx)
2708 }
2709}
2710
2711pub struct ModelContext<'a, T: ?Sized> {
2712 app: &'a mut AppContext,
2713 model_id: usize,
2714 model_type: PhantomData<T>,
2715 halt_stream: bool,
2716}
2717
2718impl<'a, T: Entity> ModelContext<'a, T> {
2719 fn new(app: &'a mut AppContext, model_id: usize) -> Self {
2720 Self {
2721 app,
2722 model_id,
2723 model_type: PhantomData,
2724 halt_stream: false,
2725 }
2726 }
2727
2728 pub fn background(&self) -> &Arc<executor::Background> {
2729 &self.app.background
2730 }
2731
2732 pub fn halt_stream(&mut self) {
2733 self.halt_stream = true;
2734 }
2735
2736 pub fn model_id(&self) -> usize {
2737 self.model_id
2738 }
2739
2740 pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
2741 where
2742 S: Entity,
2743 F: FnOnce(&mut ModelContext<S>) -> S,
2744 {
2745 self.app.add_model(build_model)
2746 }
2747
2748 pub fn emit(&mut self, payload: T::Event) {
2749 self.app.pending_effects.push_back(Effect::Event {
2750 entity_id: self.model_id,
2751 payload: Box::new(payload),
2752 });
2753 }
2754
2755 pub fn notify(&mut self) {
2756 self.app.notify_model(self.model_id);
2757 }
2758
2759 pub fn subscribe<S: Entity, F>(
2760 &mut self,
2761 handle: &ModelHandle<S>,
2762 mut callback: F,
2763 ) -> Subscription
2764 where
2765 S::Event: 'static,
2766 F: 'static + FnMut(&mut T, ModelHandle<S>, &S::Event, &mut ModelContext<T>),
2767 {
2768 let subscriber = self.weak_handle();
2769 self.app
2770 .subscribe_internal(handle, move |emitter, event, cx| {
2771 if let Some(subscriber) = subscriber.upgrade(cx) {
2772 subscriber.update(cx, |subscriber, cx| {
2773 callback(subscriber, emitter, event, cx);
2774 });
2775 true
2776 } else {
2777 false
2778 }
2779 })
2780 }
2781
2782 pub fn observe<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F) -> Subscription
2783 where
2784 S: Entity,
2785 F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ModelContext<T>),
2786 {
2787 let observer = self.weak_handle();
2788 self.app.observe_internal(handle, move |observed, cx| {
2789 if let Some(observer) = observer.upgrade(cx) {
2790 observer.update(cx, |observer, cx| {
2791 callback(observer, observed, cx);
2792 });
2793 true
2794 } else {
2795 false
2796 }
2797 })
2798 }
2799
2800 pub fn observe_global<G, F>(&mut self, mut callback: F) -> Subscription
2801 where
2802 G: Any,
2803 F: 'static + FnMut(&mut T, &mut ModelContext<T>),
2804 {
2805 let observer = self.weak_handle();
2806 self.app.observe_global::<G, _>(move |cx| {
2807 if let Some(observer) = observer.upgrade(cx) {
2808 observer.update(cx, |observer, cx| callback(observer, cx));
2809 }
2810 })
2811 }
2812
2813 pub fn observe_release<S, F>(
2814 &mut self,
2815 handle: &ModelHandle<S>,
2816 mut callback: F,
2817 ) -> Subscription
2818 where
2819 S: Entity,
2820 F: 'static + FnMut(&mut T, &S, &mut ModelContext<T>),
2821 {
2822 let observer = self.weak_handle();
2823 self.app.observe_release(handle, move |released, cx| {
2824 if let Some(observer) = observer.upgrade(cx) {
2825 observer.update(cx, |observer, cx| {
2826 callback(observer, released, cx);
2827 });
2828 }
2829 })
2830 }
2831
2832 pub fn handle(&self) -> ModelHandle<T> {
2833 ModelHandle::new(self.model_id, &self.app.ref_counts)
2834 }
2835
2836 pub fn weak_handle(&self) -> WeakModelHandle<T> {
2837 WeakModelHandle::new(self.model_id)
2838 }
2839
2840 pub fn spawn<F, Fut, S>(&mut self, f: F) -> Task<S>
2841 where
2842 F: FnOnce(ModelHandle<T>, AsyncAppContext) -> Fut,
2843 Fut: 'static + Future<Output = S>,
2844 S: 'static,
2845 {
2846 let handle = self.handle();
2847 self.app.spawn(|cx| f(handle, cx))
2848 }
2849
2850 pub fn spawn_weak<F, Fut, S>(&mut self, f: F) -> Task<S>
2851 where
2852 F: FnOnce(WeakModelHandle<T>, AsyncAppContext) -> Fut,
2853 Fut: 'static + Future<Output = S>,
2854 S: 'static,
2855 {
2856 let handle = self.weak_handle();
2857 self.app.spawn(|cx| f(handle, cx))
2858 }
2859}
2860
2861impl<M> AsRef<AppContext> for ModelContext<'_, M> {
2862 fn as_ref(&self) -> &AppContext {
2863 &self.app
2864 }
2865}
2866
2867impl<M> AsMut<AppContext> for ModelContext<'_, M> {
2868 fn as_mut(&mut self) -> &mut AppContext {
2869 self.app
2870 }
2871}
2872
2873impl<M> ReadModel for ModelContext<'_, M> {
2874 fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2875 self.app.read_model(handle)
2876 }
2877}
2878
2879impl<M> UpdateModel for ModelContext<'_, M> {
2880 fn update_model<T: Entity, V>(
2881 &mut self,
2882 handle: &ModelHandle<T>,
2883 update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
2884 ) -> V {
2885 self.app.update_model(handle, update)
2886 }
2887}
2888
2889impl<M> UpgradeModelHandle for ModelContext<'_, M> {
2890 fn upgrade_model_handle<T: Entity>(
2891 &self,
2892 handle: &WeakModelHandle<T>,
2893 ) -> Option<ModelHandle<T>> {
2894 self.app.upgrade_model_handle(handle)
2895 }
2896
2897 fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
2898 self.app.model_handle_is_upgradable(handle)
2899 }
2900
2901 fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
2902 self.app.upgrade_any_model_handle(handle)
2903 }
2904}
2905
2906impl<M> Deref for ModelContext<'_, M> {
2907 type Target = AppContext;
2908
2909 fn deref(&self) -> &Self::Target {
2910 self.app
2911 }
2912}
2913
2914impl<M> DerefMut for ModelContext<'_, M> {
2915 fn deref_mut(&mut self) -> &mut Self::Target {
2916 &mut self.app
2917 }
2918}
2919
2920pub struct ViewContext<'a, 'b, 'c, T: ?Sized> {
2921 window_context: Reference<'c, WindowContext<'a, 'b>>,
2922 view_id: usize,
2923 view_type: PhantomData<T>,
2924}
2925
2926impl<'a, 'b, 'c, T: View> Deref for ViewContext<'a, 'b, 'c, T> {
2927 type Target = WindowContext<'a, 'b>;
2928
2929 fn deref(&self) -> &Self::Target {
2930 &self.window_context
2931 }
2932}
2933
2934impl<T: View> DerefMut for ViewContext<'_, '_, '_, T> {
2935 fn deref_mut(&mut self) -> &mut Self::Target {
2936 &mut self.window_context
2937 }
2938}
2939
2940impl<'a, 'b, 'c, V: View> ViewContext<'a, 'b, 'c, V> {
2941 pub(crate) fn mutable(window_context: &'c mut WindowContext<'a, 'b>, view_id: usize) -> Self {
2942 Self {
2943 window_context: Reference::Mutable(window_context),
2944 view_id,
2945 view_type: PhantomData,
2946 }
2947 }
2948
2949 pub(crate) fn immutable(window_context: &'c WindowContext<'a, 'b>, view_id: usize) -> Self {
2950 Self {
2951 window_context: Reference::Immutable(window_context),
2952 view_id,
2953 view_type: PhantomData,
2954 }
2955 }
2956
2957 pub fn handle(&self) -> ViewHandle<V> {
2958 ViewHandle::new(
2959 self.window_id,
2960 self.view_id,
2961 &self.window_context.ref_counts,
2962 )
2963 }
2964
2965 pub fn weak_handle(&self) -> WeakViewHandle<V> {
2966 WeakViewHandle::new(self.window_id, self.view_id)
2967 }
2968
2969 pub fn parent(&self) -> Option<usize> {
2970 self.window_context.parent(self.view_id)
2971 }
2972
2973 pub fn window_id(&self) -> usize {
2974 self.window_id
2975 }
2976
2977 pub fn view_id(&self) -> usize {
2978 self.view_id
2979 }
2980
2981 pub fn foreground(&self) -> &Rc<executor::Foreground> {
2982 self.window_context.foreground()
2983 }
2984
2985 pub fn background_executor(&self) -> &Arc<executor::Background> {
2986 &self.window_context.background
2987 }
2988
2989 pub fn platform(&self) -> &Arc<dyn Platform> {
2990 self.window_context.platform()
2991 }
2992
2993 pub fn prompt_for_paths(
2994 &self,
2995 options: PathPromptOptions,
2996 ) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
2997 self.window_context.prompt_for_paths(options)
2998 }
2999
3000 pub fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
3001 self.window_context.prompt_for_new_path(directory)
3002 }
3003
3004 pub fn reveal_path(&self, path: &Path) {
3005 self.window_context.reveal_path(path)
3006 }
3007
3008 pub fn focus(&mut self, handle: &AnyViewHandle) {
3009 self.window_context
3010 .focus(handle.window_id, Some(handle.view_id));
3011 }
3012
3013 pub fn focus_self(&mut self) {
3014 let window_id = self.window_id;
3015 let view_id = self.view_id;
3016 self.window_context.focus(window_id, Some(view_id));
3017 }
3018
3019 pub fn is_self_focused(&self) -> bool {
3020 self.window.focused_view_id == Some(self.view_id)
3021 }
3022
3023 pub fn is_parent_view_focused(&self) -> bool {
3024 if let Some(parent_view_id) = self.ancestors(self.view_id).next().clone() {
3025 self.focused_view_id() == Some(parent_view_id)
3026 } else {
3027 false
3028 }
3029 }
3030
3031 pub fn focus_parent_view(&mut self) {
3032 let next = self.ancestors(self.view_id).next().clone();
3033 if let Some(parent_view_id) = next {
3034 let window_id = self.window_id;
3035 self.window_context.focus(window_id, Some(parent_view_id));
3036 }
3037 }
3038
3039 pub fn is_child(&self, view: impl Into<AnyViewHandle>) -> bool {
3040 let view = view.into();
3041 if self.window_id != view.window_id {
3042 return false;
3043 }
3044 self.ancestors(view.view_id)
3045 .skip(1) // Skip self id
3046 .any(|parent| parent == self.view_id)
3047 }
3048
3049 pub fn blur(&mut self) {
3050 let window_id = self.window_id;
3051 self.window_context.focus(window_id, None);
3052 }
3053
3054 pub fn on_window_should_close<F>(&mut self, mut callback: F)
3055 where
3056 F: 'static + FnMut(&mut V, &mut ViewContext<V>) -> bool,
3057 {
3058 let window_id = self.window_id;
3059 let view = self.weak_handle();
3060 self.pending_effects
3061 .push_back(Effect::WindowShouldCloseSubscription {
3062 window_id,
3063 callback: Box::new(move |cx| {
3064 cx.update_window(window_id, |cx| {
3065 if let Some(view) = view.upgrade(cx) {
3066 view.update(cx, |view, cx| callback(view, cx))
3067 } else {
3068 true
3069 }
3070 })
3071 .unwrap_or(true)
3072 }),
3073 });
3074 }
3075
3076 pub fn add_view<S, F>(&mut self, build_view: F) -> ViewHandle<S>
3077 where
3078 S: View,
3079 F: FnOnce(&mut ViewContext<S>) -> S,
3080 {
3081 self.window_context
3082 .build_and_insert_view(ParentId::View(self.view_id), |cx| Some(build_view(cx)))
3083 .unwrap()
3084 }
3085
3086 pub fn add_option_view<S, F>(&mut self, build_view: F) -> Option<ViewHandle<S>>
3087 where
3088 S: View,
3089 F: FnOnce(&mut ViewContext<S>) -> Option<S>,
3090 {
3091 self.window_context
3092 .build_and_insert_view(ParentId::View(self.view_id), build_view)
3093 }
3094
3095 pub fn reparent(&mut self, view_handle: &AnyViewHandle) {
3096 if self.window_id != view_handle.window_id {
3097 panic!("Can't reparent view to a view from a different window");
3098 }
3099 self.parents
3100 .remove(&(view_handle.window_id, view_handle.view_id));
3101 let new_parent_id = self.view_id;
3102 self.parents.insert(
3103 (view_handle.window_id, view_handle.view_id),
3104 ParentId::View(new_parent_id),
3105 );
3106 }
3107
3108 pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
3109 where
3110 E: Entity,
3111 E::Event: 'static,
3112 H: Handle<E>,
3113 F: 'static + FnMut(&mut V, H, &E::Event, &mut ViewContext<V>),
3114 {
3115 let subscriber = self.weak_handle();
3116 self.window_context
3117 .subscribe_internal(handle, move |emitter, event, cx| {
3118 if let Some(subscriber) = subscriber.upgrade(cx) {
3119 subscriber.update(cx, |subscriber, cx| {
3120 callback(subscriber, emitter, event, cx);
3121 });
3122 true
3123 } else {
3124 false
3125 }
3126 })
3127 }
3128
3129 pub fn observe<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
3130 where
3131 E: Entity,
3132 H: Handle<E>,
3133 F: 'static + FnMut(&mut V, H, &mut ViewContext<V>),
3134 {
3135 let window_id = self.window_id;
3136 let observer = self.weak_handle();
3137 self.window_context
3138 .observe_internal(handle, move |observed, cx| {
3139 cx.update_window(window_id, |cx| {
3140 if let Some(observer) = observer.upgrade(cx) {
3141 observer.update(cx, |observer, cx| {
3142 callback(observer, observed, cx);
3143 });
3144 true
3145 } else {
3146 false
3147 }
3148 })
3149 .unwrap_or(false)
3150 })
3151 }
3152
3153 pub fn observe_global<G, F>(&mut self, mut callback: F) -> Subscription
3154 where
3155 G: Any,
3156 F: 'static + FnMut(&mut V, &mut ViewContext<V>),
3157 {
3158 let window_id = self.window_id;
3159 let observer = self.weak_handle();
3160 self.window_context.observe_global::<G, _>(move |cx| {
3161 cx.update_window(window_id, |cx| {
3162 if let Some(observer) = observer.upgrade(cx) {
3163 observer.update(cx, |observer, cx| callback(observer, cx));
3164 }
3165 });
3166 })
3167 }
3168
3169 pub fn observe_focus<F, W>(&mut self, handle: &ViewHandle<W>, mut callback: F) -> Subscription
3170 where
3171 F: 'static + FnMut(&mut V, ViewHandle<W>, bool, &mut ViewContext<V>),
3172 W: View,
3173 {
3174 let observer = self.weak_handle();
3175 self.window_context
3176 .observe_focus(handle, move |observed, focused, cx| {
3177 if let Some(observer) = observer.upgrade(cx) {
3178 observer.update(cx, |observer, cx| {
3179 callback(observer, observed, focused, cx);
3180 });
3181 true
3182 } else {
3183 false
3184 }
3185 })
3186 }
3187
3188 pub fn observe_release<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
3189 where
3190 E: Entity,
3191 H: Handle<E>,
3192 F: 'static + FnMut(&mut V, &E, &mut ViewContext<V>),
3193 {
3194 let window_id = self.window_id;
3195 let observer = self.weak_handle();
3196 self.window_context
3197 .observe_release(handle, move |released, cx| {
3198 cx.update_window(window_id, |cx| {
3199 if let Some(observer) = observer.upgrade(cx) {
3200 observer.update(cx, |observer, cx| {
3201 callback(observer, released, cx);
3202 });
3203 }
3204 });
3205 })
3206 }
3207
3208 pub fn observe_actions<F>(&mut self, mut callback: F) -> Subscription
3209 where
3210 F: 'static + FnMut(&mut V, TypeId, &mut ViewContext<V>),
3211 {
3212 let window_id = self.window_id;
3213 let observer = self.weak_handle();
3214 self.window_context.observe_actions(move |action_id, cx| {
3215 cx.update_window(window_id, |cx| {
3216 if let Some(observer) = observer.upgrade(cx) {
3217 observer.update(cx, |observer, cx| {
3218 callback(observer, action_id, cx);
3219 });
3220 }
3221 });
3222 })
3223 }
3224
3225 pub fn observe_window_activation<F>(&mut self, mut callback: F) -> Subscription
3226 where
3227 F: 'static + FnMut(&mut V, bool, &mut ViewContext<V>),
3228 {
3229 let observer = self.weak_handle();
3230 self.window_context
3231 .observe_window_activation(move |active, cx| {
3232 if let Some(observer) = observer.upgrade(cx) {
3233 observer.update(cx, |observer, cx| {
3234 callback(observer, active, cx);
3235 });
3236 true
3237 } else {
3238 false
3239 }
3240 })
3241 }
3242
3243 pub fn observe_fullscreen<F>(&mut self, mut callback: F) -> Subscription
3244 where
3245 F: 'static + FnMut(&mut V, bool, &mut ViewContext<V>),
3246 {
3247 let observer = self.weak_handle();
3248 self.window_context.observe_fullscreen(move |active, cx| {
3249 if let Some(observer) = observer.upgrade(cx) {
3250 observer.update(cx, |observer, cx| {
3251 callback(observer, active, cx);
3252 });
3253 true
3254 } else {
3255 false
3256 }
3257 })
3258 }
3259
3260 pub fn observe_keystrokes<F>(&mut self, mut callback: F) -> Subscription
3261 where
3262 F: 'static
3263 + FnMut(
3264 &mut V,
3265 &Keystroke,
3266 Option<&Box<dyn Action>>,
3267 &MatchResult,
3268 &mut ViewContext<V>,
3269 ) -> bool,
3270 {
3271 let observer = self.weak_handle();
3272 self.window_context
3273 .observe_keystrokes(move |keystroke, result, handled_by, cx| {
3274 if let Some(observer) = observer.upgrade(cx) {
3275 observer.update(cx, |observer, cx| {
3276 callback(observer, keystroke, handled_by, result, cx);
3277 });
3278 true
3279 } else {
3280 false
3281 }
3282 })
3283 }
3284
3285 pub fn observe_window_bounds<F>(&mut self, mut callback: F) -> Subscription
3286 where
3287 F: 'static + FnMut(&mut V, WindowBounds, Uuid, &mut ViewContext<V>),
3288 {
3289 let observer = self.weak_handle();
3290 self.window_context
3291 .observe_window_bounds(move |bounds, display, cx| {
3292 if let Some(observer) = observer.upgrade(cx) {
3293 observer.update(cx, |observer, cx| {
3294 callback(observer, bounds, display, cx);
3295 });
3296 true
3297 } else {
3298 false
3299 }
3300 })
3301 }
3302
3303 pub fn observe_active_labeled_tasks<F>(&mut self, mut callback: F) -> Subscription
3304 where
3305 F: 'static + FnMut(&mut V, &mut ViewContext<V>),
3306 {
3307 let window_id = self.window_id;
3308 let observer = self.weak_handle();
3309 self.window_context.observe_active_labeled_tasks(move |cx| {
3310 cx.update_window(window_id, |cx| {
3311 if let Some(observer) = observer.upgrade(cx) {
3312 observer.update(cx, |observer, cx| {
3313 callback(observer, cx);
3314 });
3315 true
3316 } else {
3317 false
3318 }
3319 })
3320 .unwrap_or(false)
3321 })
3322 }
3323
3324 pub fn emit(&mut self, payload: V::Event) {
3325 self.window_context
3326 .pending_effects
3327 .push_back(Effect::Event {
3328 entity_id: self.view_id,
3329 payload: Box::new(payload),
3330 });
3331 }
3332
3333 pub fn notify(&mut self) {
3334 let window_id = self.window_id;
3335 let view_id = self.view_id;
3336 self.window_context.notify_view(window_id, view_id);
3337 }
3338
3339 pub fn dispatch_action(&mut self, action: impl Action) {
3340 let window_id = self.window_id;
3341 let view_id = self.view_id;
3342 self.window_context
3343 .dispatch_action_at(window_id, view_id, action)
3344 }
3345
3346 pub fn dispatch_any_action(&mut self, action: Box<dyn Action>) {
3347 let window_id = self.window_id;
3348 let view_id = self.view_id;
3349 self.window_context
3350 .dispatch_any_action_at(window_id, view_id, action)
3351 }
3352
3353 pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut V, &mut ViewContext<V>)) {
3354 let handle = self.handle();
3355 self.window_context
3356 .defer(move |cx| handle.update(cx, |view, cx| callback(view, cx)))
3357 }
3358
3359 pub fn after_window_update(
3360 &mut self,
3361 callback: impl 'static + FnOnce(&mut V, &mut ViewContext<V>),
3362 ) {
3363 let window_id = self.window_id;
3364 let handle = self.handle();
3365 self.window_context.after_window_update(move |cx| {
3366 cx.update_window(window_id, |cx| {
3367 handle.update(cx, |view, cx| {
3368 callback(view, cx);
3369 })
3370 });
3371 })
3372 }
3373
3374 pub fn propagate_action(&mut self) {
3375 self.window_context.halt_action_dispatch = false;
3376 }
3377
3378 pub fn spawn_labeled<F, Fut, S>(&mut self, task_label: &'static str, f: F) -> Task<S>
3379 where
3380 F: FnOnce(ViewHandle<V>, AsyncAppContext) -> Fut,
3381 Fut: 'static + Future<Output = S>,
3382 S: 'static,
3383 {
3384 let handle = self.handle();
3385 self.window_context
3386 .spawn_labeled(task_label, |cx| f(handle, cx))
3387 }
3388
3389 pub fn spawn<F, Fut, S>(&mut self, f: F) -> Task<S>
3390 where
3391 F: FnOnce(ViewHandle<V>, AsyncAppContext) -> Fut,
3392 Fut: 'static + Future<Output = S>,
3393 S: 'static,
3394 {
3395 let handle = self.handle();
3396 self.window_context.spawn(|cx| f(handle, cx))
3397 }
3398
3399 pub fn spawn_weak<F, Fut, S>(&mut self, f: F) -> Task<S>
3400 where
3401 F: FnOnce(WeakViewHandle<V>, AsyncAppContext) -> Fut,
3402 Fut: 'static + Future<Output = S>,
3403 S: 'static,
3404 {
3405 let handle = self.weak_handle();
3406 self.window_context.spawn(|cx| f(handle, cx))
3407 }
3408
3409 pub fn mouse_state<Tag: 'static>(&self, region_id: usize) -> MouseState {
3410 let region_id = MouseRegionId::new::<Tag>(self.view_id, region_id);
3411 MouseState {
3412 hovered: self.window.hovered_region_ids.contains(®ion_id),
3413 clicked: self
3414 .window
3415 .clicked_region_ids
3416 .get(®ion_id)
3417 .and_then(|_| self.window.clicked_button),
3418 accessed_hovered: false,
3419 accessed_clicked: false,
3420 }
3421 }
3422
3423 pub fn element_state<Tag: 'static, T: 'static>(
3424 &mut self,
3425 element_id: usize,
3426 initial: T,
3427 ) -> ElementStateHandle<T> {
3428 let id = ElementStateId {
3429 view_id: self.view_id(),
3430 element_id,
3431 tag: TypeId::of::<Tag>(),
3432 };
3433 self.element_states
3434 .entry(id)
3435 .or_insert_with(|| Box::new(initial));
3436 ElementStateHandle::new(id, self.frame_count, &self.ref_counts)
3437 }
3438
3439 pub fn default_element_state<Tag: 'static, T: 'static + Default>(
3440 &mut self,
3441 element_id: usize,
3442 ) -> ElementStateHandle<T> {
3443 self.element_state::<Tag, T>(element_id, T::default())
3444 }
3445}
3446
3447impl<V> UpgradeModelHandle for ViewContext<'_, '_, '_, V> {
3448 fn upgrade_model_handle<T: Entity>(
3449 &self,
3450 handle: &WeakModelHandle<T>,
3451 ) -> Option<ModelHandle<T>> {
3452 self.window_context.upgrade_model_handle(handle)
3453 }
3454
3455 fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
3456 self.window_context.model_handle_is_upgradable(handle)
3457 }
3458
3459 fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
3460 self.window_context.upgrade_any_model_handle(handle)
3461 }
3462}
3463
3464impl<V> UpgradeViewHandle for ViewContext<'_, '_, '_, V> {
3465 fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
3466 self.window_context.upgrade_view_handle(handle)
3467 }
3468
3469 fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
3470 self.window_context.upgrade_any_view_handle(handle)
3471 }
3472}
3473
3474impl<V: View> ReadModel for ViewContext<'_, '_, '_, V> {
3475 fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
3476 self.window_context.read_model(handle)
3477 }
3478}
3479
3480impl<V: View> UpdateModel for ViewContext<'_, '_, '_, V> {
3481 fn update_model<T: Entity, O>(
3482 &mut self,
3483 handle: &ModelHandle<T>,
3484 update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
3485 ) -> O {
3486 self.window_context.update_model(handle, update)
3487 }
3488}
3489
3490impl<V: View> ReadView for ViewContext<'_, '_, '_, V> {
3491 fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
3492 self.window_context.read_view(handle)
3493 }
3494}
3495
3496impl<V: View> UpdateView for ViewContext<'_, '_, '_, V> {
3497 type Output<S> = S;
3498
3499 fn update_view<T, S>(
3500 &mut self,
3501 handle: &ViewHandle<T>,
3502 update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
3503 ) -> S
3504 where
3505 T: View,
3506 {
3507 self.window_context.update_view(handle, update)
3508 }
3509}
3510
3511pub struct EventContext<'a, 'b, 'c, 'd, V: View> {
3512 view_context: &'d mut ViewContext<'a, 'b, 'c, V>,
3513 pub(crate) handled: bool,
3514}
3515
3516impl<'a, 'b, 'c, 'd, V: View> EventContext<'a, 'b, 'c, 'd, V> {
3517 pub(crate) fn new(view_context: &'d mut ViewContext<'a, 'b, 'c, V>) -> Self {
3518 EventContext {
3519 view_context,
3520 handled: true,
3521 }
3522 }
3523
3524 pub fn propagate_event(&mut self) {
3525 self.handled = false;
3526 }
3527}
3528
3529impl<'a, 'b, 'c, 'd, V: View> Deref for EventContext<'a, 'b, 'c, 'd, V> {
3530 type Target = ViewContext<'a, 'b, 'c, V>;
3531
3532 fn deref(&self) -> &Self::Target {
3533 &self.view_context
3534 }
3535}
3536
3537impl<V: View> DerefMut for EventContext<'_, '_, '_, '_, V> {
3538 fn deref_mut(&mut self) -> &mut Self::Target {
3539 &mut self.view_context
3540 }
3541}
3542
3543impl<V: View> UpdateModel for EventContext<'_, '_, '_, '_, V> {
3544 fn update_model<T: Entity, O>(
3545 &mut self,
3546 handle: &ModelHandle<T>,
3547 update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
3548 ) -> O {
3549 self.view_context.update_model(handle, update)
3550 }
3551}
3552
3553impl<V: View> ReadView for EventContext<'_, '_, '_, '_, V> {
3554 fn read_view<W: View>(&self, handle: &crate::ViewHandle<W>) -> &W {
3555 self.view_context.read_view(handle)
3556 }
3557}
3558
3559impl<V: View> UpdateView for EventContext<'_, '_, '_, '_, V> {
3560 type Output<S> = S;
3561
3562 fn update_view<T, S>(
3563 &mut self,
3564 handle: &ViewHandle<T>,
3565 update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
3566 ) -> S
3567 where
3568 T: View,
3569 {
3570 self.view_context.update_view(handle, update)
3571 }
3572}
3573
3574impl<V: View> UpgradeModelHandle for EventContext<'_, '_, '_, '_, V> {
3575 fn upgrade_model_handle<T: Entity>(
3576 &self,
3577 handle: &WeakModelHandle<T>,
3578 ) -> Option<ModelHandle<T>> {
3579 self.view_context.upgrade_model_handle(handle)
3580 }
3581
3582 fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
3583 self.view_context.model_handle_is_upgradable(handle)
3584 }
3585
3586 fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
3587 self.view_context.upgrade_any_model_handle(handle)
3588 }
3589}
3590
3591impl<V: View> UpgradeViewHandle for EventContext<'_, '_, '_, '_, V> {
3592 fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
3593 self.view_context.upgrade_view_handle(handle)
3594 }
3595
3596 fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
3597 self.view_context.upgrade_any_view_handle(handle)
3598 }
3599}
3600
3601pub(crate) enum Reference<'a, T> {
3602 Immutable(&'a T),
3603 Mutable(&'a mut T),
3604}
3605
3606impl<'a, T> Deref for Reference<'a, T> {
3607 type Target = T;
3608
3609 fn deref(&self) -> &Self::Target {
3610 match self {
3611 Reference::Immutable(target) => target,
3612 Reference::Mutable(target) => target,
3613 }
3614 }
3615}
3616
3617impl<'a, T> DerefMut for Reference<'a, T> {
3618 fn deref_mut(&mut self) -> &mut Self::Target {
3619 match self {
3620 Reference::Immutable(_) => {
3621 panic!("cannot mutably deref an immutable reference. this is a bug in GPUI.");
3622 }
3623 Reference::Mutable(target) => target,
3624 }
3625 }
3626}
3627
3628#[derive(Debug, Clone, Default)]
3629pub struct MouseState {
3630 pub(crate) hovered: bool,
3631 pub(crate) clicked: Option<MouseButton>,
3632 pub(crate) accessed_hovered: bool,
3633 pub(crate) accessed_clicked: bool,
3634}
3635
3636impl MouseState {
3637 pub fn hovered(&mut self) -> bool {
3638 self.accessed_hovered = true;
3639 self.hovered
3640 }
3641
3642 pub fn clicked(&mut self) -> Option<MouseButton> {
3643 self.accessed_clicked = true;
3644 self.clicked
3645 }
3646
3647 pub fn accessed_hovered(&self) -> bool {
3648 self.accessed_hovered
3649 }
3650
3651 pub fn accessed_clicked(&self) -> bool {
3652 self.accessed_clicked
3653 }
3654}
3655
3656pub trait Handle<T> {
3657 type Weak: 'static;
3658 fn id(&self) -> usize;
3659 fn location(&self) -> EntityLocation;
3660 fn downgrade(&self) -> Self::Weak;
3661 fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
3662 where
3663 Self: Sized;
3664}
3665
3666pub trait WeakHandle {
3667 fn id(&self) -> usize;
3668}
3669
3670#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
3671pub enum EntityLocation {
3672 Model(usize),
3673 View(usize, usize),
3674}
3675
3676pub struct ModelHandle<T: Entity> {
3677 any_handle: AnyModelHandle,
3678 model_type: PhantomData<T>,
3679}
3680
3681impl<T: Entity> Deref for ModelHandle<T> {
3682 type Target = AnyModelHandle;
3683
3684 fn deref(&self) -> &Self::Target {
3685 &self.any_handle
3686 }
3687}
3688
3689impl<T: Entity> ModelHandle<T> {
3690 fn new(model_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
3691 Self {
3692 any_handle: AnyModelHandle::new(model_id, TypeId::of::<T>(), ref_counts.clone()),
3693 model_type: PhantomData,
3694 }
3695 }
3696
3697 pub fn downgrade(&self) -> WeakModelHandle<T> {
3698 WeakModelHandle::new(self.model_id)
3699 }
3700
3701 pub fn id(&self) -> usize {
3702 self.model_id
3703 }
3704
3705 pub fn read<'a, C: ReadModel>(&self, cx: &'a C) -> &'a T {
3706 cx.read_model(self)
3707 }
3708
3709 pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> S
3710 where
3711 C: ReadModelWith,
3712 F: FnOnce(&T, &AppContext) -> S,
3713 {
3714 let mut read = Some(read);
3715 cx.read_model_with(self, &mut |model, cx| {
3716 let read = read.take().unwrap();
3717 read(model, cx)
3718 })
3719 }
3720
3721 pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
3722 where
3723 C: UpdateModel,
3724 F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
3725 {
3726 let mut update = Some(update);
3727 cx.update_model(self, &mut |model, cx| {
3728 let update = update.take().unwrap();
3729 update(model, cx)
3730 })
3731 }
3732}
3733
3734impl<T: Entity> Clone for ModelHandle<T> {
3735 fn clone(&self) -> Self {
3736 Self::new(self.model_id, &self.ref_counts)
3737 }
3738}
3739
3740impl<T: Entity> PartialEq for ModelHandle<T> {
3741 fn eq(&self, other: &Self) -> bool {
3742 self.model_id == other.model_id
3743 }
3744}
3745
3746impl<T: Entity> Eq for ModelHandle<T> {}
3747
3748impl<T: Entity> PartialEq<WeakModelHandle<T>> for ModelHandle<T> {
3749 fn eq(&self, other: &WeakModelHandle<T>) -> bool {
3750 self.model_id == other.model_id
3751 }
3752}
3753
3754impl<T: Entity> Hash for ModelHandle<T> {
3755 fn hash<H: Hasher>(&self, state: &mut H) {
3756 self.model_id.hash(state);
3757 }
3758}
3759
3760impl<T: Entity> std::borrow::Borrow<usize> for ModelHandle<T> {
3761 fn borrow(&self) -> &usize {
3762 &self.model_id
3763 }
3764}
3765
3766impl<T: Entity> Debug for ModelHandle<T> {
3767 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3768 f.debug_tuple(&format!("ModelHandle<{}>", type_name::<T>()))
3769 .field(&self.model_id)
3770 .finish()
3771 }
3772}
3773
3774unsafe impl<T: Entity> Send for ModelHandle<T> {}
3775unsafe impl<T: Entity> Sync for ModelHandle<T> {}
3776
3777impl<T: Entity> Handle<T> for ModelHandle<T> {
3778 type Weak = WeakModelHandle<T>;
3779
3780 fn id(&self) -> usize {
3781 self.model_id
3782 }
3783
3784 fn location(&self) -> EntityLocation {
3785 EntityLocation::Model(self.model_id)
3786 }
3787
3788 fn downgrade(&self) -> Self::Weak {
3789 self.downgrade()
3790 }
3791
3792 fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
3793 where
3794 Self: Sized,
3795 {
3796 weak.upgrade(cx)
3797 }
3798}
3799
3800pub struct WeakModelHandle<T> {
3801 any_handle: AnyWeakModelHandle,
3802 model_type: PhantomData<T>,
3803}
3804
3805impl<T> WeakModelHandle<T> {
3806 pub fn into_any(self) -> AnyWeakModelHandle {
3807 self.any_handle
3808 }
3809}
3810
3811impl<T> Deref for WeakModelHandle<T> {
3812 type Target = AnyWeakModelHandle;
3813
3814 fn deref(&self) -> &Self::Target {
3815 &self.any_handle
3816 }
3817}
3818
3819impl<T> WeakHandle for WeakModelHandle<T> {
3820 fn id(&self) -> usize {
3821 self.model_id
3822 }
3823}
3824
3825unsafe impl<T> Send for WeakModelHandle<T> {}
3826unsafe impl<T> Sync for WeakModelHandle<T> {}
3827
3828impl<T: Entity> WeakModelHandle<T> {
3829 fn new(model_id: usize) -> Self {
3830 Self {
3831 any_handle: AnyWeakModelHandle {
3832 model_id,
3833 model_type: TypeId::of::<T>(),
3834 },
3835 model_type: PhantomData,
3836 }
3837 }
3838
3839 pub fn id(&self) -> usize {
3840 self.model_id
3841 }
3842
3843 pub fn is_upgradable(&self, cx: &impl UpgradeModelHandle) -> bool {
3844 cx.model_handle_is_upgradable(self)
3845 }
3846
3847 pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<ModelHandle<T>> {
3848 cx.upgrade_model_handle(self)
3849 }
3850}
3851
3852impl<T> Hash for WeakModelHandle<T> {
3853 fn hash<H: Hasher>(&self, state: &mut H) {
3854 self.model_id.hash(state)
3855 }
3856}
3857
3858impl<T> PartialEq for WeakModelHandle<T> {
3859 fn eq(&self, other: &Self) -> bool {
3860 self.model_id == other.model_id
3861 }
3862}
3863
3864impl<T> Eq for WeakModelHandle<T> {}
3865
3866impl<T: Entity> PartialEq<ModelHandle<T>> for WeakModelHandle<T> {
3867 fn eq(&self, other: &ModelHandle<T>) -> bool {
3868 self.model_id == other.model_id
3869 }
3870}
3871
3872impl<T> Clone for WeakModelHandle<T> {
3873 fn clone(&self) -> Self {
3874 Self {
3875 any_handle: self.any_handle.clone(),
3876 model_type: PhantomData,
3877 }
3878 }
3879}
3880
3881impl<T> Copy for WeakModelHandle<T> {}
3882
3883#[repr(transparent)]
3884pub struct ViewHandle<T> {
3885 any_handle: AnyViewHandle,
3886 view_type: PhantomData<T>,
3887}
3888
3889impl<T> Deref for ViewHandle<T> {
3890 type Target = AnyViewHandle;
3891
3892 fn deref(&self) -> &Self::Target {
3893 &self.any_handle
3894 }
3895}
3896
3897impl<T: View> ViewHandle<T> {
3898 fn new(window_id: usize, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
3899 Self {
3900 any_handle: AnyViewHandle::new(
3901 window_id,
3902 view_id,
3903 TypeId::of::<T>(),
3904 ref_counts.clone(),
3905 ),
3906 view_type: PhantomData,
3907 }
3908 }
3909
3910 pub fn downgrade(&self) -> WeakViewHandle<T> {
3911 WeakViewHandle::new(self.window_id, self.view_id)
3912 }
3913
3914 pub fn into_any(self) -> AnyViewHandle {
3915 self.any_handle
3916 }
3917
3918 pub fn window_id(&self) -> usize {
3919 self.window_id
3920 }
3921
3922 pub fn id(&self) -> usize {
3923 self.view_id
3924 }
3925
3926 pub fn read<'a, C: ReadView>(&self, cx: &'a C) -> &'a T {
3927 cx.read_view(self)
3928 }
3929
3930 pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> S
3931 where
3932 C: ReadViewWith,
3933 F: FnOnce(&T, &AppContext) -> S,
3934 {
3935 let mut read = Some(read);
3936 cx.read_view_with(self, &mut |view, cx| {
3937 let read = read.take().unwrap();
3938 read(view, cx)
3939 })
3940 }
3941
3942 pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> C::Output<S>
3943 where
3944 C: UpdateView,
3945 F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
3946 {
3947 let mut update = Some(update);
3948 cx.update_view(self, &mut |view, cx| {
3949 let update = update.take().unwrap();
3950 update(view, cx)
3951 })
3952 }
3953
3954 pub fn is_focused(&self, cx: &WindowContext) -> bool {
3955 cx.focused_view_id() == Some(self.view_id)
3956 }
3957}
3958
3959impl<T: View> Clone for ViewHandle<T> {
3960 fn clone(&self) -> Self {
3961 ViewHandle::new(self.window_id, self.view_id, &self.ref_counts)
3962 }
3963}
3964
3965impl<T> PartialEq for ViewHandle<T> {
3966 fn eq(&self, other: &Self) -> bool {
3967 self.window_id == other.window_id && self.view_id == other.view_id
3968 }
3969}
3970
3971impl<T> PartialEq<WeakViewHandle<T>> for ViewHandle<T> {
3972 fn eq(&self, other: &WeakViewHandle<T>) -> bool {
3973 self.window_id == other.window_id && self.view_id == other.view_id
3974 }
3975}
3976
3977impl<T> PartialEq<ViewHandle<T>> for WeakViewHandle<T> {
3978 fn eq(&self, other: &ViewHandle<T>) -> bool {
3979 self.window_id == other.window_id && self.view_id == other.view_id
3980 }
3981}
3982
3983impl<T> Eq for ViewHandle<T> {}
3984
3985impl<T> Hash for ViewHandle<T> {
3986 fn hash<H: Hasher>(&self, state: &mut H) {
3987 self.window_id.hash(state);
3988 self.view_id.hash(state);
3989 }
3990}
3991
3992impl<T> Debug for ViewHandle<T> {
3993 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3994 f.debug_struct(&format!("ViewHandle<{}>", type_name::<T>()))
3995 .field("window_id", &self.window_id)
3996 .field("view_id", &self.view_id)
3997 .finish()
3998 }
3999}
4000
4001impl<T: View> Handle<T> for ViewHandle<T> {
4002 type Weak = WeakViewHandle<T>;
4003
4004 fn id(&self) -> usize {
4005 self.view_id
4006 }
4007
4008 fn location(&self) -> EntityLocation {
4009 EntityLocation::View(self.window_id, self.view_id)
4010 }
4011
4012 fn downgrade(&self) -> Self::Weak {
4013 self.downgrade()
4014 }
4015
4016 fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
4017 where
4018 Self: Sized,
4019 {
4020 weak.upgrade(cx)
4021 }
4022}
4023
4024pub struct AnyViewHandle {
4025 window_id: usize,
4026 view_id: usize,
4027 view_type: TypeId,
4028 ref_counts: Arc<Mutex<RefCounts>>,
4029
4030 #[cfg(any(test, feature = "test-support"))]
4031 handle_id: usize,
4032}
4033
4034impl AnyViewHandle {
4035 fn new(
4036 window_id: usize,
4037 view_id: usize,
4038 view_type: TypeId,
4039 ref_counts: Arc<Mutex<RefCounts>>,
4040 ) -> Self {
4041 ref_counts.lock().inc_view(window_id, view_id);
4042
4043 #[cfg(any(test, feature = "test-support"))]
4044 let handle_id = ref_counts
4045 .lock()
4046 .leak_detector
4047 .lock()
4048 .handle_created(None, view_id);
4049
4050 Self {
4051 window_id,
4052 view_id,
4053 view_type,
4054 ref_counts,
4055 #[cfg(any(test, feature = "test-support"))]
4056 handle_id,
4057 }
4058 }
4059
4060 pub fn window_id(&self) -> usize {
4061 self.window_id
4062 }
4063
4064 pub fn id(&self) -> usize {
4065 self.view_id
4066 }
4067
4068 pub fn is<T: 'static>(&self) -> bool {
4069 TypeId::of::<T>() == self.view_type
4070 }
4071
4072 pub fn downcast<T: View>(self) -> Option<ViewHandle<T>> {
4073 if self.is::<T>() {
4074 Some(ViewHandle {
4075 any_handle: self,
4076 view_type: PhantomData,
4077 })
4078 } else {
4079 None
4080 }
4081 }
4082
4083 pub fn downcast_ref<T: View>(&self) -> Option<&ViewHandle<T>> {
4084 if self.is::<T>() {
4085 Some(unsafe { mem::transmute(self) })
4086 } else {
4087 None
4088 }
4089 }
4090
4091 pub fn downgrade(&self) -> AnyWeakViewHandle {
4092 AnyWeakViewHandle {
4093 window_id: self.window_id,
4094 view_id: self.view_id,
4095 view_type: self.view_type,
4096 }
4097 }
4098
4099 pub fn view_type(&self) -> TypeId {
4100 self.view_type
4101 }
4102
4103 pub fn debug_json<'a, 'b>(&self, cx: &'b WindowContext<'a, 'b>) -> serde_json::Value {
4104 cx.views
4105 .get(&(self.window_id, self.view_id))
4106 .map_or_else(|| serde_json::Value::Null, |view| view.debug_json(cx))
4107 }
4108}
4109
4110impl Clone for AnyViewHandle {
4111 fn clone(&self) -> Self {
4112 Self::new(
4113 self.window_id,
4114 self.view_id,
4115 self.view_type,
4116 self.ref_counts.clone(),
4117 )
4118 }
4119}
4120
4121impl<T> PartialEq<ViewHandle<T>> for AnyViewHandle {
4122 fn eq(&self, other: &ViewHandle<T>) -> bool {
4123 self.window_id == other.window_id && self.view_id == other.view_id
4124 }
4125}
4126
4127impl Drop for AnyViewHandle {
4128 fn drop(&mut self) {
4129 self.ref_counts
4130 .lock()
4131 .dec_view(self.window_id, self.view_id);
4132 #[cfg(any(test, feature = "test-support"))]
4133 self.ref_counts
4134 .lock()
4135 .leak_detector
4136 .lock()
4137 .handle_dropped(self.view_id, self.handle_id);
4138 }
4139}
4140
4141pub struct AnyModelHandle {
4142 model_id: usize,
4143 model_type: TypeId,
4144 ref_counts: Arc<Mutex<RefCounts>>,
4145
4146 #[cfg(any(test, feature = "test-support"))]
4147 handle_id: usize,
4148}
4149
4150impl AnyModelHandle {
4151 fn new(model_id: usize, model_type: TypeId, ref_counts: Arc<Mutex<RefCounts>>) -> Self {
4152 ref_counts.lock().inc_model(model_id);
4153
4154 #[cfg(any(test, feature = "test-support"))]
4155 let handle_id = ref_counts
4156 .lock()
4157 .leak_detector
4158 .lock()
4159 .handle_created(None, model_id);
4160
4161 Self {
4162 model_id,
4163 model_type,
4164 ref_counts,
4165
4166 #[cfg(any(test, feature = "test-support"))]
4167 handle_id,
4168 }
4169 }
4170
4171 pub fn downcast<T: Entity>(self) -> Option<ModelHandle<T>> {
4172 if self.is::<T>() {
4173 Some(ModelHandle {
4174 any_handle: self,
4175 model_type: PhantomData,
4176 })
4177 } else {
4178 None
4179 }
4180 }
4181
4182 pub fn downgrade(&self) -> AnyWeakModelHandle {
4183 AnyWeakModelHandle {
4184 model_id: self.model_id,
4185 model_type: self.model_type,
4186 }
4187 }
4188
4189 pub fn is<T: Entity>(&self) -> bool {
4190 self.model_type == TypeId::of::<T>()
4191 }
4192
4193 pub fn model_type(&self) -> TypeId {
4194 self.model_type
4195 }
4196}
4197
4198impl Clone for AnyModelHandle {
4199 fn clone(&self) -> Self {
4200 Self::new(self.model_id, self.model_type, self.ref_counts.clone())
4201 }
4202}
4203
4204impl Drop for AnyModelHandle {
4205 fn drop(&mut self) {
4206 let mut ref_counts = self.ref_counts.lock();
4207 ref_counts.dec_model(self.model_id);
4208
4209 #[cfg(any(test, feature = "test-support"))]
4210 ref_counts
4211 .leak_detector
4212 .lock()
4213 .handle_dropped(self.model_id, self.handle_id);
4214 }
4215}
4216
4217#[derive(Hash, PartialEq, Eq, Debug, Clone, Copy)]
4218pub struct AnyWeakModelHandle {
4219 model_id: usize,
4220 model_type: TypeId,
4221}
4222
4223impl AnyWeakModelHandle {
4224 pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<AnyModelHandle> {
4225 cx.upgrade_any_model_handle(self)
4226 }
4227 pub fn model_type(&self) -> TypeId {
4228 self.model_type
4229 }
4230
4231 fn is<T: 'static>(&self) -> bool {
4232 TypeId::of::<T>() == self.model_type
4233 }
4234
4235 pub fn downcast<T: Entity>(self) -> Option<WeakModelHandle<T>> {
4236 if self.is::<T>() {
4237 let result = Some(WeakModelHandle {
4238 any_handle: self,
4239 model_type: PhantomData,
4240 });
4241
4242 result
4243 } else {
4244 None
4245 }
4246 }
4247}
4248
4249#[derive(Debug, Copy)]
4250pub struct WeakViewHandle<T> {
4251 any_handle: AnyWeakViewHandle,
4252 view_type: PhantomData<T>,
4253}
4254
4255impl<T> WeakHandle for WeakViewHandle<T> {
4256 fn id(&self) -> usize {
4257 self.view_id
4258 }
4259}
4260
4261impl<T: View> WeakViewHandle<T> {
4262 fn new(window_id: usize, view_id: usize) -> Self {
4263 Self {
4264 any_handle: AnyWeakViewHandle {
4265 window_id,
4266 view_id,
4267 view_type: TypeId::of::<T>(),
4268 },
4269 view_type: PhantomData,
4270 }
4271 }
4272
4273 pub fn id(&self) -> usize {
4274 self.view_id
4275 }
4276
4277 pub fn window_id(&self) -> usize {
4278 self.window_id
4279 }
4280
4281 pub fn into_any(self) -> AnyWeakViewHandle {
4282 self.any_handle
4283 }
4284
4285 pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<ViewHandle<T>> {
4286 cx.upgrade_view_handle(self)
4287 }
4288}
4289
4290impl<T> Deref for WeakViewHandle<T> {
4291 type Target = AnyWeakViewHandle;
4292
4293 fn deref(&self) -> &Self::Target {
4294 &self.any_handle
4295 }
4296}
4297
4298impl<T> Clone for WeakViewHandle<T> {
4299 fn clone(&self) -> Self {
4300 Self {
4301 any_handle: self.any_handle.clone(),
4302 view_type: PhantomData,
4303 }
4304 }
4305}
4306
4307impl<T> PartialEq for WeakViewHandle<T> {
4308 fn eq(&self, other: &Self) -> bool {
4309 self.window_id == other.window_id && self.view_id == other.view_id
4310 }
4311}
4312
4313impl<T> Eq for WeakViewHandle<T> {}
4314
4315impl<T> Hash for WeakViewHandle<T> {
4316 fn hash<H: Hasher>(&self, state: &mut H) {
4317 self.any_handle.hash(state);
4318 }
4319}
4320
4321#[derive(Debug, Clone, Copy)]
4322pub struct AnyWeakViewHandle {
4323 window_id: usize,
4324 view_id: usize,
4325 view_type: TypeId,
4326}
4327
4328impl AnyWeakViewHandle {
4329 pub fn id(&self) -> usize {
4330 self.view_id
4331 }
4332
4333 pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<AnyViewHandle> {
4334 cx.upgrade_any_view_handle(self)
4335 }
4336}
4337
4338impl Hash for AnyWeakViewHandle {
4339 fn hash<H: Hasher>(&self, state: &mut H) {
4340 self.window_id.hash(state);
4341 self.view_id.hash(state);
4342 self.view_type.hash(state);
4343 }
4344}
4345
4346#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4347pub struct ElementStateId {
4348 view_id: usize,
4349 element_id: usize,
4350 tag: TypeId,
4351}
4352
4353pub struct ElementStateHandle<T> {
4354 value_type: PhantomData<T>,
4355 id: ElementStateId,
4356 ref_counts: Weak<Mutex<RefCounts>>,
4357}
4358
4359impl<T: 'static> ElementStateHandle<T> {
4360 fn new(id: ElementStateId, frame_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
4361 ref_counts.lock().inc_element_state(id, frame_id);
4362 Self {
4363 value_type: PhantomData,
4364 id,
4365 ref_counts: Arc::downgrade(ref_counts),
4366 }
4367 }
4368
4369 pub fn id(&self) -> ElementStateId {
4370 self.id
4371 }
4372
4373 pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
4374 cx.element_states
4375 .get(&self.id)
4376 .unwrap()
4377 .downcast_ref()
4378 .unwrap()
4379 }
4380
4381 pub fn update<C, D, R>(&self, cx: &mut C, f: impl FnOnce(&mut T, &mut C) -> R) -> R
4382 where
4383 C: DerefMut<Target = D>,
4384 D: DerefMut<Target = AppContext>,
4385 {
4386 let mut element_state = cx.deref_mut().element_states.remove(&self.id).unwrap();
4387 let result = f(element_state.downcast_mut().unwrap(), cx);
4388 cx.deref_mut().element_states.insert(self.id, element_state);
4389 result
4390 }
4391}
4392
4393impl<T> Drop for ElementStateHandle<T> {
4394 fn drop(&mut self) {
4395 if let Some(ref_counts) = self.ref_counts.upgrade() {
4396 ref_counts.lock().dec_element_state(self.id);
4397 }
4398 }
4399}
4400
4401#[must_use]
4402pub enum Subscription {
4403 Subscription(callback_collection::Subscription<usize, SubscriptionCallback>),
4404 Observation(callback_collection::Subscription<usize, ObservationCallback>),
4405 GlobalSubscription(callback_collection::Subscription<TypeId, GlobalSubscriptionCallback>),
4406 GlobalObservation(callback_collection::Subscription<TypeId, GlobalObservationCallback>),
4407 FocusObservation(callback_collection::Subscription<usize, FocusObservationCallback>),
4408 WindowActivationObservation(callback_collection::Subscription<usize, WindowActivationCallback>),
4409 WindowFullscreenObservation(callback_collection::Subscription<usize, WindowFullscreenCallback>),
4410 WindowBoundsObservation(callback_collection::Subscription<usize, WindowBoundsCallback>),
4411 KeystrokeObservation(callback_collection::Subscription<usize, KeystrokeCallback>),
4412 ReleaseObservation(callback_collection::Subscription<usize, ReleaseObservationCallback>),
4413 ActionObservation(callback_collection::Subscription<(), ActionObservationCallback>),
4414 ActiveLabeledTasksObservation(
4415 callback_collection::Subscription<(), ActiveLabeledTasksCallback>,
4416 ),
4417}
4418
4419impl Subscription {
4420 pub fn id(&self) -> usize {
4421 match self {
4422 Subscription::Subscription(subscription) => subscription.id(),
4423 Subscription::Observation(subscription) => subscription.id(),
4424 Subscription::GlobalSubscription(subscription) => subscription.id(),
4425 Subscription::GlobalObservation(subscription) => subscription.id(),
4426 Subscription::FocusObservation(subscription) => subscription.id(),
4427 Subscription::WindowActivationObservation(subscription) => subscription.id(),
4428 Subscription::WindowFullscreenObservation(subscription) => subscription.id(),
4429 Subscription::WindowBoundsObservation(subscription) => subscription.id(),
4430 Subscription::KeystrokeObservation(subscription) => subscription.id(),
4431 Subscription::ReleaseObservation(subscription) => subscription.id(),
4432 Subscription::ActionObservation(subscription) => subscription.id(),
4433 Subscription::ActiveLabeledTasksObservation(subscription) => subscription.id(),
4434 }
4435 }
4436
4437 pub fn detach(&mut self) {
4438 match self {
4439 Subscription::Subscription(subscription) => subscription.detach(),
4440 Subscription::GlobalSubscription(subscription) => subscription.detach(),
4441 Subscription::Observation(subscription) => subscription.detach(),
4442 Subscription::GlobalObservation(subscription) => subscription.detach(),
4443 Subscription::FocusObservation(subscription) => subscription.detach(),
4444 Subscription::KeystrokeObservation(subscription) => subscription.detach(),
4445 Subscription::WindowActivationObservation(subscription) => subscription.detach(),
4446 Subscription::WindowFullscreenObservation(subscription) => subscription.detach(),
4447 Subscription::WindowBoundsObservation(subscription) => subscription.detach(),
4448 Subscription::ReleaseObservation(subscription) => subscription.detach(),
4449 Subscription::ActionObservation(subscription) => subscription.detach(),
4450 Subscription::ActiveLabeledTasksObservation(subscription) => subscription.detach(),
4451 }
4452 }
4453}
4454
4455#[cfg(test)]
4456mod tests {
4457 use super::*;
4458 use crate::{
4459 actions,
4460 elements::*,
4461 impl_actions,
4462 platform::{MouseButton, MouseButtonEvent},
4463 window::ChildView,
4464 };
4465 use itertools::Itertools;
4466 use postage::{sink::Sink, stream::Stream};
4467 use serde::Deserialize;
4468 use smol::future::poll_once;
4469 use std::{
4470 cell::Cell,
4471 sync::atomic::{AtomicBool, AtomicUsize, Ordering::SeqCst},
4472 };
4473
4474 #[crate::test(self)]
4475 fn test_model_handles(cx: &mut AppContext) {
4476 struct Model {
4477 other: Option<ModelHandle<Model>>,
4478 events: Vec<String>,
4479 }
4480
4481 impl Entity for Model {
4482 type Event = usize;
4483 }
4484
4485 impl Model {
4486 fn new(other: Option<ModelHandle<Self>>, cx: &mut ModelContext<Self>) -> Self {
4487 if let Some(other) = other.as_ref() {
4488 cx.observe(other, |me, _, _| {
4489 me.events.push("notified".into());
4490 })
4491 .detach();
4492 cx.subscribe(other, |me, _, event, _| {
4493 me.events.push(format!("observed event {}", event));
4494 })
4495 .detach();
4496 }
4497
4498 Self {
4499 other,
4500 events: Vec::new(),
4501 }
4502 }
4503 }
4504
4505 let handle_1 = cx.add_model(|cx| Model::new(None, cx));
4506 let handle_2 = cx.add_model(|cx| Model::new(Some(handle_1.clone()), cx));
4507 assert_eq!(cx.models.len(), 2);
4508
4509 handle_1.update(cx, |model, cx| {
4510 model.events.push("updated".into());
4511 cx.emit(1);
4512 cx.notify();
4513 cx.emit(2);
4514 });
4515 assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
4516 assert_eq!(
4517 handle_2.read(cx).events,
4518 vec![
4519 "observed event 1".to_string(),
4520 "notified".to_string(),
4521 "observed event 2".to_string(),
4522 ]
4523 );
4524
4525 handle_2.update(cx, |model, _| {
4526 drop(handle_1);
4527 model.other.take();
4528 });
4529
4530 assert_eq!(cx.models.len(), 1);
4531 assert!(cx.subscriptions.is_empty());
4532 assert!(cx.observations.is_empty());
4533 }
4534
4535 #[crate::test(self)]
4536 fn test_model_events(cx: &mut AppContext) {
4537 #[derive(Default)]
4538 struct Model {
4539 events: Vec<usize>,
4540 }
4541
4542 impl Entity for Model {
4543 type Event = usize;
4544 }
4545
4546 let handle_1 = cx.add_model(|_| Model::default());
4547 let handle_2 = cx.add_model(|_| Model::default());
4548
4549 handle_1.update(cx, |_, cx| {
4550 cx.subscribe(&handle_2, move |model: &mut Model, emitter, event, cx| {
4551 model.events.push(*event);
4552
4553 cx.subscribe(&emitter, |model, _, event, _| {
4554 model.events.push(*event * 2);
4555 })
4556 .detach();
4557 })
4558 .detach();
4559 });
4560
4561 handle_2.update(cx, |_, c| c.emit(7));
4562 assert_eq!(handle_1.read(cx).events, vec![7]);
4563
4564 handle_2.update(cx, |_, c| c.emit(5));
4565 assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
4566 }
4567
4568 #[crate::test(self)]
4569 fn test_model_emit_before_subscribe_in_same_update_cycle(cx: &mut AppContext) {
4570 #[derive(Default)]
4571 struct Model;
4572
4573 impl Entity for Model {
4574 type Event = ();
4575 }
4576
4577 let events = Rc::new(RefCell::new(Vec::new()));
4578 cx.add_model(|cx| {
4579 drop(cx.subscribe(&cx.handle(), {
4580 let events = events.clone();
4581 move |_, _, _, _| events.borrow_mut().push("dropped before flush")
4582 }));
4583 cx.subscribe(&cx.handle(), {
4584 let events = events.clone();
4585 move |_, _, _, _| events.borrow_mut().push("before emit")
4586 })
4587 .detach();
4588 cx.emit(());
4589 cx.subscribe(&cx.handle(), {
4590 let events = events.clone();
4591 move |_, _, _, _| events.borrow_mut().push("after emit")
4592 })
4593 .detach();
4594 Model
4595 });
4596 assert_eq!(*events.borrow(), ["before emit"]);
4597 }
4598
4599 #[crate::test(self)]
4600 fn test_observe_and_notify_from_model(cx: &mut AppContext) {
4601 #[derive(Default)]
4602 struct Model {
4603 count: usize,
4604 events: Vec<usize>,
4605 }
4606
4607 impl Entity for Model {
4608 type Event = ();
4609 }
4610
4611 let handle_1 = cx.add_model(|_| Model::default());
4612 let handle_2 = cx.add_model(|_| Model::default());
4613
4614 handle_1.update(cx, |_, c| {
4615 c.observe(&handle_2, move |model, observed, c| {
4616 model.events.push(observed.read(c).count);
4617 c.observe(&observed, |model, observed, c| {
4618 model.events.push(observed.read(c).count * 2);
4619 })
4620 .detach();
4621 })
4622 .detach();
4623 });
4624
4625 handle_2.update(cx, |model, c| {
4626 model.count = 7;
4627 c.notify()
4628 });
4629 assert_eq!(handle_1.read(cx).events, vec![7]);
4630
4631 handle_2.update(cx, |model, c| {
4632 model.count = 5;
4633 c.notify()
4634 });
4635 assert_eq!(handle_1.read(cx).events, vec![7, 5, 10])
4636 }
4637
4638 #[crate::test(self)]
4639 fn test_model_notify_before_observe_in_same_update_cycle(cx: &mut AppContext) {
4640 #[derive(Default)]
4641 struct Model;
4642
4643 impl Entity for Model {
4644 type Event = ();
4645 }
4646
4647 let events = Rc::new(RefCell::new(Vec::new()));
4648 cx.add_model(|cx| {
4649 drop(cx.observe(&cx.handle(), {
4650 let events = events.clone();
4651 move |_, _, _| events.borrow_mut().push("dropped before flush")
4652 }));
4653 cx.observe(&cx.handle(), {
4654 let events = events.clone();
4655 move |_, _, _| events.borrow_mut().push("before notify")
4656 })
4657 .detach();
4658 cx.notify();
4659 cx.observe(&cx.handle(), {
4660 let events = events.clone();
4661 move |_, _, _| events.borrow_mut().push("after notify")
4662 })
4663 .detach();
4664 Model
4665 });
4666 assert_eq!(*events.borrow(), ["before notify"]);
4667 }
4668
4669 #[crate::test(self)]
4670 fn test_defer_and_after_window_update(cx: &mut TestAppContext) {
4671 struct View {
4672 render_count: usize,
4673 }
4674
4675 impl Entity for View {
4676 type Event = usize;
4677 }
4678
4679 impl super::View for View {
4680 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
4681 post_inc(&mut self.render_count);
4682 Empty::new().boxed()
4683 }
4684
4685 fn ui_name() -> &'static str {
4686 "View"
4687 }
4688 }
4689
4690 let (_, view) = cx.add_window(|_| View { render_count: 0 });
4691 let called_defer = Rc::new(AtomicBool::new(false));
4692 let called_after_window_update = Rc::new(AtomicBool::new(false));
4693
4694 view.update(cx, |this, cx| {
4695 assert_eq!(this.render_count, 1);
4696 cx.defer({
4697 let called_defer = called_defer.clone();
4698 move |this, _| {
4699 assert_eq!(this.render_count, 1);
4700 called_defer.store(true, SeqCst);
4701 }
4702 });
4703 cx.after_window_update({
4704 let called_after_window_update = called_after_window_update.clone();
4705 move |this, cx| {
4706 assert_eq!(this.render_count, 2);
4707 called_after_window_update.store(true, SeqCst);
4708 cx.notify();
4709 }
4710 });
4711 assert!(!called_defer.load(SeqCst));
4712 assert!(!called_after_window_update.load(SeqCst));
4713 cx.notify();
4714 });
4715
4716 assert!(called_defer.load(SeqCst));
4717 assert!(called_after_window_update.load(SeqCst));
4718 assert_eq!(view.read_with(cx, |view, _| view.render_count), 3);
4719 }
4720
4721 #[crate::test(self)]
4722 fn test_view_handles(cx: &mut TestAppContext) {
4723 struct View {
4724 other: Option<ViewHandle<View>>,
4725 events: Vec<String>,
4726 }
4727
4728 impl Entity for View {
4729 type Event = usize;
4730 }
4731
4732 impl super::View for View {
4733 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
4734 Empty::new().boxed()
4735 }
4736
4737 fn ui_name() -> &'static str {
4738 "View"
4739 }
4740 }
4741
4742 impl View {
4743 fn new(other: Option<ViewHandle<View>>, cx: &mut ViewContext<Self>) -> Self {
4744 if let Some(other) = other.as_ref() {
4745 cx.subscribe(other, |me, _, event, _| {
4746 me.events.push(format!("observed event {}", event));
4747 })
4748 .detach();
4749 }
4750 Self {
4751 other,
4752 events: Vec::new(),
4753 }
4754 }
4755 }
4756
4757 let (_, root_view) = cx.add_window(|cx| View::new(None, cx));
4758 let handle_1 = cx.add_view(&root_view, |cx| View::new(None, cx));
4759 let handle_2 = cx.add_view(&root_view, |cx| View::new(Some(handle_1.clone()), cx));
4760 assert_eq!(cx.read(|cx| cx.views.len()), 3);
4761
4762 handle_1.update(cx, |view, cx| {
4763 view.events.push("updated".into());
4764 cx.emit(1);
4765 cx.emit(2);
4766 });
4767 handle_1.read_with(cx, |view, _| {
4768 assert_eq!(view.events, vec!["updated".to_string()]);
4769 });
4770 handle_2.read_with(cx, |view, _| {
4771 assert_eq!(
4772 view.events,
4773 vec![
4774 "observed event 1".to_string(),
4775 "observed event 2".to_string(),
4776 ]
4777 );
4778 });
4779
4780 handle_2.update(cx, |view, _| {
4781 drop(handle_1);
4782 view.other.take();
4783 });
4784
4785 cx.read(|cx| {
4786 assert_eq!(cx.views.len(), 2);
4787 assert!(cx.subscriptions.is_empty());
4788 assert!(cx.observations.is_empty());
4789 });
4790 }
4791
4792 #[crate::test(self)]
4793 fn test_add_window(cx: &mut AppContext) {
4794 struct View {
4795 mouse_down_count: Arc<AtomicUsize>,
4796 }
4797
4798 impl Entity for View {
4799 type Event = ();
4800 }
4801
4802 impl super::View for View {
4803 fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
4804 enum Handler {}
4805 let mouse_down_count = self.mouse_down_count.clone();
4806 MouseEventHandler::<Handler, _>::new(0, cx, |_, _| Empty::new().boxed())
4807 .on_down(MouseButton::Left, move |_, _, _| {
4808 mouse_down_count.fetch_add(1, SeqCst);
4809 })
4810 .boxed()
4811 }
4812
4813 fn ui_name() -> &'static str {
4814 "View"
4815 }
4816 }
4817
4818 let mouse_down_count = Arc::new(AtomicUsize::new(0));
4819 let (window_id, _) = cx.add_window(Default::default(), |_| View {
4820 mouse_down_count: mouse_down_count.clone(),
4821 });
4822
4823 cx.update_window(window_id, |cx| {
4824 // Ensure window's root element is in a valid lifecycle state.
4825 cx.dispatch_event(
4826 Event::MouseDown(MouseButtonEvent {
4827 position: Default::default(),
4828 button: MouseButton::Left,
4829 modifiers: Default::default(),
4830 click_count: 1,
4831 }),
4832 false,
4833 );
4834 assert_eq!(mouse_down_count.load(SeqCst), 1);
4835 });
4836 }
4837
4838 #[crate::test(self)]
4839 fn test_entity_release_hooks(cx: &mut AppContext) {
4840 struct Model {
4841 released: Rc<Cell<bool>>,
4842 }
4843
4844 struct View {
4845 released: Rc<Cell<bool>>,
4846 }
4847
4848 impl Entity for Model {
4849 type Event = ();
4850
4851 fn release(&mut self, _: &mut AppContext) {
4852 self.released.set(true);
4853 }
4854 }
4855
4856 impl Entity for View {
4857 type Event = ();
4858
4859 fn release(&mut self, _: &mut AppContext) {
4860 self.released.set(true);
4861 }
4862 }
4863
4864 impl super::View for View {
4865 fn ui_name() -> &'static str {
4866 "View"
4867 }
4868
4869 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
4870 Empty::new().boxed()
4871 }
4872 }
4873
4874 let model_released = Rc::new(Cell::new(false));
4875 let model_release_observed = Rc::new(Cell::new(false));
4876 let view_released = Rc::new(Cell::new(false));
4877 let view_release_observed = Rc::new(Cell::new(false));
4878
4879 let model = cx.add_model(|_| Model {
4880 released: model_released.clone(),
4881 });
4882 let (window_id, view) = cx.add_window(Default::default(), |_| View {
4883 released: view_released.clone(),
4884 });
4885 assert!(!model_released.get());
4886 assert!(!view_released.get());
4887
4888 cx.observe_release(&model, {
4889 let model_release_observed = model_release_observed.clone();
4890 move |_, _| model_release_observed.set(true)
4891 })
4892 .detach();
4893 cx.observe_release(&view, {
4894 let view_release_observed = view_release_observed.clone();
4895 move |_, _| view_release_observed.set(true)
4896 })
4897 .detach();
4898
4899 cx.update(move |_| {
4900 drop(model);
4901 });
4902 assert!(model_released.get());
4903 assert!(model_release_observed.get());
4904
4905 drop(view);
4906 cx.remove_window(window_id);
4907 assert!(view_released.get());
4908 assert!(view_release_observed.get());
4909 }
4910
4911 #[crate::test(self)]
4912 fn test_view_events(cx: &mut TestAppContext) {
4913 struct Model;
4914
4915 impl Entity for Model {
4916 type Event = String;
4917 }
4918
4919 let (_, handle_1) = cx.add_window(|_| TestView::default());
4920 let handle_2 = cx.add_view(&handle_1, |_| TestView::default());
4921 let handle_3 = cx.add_model(|_| Model);
4922
4923 handle_1.update(cx, |_, cx| {
4924 cx.subscribe(&handle_2, move |me, emitter, event, cx| {
4925 me.events.push(event.clone());
4926
4927 cx.subscribe(&emitter, |me, _, event, _| {
4928 me.events.push(format!("{event} from inner"));
4929 })
4930 .detach();
4931 })
4932 .detach();
4933
4934 cx.subscribe(&handle_3, |me, _, event, _| {
4935 me.events.push(event.clone());
4936 })
4937 .detach();
4938 });
4939
4940 handle_2.update(cx, |_, c| c.emit("7".into()));
4941 handle_1.read_with(cx, |view, _| assert_eq!(view.events, ["7"]));
4942
4943 handle_2.update(cx, |_, c| c.emit("5".into()));
4944 handle_1.read_with(cx, |view, _| {
4945 assert_eq!(view.events, ["7", "5", "5 from inner"])
4946 });
4947
4948 handle_3.update(cx, |_, c| c.emit("9".into()));
4949 handle_1.read_with(cx, |view, _| {
4950 assert_eq!(view.events, ["7", "5", "5 from inner", "9"])
4951 });
4952 }
4953
4954 #[crate::test(self)]
4955 fn test_global_events(cx: &mut AppContext) {
4956 #[derive(Clone, Debug, Eq, PartialEq)]
4957 struct GlobalEvent(u64);
4958
4959 let events = Rc::new(RefCell::new(Vec::new()));
4960 let first_subscription;
4961 let second_subscription;
4962
4963 {
4964 let events = events.clone();
4965 first_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
4966 events.borrow_mut().push(("First", e.clone()));
4967 });
4968 }
4969
4970 {
4971 let events = events.clone();
4972 second_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
4973 events.borrow_mut().push(("Second", e.clone()));
4974 });
4975 }
4976
4977 cx.update(|cx| {
4978 cx.emit_global(GlobalEvent(1));
4979 cx.emit_global(GlobalEvent(2));
4980 });
4981
4982 drop(first_subscription);
4983
4984 cx.update(|cx| {
4985 cx.emit_global(GlobalEvent(3));
4986 });
4987
4988 drop(second_subscription);
4989
4990 cx.update(|cx| {
4991 cx.emit_global(GlobalEvent(4));
4992 });
4993
4994 assert_eq!(
4995 &*events.borrow(),
4996 &[
4997 ("First", GlobalEvent(1)),
4998 ("Second", GlobalEvent(1)),
4999 ("First", GlobalEvent(2)),
5000 ("Second", GlobalEvent(2)),
5001 ("Second", GlobalEvent(3)),
5002 ]
5003 );
5004 }
5005
5006 #[crate::test(self)]
5007 fn test_global_events_emitted_before_subscription_in_same_update_cycle(cx: &mut AppContext) {
5008 let events = Rc::new(RefCell::new(Vec::new()));
5009 cx.update(|cx| {
5010 {
5011 let events = events.clone();
5012 drop(cx.subscribe_global(move |_: &(), _| {
5013 events.borrow_mut().push("dropped before emit");
5014 }));
5015 }
5016
5017 {
5018 let events = events.clone();
5019 cx.subscribe_global(move |_: &(), _| {
5020 events.borrow_mut().push("before emit");
5021 })
5022 .detach();
5023 }
5024
5025 cx.emit_global(());
5026
5027 {
5028 let events = events.clone();
5029 cx.subscribe_global(move |_: &(), _| {
5030 events.borrow_mut().push("after emit");
5031 })
5032 .detach();
5033 }
5034 });
5035
5036 assert_eq!(*events.borrow(), ["before emit"]);
5037 }
5038
5039 #[crate::test(self)]
5040 fn test_global_nested_events(cx: &mut AppContext) {
5041 #[derive(Clone, Debug, Eq, PartialEq)]
5042 struct GlobalEvent(u64);
5043
5044 let events = Rc::new(RefCell::new(Vec::new()));
5045
5046 {
5047 let events = events.clone();
5048 cx.subscribe_global(move |e: &GlobalEvent, cx| {
5049 events.borrow_mut().push(("Outer", e.clone()));
5050
5051 if e.0 == 1 {
5052 let events = events.clone();
5053 cx.subscribe_global(move |e: &GlobalEvent, _| {
5054 events.borrow_mut().push(("Inner", e.clone()));
5055 })
5056 .detach();
5057 }
5058 })
5059 .detach();
5060 }
5061
5062 cx.update(|cx| {
5063 cx.emit_global(GlobalEvent(1));
5064 cx.emit_global(GlobalEvent(2));
5065 cx.emit_global(GlobalEvent(3));
5066 });
5067 cx.update(|cx| {
5068 cx.emit_global(GlobalEvent(4));
5069 });
5070
5071 assert_eq!(
5072 &*events.borrow(),
5073 &[
5074 ("Outer", GlobalEvent(1)),
5075 ("Outer", GlobalEvent(2)),
5076 ("Outer", GlobalEvent(3)),
5077 ("Outer", GlobalEvent(4)),
5078 ("Inner", GlobalEvent(4)),
5079 ]
5080 );
5081 }
5082
5083 #[crate::test(self)]
5084 fn test_global(cx: &mut AppContext) {
5085 type Global = usize;
5086
5087 let observation_count = Rc::new(RefCell::new(0));
5088 let subscription = cx.observe_global::<Global, _>({
5089 let observation_count = observation_count.clone();
5090 move |_| {
5091 *observation_count.borrow_mut() += 1;
5092 }
5093 });
5094
5095 assert!(!cx.has_global::<Global>());
5096 assert_eq!(cx.default_global::<Global>(), &0);
5097 assert_eq!(*observation_count.borrow(), 1);
5098 assert!(cx.has_global::<Global>());
5099 assert_eq!(
5100 cx.update_global::<Global, _, _>(|global, _| {
5101 *global = 1;
5102 "Update Result"
5103 }),
5104 "Update Result"
5105 );
5106 assert_eq!(*observation_count.borrow(), 2);
5107 assert_eq!(cx.global::<Global>(), &1);
5108
5109 drop(subscription);
5110 cx.update_global::<Global, _, _>(|global, _| {
5111 *global = 2;
5112 });
5113 assert_eq!(*observation_count.borrow(), 2);
5114
5115 type OtherGlobal = f32;
5116
5117 let observation_count = Rc::new(RefCell::new(0));
5118 cx.observe_global::<OtherGlobal, _>({
5119 let observation_count = observation_count.clone();
5120 move |_| {
5121 *observation_count.borrow_mut() += 1;
5122 }
5123 })
5124 .detach();
5125
5126 assert_eq!(
5127 cx.update_default_global::<OtherGlobal, _, _>(|global, _| {
5128 assert_eq!(global, &0.0);
5129 *global = 2.0;
5130 "Default update result"
5131 }),
5132 "Default update result"
5133 );
5134 assert_eq!(cx.global::<OtherGlobal>(), &2.0);
5135 assert_eq!(*observation_count.borrow(), 1);
5136 }
5137
5138 #[crate::test(self)]
5139 fn test_dropping_subscribers(cx: &mut TestAppContext) {
5140 struct Model;
5141
5142 impl Entity for Model {
5143 type Event = ();
5144 }
5145
5146 let (_, root_view) = cx.add_window(|_| TestView::default());
5147 let observing_view = cx.add_view(&root_view, |_| TestView::default());
5148 let emitting_view = cx.add_view(&root_view, |_| TestView::default());
5149 let observing_model = cx.add_model(|_| Model);
5150 let observed_model = cx.add_model(|_| Model);
5151
5152 observing_view.update(cx, |_, cx| {
5153 cx.subscribe(&emitting_view, |_, _, _, _| {}).detach();
5154 cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
5155 });
5156 observing_model.update(cx, |_, cx| {
5157 cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
5158 });
5159
5160 cx.update(|_| {
5161 drop(observing_view);
5162 drop(observing_model);
5163 });
5164
5165 emitting_view.update(cx, |_, cx| cx.emit(Default::default()));
5166 observed_model.update(cx, |_, cx| cx.emit(()));
5167 }
5168
5169 #[crate::test(self)]
5170 fn test_view_emit_before_subscribe_in_same_update_cycle(cx: &mut AppContext) {
5171 let (_, view) = cx.add_window::<TestView, _>(Default::default(), |cx| {
5172 drop(cx.subscribe(&cx.handle(), {
5173 move |this, _, _, _| this.events.push("dropped before flush".into())
5174 }));
5175 cx.subscribe(&cx.handle(), {
5176 move |this, _, _, _| this.events.push("before emit".into())
5177 })
5178 .detach();
5179 cx.emit("the event".into());
5180 cx.subscribe(&cx.handle(), {
5181 move |this, _, _, _| this.events.push("after emit".into())
5182 })
5183 .detach();
5184 TestView { events: Vec::new() }
5185 });
5186
5187 assert_eq!(view.read(cx).events, ["before emit"]);
5188 }
5189
5190 #[crate::test(self)]
5191 fn test_observe_and_notify_from_view(cx: &mut TestAppContext) {
5192 #[derive(Default)]
5193 struct Model {
5194 state: String,
5195 }
5196
5197 impl Entity for Model {
5198 type Event = ();
5199 }
5200
5201 let (_, view) = cx.add_window(|_| TestView::default());
5202 let model = cx.add_model(|_| Model {
5203 state: "old-state".into(),
5204 });
5205
5206 view.update(cx, |_, c| {
5207 c.observe(&model, |me, observed, cx| {
5208 me.events.push(observed.read(cx).state.clone())
5209 })
5210 .detach();
5211 });
5212
5213 model.update(cx, |model, cx| {
5214 model.state = "new-state".into();
5215 cx.notify();
5216 });
5217 view.read_with(cx, |view, _| assert_eq!(view.events, ["new-state"]));
5218 }
5219
5220 #[crate::test(self)]
5221 fn test_view_notify_before_observe_in_same_update_cycle(cx: &mut AppContext) {
5222 let (_, view) = cx.add_window::<TestView, _>(Default::default(), |cx| {
5223 drop(cx.observe(&cx.handle(), {
5224 move |this, _, _| this.events.push("dropped before flush".into())
5225 }));
5226 cx.observe(&cx.handle(), {
5227 move |this, _, _| this.events.push("before notify".into())
5228 })
5229 .detach();
5230 cx.notify();
5231 cx.observe(&cx.handle(), {
5232 move |this, _, _| this.events.push("after notify".into())
5233 })
5234 .detach();
5235 TestView { events: Vec::new() }
5236 });
5237
5238 assert_eq!(view.read(cx).events, ["before notify"]);
5239 }
5240
5241 #[crate::test(self)]
5242 fn test_notify_and_drop_observe_subscription_in_same_update_cycle(cx: &mut TestAppContext) {
5243 struct Model;
5244 impl Entity for Model {
5245 type Event = ();
5246 }
5247
5248 let model = cx.add_model(|_| Model);
5249 let (_, view) = cx.add_window(|_| TestView::default());
5250
5251 view.update(cx, |_, cx| {
5252 model.update(cx, |_, cx| cx.notify());
5253 drop(cx.observe(&model, move |this, _, _| {
5254 this.events.push("model notified".into());
5255 }));
5256 model.update(cx, |_, cx| cx.notify());
5257 });
5258
5259 for _ in 0..3 {
5260 model.update(cx, |_, cx| cx.notify());
5261 }
5262 view.read_with(cx, |view, _| assert_eq!(view.events, Vec::<&str>::new()));
5263 }
5264
5265 #[crate::test(self)]
5266 fn test_dropping_observers(cx: &mut TestAppContext) {
5267 struct Model;
5268
5269 impl Entity for Model {
5270 type Event = ();
5271 }
5272
5273 let (_, root_view) = cx.add_window(|_| TestView::default());
5274 let observing_view = cx.add_view(&root_view, |_| TestView::default());
5275 let observing_model = cx.add_model(|_| Model);
5276 let observed_model = cx.add_model(|_| Model);
5277
5278 observing_view.update(cx, |_, cx| {
5279 cx.observe(&observed_model, |_, _, _| {}).detach();
5280 });
5281 observing_model.update(cx, |_, cx| {
5282 cx.observe(&observed_model, |_, _, _| {}).detach();
5283 });
5284
5285 cx.update(|_| {
5286 drop(observing_view);
5287 drop(observing_model);
5288 });
5289
5290 observed_model.update(cx, |_, cx| cx.notify());
5291 }
5292
5293 #[crate::test(self)]
5294 fn test_dropping_subscriptions_during_callback(cx: &mut TestAppContext) {
5295 struct Model;
5296
5297 impl Entity for Model {
5298 type Event = u64;
5299 }
5300
5301 // Events
5302 let observing_model = cx.add_model(|_| Model);
5303 let observed_model = cx.add_model(|_| Model);
5304
5305 let events = Rc::new(RefCell::new(Vec::new()));
5306
5307 observing_model.update(cx, |_, cx| {
5308 let events = events.clone();
5309 let subscription = Rc::new(RefCell::new(None));
5310 *subscription.borrow_mut() = Some(cx.subscribe(&observed_model, {
5311 let subscription = subscription.clone();
5312 move |_, _, e, _| {
5313 subscription.borrow_mut().take();
5314 events.borrow_mut().push(*e);
5315 }
5316 }));
5317 });
5318
5319 observed_model.update(cx, |_, cx| {
5320 cx.emit(1);
5321 cx.emit(2);
5322 });
5323
5324 assert_eq!(*events.borrow(), [1]);
5325
5326 // Global Events
5327 #[derive(Clone, Debug, Eq, PartialEq)]
5328 struct GlobalEvent(u64);
5329
5330 let events = Rc::new(RefCell::new(Vec::new()));
5331
5332 {
5333 let events = events.clone();
5334 let subscription = Rc::new(RefCell::new(None));
5335 *subscription.borrow_mut() = Some(cx.subscribe_global({
5336 let subscription = subscription.clone();
5337 move |e: &GlobalEvent, _| {
5338 subscription.borrow_mut().take();
5339 events.borrow_mut().push(e.clone());
5340 }
5341 }));
5342 }
5343
5344 cx.update(|cx| {
5345 cx.emit_global(GlobalEvent(1));
5346 cx.emit_global(GlobalEvent(2));
5347 });
5348
5349 assert_eq!(*events.borrow(), [GlobalEvent(1)]);
5350
5351 // Model Observation
5352 let observing_model = cx.add_model(|_| Model);
5353 let observed_model = cx.add_model(|_| Model);
5354
5355 let observation_count = Rc::new(RefCell::new(0));
5356
5357 observing_model.update(cx, |_, cx| {
5358 let observation_count = observation_count.clone();
5359 let subscription = Rc::new(RefCell::new(None));
5360 *subscription.borrow_mut() = Some(cx.observe(&observed_model, {
5361 let subscription = subscription.clone();
5362 move |_, _, _| {
5363 subscription.borrow_mut().take();
5364 *observation_count.borrow_mut() += 1;
5365 }
5366 }));
5367 });
5368
5369 observed_model.update(cx, |_, cx| {
5370 cx.notify();
5371 });
5372
5373 observed_model.update(cx, |_, cx| {
5374 cx.notify();
5375 });
5376
5377 assert_eq!(*observation_count.borrow(), 1);
5378
5379 // View Observation
5380 struct View;
5381
5382 impl Entity for View {
5383 type Event = ();
5384 }
5385
5386 impl super::View for View {
5387 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
5388 Empty::new().boxed()
5389 }
5390
5391 fn ui_name() -> &'static str {
5392 "View"
5393 }
5394 }
5395
5396 let (_, root_view) = cx.add_window(|_| View);
5397 let observing_view = cx.add_view(&root_view, |_| View);
5398 let observed_view = cx.add_view(&root_view, |_| View);
5399
5400 let observation_count = Rc::new(RefCell::new(0));
5401 observing_view.update(cx, |_, cx| {
5402 let observation_count = observation_count.clone();
5403 let subscription = Rc::new(RefCell::new(None));
5404 *subscription.borrow_mut() = Some(cx.observe(&observed_view, {
5405 let subscription = subscription.clone();
5406 move |_, _, _| {
5407 subscription.borrow_mut().take();
5408 *observation_count.borrow_mut() += 1;
5409 }
5410 }));
5411 });
5412
5413 observed_view.update(cx, |_, cx| {
5414 cx.notify();
5415 });
5416
5417 observed_view.update(cx, |_, cx| {
5418 cx.notify();
5419 });
5420
5421 assert_eq!(*observation_count.borrow(), 1);
5422
5423 // Global Observation
5424 let observation_count = Rc::new(RefCell::new(0));
5425 let subscription = Rc::new(RefCell::new(None));
5426 *subscription.borrow_mut() = Some(cx.observe_global::<(), _>({
5427 let observation_count = observation_count.clone();
5428 let subscription = subscription.clone();
5429 move |_| {
5430 subscription.borrow_mut().take();
5431 *observation_count.borrow_mut() += 1;
5432 }
5433 }));
5434
5435 cx.update(|cx| {
5436 cx.default_global::<()>();
5437 cx.set_global(());
5438 });
5439 assert_eq!(*observation_count.borrow(), 1);
5440 }
5441
5442 #[crate::test(self)]
5443 fn test_focus(cx: &mut TestAppContext) {
5444 struct View {
5445 name: String,
5446 events: Arc<Mutex<Vec<String>>>,
5447 }
5448
5449 impl Entity for View {
5450 type Event = ();
5451 }
5452
5453 impl super::View for View {
5454 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
5455 Empty::new().boxed()
5456 }
5457
5458 fn ui_name() -> &'static str {
5459 "View"
5460 }
5461
5462 fn focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext<Self>) {
5463 if cx.handle().id() == focused.id() {
5464 self.events.lock().push(format!("{} focused", &self.name));
5465 }
5466 }
5467
5468 fn focus_out(&mut self, blurred: AnyViewHandle, cx: &mut ViewContext<Self>) {
5469 if cx.handle().id() == blurred.id() {
5470 self.events.lock().push(format!("{} blurred", &self.name));
5471 }
5472 }
5473 }
5474
5475 let view_events: Arc<Mutex<Vec<String>>> = Default::default();
5476 let (window_id, view_1) = cx.add_window(|_| View {
5477 events: view_events.clone(),
5478 name: "view 1".to_string(),
5479 });
5480 let view_2 = cx.add_view(&view_1, |_| View {
5481 events: view_events.clone(),
5482 name: "view 2".to_string(),
5483 });
5484
5485 let observed_events: Arc<Mutex<Vec<String>>> = Default::default();
5486 view_1.update(cx, |_, cx| {
5487 cx.observe_focus(&view_2, {
5488 let observed_events = observed_events.clone();
5489 move |this, view, focused, cx| {
5490 let label = if focused { "focus" } else { "blur" };
5491 observed_events.lock().push(format!(
5492 "{} observed {}'s {}",
5493 this.name,
5494 view.read(cx).name,
5495 label
5496 ))
5497 }
5498 })
5499 .detach();
5500 });
5501 view_2.update(cx, |_, cx| {
5502 cx.observe_focus(&view_1, {
5503 let observed_events = observed_events.clone();
5504 move |this, view, focused, cx| {
5505 let label = if focused { "focus" } else { "blur" };
5506 observed_events.lock().push(format!(
5507 "{} observed {}'s {}",
5508 this.name,
5509 view.read(cx).name,
5510 label
5511 ))
5512 }
5513 })
5514 .detach();
5515 });
5516 assert_eq!(mem::take(&mut *view_events.lock()), ["view 1 focused"]);
5517 assert_eq!(mem::take(&mut *observed_events.lock()), Vec::<&str>::new());
5518
5519 view_1.update(cx, |_, cx| {
5520 // Ensure focus events are sent for all intermediate focuses
5521 cx.focus(&view_2);
5522 cx.focus(&view_1);
5523 cx.focus(&view_2);
5524 });
5525
5526 cx.read_window(window_id, |cx| {
5527 assert!(cx.is_child_focused(&view_1));
5528 assert!(!cx.is_child_focused(&view_2));
5529 });
5530 assert_eq!(
5531 mem::take(&mut *view_events.lock()),
5532 [
5533 "view 1 blurred",
5534 "view 2 focused",
5535 "view 2 blurred",
5536 "view 1 focused",
5537 "view 1 blurred",
5538 "view 2 focused"
5539 ],
5540 );
5541 assert_eq!(
5542 mem::take(&mut *observed_events.lock()),
5543 [
5544 "view 2 observed view 1's blur",
5545 "view 1 observed view 2's focus",
5546 "view 1 observed view 2's blur",
5547 "view 2 observed view 1's focus",
5548 "view 2 observed view 1's blur",
5549 "view 1 observed view 2's focus"
5550 ]
5551 );
5552
5553 view_1.update(cx, |_, cx| cx.focus(&view_1));
5554 cx.read_window(window_id, |cx| {
5555 assert!(!cx.is_child_focused(&view_1));
5556 assert!(!cx.is_child_focused(&view_2));
5557 });
5558 assert_eq!(
5559 mem::take(&mut *view_events.lock()),
5560 ["view 2 blurred", "view 1 focused"],
5561 );
5562 assert_eq!(
5563 mem::take(&mut *observed_events.lock()),
5564 [
5565 "view 1 observed view 2's blur",
5566 "view 2 observed view 1's focus"
5567 ]
5568 );
5569
5570 view_1.update(cx, |_, cx| cx.focus(&view_2));
5571 assert_eq!(
5572 mem::take(&mut *view_events.lock()),
5573 ["view 1 blurred", "view 2 focused"],
5574 );
5575 assert_eq!(
5576 mem::take(&mut *observed_events.lock()),
5577 [
5578 "view 2 observed view 1's blur",
5579 "view 1 observed view 2's focus"
5580 ]
5581 );
5582
5583 view_1.update(cx, |_, _| drop(view_2));
5584 assert_eq!(mem::take(&mut *view_events.lock()), ["view 1 focused"]);
5585 assert_eq!(mem::take(&mut *observed_events.lock()), Vec::<&str>::new());
5586 }
5587
5588 #[crate::test(self)]
5589 fn test_deserialize_actions(cx: &mut AppContext) {
5590 #[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
5591 pub struct ComplexAction {
5592 arg: String,
5593 count: usize,
5594 }
5595
5596 actions!(test::something, [SimpleAction]);
5597 impl_actions!(test::something, [ComplexAction]);
5598
5599 cx.add_global_action(move |_: &SimpleAction, _: &mut AppContext| {});
5600 cx.add_global_action(move |_: &ComplexAction, _: &mut AppContext| {});
5601
5602 let action1 = cx
5603 .deserialize_action(
5604 "test::something::ComplexAction",
5605 Some(r#"{"arg": "a", "count": 5}"#),
5606 )
5607 .unwrap();
5608 let action2 = cx
5609 .deserialize_action("test::something::SimpleAction", None)
5610 .unwrap();
5611 assert_eq!(
5612 action1.as_any().downcast_ref::<ComplexAction>().unwrap(),
5613 &ComplexAction {
5614 arg: "a".to_string(),
5615 count: 5,
5616 }
5617 );
5618 assert_eq!(
5619 action2.as_any().downcast_ref::<SimpleAction>().unwrap(),
5620 &SimpleAction
5621 );
5622 }
5623
5624 #[crate::test(self)]
5625 fn test_dispatch_action(cx: &mut AppContext) {
5626 struct ViewA {
5627 id: usize,
5628 }
5629
5630 impl Entity for ViewA {
5631 type Event = ();
5632 }
5633
5634 impl View for ViewA {
5635 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
5636 Empty::new().boxed()
5637 }
5638
5639 fn ui_name() -> &'static str {
5640 "View"
5641 }
5642 }
5643
5644 struct ViewB {
5645 id: usize,
5646 }
5647
5648 impl Entity for ViewB {
5649 type Event = ();
5650 }
5651
5652 impl View for ViewB {
5653 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
5654 Empty::new().boxed()
5655 }
5656
5657 fn ui_name() -> &'static str {
5658 "View"
5659 }
5660 }
5661
5662 #[derive(Clone, Default, Deserialize, PartialEq)]
5663 pub struct Action(pub String);
5664
5665 impl_actions!(test, [Action]);
5666
5667 let actions = Rc::new(RefCell::new(Vec::new()));
5668
5669 cx.add_global_action({
5670 let actions = actions.clone();
5671 move |_: &Action, _: &mut AppContext| {
5672 actions.borrow_mut().push("global".to_string());
5673 }
5674 });
5675
5676 cx.add_action({
5677 let actions = actions.clone();
5678 move |view: &mut ViewA, action: &Action, cx| {
5679 assert_eq!(action.0, "bar");
5680 cx.propagate_action();
5681 actions.borrow_mut().push(format!("{} a", view.id));
5682 }
5683 });
5684
5685 cx.add_action({
5686 let actions = actions.clone();
5687 move |view: &mut ViewA, _: &Action, cx| {
5688 if view.id != 1 {
5689 cx.add_view(|cx| {
5690 cx.propagate_action(); // Still works on a nested ViewContext
5691 ViewB { id: 5 }
5692 });
5693 }
5694 actions.borrow_mut().push(format!("{} b", view.id));
5695 }
5696 });
5697
5698 cx.add_action({
5699 let actions = actions.clone();
5700 move |view: &mut ViewB, _: &Action, cx| {
5701 cx.propagate_action();
5702 actions.borrow_mut().push(format!("{} c", view.id));
5703 }
5704 });
5705
5706 cx.add_action({
5707 let actions = actions.clone();
5708 move |view: &mut ViewB, _: &Action, cx| {
5709 cx.propagate_action();
5710 actions.borrow_mut().push(format!("{} d", view.id));
5711 }
5712 });
5713
5714 cx.capture_action({
5715 let actions = actions.clone();
5716 move |view: &mut ViewA, _: &Action, cx| {
5717 cx.propagate_action();
5718 actions.borrow_mut().push(format!("{} capture", view.id));
5719 }
5720 });
5721
5722 let observed_actions = Rc::new(RefCell::new(Vec::new()));
5723 cx.observe_actions({
5724 let observed_actions = observed_actions.clone();
5725 move |action_id, _| observed_actions.borrow_mut().push(action_id)
5726 })
5727 .detach();
5728
5729 let (window_id, view_1) = cx.add_window(Default::default(), |_| ViewA { id: 1 });
5730 let view_2 = cx.add_view(&view_1, |_| ViewB { id: 2 });
5731 let view_3 = cx.add_view(&view_2, |_| ViewA { id: 3 });
5732 let view_4 = cx.add_view(&view_3, |_| ViewB { id: 4 });
5733
5734 cx.update_window(window_id, |cx| {
5735 cx.handle_dispatch_action_from_effect(Some(view_4.id()), &Action("bar".to_string()))
5736 });
5737
5738 assert_eq!(
5739 *actions.borrow(),
5740 vec![
5741 "1 capture",
5742 "3 capture",
5743 "4 d",
5744 "4 c",
5745 "3 b",
5746 "3 a",
5747 "2 d",
5748 "2 c",
5749 "1 b"
5750 ]
5751 );
5752 assert_eq!(*observed_actions.borrow(), [Action::default().id()]);
5753
5754 // Remove view_1, which doesn't propagate the action
5755
5756 let (window_id, view_2) = cx.add_window(Default::default(), |_| ViewB { id: 2 });
5757 let view_3 = cx.add_view(&view_2, |_| ViewA { id: 3 });
5758 let view_4 = cx.add_view(&view_3, |_| ViewB { id: 4 });
5759
5760 actions.borrow_mut().clear();
5761 cx.update_window(window_id, |cx| {
5762 cx.handle_dispatch_action_from_effect(Some(view_4.id()), &Action("bar".to_string()))
5763 });
5764
5765 assert_eq!(
5766 *actions.borrow(),
5767 vec![
5768 "3 capture",
5769 "4 d",
5770 "4 c",
5771 "3 b",
5772 "3 a",
5773 "2 d",
5774 "2 c",
5775 "global"
5776 ]
5777 );
5778 assert_eq!(
5779 *observed_actions.borrow(),
5780 [Action::default().id(), Action::default().id()]
5781 );
5782 }
5783
5784 #[crate::test(self)]
5785 fn test_dispatch_keystroke(cx: &mut AppContext) {
5786 #[derive(Clone, Deserialize, PartialEq)]
5787 pub struct Action(String);
5788
5789 impl_actions!(test, [Action]);
5790
5791 struct View {
5792 id: usize,
5793 keymap_context: KeymapContext,
5794 }
5795
5796 impl Entity for View {
5797 type Event = ();
5798 }
5799
5800 impl super::View for View {
5801 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
5802 Empty::new().boxed()
5803 }
5804
5805 fn ui_name() -> &'static str {
5806 "View"
5807 }
5808
5809 fn keymap_context(&self, _: &AppContext) -> KeymapContext {
5810 self.keymap_context.clone()
5811 }
5812 }
5813
5814 impl View {
5815 fn new(id: usize) -> Self {
5816 View {
5817 id,
5818 keymap_context: KeymapContext::default(),
5819 }
5820 }
5821 }
5822
5823 let mut view_1 = View::new(1);
5824 let mut view_2 = View::new(2);
5825 let mut view_3 = View::new(3);
5826 view_1.keymap_context.add_identifier("a");
5827 view_2.keymap_context.add_identifier("a");
5828 view_2.keymap_context.add_identifier("b");
5829 view_3.keymap_context.add_identifier("a");
5830 view_3.keymap_context.add_identifier("b");
5831 view_3.keymap_context.add_identifier("c");
5832
5833 let (window_id, view_1) = cx.add_window(Default::default(), |_| view_1);
5834 let view_2 = cx.add_view(&view_1, |_| view_2);
5835 let _view_3 = cx.add_view(&view_2, |cx| {
5836 cx.focus_self();
5837 view_3
5838 });
5839
5840 // This binding only dispatches an action on view 2 because that view will have
5841 // "a" and "b" in its context, but not "c".
5842 cx.add_bindings(vec![Binding::new(
5843 "a",
5844 Action("a".to_string()),
5845 Some("a && b && !c"),
5846 )]);
5847
5848 cx.add_bindings(vec![Binding::new("b", Action("b".to_string()), None)]);
5849
5850 // This binding only dispatches an action on views 2 and 3, because they have
5851 // a parent view with a in its context
5852 cx.add_bindings(vec![Binding::new(
5853 "c",
5854 Action("c".to_string()),
5855 Some("b > c"),
5856 )]);
5857
5858 // This binding only dispatches an action on view 2, because they have
5859 // a parent view with a in its context
5860 cx.add_bindings(vec![Binding::new(
5861 "d",
5862 Action("d".to_string()),
5863 Some("a && !b > b"),
5864 )]);
5865
5866 let actions = Rc::new(RefCell::new(Vec::new()));
5867 cx.add_action({
5868 let actions = actions.clone();
5869 move |view: &mut View, action: &Action, cx| {
5870 actions
5871 .borrow_mut()
5872 .push(format!("{} {}", view.id, action.0));
5873
5874 if action.0 == "b" {
5875 cx.propagate_action();
5876 }
5877 }
5878 });
5879
5880 cx.add_global_action({
5881 let actions = actions.clone();
5882 move |action: &Action, _| {
5883 actions.borrow_mut().push(format!("global {}", action.0));
5884 }
5885 });
5886
5887 cx.update_window(window_id, |cx| {
5888 cx.dispatch_keystroke(&Keystroke::parse("a").unwrap())
5889 });
5890 assert_eq!(&*actions.borrow(), &["2 a"]);
5891 actions.borrow_mut().clear();
5892
5893 cx.update_window(window_id, |cx| {
5894 cx.dispatch_keystroke(&Keystroke::parse("b").unwrap());
5895 });
5896
5897 assert_eq!(&*actions.borrow(), &["3 b", "2 b", "1 b", "global b"]);
5898 actions.borrow_mut().clear();
5899
5900 cx.update_window(window_id, |cx| {
5901 cx.dispatch_keystroke(&Keystroke::parse("c").unwrap());
5902 });
5903 assert_eq!(&*actions.borrow(), &["3 c"]);
5904 actions.borrow_mut().clear();
5905
5906 cx.update_window(window_id, |cx| {
5907 cx.dispatch_keystroke(&Keystroke::parse("d").unwrap());
5908 });
5909 assert_eq!(&*actions.borrow(), &["2 d"]);
5910 actions.borrow_mut().clear();
5911 }
5912
5913 #[crate::test(self)]
5914 fn test_keystrokes_for_action(cx: &mut AppContext) {
5915 actions!(test, [Action1, Action2, GlobalAction]);
5916
5917 struct View1 {}
5918 struct View2 {}
5919
5920 impl Entity for View1 {
5921 type Event = ();
5922 }
5923 impl Entity for View2 {
5924 type Event = ();
5925 }
5926
5927 impl super::View for View1 {
5928 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
5929 Empty::new().boxed()
5930 }
5931 fn ui_name() -> &'static str {
5932 "View1"
5933 }
5934 }
5935 impl super::View for View2 {
5936 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
5937 Empty::new().boxed()
5938 }
5939 fn ui_name() -> &'static str {
5940 "View2"
5941 }
5942 }
5943
5944 let (window_id, view_1) = cx.add_window(Default::default(), |_| View1 {});
5945 let view_2 = cx.add_view(&view_1, |cx| {
5946 cx.focus_self();
5947 View2 {}
5948 });
5949
5950 cx.add_action(|_: &mut View1, _: &Action1, _cx| {});
5951 cx.add_action(|_: &mut View2, _: &Action2, _cx| {});
5952 cx.add_global_action(|_: &GlobalAction, _| {});
5953
5954 cx.add_bindings(vec![
5955 Binding::new("a", Action1, Some("View1")),
5956 Binding::new("b", Action2, Some("View1 > View2")),
5957 Binding::new("c", GlobalAction, Some("View3")), // View 3 does not exist
5958 ]);
5959
5960 cx.update_window(window_id, |cx| {
5961 // Sanity check
5962 assert_eq!(
5963 cx.keystrokes_for_action(view_1.id(), &Action1)
5964 .unwrap()
5965 .as_slice(),
5966 &[Keystroke::parse("a").unwrap()]
5967 );
5968 assert_eq!(
5969 cx.keystrokes_for_action(view_2.id(), &Action2)
5970 .unwrap()
5971 .as_slice(),
5972 &[Keystroke::parse("b").unwrap()]
5973 );
5974
5975 // The 'a' keystroke propagates up the view tree from view_2
5976 // to view_1. The action, Action1, is handled by view_1.
5977 assert_eq!(
5978 cx.keystrokes_for_action(view_2.id(), &Action1)
5979 .unwrap()
5980 .as_slice(),
5981 &[Keystroke::parse("a").unwrap()]
5982 );
5983
5984 // Actions that are handled below the current view don't have bindings
5985 assert_eq!(cx.keystrokes_for_action(view_1.id(), &Action2), None);
5986
5987 // Actions that are handled in other branches of the tree should not have a binding
5988 assert_eq!(cx.keystrokes_for_action(view_2.id(), &GlobalAction), None);
5989
5990 // Check that global actions do not have a binding, even if a binding does exist in another view
5991 assert_eq!(
5992 &available_actions(view_1.id(), cx),
5993 &[
5994 ("test::Action1", vec![Keystroke::parse("a").unwrap()]),
5995 ("test::GlobalAction", vec![])
5996 ],
5997 );
5998
5999 // Check that view 1 actions and bindings are available even when called from view 2
6000 assert_eq!(
6001 &available_actions(view_2.id(), cx),
6002 &[
6003 ("test::Action1", vec![Keystroke::parse("a").unwrap()]),
6004 ("test::Action2", vec![Keystroke::parse("b").unwrap()]),
6005 ("test::GlobalAction", vec![]),
6006 ],
6007 );
6008 });
6009
6010 // Produces a list of actions and key bindings
6011 fn available_actions(
6012 view_id: usize,
6013 cx: &WindowContext,
6014 ) -> Vec<(&'static str, Vec<Keystroke>)> {
6015 cx.available_actions(view_id)
6016 .map(|(action_name, _, bindings)| {
6017 (
6018 action_name,
6019 bindings
6020 .iter()
6021 .map(|binding| binding.keystrokes()[0].clone())
6022 .collect::<Vec<_>>(),
6023 )
6024 })
6025 .sorted_by(|(name1, _), (name2, _)| name1.cmp(name2))
6026 .collect()
6027 }
6028 }
6029
6030 #[crate::test(self)]
6031 async fn test_model_condition(cx: &mut TestAppContext) {
6032 struct Counter(usize);
6033
6034 impl super::Entity for Counter {
6035 type Event = ();
6036 }
6037
6038 impl Counter {
6039 fn inc(&mut self, cx: &mut ModelContext<Self>) {
6040 self.0 += 1;
6041 cx.notify();
6042 }
6043 }
6044
6045 let model = cx.add_model(|_| Counter(0));
6046
6047 let condition1 = model.condition(cx, |model, _| model.0 == 2);
6048 let condition2 = model.condition(cx, |model, _| model.0 == 3);
6049 smol::pin!(condition1, condition2);
6050
6051 model.update(cx, |model, cx| model.inc(cx));
6052 assert_eq!(poll_once(&mut condition1).await, None);
6053 assert_eq!(poll_once(&mut condition2).await, None);
6054
6055 model.update(cx, |model, cx| model.inc(cx));
6056 assert_eq!(poll_once(&mut condition1).await, Some(()));
6057 assert_eq!(poll_once(&mut condition2).await, None);
6058
6059 model.update(cx, |model, cx| model.inc(cx));
6060 assert_eq!(poll_once(&mut condition2).await, Some(()));
6061
6062 model.update(cx, |_, cx| cx.notify());
6063 }
6064
6065 #[crate::test(self)]
6066 #[should_panic]
6067 async fn test_model_condition_timeout(cx: &mut TestAppContext) {
6068 struct Model;
6069
6070 impl super::Entity for Model {
6071 type Event = ();
6072 }
6073
6074 let model = cx.add_model(|_| Model);
6075 model.condition(cx, |_, _| false).await;
6076 }
6077
6078 #[crate::test(self)]
6079 #[should_panic(expected = "model dropped with pending condition")]
6080 async fn test_model_condition_panic_on_drop(cx: &mut TestAppContext) {
6081 struct Model;
6082
6083 impl super::Entity for Model {
6084 type Event = ();
6085 }
6086
6087 let model = cx.add_model(|_| Model);
6088 let condition = model.condition(cx, |_, _| false);
6089 cx.update(|_| drop(model));
6090 condition.await;
6091 }
6092
6093 #[crate::test(self)]
6094 async fn test_view_condition(cx: &mut TestAppContext) {
6095 struct Counter(usize);
6096
6097 impl super::Entity for Counter {
6098 type Event = ();
6099 }
6100
6101 impl super::View for Counter {
6102 fn ui_name() -> &'static str {
6103 "test view"
6104 }
6105
6106 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
6107 Empty::new().boxed()
6108 }
6109 }
6110
6111 impl Counter {
6112 fn inc(&mut self, cx: &mut ViewContext<Self>) {
6113 self.0 += 1;
6114 cx.notify();
6115 }
6116 }
6117
6118 let (_, view) = cx.add_window(|_| Counter(0));
6119
6120 let condition1 = view.condition(cx, |view, _| view.0 == 2);
6121 let condition2 = view.condition(cx, |view, _| view.0 == 3);
6122 smol::pin!(condition1, condition2);
6123
6124 view.update(cx, |view, cx| view.inc(cx));
6125 assert_eq!(poll_once(&mut condition1).await, None);
6126 assert_eq!(poll_once(&mut condition2).await, None);
6127
6128 view.update(cx, |view, cx| view.inc(cx));
6129 assert_eq!(poll_once(&mut condition1).await, Some(()));
6130 assert_eq!(poll_once(&mut condition2).await, None);
6131
6132 view.update(cx, |view, cx| view.inc(cx));
6133 assert_eq!(poll_once(&mut condition2).await, Some(()));
6134 view.update(cx, |_, cx| cx.notify());
6135 }
6136
6137 #[crate::test(self)]
6138 #[should_panic]
6139 async fn test_view_condition_timeout(cx: &mut TestAppContext) {
6140 let (_, view) = cx.add_window(|_| TestView::default());
6141 view.condition(cx, |_, _| false).await;
6142 }
6143
6144 #[crate::test(self)]
6145 #[should_panic(expected = "view dropped with pending condition")]
6146 async fn test_view_condition_panic_on_drop(cx: &mut TestAppContext) {
6147 let (_, root_view) = cx.add_window(|_| TestView::default());
6148 let view = cx.add_view(&root_view, |_| TestView::default());
6149
6150 let condition = view.condition(cx, |_, _| false);
6151 cx.update(|_| drop(view));
6152 condition.await;
6153 }
6154
6155 #[crate::test(self)]
6156 fn test_refresh_windows(cx: &mut AppContext) {
6157 struct View(usize);
6158
6159 impl super::Entity for View {
6160 type Event = ();
6161 }
6162
6163 impl super::View for View {
6164 fn ui_name() -> &'static str {
6165 "test view"
6166 }
6167
6168 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
6169 Empty::new().named(format!("render count: {}", post_inc(&mut self.0)))
6170 }
6171 }
6172
6173 let (window_id, root_view) = cx.add_window(Default::default(), |_| View(0));
6174 cx.update_window(window_id, |cx| {
6175 assert_eq!(
6176 cx.window.rendered_views[&root_view.id()].name(),
6177 Some("render count: 0")
6178 );
6179 });
6180
6181 let view = cx.add_view(&root_view, |cx| {
6182 cx.refresh_windows();
6183 View(0)
6184 });
6185
6186 cx.update_window(window_id, |cx| {
6187 assert_eq!(
6188 cx.window.rendered_views[&root_view.id()].name(),
6189 Some("render count: 1")
6190 );
6191 assert_eq!(
6192 cx.window.rendered_views[&view.id()].name(),
6193 Some("render count: 0")
6194 );
6195 });
6196
6197 cx.update(|cx| cx.refresh_windows());
6198
6199 cx.update_window(window_id, |cx| {
6200 assert_eq!(
6201 cx.window.rendered_views[&root_view.id()].name(),
6202 Some("render count: 2")
6203 );
6204 assert_eq!(
6205 cx.window.rendered_views[&view.id()].name(),
6206 Some("render count: 1")
6207 );
6208 });
6209
6210 cx.update(|cx| {
6211 cx.refresh_windows();
6212 drop(view);
6213 });
6214
6215 cx.update_window(window_id, |cx| {
6216 assert_eq!(
6217 cx.window.rendered_views[&root_view.id()].name(),
6218 Some("render count: 3")
6219 );
6220 assert_eq!(cx.window.rendered_views.len(), 1);
6221 });
6222 }
6223
6224 #[crate::test(self)]
6225 async fn test_labeled_tasks(cx: &mut TestAppContext) {
6226 assert_eq!(None, cx.update(|cx| cx.active_labeled_tasks().next()));
6227 let (mut sender, mut reciever) = postage::oneshot::channel::<()>();
6228 let task = cx
6229 .update(|cx| cx.spawn_labeled("Test Label", |_| async move { reciever.recv().await }));
6230
6231 assert_eq!(
6232 Some("Test Label"),
6233 cx.update(|cx| cx.active_labeled_tasks().next())
6234 );
6235 sender
6236 .send(())
6237 .await
6238 .expect("Could not send message to complete task");
6239 task.await;
6240
6241 assert_eq!(None, cx.update(|cx| cx.active_labeled_tasks().next()));
6242 }
6243
6244 #[crate::test(self)]
6245 async fn test_window_activation(cx: &mut TestAppContext) {
6246 struct View(&'static str);
6247
6248 impl super::Entity for View {
6249 type Event = ();
6250 }
6251
6252 impl super::View for View {
6253 fn ui_name() -> &'static str {
6254 "test view"
6255 }
6256
6257 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
6258 Empty::new().boxed()
6259 }
6260 }
6261
6262 let events = Rc::new(RefCell::new(Vec::new()));
6263 let (window_1, _) = cx.add_window(|cx: &mut ViewContext<View>| {
6264 cx.observe_window_activation({
6265 let events = events.clone();
6266 move |this, active, _| events.borrow_mut().push((this.0, active))
6267 })
6268 .detach();
6269 View("window 1")
6270 });
6271 assert_eq!(mem::take(&mut *events.borrow_mut()), [("window 1", true)]);
6272
6273 let (window_2, _) = cx.add_window(|cx: &mut ViewContext<View>| {
6274 cx.observe_window_activation({
6275 let events = events.clone();
6276 move |this, active, _| events.borrow_mut().push((this.0, active))
6277 })
6278 .detach();
6279 View("window 2")
6280 });
6281 assert_eq!(
6282 mem::take(&mut *events.borrow_mut()),
6283 [("window 1", false), ("window 2", true)]
6284 );
6285
6286 let (window_3, _) = cx.add_window(|cx: &mut ViewContext<View>| {
6287 cx.observe_window_activation({
6288 let events = events.clone();
6289 move |this, active, _| events.borrow_mut().push((this.0, active))
6290 })
6291 .detach();
6292 View("window 3")
6293 });
6294 assert_eq!(
6295 mem::take(&mut *events.borrow_mut()),
6296 [("window 2", false), ("window 3", true)]
6297 );
6298
6299 cx.simulate_window_activation(Some(window_2));
6300 assert_eq!(
6301 mem::take(&mut *events.borrow_mut()),
6302 [("window 3", false), ("window 2", true)]
6303 );
6304
6305 cx.simulate_window_activation(Some(window_1));
6306 assert_eq!(
6307 mem::take(&mut *events.borrow_mut()),
6308 [("window 2", false), ("window 1", true)]
6309 );
6310
6311 cx.simulate_window_activation(Some(window_3));
6312 assert_eq!(
6313 mem::take(&mut *events.borrow_mut()),
6314 [("window 1", false), ("window 3", true)]
6315 );
6316
6317 cx.simulate_window_activation(Some(window_3));
6318 assert_eq!(mem::take(&mut *events.borrow_mut()), []);
6319 }
6320
6321 #[crate::test(self)]
6322 fn test_child_view(cx: &mut TestAppContext) {
6323 struct Child {
6324 rendered: Rc<Cell<bool>>,
6325 dropped: Rc<Cell<bool>>,
6326 }
6327
6328 impl super::Entity for Child {
6329 type Event = ();
6330 }
6331
6332 impl super::View for Child {
6333 fn ui_name() -> &'static str {
6334 "child view"
6335 }
6336
6337 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
6338 self.rendered.set(true);
6339 Empty::new().boxed()
6340 }
6341 }
6342
6343 impl Drop for Child {
6344 fn drop(&mut self) {
6345 self.dropped.set(true);
6346 }
6347 }
6348
6349 struct Parent {
6350 child: Option<ViewHandle<Child>>,
6351 }
6352
6353 impl super::Entity for Parent {
6354 type Event = ();
6355 }
6356
6357 impl super::View for Parent {
6358 fn ui_name() -> &'static str {
6359 "parent view"
6360 }
6361
6362 fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
6363 if let Some(child) = self.child.as_ref() {
6364 ChildView::new(child, cx).boxed()
6365 } else {
6366 Empty::new().boxed()
6367 }
6368 }
6369 }
6370
6371 let child_rendered = Rc::new(Cell::new(false));
6372 let child_dropped = Rc::new(Cell::new(false));
6373 let (_, root_view) = cx.add_window(|cx| Parent {
6374 child: Some(cx.add_view(|_| Child {
6375 rendered: child_rendered.clone(),
6376 dropped: child_dropped.clone(),
6377 })),
6378 });
6379 assert!(child_rendered.take());
6380 assert!(!child_dropped.take());
6381
6382 root_view.update(cx, |view, cx| {
6383 view.child.take();
6384 cx.notify();
6385 });
6386 assert!(!child_rendered.take());
6387 assert!(child_dropped.take());
6388 }
6389
6390 #[derive(Default)]
6391 struct TestView {
6392 events: Vec<String>,
6393 }
6394
6395 impl Entity for TestView {
6396 type Event = String;
6397 }
6398
6399 impl View for TestView {
6400 fn ui_name() -> &'static str {
6401 "TestView"
6402 }
6403
6404 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
6405 Empty::new().boxed()
6406 }
6407 }
6408}