app.rs

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