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