app.rs

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