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 replace_root_view<T, F>(&mut self, window_id: usize, build_root_view: F) -> ViewHandle<T>
1615    where
1616        T: View,
1617        F: FnOnce(&mut ViewContext<T>) -> T,
1618    {
1619        self.update(|this| {
1620            let root_view = this.add_view(window_id, build_root_view);
1621            let window = this.cx.windows.get_mut(&window_id).unwrap();
1622            window.root_view = root_view.clone().into();
1623            window.focused_view_id = Some(root_view.id());
1624            root_view
1625        })
1626    }
1627
1628    pub fn remove_window(&mut self, window_id: usize) {
1629        self.cx.windows.remove(&window_id);
1630        self.presenters_and_platform_windows.remove(&window_id);
1631        self.flush_effects();
1632    }
1633
1634    fn open_platform_window(&mut self, window_id: usize, window_options: WindowOptions) {
1635        let mut window =
1636            self.cx
1637                .platform
1638                .open_window(window_id, window_options, self.foreground.clone());
1639        let presenter = Rc::new(RefCell::new(
1640            self.build_presenter(window_id, window.titlebar_height()),
1641        ));
1642
1643        {
1644            let mut app = self.upgrade();
1645            let presenter = Rc::downgrade(&presenter);
1646            window.on_event(Box::new(move |event| {
1647                app.update(|cx| {
1648                    if let Some(presenter) = presenter.upgrade() {
1649                        if let Event::KeyDown { keystroke, .. } = &event {
1650                            if cx.dispatch_keystroke(
1651                                window_id,
1652                                presenter.borrow().dispatch_path(cx.as_ref()),
1653                                keystroke,
1654                            ) {
1655                                return;
1656                            }
1657                        }
1658
1659                        presenter.borrow_mut().dispatch_event(event, cx);
1660                    }
1661                })
1662            }));
1663        }
1664
1665        {
1666            let mut app = self.upgrade();
1667            window.on_active_status_change(Box::new(move |is_active| {
1668                app.update(|cx| cx.window_changed_active_status(window_id, is_active))
1669            }));
1670        }
1671
1672        {
1673            let mut app = self.upgrade();
1674            window.on_resize(Box::new(move || {
1675                app.update(|cx| cx.window_was_resized(window_id))
1676            }));
1677        }
1678
1679        {
1680            let mut app = self.upgrade();
1681            window.on_close(Box::new(move || {
1682                app.update(|cx| cx.remove_window(window_id));
1683            }));
1684        }
1685
1686        let scene =
1687            presenter
1688                .borrow_mut()
1689                .build_scene(window.size(), window.scale_factor(), false, self);
1690        window.present_scene(scene);
1691        self.presenters_and_platform_windows
1692            .insert(window_id, (presenter.clone(), window));
1693    }
1694
1695    pub fn build_presenter(&mut self, window_id: usize, titlebar_height: f32) -> Presenter {
1696        Presenter::new(
1697            window_id,
1698            titlebar_height,
1699            self.cx.font_cache.clone(),
1700            TextLayoutCache::new(self.cx.platform.fonts()),
1701            self.assets.clone(),
1702            self,
1703        )
1704    }
1705
1706    pub fn build_render_context<V: View>(
1707        &mut self,
1708        window_id: usize,
1709        view_id: usize,
1710        titlebar_height: f32,
1711        refreshing: bool,
1712    ) -> RenderContext<V> {
1713        RenderContext {
1714            app: self,
1715            titlebar_height,
1716            refreshing,
1717            window_id,
1718            view_id,
1719            view_type: PhantomData,
1720        }
1721    }
1722
1723    pub fn add_view<T, F>(&mut self, window_id: usize, build_view: F) -> ViewHandle<T>
1724    where
1725        T: View,
1726        F: FnOnce(&mut ViewContext<T>) -> T,
1727    {
1728        self.add_option_view(window_id, |cx| Some(build_view(cx)))
1729            .unwrap()
1730    }
1731
1732    pub fn add_option_view<T, F>(
1733        &mut self,
1734        window_id: usize,
1735        build_view: F,
1736    ) -> Option<ViewHandle<T>>
1737    where
1738        T: View,
1739        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
1740    {
1741        self.update(|this| {
1742            let view_id = post_inc(&mut this.next_entity_id);
1743            let mut cx = ViewContext::new(this, window_id, view_id);
1744            let handle = if let Some(view) = build_view(&mut cx) {
1745                this.cx.views.insert((window_id, view_id), Box::new(view));
1746                if let Some(window) = this.cx.windows.get_mut(&window_id) {
1747                    window
1748                        .invalidation
1749                        .get_or_insert_with(Default::default)
1750                        .updated
1751                        .insert(view_id);
1752                }
1753                Some(ViewHandle::new(window_id, view_id, &this.cx.ref_counts))
1754            } else {
1755                None
1756            };
1757            handle
1758        })
1759    }
1760
1761    fn remove_dropped_entities(&mut self) {
1762        loop {
1763            let (dropped_models, dropped_views, dropped_element_states) =
1764                self.cx.ref_counts.lock().take_dropped();
1765            if dropped_models.is_empty()
1766                && dropped_views.is_empty()
1767                && dropped_element_states.is_empty()
1768            {
1769                break;
1770            }
1771
1772            for model_id in dropped_models {
1773                self.subscriptions.lock().remove(&model_id);
1774                self.observations.lock().remove(&model_id);
1775                let mut model = self.cx.models.remove(&model_id).unwrap();
1776                model.release(self);
1777                self.pending_effects
1778                    .push_back(Effect::ModelRelease { model_id, model });
1779            }
1780
1781            for (window_id, view_id) in dropped_views {
1782                self.subscriptions.lock().remove(&view_id);
1783                self.observations.lock().remove(&view_id);
1784                let mut view = self.cx.views.remove(&(window_id, view_id)).unwrap();
1785                view.release(self);
1786                let change_focus_to = self.cx.windows.get_mut(&window_id).and_then(|window| {
1787                    window
1788                        .invalidation
1789                        .get_or_insert_with(Default::default)
1790                        .removed
1791                        .push(view_id);
1792                    if window.focused_view_id == Some(view_id) {
1793                        Some(window.root_view.id())
1794                    } else {
1795                        None
1796                    }
1797                });
1798
1799                if let Some(view_id) = change_focus_to {
1800                    self.handle_focus_effect(window_id, Some(view_id));
1801                }
1802
1803                self.pending_effects
1804                    .push_back(Effect::ViewRelease { view_id, view });
1805            }
1806
1807            for key in dropped_element_states {
1808                self.cx.element_states.remove(&key);
1809            }
1810        }
1811    }
1812
1813    fn flush_effects(&mut self) {
1814        self.pending_flushes = self.pending_flushes.saturating_sub(1);
1815        let mut after_window_update_callbacks = Vec::new();
1816
1817        if !self.flushing_effects && self.pending_flushes == 0 {
1818            self.flushing_effects = true;
1819
1820            let mut refreshing = false;
1821            loop {
1822                if let Some(effect) = self.pending_effects.pop_front() {
1823                    if let Some(pending_focus_index) = self.pending_focus_index.as_mut() {
1824                        *pending_focus_index = pending_focus_index.saturating_sub(1);
1825                    }
1826                    match effect {
1827                        Effect::Subscription {
1828                            entity_id,
1829                            subscription_id,
1830                            callback,
1831                        } => self.handle_subscription_effect(entity_id, subscription_id, callback),
1832                        Effect::Event { entity_id, payload } => self.emit_event(entity_id, payload),
1833                        Effect::GlobalSubscription {
1834                            type_id,
1835                            subscription_id,
1836                            callback,
1837                        } => self.handle_global_subscription_effect(
1838                            type_id,
1839                            subscription_id,
1840                            callback,
1841                        ),
1842                        Effect::GlobalEvent { payload } => self.emit_global_event(payload),
1843                        Effect::Observation {
1844                            entity_id,
1845                            subscription_id,
1846                            callback,
1847                        } => self.handle_observation_effect(entity_id, subscription_id, callback),
1848                        Effect::ModelNotification { model_id } => {
1849                            self.handle_model_notification_effect(model_id)
1850                        }
1851                        Effect::ViewNotification { window_id, view_id } => {
1852                            self.handle_view_notification_effect(window_id, view_id)
1853                        }
1854                        Effect::GlobalNotification { type_id } => {
1855                            self.handle_global_notification_effect(type_id)
1856                        }
1857                        Effect::Deferred {
1858                            callback,
1859                            after_window_update,
1860                        } => {
1861                            if after_window_update {
1862                                after_window_update_callbacks.push(callback);
1863                            } else {
1864                                callback(self)
1865                            }
1866                        }
1867                        Effect::ModelRelease { model_id, model } => {
1868                            self.handle_entity_release_effect(model_id, model.as_any())
1869                        }
1870                        Effect::ViewRelease { view_id, view } => {
1871                            self.handle_entity_release_effect(view_id, view.as_any())
1872                        }
1873                        Effect::Focus { window_id, view_id } => {
1874                            self.handle_focus_effect(window_id, view_id);
1875                        }
1876                        Effect::FocusObservation {
1877                            view_id,
1878                            subscription_id,
1879                            callback,
1880                        } => {
1881                            self.handle_focus_observation_effect(view_id, subscription_id, callback)
1882                        }
1883                        Effect::ResizeWindow { window_id } => {
1884                            if let Some(window) = self.cx.windows.get_mut(&window_id) {
1885                                window
1886                                    .invalidation
1887                                    .get_or_insert(WindowInvalidation::default());
1888                            }
1889                        }
1890                        Effect::ActivateWindow {
1891                            window_id,
1892                            is_active,
1893                        } => self.handle_activation_effect(window_id, is_active),
1894                        Effect::RefreshWindows => {
1895                            refreshing = true;
1896                        }
1897                    }
1898                    self.pending_notifications.clear();
1899                    self.remove_dropped_entities();
1900                } else {
1901                    self.remove_dropped_entities();
1902                    if refreshing {
1903                        self.perform_window_refresh();
1904                    } else {
1905                        self.update_windows();
1906                    }
1907
1908                    if self.pending_effects.is_empty() {
1909                        for callback in after_window_update_callbacks.drain(..) {
1910                            callback(self);
1911                        }
1912
1913                        if self.pending_effects.is_empty() {
1914                            self.flushing_effects = false;
1915                            self.pending_notifications.clear();
1916                            self.pending_global_notifications.clear();
1917                            break;
1918                        }
1919                    }
1920
1921                    refreshing = false;
1922                }
1923            }
1924        }
1925    }
1926
1927    fn update_windows(&mut self) {
1928        let mut invalidations = HashMap::new();
1929        for (window_id, window) in &mut self.cx.windows {
1930            if let Some(invalidation) = window.invalidation.take() {
1931                invalidations.insert(*window_id, invalidation);
1932            }
1933        }
1934
1935        for (window_id, mut invalidation) in invalidations {
1936            if let Some((presenter, mut window)) =
1937                self.presenters_and_platform_windows.remove(&window_id)
1938            {
1939                {
1940                    let mut presenter = presenter.borrow_mut();
1941                    presenter.invalidate(&mut invalidation, self);
1942                    let scene =
1943                        presenter.build_scene(window.size(), window.scale_factor(), false, self);
1944                    window.present_scene(scene);
1945                }
1946                self.presenters_and_platform_windows
1947                    .insert(window_id, (presenter, window));
1948            }
1949        }
1950    }
1951
1952    fn window_was_resized(&mut self, window_id: usize) {
1953        self.pending_effects
1954            .push_back(Effect::ResizeWindow { window_id });
1955    }
1956
1957    fn window_changed_active_status(&mut self, window_id: usize, is_active: bool) {
1958        self.pending_effects.push_back(Effect::ActivateWindow {
1959            window_id,
1960            is_active,
1961        });
1962    }
1963
1964    pub fn refresh_windows(&mut self) {
1965        self.pending_effects.push_back(Effect::RefreshWindows);
1966    }
1967
1968    fn perform_window_refresh(&mut self) {
1969        let mut presenters = mem::take(&mut self.presenters_and_platform_windows);
1970        for (window_id, (presenter, window)) in &mut presenters {
1971            let mut invalidation = self
1972                .cx
1973                .windows
1974                .get_mut(&window_id)
1975                .unwrap()
1976                .invalidation
1977                .take();
1978            let mut presenter = presenter.borrow_mut();
1979            presenter.refresh(
1980                invalidation.as_mut().unwrap_or(&mut Default::default()),
1981                self,
1982            );
1983            let scene = presenter.build_scene(window.size(), window.scale_factor(), true, self);
1984            window.present_scene(scene);
1985        }
1986        self.presenters_and_platform_windows = presenters;
1987    }
1988
1989    fn handle_subscription_effect(
1990        &mut self,
1991        entity_id: usize,
1992        subscription_id: usize,
1993        callback: SubscriptionCallback,
1994    ) {
1995        match self
1996            .subscriptions
1997            .lock()
1998            .entry(entity_id)
1999            .or_default()
2000            .entry(subscription_id)
2001        {
2002            btree_map::Entry::Vacant(entry) => {
2003                entry.insert(Some(callback));
2004            }
2005            // Subscription was dropped before effect was processed
2006            btree_map::Entry::Occupied(entry) => {
2007                debug_assert!(entry.get().is_none());
2008                entry.remove();
2009            }
2010        }
2011    }
2012
2013    fn emit_event(&mut self, entity_id: usize, payload: Box<dyn Any>) {
2014        let callbacks = self.subscriptions.lock().remove(&entity_id);
2015        if let Some(callbacks) = callbacks {
2016            for (id, callback) in callbacks {
2017                if let Some(mut callback) = callback {
2018                    let alive = callback(payload.as_ref(), self);
2019                    if alive {
2020                        match self
2021                            .subscriptions
2022                            .lock()
2023                            .entry(entity_id)
2024                            .or_default()
2025                            .entry(id)
2026                        {
2027                            btree_map::Entry::Vacant(entry) => {
2028                                entry.insert(Some(callback));
2029                            }
2030                            btree_map::Entry::Occupied(entry) => {
2031                                entry.remove();
2032                            }
2033                        }
2034                    }
2035                }
2036            }
2037        }
2038    }
2039
2040    fn handle_global_subscription_effect(
2041        &mut self,
2042        type_id: TypeId,
2043        subscription_id: usize,
2044        callback: GlobalSubscriptionCallback,
2045    ) {
2046        match self
2047            .global_subscriptions
2048            .lock()
2049            .entry(type_id)
2050            .or_default()
2051            .entry(subscription_id)
2052        {
2053            btree_map::Entry::Vacant(entry) => {
2054                entry.insert(Some(callback));
2055            }
2056            // Subscription was dropped before effect was processed
2057            btree_map::Entry::Occupied(entry) => {
2058                debug_assert!(entry.get().is_none());
2059                entry.remove();
2060            }
2061        }
2062    }
2063
2064    fn emit_global_event(&mut self, payload: Box<dyn Any>) {
2065        let type_id = (&*payload).type_id();
2066        let callbacks = self.global_subscriptions.lock().remove(&type_id);
2067        if let Some(callbacks) = callbacks {
2068            for (id, callback) in callbacks {
2069                if let Some(mut callback) = callback {
2070                    callback(payload.as_ref(), self);
2071                    match self
2072                        .global_subscriptions
2073                        .lock()
2074                        .entry(type_id)
2075                        .or_default()
2076                        .entry(id)
2077                    {
2078                        btree_map::Entry::Vacant(entry) => {
2079                            entry.insert(Some(callback));
2080                        }
2081                        btree_map::Entry::Occupied(entry) => {
2082                            entry.remove();
2083                        }
2084                    }
2085                }
2086            }
2087        }
2088    }
2089
2090    fn handle_observation_effect(
2091        &mut self,
2092        entity_id: usize,
2093        subscription_id: usize,
2094        callback: ObservationCallback,
2095    ) {
2096        match self
2097            .observations
2098            .lock()
2099            .entry(entity_id)
2100            .or_default()
2101            .entry(subscription_id)
2102        {
2103            btree_map::Entry::Vacant(entry) => {
2104                entry.insert(Some(callback));
2105            }
2106            // Observation was dropped before effect was processed
2107            btree_map::Entry::Occupied(entry) => {
2108                debug_assert!(entry.get().is_none());
2109                entry.remove();
2110            }
2111        }
2112    }
2113
2114    fn handle_focus_observation_effect(
2115        &mut self,
2116        view_id: usize,
2117        subscription_id: usize,
2118        callback: FocusObservationCallback,
2119    ) {
2120        match self
2121            .focus_observations
2122            .lock()
2123            .entry(view_id)
2124            .or_default()
2125            .entry(subscription_id)
2126        {
2127            btree_map::Entry::Vacant(entry) => {
2128                entry.insert(Some(callback));
2129            }
2130            // Observation was dropped before effect was processed
2131            btree_map::Entry::Occupied(entry) => {
2132                debug_assert!(entry.get().is_none());
2133                entry.remove();
2134            }
2135        }
2136    }
2137
2138    fn handle_model_notification_effect(&mut self, observed_id: usize) {
2139        let callbacks = self.observations.lock().remove(&observed_id);
2140        if let Some(callbacks) = callbacks {
2141            if self.cx.models.contains_key(&observed_id) {
2142                for (id, callback) in callbacks {
2143                    if let Some(mut callback) = callback {
2144                        let alive = callback(self);
2145                        if alive {
2146                            match self
2147                                .observations
2148                                .lock()
2149                                .entry(observed_id)
2150                                .or_default()
2151                                .entry(id)
2152                            {
2153                                btree_map::Entry::Vacant(entry) => {
2154                                    entry.insert(Some(callback));
2155                                }
2156                                btree_map::Entry::Occupied(entry) => {
2157                                    entry.remove();
2158                                }
2159                            }
2160                        }
2161                    }
2162                }
2163            }
2164        }
2165    }
2166
2167    fn handle_view_notification_effect(
2168        &mut self,
2169        observed_window_id: usize,
2170        observed_view_id: usize,
2171    ) {
2172        if let Some(window) = self.cx.windows.get_mut(&observed_window_id) {
2173            window
2174                .invalidation
2175                .get_or_insert_with(Default::default)
2176                .updated
2177                .insert(observed_view_id);
2178        }
2179
2180        let callbacks = self.observations.lock().remove(&observed_view_id);
2181        if let Some(callbacks) = callbacks {
2182            if self
2183                .cx
2184                .views
2185                .contains_key(&(observed_window_id, observed_view_id))
2186            {
2187                for (id, callback) in callbacks {
2188                    if let Some(mut callback) = callback {
2189                        let alive = callback(self);
2190                        if alive {
2191                            match self
2192                                .observations
2193                                .lock()
2194                                .entry(observed_view_id)
2195                                .or_default()
2196                                .entry(id)
2197                            {
2198                                btree_map::Entry::Vacant(entry) => {
2199                                    entry.insert(Some(callback));
2200                                }
2201                                btree_map::Entry::Occupied(entry) => {
2202                                    entry.remove();
2203                                }
2204                            }
2205                        }
2206                    }
2207                }
2208            }
2209        }
2210    }
2211
2212    fn handle_global_notification_effect(&mut self, observed_type_id: TypeId) {
2213        let callbacks = self.global_observations.lock().remove(&observed_type_id);
2214        if let Some(callbacks) = callbacks {
2215            if let Some(global) = self.cx.globals.remove(&observed_type_id) {
2216                for (id, callback) in callbacks {
2217                    if let Some(mut callback) = callback {
2218                        callback(global.as_ref(), self);
2219                        match self
2220                            .global_observations
2221                            .lock()
2222                            .entry(observed_type_id)
2223                            .or_default()
2224                            .entry(id)
2225                        {
2226                            collections::btree_map::Entry::Vacant(entry) => {
2227                                entry.insert(Some(callback));
2228                            }
2229                            collections::btree_map::Entry::Occupied(entry) => {
2230                                entry.remove();
2231                            }
2232                        }
2233                    }
2234                }
2235                self.cx.globals.insert(observed_type_id, global);
2236            }
2237        }
2238    }
2239
2240    fn handle_entity_release_effect(&mut self, entity_id: usize, entity: &dyn Any) {
2241        let callbacks = self.release_observations.lock().remove(&entity_id);
2242        if let Some(callbacks) = callbacks {
2243            for (_, callback) in callbacks {
2244                callback(entity, self);
2245            }
2246        }
2247    }
2248
2249    fn handle_activation_effect(&mut self, window_id: usize, active: bool) {
2250        if self
2251            .cx
2252            .windows
2253            .get(&window_id)
2254            .map(|w| w.is_active)
2255            .map_or(false, |cur_active| cur_active == active)
2256        {
2257            return;
2258        }
2259
2260        self.update(|this| {
2261            let window = this.cx.windows.get_mut(&window_id)?;
2262            window.is_active = active;
2263            let view_id = window.focused_view_id?;
2264            if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) {
2265                if active {
2266                    view.on_focus(this, window_id, view_id);
2267                } else {
2268                    view.on_blur(this, window_id, view_id);
2269                }
2270                this.cx.views.insert((window_id, view_id), view);
2271            }
2272
2273            Some(())
2274        });
2275    }
2276
2277    fn handle_focus_effect(&mut self, window_id: usize, focused_id: Option<usize>) {
2278        self.pending_focus_index.take();
2279
2280        if self
2281            .cx
2282            .windows
2283            .get(&window_id)
2284            .map(|w| w.focused_view_id)
2285            .map_or(false, |cur_focused| cur_focused == focused_id)
2286        {
2287            return;
2288        }
2289
2290        self.update(|this| {
2291            let blurred_id = this.cx.windows.get_mut(&window_id).and_then(|window| {
2292                let blurred_id = window.focused_view_id;
2293                window.focused_view_id = focused_id;
2294                blurred_id
2295            });
2296
2297            if let Some(blurred_id) = blurred_id {
2298                if let Some(mut blurred_view) = this.cx.views.remove(&(window_id, blurred_id)) {
2299                    blurred_view.on_blur(this, window_id, blurred_id);
2300                    this.cx.views.insert((window_id, blurred_id), blurred_view);
2301                }
2302            }
2303
2304            if let Some(focused_id) = focused_id {
2305                if let Some(mut focused_view) = this.cx.views.remove(&(window_id, focused_id)) {
2306                    focused_view.on_focus(this, window_id, focused_id);
2307                    this.cx.views.insert((window_id, focused_id), focused_view);
2308
2309                    let callbacks = this.focus_observations.lock().remove(&focused_id);
2310                    if let Some(callbacks) = callbacks {
2311                        for (id, callback) in callbacks {
2312                            if let Some(mut callback) = callback {
2313                                let alive = callback(this);
2314                                if alive {
2315                                    match this
2316                                        .focus_observations
2317                                        .lock()
2318                                        .entry(focused_id)
2319                                        .or_default()
2320                                        .entry(id)
2321                                    {
2322                                        btree_map::Entry::Vacant(entry) => {
2323                                            entry.insert(Some(callback));
2324                                        }
2325                                        btree_map::Entry::Occupied(entry) => {
2326                                            entry.remove();
2327                                        }
2328                                    }
2329                                }
2330                            }
2331                        }
2332                    }
2333                }
2334            }
2335        })
2336    }
2337
2338    fn focus(&mut self, window_id: usize, view_id: Option<usize>) {
2339        if let Some(pending_focus_index) = self.pending_focus_index {
2340            self.pending_effects.remove(pending_focus_index);
2341        }
2342        self.pending_focus_index = Some(self.pending_effects.len());
2343        self.pending_effects
2344            .push_back(Effect::Focus { window_id, view_id });
2345    }
2346
2347    pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
2348    where
2349        F: FnOnce(AsyncAppContext) -> Fut,
2350        Fut: 'static + Future<Output = T>,
2351        T: 'static,
2352    {
2353        let future = f(self.to_async());
2354        let cx = self.to_async();
2355        self.foreground.spawn(async move {
2356            let result = future.await;
2357            cx.0.borrow_mut().flush_effects();
2358            result
2359        })
2360    }
2361
2362    pub fn to_async(&self) -> AsyncAppContext {
2363        AsyncAppContext(self.weak_self.as_ref().unwrap().upgrade().unwrap())
2364    }
2365
2366    pub fn write_to_clipboard(&self, item: ClipboardItem) {
2367        self.cx.platform.write_to_clipboard(item);
2368    }
2369
2370    pub fn read_from_clipboard(&self) -> Option<ClipboardItem> {
2371        self.cx.platform.read_from_clipboard()
2372    }
2373
2374    #[cfg(any(test, feature = "test-support"))]
2375    pub fn leak_detector(&self) -> Arc<Mutex<LeakDetector>> {
2376        self.cx.ref_counts.lock().leak_detector.clone()
2377    }
2378}
2379
2380impl ReadModel for MutableAppContext {
2381    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2382        if let Some(model) = self.cx.models.get(&handle.model_id) {
2383            model
2384                .as_any()
2385                .downcast_ref()
2386                .expect("downcast is type safe")
2387        } else {
2388            panic!("circular model reference");
2389        }
2390    }
2391}
2392
2393impl UpdateModel for MutableAppContext {
2394    fn update_model<T: Entity, V>(
2395        &mut self,
2396        handle: &ModelHandle<T>,
2397        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
2398    ) -> V {
2399        if let Some(mut model) = self.cx.models.remove(&handle.model_id) {
2400            self.update(|this| {
2401                let mut cx = ModelContext::new(this, handle.model_id);
2402                let result = update(
2403                    model
2404                        .as_any_mut()
2405                        .downcast_mut()
2406                        .expect("downcast is type safe"),
2407                    &mut cx,
2408                );
2409                this.cx.models.insert(handle.model_id, model);
2410                result
2411            })
2412        } else {
2413            panic!("circular model update");
2414        }
2415    }
2416}
2417
2418impl UpgradeModelHandle for MutableAppContext {
2419    fn upgrade_model_handle<T: Entity>(
2420        &self,
2421        handle: &WeakModelHandle<T>,
2422    ) -> Option<ModelHandle<T>> {
2423        self.cx.upgrade_model_handle(handle)
2424    }
2425
2426    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
2427        self.cx.model_handle_is_upgradable(handle)
2428    }
2429
2430    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
2431        self.cx.upgrade_any_model_handle(handle)
2432    }
2433}
2434
2435impl UpgradeViewHandle for MutableAppContext {
2436    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
2437        self.cx.upgrade_view_handle(handle)
2438    }
2439
2440    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
2441        self.cx.upgrade_any_view_handle(handle)
2442    }
2443}
2444
2445impl ReadView for MutableAppContext {
2446    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
2447        if let Some(view) = self.cx.views.get(&(handle.window_id, handle.view_id)) {
2448            view.as_any().downcast_ref().expect("downcast is type safe")
2449        } else {
2450            panic!("circular view reference");
2451        }
2452    }
2453}
2454
2455impl UpdateView for MutableAppContext {
2456    fn update_view<T, S>(
2457        &mut self,
2458        handle: &ViewHandle<T>,
2459        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
2460    ) -> S
2461    where
2462        T: View,
2463    {
2464        self.update(|this| {
2465            let mut view = this
2466                .cx
2467                .views
2468                .remove(&(handle.window_id, handle.view_id))
2469                .expect("circular view update");
2470
2471            let mut cx = ViewContext::new(this, handle.window_id, handle.view_id);
2472            let result = update(
2473                view.as_any_mut()
2474                    .downcast_mut()
2475                    .expect("downcast is type safe"),
2476                &mut cx,
2477            );
2478            this.cx
2479                .views
2480                .insert((handle.window_id, handle.view_id), view);
2481            result
2482        })
2483    }
2484}
2485
2486impl AsRef<AppContext> for MutableAppContext {
2487    fn as_ref(&self) -> &AppContext {
2488        &self.cx
2489    }
2490}
2491
2492impl Deref for MutableAppContext {
2493    type Target = AppContext;
2494
2495    fn deref(&self) -> &Self::Target {
2496        &self.cx
2497    }
2498}
2499
2500pub struct AppContext {
2501    models: HashMap<usize, Box<dyn AnyModel>>,
2502    views: HashMap<(usize, usize), Box<dyn AnyView>>,
2503    windows: HashMap<usize, Window>,
2504    globals: HashMap<TypeId, Box<dyn Any>>,
2505    element_states: HashMap<ElementStateId, Box<dyn Any>>,
2506    background: Arc<executor::Background>,
2507    ref_counts: Arc<Mutex<RefCounts>>,
2508    font_cache: Arc<FontCache>,
2509    platform: Arc<dyn Platform>,
2510}
2511
2512impl AppContext {
2513    pub(crate) fn root_view(&self, window_id: usize) -> Option<AnyViewHandle> {
2514        self.windows
2515            .get(&window_id)
2516            .map(|window| window.root_view.clone())
2517    }
2518
2519    pub fn root_view_id(&self, window_id: usize) -> Option<usize> {
2520        self.windows
2521            .get(&window_id)
2522            .map(|window| window.root_view.id())
2523    }
2524
2525    pub fn focused_view_id(&self, window_id: usize) -> Option<usize> {
2526        self.windows
2527            .get(&window_id)
2528            .and_then(|window| window.focused_view_id)
2529    }
2530
2531    pub fn background(&self) -> &Arc<executor::Background> {
2532        &self.background
2533    }
2534
2535    pub fn font_cache(&self) -> &Arc<FontCache> {
2536        &self.font_cache
2537    }
2538
2539    pub fn platform(&self) -> &Arc<dyn Platform> {
2540        &self.platform
2541    }
2542
2543    pub fn has_global<T: 'static>(&self) -> bool {
2544        self.globals.contains_key(&TypeId::of::<T>())
2545    }
2546
2547    pub fn global<T: 'static>(&self) -> &T {
2548        if let Some(global) = self.globals.get(&TypeId::of::<T>()) {
2549            global.downcast_ref().unwrap()
2550        } else {
2551            panic!("no global has been added for {}", type_name::<T>());
2552        }
2553    }
2554}
2555
2556impl ReadModel for AppContext {
2557    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2558        if let Some(model) = self.models.get(&handle.model_id) {
2559            model
2560                .as_any()
2561                .downcast_ref()
2562                .expect("downcast should be type safe")
2563        } else {
2564            panic!("circular model reference");
2565        }
2566    }
2567}
2568
2569impl UpgradeModelHandle for AppContext {
2570    fn upgrade_model_handle<T: Entity>(
2571        &self,
2572        handle: &WeakModelHandle<T>,
2573    ) -> Option<ModelHandle<T>> {
2574        if self.models.contains_key(&handle.model_id) {
2575            Some(ModelHandle::new(handle.model_id, &self.ref_counts))
2576        } else {
2577            None
2578        }
2579    }
2580
2581    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
2582        self.models.contains_key(&handle.model_id)
2583    }
2584
2585    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
2586        if self.models.contains_key(&handle.model_id) {
2587            Some(AnyModelHandle::new(
2588                handle.model_id,
2589                handle.model_type,
2590                self.ref_counts.clone(),
2591            ))
2592        } else {
2593            None
2594        }
2595    }
2596}
2597
2598impl UpgradeViewHandle for AppContext {
2599    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
2600        if self.ref_counts.lock().is_entity_alive(handle.view_id) {
2601            Some(ViewHandle::new(
2602                handle.window_id,
2603                handle.view_id,
2604                &self.ref_counts,
2605            ))
2606        } else {
2607            None
2608        }
2609    }
2610
2611    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
2612        if self.ref_counts.lock().is_entity_alive(handle.view_id) {
2613            Some(AnyViewHandle::new(
2614                handle.window_id,
2615                handle.view_id,
2616                handle.view_type,
2617                self.ref_counts.clone(),
2618            ))
2619        } else {
2620            None
2621        }
2622    }
2623}
2624
2625impl ReadView for AppContext {
2626    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
2627        if let Some(view) = self.views.get(&(handle.window_id, handle.view_id)) {
2628            view.as_any()
2629                .downcast_ref()
2630                .expect("downcast should be type safe")
2631        } else {
2632            panic!("circular view reference");
2633        }
2634    }
2635}
2636
2637struct Window {
2638    root_view: AnyViewHandle,
2639    focused_view_id: Option<usize>,
2640    is_active: bool,
2641    invalidation: Option<WindowInvalidation>,
2642}
2643
2644#[derive(Default, Clone)]
2645pub struct WindowInvalidation {
2646    pub updated: HashSet<usize>,
2647    pub removed: Vec<usize>,
2648}
2649
2650pub enum Effect {
2651    Subscription {
2652        entity_id: usize,
2653        subscription_id: usize,
2654        callback: SubscriptionCallback,
2655    },
2656    Event {
2657        entity_id: usize,
2658        payload: Box<dyn Any>,
2659    },
2660    GlobalSubscription {
2661        type_id: TypeId,
2662        subscription_id: usize,
2663        callback: GlobalSubscriptionCallback,
2664    },
2665    GlobalEvent {
2666        payload: Box<dyn Any>,
2667    },
2668    Observation {
2669        entity_id: usize,
2670        subscription_id: usize,
2671        callback: ObservationCallback,
2672    },
2673    ModelNotification {
2674        model_id: usize,
2675    },
2676    ViewNotification {
2677        window_id: usize,
2678        view_id: usize,
2679    },
2680    Deferred {
2681        callback: Box<dyn FnOnce(&mut MutableAppContext)>,
2682        after_window_update: bool,
2683    },
2684    GlobalNotification {
2685        type_id: TypeId,
2686    },
2687    ModelRelease {
2688        model_id: usize,
2689        model: Box<dyn AnyModel>,
2690    },
2691    ViewRelease {
2692        view_id: usize,
2693        view: Box<dyn AnyView>,
2694    },
2695    Focus {
2696        window_id: usize,
2697        view_id: Option<usize>,
2698    },
2699    FocusObservation {
2700        view_id: usize,
2701        subscription_id: usize,
2702        callback: FocusObservationCallback,
2703    },
2704    ResizeWindow {
2705        window_id: usize,
2706    },
2707    ActivateWindow {
2708        window_id: usize,
2709        is_active: bool,
2710    },
2711    RefreshWindows,
2712}
2713
2714impl Debug for Effect {
2715    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2716        match self {
2717            Effect::Subscription {
2718                entity_id,
2719                subscription_id,
2720                ..
2721            } => f
2722                .debug_struct("Effect::Subscribe")
2723                .field("entity_id", entity_id)
2724                .field("subscription_id", subscription_id)
2725                .finish(),
2726            Effect::Event { entity_id, .. } => f
2727                .debug_struct("Effect::Event")
2728                .field("entity_id", entity_id)
2729                .finish(),
2730            Effect::GlobalSubscription {
2731                type_id,
2732                subscription_id,
2733                ..
2734            } => f
2735                .debug_struct("Effect::Subscribe")
2736                .field("type_id", type_id)
2737                .field("subscription_id", subscription_id)
2738                .finish(),
2739            Effect::GlobalEvent { payload, .. } => f
2740                .debug_struct("Effect::GlobalEvent")
2741                .field("type_id", &(&*payload).type_id())
2742                .finish(),
2743            Effect::Observation {
2744                entity_id,
2745                subscription_id,
2746                ..
2747            } => f
2748                .debug_struct("Effect::Observation")
2749                .field("entity_id", entity_id)
2750                .field("subscription_id", subscription_id)
2751                .finish(),
2752            Effect::ModelNotification { model_id } => f
2753                .debug_struct("Effect::ModelNotification")
2754                .field("model_id", model_id)
2755                .finish(),
2756            Effect::ViewNotification { window_id, view_id } => f
2757                .debug_struct("Effect::ViewNotification")
2758                .field("window_id", window_id)
2759                .field("view_id", view_id)
2760                .finish(),
2761            Effect::GlobalNotification { type_id } => f
2762                .debug_struct("Effect::GlobalNotification")
2763                .field("type_id", type_id)
2764                .finish(),
2765            Effect::Deferred { .. } => f.debug_struct("Effect::Deferred").finish(),
2766            Effect::ModelRelease { model_id, .. } => f
2767                .debug_struct("Effect::ModelRelease")
2768                .field("model_id", model_id)
2769                .finish(),
2770            Effect::ViewRelease { view_id, .. } => f
2771                .debug_struct("Effect::ViewRelease")
2772                .field("view_id", view_id)
2773                .finish(),
2774            Effect::Focus { window_id, view_id } => f
2775                .debug_struct("Effect::Focus")
2776                .field("window_id", window_id)
2777                .field("view_id", view_id)
2778                .finish(),
2779            Effect::FocusObservation {
2780                view_id,
2781                subscription_id,
2782                ..
2783            } => f
2784                .debug_struct("Effect::FocusObservation")
2785                .field("view_id", view_id)
2786                .field("subscription_id", subscription_id)
2787                .finish(),
2788            Effect::ResizeWindow { window_id } => f
2789                .debug_struct("Effect::RefreshWindow")
2790                .field("window_id", window_id)
2791                .finish(),
2792            Effect::ActivateWindow {
2793                window_id,
2794                is_active,
2795            } => f
2796                .debug_struct("Effect::ActivateWindow")
2797                .field("window_id", window_id)
2798                .field("is_active", is_active)
2799                .finish(),
2800            Effect::RefreshWindows => f.debug_struct("Effect::FullViewRefresh").finish(),
2801        }
2802    }
2803}
2804
2805pub trait AnyModel {
2806    fn as_any(&self) -> &dyn Any;
2807    fn as_any_mut(&mut self) -> &mut dyn Any;
2808    fn release(&mut self, cx: &mut MutableAppContext);
2809    fn app_will_quit(
2810        &mut self,
2811        cx: &mut MutableAppContext,
2812    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
2813}
2814
2815impl<T> AnyModel for T
2816where
2817    T: Entity,
2818{
2819    fn as_any(&self) -> &dyn Any {
2820        self
2821    }
2822
2823    fn as_any_mut(&mut self) -> &mut dyn Any {
2824        self
2825    }
2826
2827    fn release(&mut self, cx: &mut MutableAppContext) {
2828        self.release(cx);
2829    }
2830
2831    fn app_will_quit(
2832        &mut self,
2833        cx: &mut MutableAppContext,
2834    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
2835        self.app_will_quit(cx)
2836    }
2837}
2838
2839pub trait AnyView {
2840    fn as_any(&self) -> &dyn Any;
2841    fn as_any_mut(&mut self) -> &mut dyn Any;
2842    fn release(&mut self, cx: &mut MutableAppContext);
2843    fn app_will_quit(
2844        &mut self,
2845        cx: &mut MutableAppContext,
2846    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
2847    fn ui_name(&self) -> &'static str;
2848    fn render<'a>(
2849        &mut self,
2850        window_id: usize,
2851        view_id: usize,
2852        titlebar_height: f32,
2853        refreshing: bool,
2854        cx: &mut MutableAppContext,
2855    ) -> ElementBox;
2856    fn on_focus(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize);
2857    fn on_blur(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize);
2858    fn keymap_context(&self, cx: &AppContext) -> keymap::Context;
2859    fn debug_json(&self, cx: &AppContext) -> serde_json::Value;
2860}
2861
2862impl<T> AnyView for T
2863where
2864    T: View,
2865{
2866    fn as_any(&self) -> &dyn Any {
2867        self
2868    }
2869
2870    fn as_any_mut(&mut self) -> &mut dyn Any {
2871        self
2872    }
2873
2874    fn release(&mut self, cx: &mut MutableAppContext) {
2875        self.release(cx);
2876    }
2877
2878    fn app_will_quit(
2879        &mut self,
2880        cx: &mut MutableAppContext,
2881    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
2882        self.app_will_quit(cx)
2883    }
2884
2885    fn ui_name(&self) -> &'static str {
2886        T::ui_name()
2887    }
2888
2889    fn render<'a>(
2890        &mut self,
2891        window_id: usize,
2892        view_id: usize,
2893        titlebar_height: f32,
2894        refreshing: bool,
2895        cx: &mut MutableAppContext,
2896    ) -> ElementBox {
2897        View::render(
2898            self,
2899            &mut RenderContext {
2900                window_id,
2901                view_id,
2902                app: cx,
2903                view_type: PhantomData::<T>,
2904                titlebar_height,
2905                refreshing,
2906            },
2907        )
2908    }
2909
2910    fn on_focus(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize) {
2911        let mut cx = ViewContext::new(cx, window_id, view_id);
2912        View::on_focus(self, &mut cx);
2913    }
2914
2915    fn on_blur(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize) {
2916        let mut cx = ViewContext::new(cx, window_id, view_id);
2917        View::on_blur(self, &mut cx);
2918    }
2919
2920    fn keymap_context(&self, cx: &AppContext) -> keymap::Context {
2921        View::keymap_context(self, cx)
2922    }
2923
2924    fn debug_json(&self, cx: &AppContext) -> serde_json::Value {
2925        View::debug_json(self, cx)
2926    }
2927}
2928
2929pub struct ModelContext<'a, T: ?Sized> {
2930    app: &'a mut MutableAppContext,
2931    model_id: usize,
2932    model_type: PhantomData<T>,
2933    halt_stream: bool,
2934}
2935
2936impl<'a, T: Entity> ModelContext<'a, T> {
2937    fn new(app: &'a mut MutableAppContext, model_id: usize) -> Self {
2938        Self {
2939            app,
2940            model_id,
2941            model_type: PhantomData,
2942            halt_stream: false,
2943        }
2944    }
2945
2946    pub fn background(&self) -> &Arc<executor::Background> {
2947        &self.app.cx.background
2948    }
2949
2950    pub fn halt_stream(&mut self) {
2951        self.halt_stream = true;
2952    }
2953
2954    pub fn model_id(&self) -> usize {
2955        self.model_id
2956    }
2957
2958    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
2959    where
2960        S: Entity,
2961        F: FnOnce(&mut ModelContext<S>) -> S,
2962    {
2963        self.app.add_model(build_model)
2964    }
2965
2966    pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut T, &mut ModelContext<T>)) {
2967        let handle = self.handle();
2968        self.app.defer(move |cx| {
2969            handle.update(cx, |model, cx| {
2970                callback(model, cx);
2971            })
2972        })
2973    }
2974
2975    pub fn emit(&mut self, payload: T::Event) {
2976        self.app.pending_effects.push_back(Effect::Event {
2977            entity_id: self.model_id,
2978            payload: Box::new(payload),
2979        });
2980    }
2981
2982    pub fn notify(&mut self) {
2983        self.app.notify_model(self.model_id);
2984    }
2985
2986    pub fn subscribe<S: Entity, F>(
2987        &mut self,
2988        handle: &ModelHandle<S>,
2989        mut callback: F,
2990    ) -> Subscription
2991    where
2992        S::Event: 'static,
2993        F: 'static + FnMut(&mut T, ModelHandle<S>, &S::Event, &mut ModelContext<T>),
2994    {
2995        let subscriber = self.weak_handle();
2996        self.app
2997            .subscribe_internal(handle, move |emitter, event, cx| {
2998                if let Some(subscriber) = subscriber.upgrade(cx) {
2999                    subscriber.update(cx, |subscriber, cx| {
3000                        callback(subscriber, emitter, event, cx);
3001                    });
3002                    true
3003                } else {
3004                    false
3005                }
3006            })
3007    }
3008
3009    pub fn observe<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F) -> Subscription
3010    where
3011        S: Entity,
3012        F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ModelContext<T>),
3013    {
3014        let observer = self.weak_handle();
3015        self.app.observe_internal(handle, move |observed, cx| {
3016            if let Some(observer) = observer.upgrade(cx) {
3017                observer.update(cx, |observer, cx| {
3018                    callback(observer, observed, cx);
3019                });
3020                true
3021            } else {
3022                false
3023            }
3024        })
3025    }
3026
3027    pub fn observe_release<S, F>(
3028        &mut self,
3029        handle: &ModelHandle<S>,
3030        mut callback: F,
3031    ) -> Subscription
3032    where
3033        S: Entity,
3034        F: 'static + FnMut(&mut T, &S, &mut ModelContext<T>),
3035    {
3036        let observer = self.weak_handle();
3037        self.app.observe_release(handle, move |released, cx| {
3038            if let Some(observer) = observer.upgrade(cx) {
3039                observer.update(cx, |observer, cx| {
3040                    callback(observer, released, cx);
3041                });
3042            }
3043        })
3044    }
3045
3046    pub fn handle(&self) -> ModelHandle<T> {
3047        ModelHandle::new(self.model_id, &self.app.cx.ref_counts)
3048    }
3049
3050    pub fn weak_handle(&self) -> WeakModelHandle<T> {
3051        WeakModelHandle::new(self.model_id)
3052    }
3053
3054    pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
3055    where
3056        F: FnOnce(ModelHandle<T>, AsyncAppContext) -> Fut,
3057        Fut: 'static + Future<Output = S>,
3058        S: 'static,
3059    {
3060        let handle = self.handle();
3061        self.app.spawn(|cx| f(handle, cx))
3062    }
3063
3064    pub fn spawn_weak<F, Fut, S>(&self, f: F) -> Task<S>
3065    where
3066        F: FnOnce(WeakModelHandle<T>, AsyncAppContext) -> Fut,
3067        Fut: 'static + Future<Output = S>,
3068        S: 'static,
3069    {
3070        let handle = self.weak_handle();
3071        self.app.spawn(|cx| f(handle, cx))
3072    }
3073}
3074
3075impl<M> AsRef<AppContext> for ModelContext<'_, M> {
3076    fn as_ref(&self) -> &AppContext {
3077        &self.app.cx
3078    }
3079}
3080
3081impl<M> AsMut<MutableAppContext> for ModelContext<'_, M> {
3082    fn as_mut(&mut self) -> &mut MutableAppContext {
3083        self.app
3084    }
3085}
3086
3087impl<M> ReadModel for ModelContext<'_, M> {
3088    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
3089        self.app.read_model(handle)
3090    }
3091}
3092
3093impl<M> UpdateModel for ModelContext<'_, M> {
3094    fn update_model<T: Entity, V>(
3095        &mut self,
3096        handle: &ModelHandle<T>,
3097        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
3098    ) -> V {
3099        self.app.update_model(handle, update)
3100    }
3101}
3102
3103impl<M> UpgradeModelHandle for ModelContext<'_, M> {
3104    fn upgrade_model_handle<T: Entity>(
3105        &self,
3106        handle: &WeakModelHandle<T>,
3107    ) -> Option<ModelHandle<T>> {
3108        self.cx.upgrade_model_handle(handle)
3109    }
3110
3111    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
3112        self.cx.model_handle_is_upgradable(handle)
3113    }
3114
3115    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
3116        self.cx.upgrade_any_model_handle(handle)
3117    }
3118}
3119
3120impl<M> Deref for ModelContext<'_, M> {
3121    type Target = MutableAppContext;
3122
3123    fn deref(&self) -> &Self::Target {
3124        &self.app
3125    }
3126}
3127
3128impl<M> DerefMut for ModelContext<'_, M> {
3129    fn deref_mut(&mut self) -> &mut Self::Target {
3130        &mut self.app
3131    }
3132}
3133
3134pub struct ViewContext<'a, T: ?Sized> {
3135    app: &'a mut MutableAppContext,
3136    window_id: usize,
3137    view_id: usize,
3138    view_type: PhantomData<T>,
3139}
3140
3141impl<'a, T: View> ViewContext<'a, T> {
3142    fn new(app: &'a mut MutableAppContext, window_id: usize, view_id: usize) -> Self {
3143        Self {
3144            app,
3145            window_id,
3146            view_id,
3147            view_type: PhantomData,
3148        }
3149    }
3150
3151    pub fn handle(&self) -> ViewHandle<T> {
3152        ViewHandle::new(self.window_id, self.view_id, &self.app.cx.ref_counts)
3153    }
3154
3155    pub fn weak_handle(&self) -> WeakViewHandle<T> {
3156        WeakViewHandle::new(self.window_id, self.view_id)
3157    }
3158
3159    pub fn window_id(&self) -> usize {
3160        self.window_id
3161    }
3162
3163    pub fn view_id(&self) -> usize {
3164        self.view_id
3165    }
3166
3167    pub fn foreground(&self) -> &Rc<executor::Foreground> {
3168        self.app.foreground()
3169    }
3170
3171    pub fn background_executor(&self) -> &Arc<executor::Background> {
3172        &self.app.cx.background
3173    }
3174
3175    pub fn platform(&self) -> Arc<dyn Platform> {
3176        self.app.platform()
3177    }
3178
3179    pub fn prompt(
3180        &self,
3181        level: PromptLevel,
3182        msg: &str,
3183        answers: &[&str],
3184    ) -> oneshot::Receiver<usize> {
3185        self.app.prompt(self.window_id, level, msg, answers)
3186    }
3187
3188    pub fn prompt_for_paths(
3189        &self,
3190        options: PathPromptOptions,
3191    ) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
3192        self.app.prompt_for_paths(options)
3193    }
3194
3195    pub fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
3196        self.app.prompt_for_new_path(directory)
3197    }
3198
3199    pub fn debug_elements(&self) -> crate::json::Value {
3200        self.app.debug_elements(self.window_id).unwrap()
3201    }
3202
3203    pub fn focus<S>(&mut self, handle: S)
3204    where
3205        S: Into<AnyViewHandle>,
3206    {
3207        let handle = handle.into();
3208        self.app.focus(handle.window_id, Some(handle.view_id));
3209    }
3210
3211    pub fn focus_self(&mut self) {
3212        self.app.focus(self.window_id, Some(self.view_id));
3213    }
3214
3215    pub fn blur(&mut self) {
3216        self.app.focus(self.window_id, None);
3217    }
3218
3219    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
3220    where
3221        S: Entity,
3222        F: FnOnce(&mut ModelContext<S>) -> S,
3223    {
3224        self.app.add_model(build_model)
3225    }
3226
3227    pub fn add_view<S, F>(&mut self, build_view: F) -> ViewHandle<S>
3228    where
3229        S: View,
3230        F: FnOnce(&mut ViewContext<S>) -> S,
3231    {
3232        self.app.add_view(self.window_id, build_view)
3233    }
3234
3235    pub fn add_option_view<S, F>(&mut self, build_view: F) -> Option<ViewHandle<S>>
3236    where
3237        S: View,
3238        F: FnOnce(&mut ViewContext<S>) -> Option<S>,
3239    {
3240        self.app.add_option_view(self.window_id, build_view)
3241    }
3242
3243    pub fn replace_root_view<V, F>(&mut self, build_root_view: F) -> ViewHandle<V>
3244    where
3245        V: View,
3246        F: FnOnce(&mut ViewContext<V>) -> V,
3247    {
3248        let window_id = self.window_id;
3249        self.update(|this| {
3250            let root_view = this.add_view(window_id, build_root_view);
3251            let window = this.cx.windows.get_mut(&window_id).unwrap();
3252            window.root_view = root_view.clone().into();
3253            window.focused_view_id = Some(root_view.id());
3254            root_view
3255        })
3256    }
3257
3258    pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
3259    where
3260        E: Entity,
3261        E::Event: 'static,
3262        H: Handle<E>,
3263        F: 'static + FnMut(&mut T, H, &E::Event, &mut ViewContext<T>),
3264    {
3265        let subscriber = self.weak_handle();
3266        self.app
3267            .subscribe_internal(handle, move |emitter, event, cx| {
3268                if let Some(subscriber) = subscriber.upgrade(cx) {
3269                    subscriber.update(cx, |subscriber, cx| {
3270                        callback(subscriber, emitter, event, cx);
3271                    });
3272                    true
3273                } else {
3274                    false
3275                }
3276            })
3277    }
3278
3279    pub fn observe<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
3280    where
3281        E: Entity,
3282        H: Handle<E>,
3283        F: 'static + FnMut(&mut T, H, &mut ViewContext<T>),
3284    {
3285        let observer = self.weak_handle();
3286        self.app.observe_internal(handle, move |observed, cx| {
3287            if let Some(observer) = observer.upgrade(cx) {
3288                observer.update(cx, |observer, cx| {
3289                    callback(observer, observed, cx);
3290                });
3291                true
3292            } else {
3293                false
3294            }
3295        })
3296    }
3297
3298    pub fn observe_focus<F, V>(&mut self, handle: &ViewHandle<V>, mut callback: F) -> Subscription
3299    where
3300        F: 'static + FnMut(&mut T, ViewHandle<V>, &mut ViewContext<T>),
3301        V: View,
3302    {
3303        let observer = self.weak_handle();
3304        self.app.observe_focus(handle, move |observed, cx| {
3305            if let Some(observer) = observer.upgrade(cx) {
3306                observer.update(cx, |observer, cx| {
3307                    callback(observer, observed, cx);
3308                });
3309                true
3310            } else {
3311                false
3312            }
3313        })
3314    }
3315
3316    pub fn observe_release<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
3317    where
3318        E: Entity,
3319        H: Handle<E>,
3320        F: 'static + FnMut(&mut T, &E, &mut ViewContext<T>),
3321    {
3322        let observer = self.weak_handle();
3323        self.app.observe_release(handle, move |released, cx| {
3324            if let Some(observer) = observer.upgrade(cx) {
3325                observer.update(cx, |observer, cx| {
3326                    callback(observer, released, cx);
3327                });
3328            }
3329        })
3330    }
3331
3332    pub fn emit(&mut self, payload: T::Event) {
3333        self.app.pending_effects.push_back(Effect::Event {
3334            entity_id: self.view_id,
3335            payload: Box::new(payload),
3336        });
3337    }
3338
3339    pub fn notify(&mut self) {
3340        self.app.notify_view(self.window_id, self.view_id);
3341    }
3342
3343    pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut T, &mut ViewContext<T>)) {
3344        let handle = self.handle();
3345        self.app.defer(move |cx| {
3346            handle.update(cx, |view, cx| {
3347                callback(view, cx);
3348            })
3349        })
3350    }
3351
3352    pub fn after_window_update(
3353        &mut self,
3354        callback: impl 'static + FnOnce(&mut T, &mut ViewContext<T>),
3355    ) {
3356        let handle = self.handle();
3357        self.app.after_window_update(move |cx| {
3358            handle.update(cx, |view, cx| {
3359                callback(view, cx);
3360            })
3361        })
3362    }
3363
3364    pub fn propagate_action(&mut self) {
3365        self.app.halt_action_dispatch = false;
3366    }
3367
3368    pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
3369    where
3370        F: FnOnce(ViewHandle<T>, AsyncAppContext) -> Fut,
3371        Fut: 'static + Future<Output = S>,
3372        S: 'static,
3373    {
3374        let handle = self.handle();
3375        self.app.spawn(|cx| f(handle, cx))
3376    }
3377
3378    pub fn spawn_weak<F, Fut, S>(&self, f: F) -> Task<S>
3379    where
3380        F: FnOnce(WeakViewHandle<T>, AsyncAppContext) -> Fut,
3381        Fut: 'static + Future<Output = S>,
3382        S: 'static,
3383    {
3384        let handle = self.weak_handle();
3385        self.app.spawn(|cx| f(handle, cx))
3386    }
3387}
3388
3389pub struct RenderContext<'a, T: View> {
3390    pub app: &'a mut MutableAppContext,
3391    pub titlebar_height: f32,
3392    pub refreshing: bool,
3393    window_id: usize,
3394    view_id: usize,
3395    view_type: PhantomData<T>,
3396}
3397
3398impl<'a, T: View> RenderContext<'a, T> {
3399    pub fn handle(&self) -> WeakViewHandle<T> {
3400        WeakViewHandle::new(self.window_id, self.view_id)
3401    }
3402
3403    pub fn view_id(&self) -> usize {
3404        self.view_id
3405    }
3406}
3407
3408impl AsRef<AppContext> for &AppContext {
3409    fn as_ref(&self) -> &AppContext {
3410        self
3411    }
3412}
3413
3414impl<V: View> Deref for RenderContext<'_, V> {
3415    type Target = MutableAppContext;
3416
3417    fn deref(&self) -> &Self::Target {
3418        self.app
3419    }
3420}
3421
3422impl<V: View> DerefMut for RenderContext<'_, V> {
3423    fn deref_mut(&mut self) -> &mut Self::Target {
3424        self.app
3425    }
3426}
3427
3428impl<V: View> ReadModel for RenderContext<'_, V> {
3429    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
3430        self.app.read_model(handle)
3431    }
3432}
3433
3434impl<V: View> UpdateModel for RenderContext<'_, V> {
3435    fn update_model<T: Entity, O>(
3436        &mut self,
3437        handle: &ModelHandle<T>,
3438        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
3439    ) -> O {
3440        self.app.update_model(handle, update)
3441    }
3442}
3443
3444impl<V: View> ReadView for RenderContext<'_, V> {
3445    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
3446        self.app.read_view(handle)
3447    }
3448}
3449
3450impl<V: View> ElementStateContext for RenderContext<'_, V> {
3451    fn current_view_id(&self) -> usize {
3452        self.view_id
3453    }
3454}
3455
3456impl<M> AsRef<AppContext> for ViewContext<'_, M> {
3457    fn as_ref(&self) -> &AppContext {
3458        &self.app.cx
3459    }
3460}
3461
3462impl<M> Deref for ViewContext<'_, M> {
3463    type Target = MutableAppContext;
3464
3465    fn deref(&self) -> &Self::Target {
3466        &self.app
3467    }
3468}
3469
3470impl<M> DerefMut for ViewContext<'_, M> {
3471    fn deref_mut(&mut self) -> &mut Self::Target {
3472        &mut self.app
3473    }
3474}
3475
3476impl<M> AsMut<MutableAppContext> for ViewContext<'_, M> {
3477    fn as_mut(&mut self) -> &mut MutableAppContext {
3478        self.app
3479    }
3480}
3481
3482impl<V> ReadModel for ViewContext<'_, V> {
3483    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
3484        self.app.read_model(handle)
3485    }
3486}
3487
3488impl<V> UpgradeModelHandle for ViewContext<'_, V> {
3489    fn upgrade_model_handle<T: Entity>(
3490        &self,
3491        handle: &WeakModelHandle<T>,
3492    ) -> Option<ModelHandle<T>> {
3493        self.cx.upgrade_model_handle(handle)
3494    }
3495
3496    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
3497        self.cx.model_handle_is_upgradable(handle)
3498    }
3499
3500    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
3501        self.cx.upgrade_any_model_handle(handle)
3502    }
3503}
3504
3505impl<V> UpgradeViewHandle for ViewContext<'_, V> {
3506    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
3507        self.cx.upgrade_view_handle(handle)
3508    }
3509
3510    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
3511        self.cx.upgrade_any_view_handle(handle)
3512    }
3513}
3514
3515impl<V: View> UpdateModel for ViewContext<'_, V> {
3516    fn update_model<T: Entity, O>(
3517        &mut self,
3518        handle: &ModelHandle<T>,
3519        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
3520    ) -> O {
3521        self.app.update_model(handle, update)
3522    }
3523}
3524
3525impl<V: View> ReadView for ViewContext<'_, V> {
3526    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
3527        self.app.read_view(handle)
3528    }
3529}
3530
3531impl<V: View> UpdateView for ViewContext<'_, V> {
3532    fn update_view<T, S>(
3533        &mut self,
3534        handle: &ViewHandle<T>,
3535        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
3536    ) -> S
3537    where
3538        T: View,
3539    {
3540        self.app.update_view(handle, update)
3541    }
3542}
3543
3544impl<V: View> ElementStateContext for ViewContext<'_, V> {
3545    fn current_view_id(&self) -> usize {
3546        self.view_id
3547    }
3548}
3549
3550pub trait Handle<T> {
3551    type Weak: 'static;
3552    fn id(&self) -> usize;
3553    fn location(&self) -> EntityLocation;
3554    fn downgrade(&self) -> Self::Weak;
3555    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
3556    where
3557        Self: Sized;
3558}
3559
3560pub trait WeakHandle {
3561    fn id(&self) -> usize;
3562}
3563
3564#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
3565pub enum EntityLocation {
3566    Model(usize),
3567    View(usize, usize),
3568}
3569
3570pub struct ModelHandle<T: Entity> {
3571    model_id: usize,
3572    model_type: PhantomData<T>,
3573    ref_counts: Arc<Mutex<RefCounts>>,
3574
3575    #[cfg(any(test, feature = "test-support"))]
3576    handle_id: usize,
3577}
3578
3579impl<T: Entity> ModelHandle<T> {
3580    fn new(model_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
3581        ref_counts.lock().inc_model(model_id);
3582
3583        #[cfg(any(test, feature = "test-support"))]
3584        let handle_id = ref_counts
3585            .lock()
3586            .leak_detector
3587            .lock()
3588            .handle_created(Some(type_name::<T>()), model_id);
3589
3590        Self {
3591            model_id,
3592            model_type: PhantomData,
3593            ref_counts: ref_counts.clone(),
3594
3595            #[cfg(any(test, feature = "test-support"))]
3596            handle_id,
3597        }
3598    }
3599
3600    pub fn downgrade(&self) -> WeakModelHandle<T> {
3601        WeakModelHandle::new(self.model_id)
3602    }
3603
3604    pub fn id(&self) -> usize {
3605        self.model_id
3606    }
3607
3608    pub fn read<'a, C: ReadModel>(&self, cx: &'a C) -> &'a T {
3609        cx.read_model(self)
3610    }
3611
3612    pub fn read_with<'a, C, F, S>(&self, cx: &C, read: F) -> S
3613    where
3614        C: ReadModelWith,
3615        F: FnOnce(&T, &AppContext) -> S,
3616    {
3617        let mut read = Some(read);
3618        cx.read_model_with(self, &mut |model, cx| {
3619            let read = read.take().unwrap();
3620            read(model, cx)
3621        })
3622    }
3623
3624    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
3625    where
3626        C: UpdateModel,
3627        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
3628    {
3629        let mut update = Some(update);
3630        cx.update_model(self, &mut |model, cx| {
3631            let update = update.take().unwrap();
3632            update(model, cx)
3633        })
3634    }
3635
3636    #[cfg(any(test, feature = "test-support"))]
3637    pub fn next_notification(&self, cx: &TestAppContext) -> impl Future<Output = ()> {
3638        let (tx, mut rx) = futures::channel::mpsc::unbounded();
3639        let mut cx = cx.cx.borrow_mut();
3640        let subscription = cx.observe(self, move |_, _| {
3641            tx.unbounded_send(()).ok();
3642        });
3643
3644        let duration = if std::env::var("CI").is_ok() {
3645            Duration::from_secs(5)
3646        } else {
3647            Duration::from_secs(1)
3648        };
3649
3650        async move {
3651            let notification = crate::util::timeout(duration, rx.next())
3652                .await
3653                .expect("next notification timed out");
3654            drop(subscription);
3655            notification.expect("model dropped while test was waiting for its next notification")
3656        }
3657    }
3658
3659    #[cfg(any(test, feature = "test-support"))]
3660    pub fn next_event(&self, cx: &TestAppContext) -> impl Future<Output = T::Event>
3661    where
3662        T::Event: Clone,
3663    {
3664        let (tx, mut rx) = futures::channel::mpsc::unbounded();
3665        let mut cx = cx.cx.borrow_mut();
3666        let subscription = cx.subscribe(self, move |_, event, _| {
3667            tx.unbounded_send(event.clone()).ok();
3668        });
3669
3670        let duration = if std::env::var("CI").is_ok() {
3671            Duration::from_secs(5)
3672        } else {
3673            Duration::from_secs(1)
3674        };
3675
3676        cx.foreground.start_waiting();
3677        async move {
3678            let event = crate::util::timeout(duration, rx.next())
3679                .await
3680                .expect("next event timed out");
3681            drop(subscription);
3682            event.expect("model dropped while test was waiting for its next event")
3683        }
3684    }
3685
3686    #[cfg(any(test, feature = "test-support"))]
3687    pub fn condition(
3688        &self,
3689        cx: &TestAppContext,
3690        mut predicate: impl FnMut(&T, &AppContext) -> bool,
3691    ) -> impl Future<Output = ()> {
3692        let (tx, mut rx) = futures::channel::mpsc::unbounded();
3693
3694        let mut cx = cx.cx.borrow_mut();
3695        let subscriptions = (
3696            cx.observe(self, {
3697                let tx = tx.clone();
3698                move |_, _| {
3699                    tx.unbounded_send(()).ok();
3700                }
3701            }),
3702            cx.subscribe(self, {
3703                let tx = tx.clone();
3704                move |_, _, _| {
3705                    tx.unbounded_send(()).ok();
3706                }
3707            }),
3708        );
3709
3710        let cx = cx.weak_self.as_ref().unwrap().upgrade().unwrap();
3711        let handle = self.downgrade();
3712        let duration = if std::env::var("CI").is_ok() {
3713            Duration::from_secs(5)
3714        } else {
3715            Duration::from_secs(1)
3716        };
3717
3718        async move {
3719            crate::util::timeout(duration, async move {
3720                loop {
3721                    {
3722                        let cx = cx.borrow();
3723                        let cx = cx.as_ref();
3724                        if predicate(
3725                            handle
3726                                .upgrade(cx)
3727                                .expect("model dropped with pending condition")
3728                                .read(cx),
3729                            cx,
3730                        ) {
3731                            break;
3732                        }
3733                    }
3734
3735                    cx.borrow().foreground().start_waiting();
3736                    rx.next()
3737                        .await
3738                        .expect("model dropped with pending condition");
3739                    cx.borrow().foreground().finish_waiting();
3740                }
3741            })
3742            .await
3743            .expect("condition timed out");
3744            drop(subscriptions);
3745        }
3746    }
3747}
3748
3749impl<T: Entity> Clone for ModelHandle<T> {
3750    fn clone(&self) -> Self {
3751        Self::new(self.model_id, &self.ref_counts)
3752    }
3753}
3754
3755impl<T: Entity> PartialEq for ModelHandle<T> {
3756    fn eq(&self, other: &Self) -> bool {
3757        self.model_id == other.model_id
3758    }
3759}
3760
3761impl<T: Entity> Eq for ModelHandle<T> {}
3762
3763impl<T: Entity> PartialEq<WeakModelHandle<T>> for ModelHandle<T> {
3764    fn eq(&self, other: &WeakModelHandle<T>) -> bool {
3765        self.model_id == other.model_id
3766    }
3767}
3768
3769impl<T: Entity> Hash for ModelHandle<T> {
3770    fn hash<H: Hasher>(&self, state: &mut H) {
3771        self.model_id.hash(state);
3772    }
3773}
3774
3775impl<T: Entity> std::borrow::Borrow<usize> for ModelHandle<T> {
3776    fn borrow(&self) -> &usize {
3777        &self.model_id
3778    }
3779}
3780
3781impl<T: Entity> Debug for ModelHandle<T> {
3782    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3783        f.debug_tuple(&format!("ModelHandle<{}>", type_name::<T>()))
3784            .field(&self.model_id)
3785            .finish()
3786    }
3787}
3788
3789unsafe impl<T: Entity> Send for ModelHandle<T> {}
3790unsafe impl<T: Entity> Sync for ModelHandle<T> {}
3791
3792impl<T: Entity> Drop for ModelHandle<T> {
3793    fn drop(&mut self) {
3794        let mut ref_counts = self.ref_counts.lock();
3795        ref_counts.dec_model(self.model_id);
3796
3797        #[cfg(any(test, feature = "test-support"))]
3798        ref_counts
3799            .leak_detector
3800            .lock()
3801            .handle_dropped(self.model_id, self.handle_id);
3802    }
3803}
3804
3805impl<T: Entity> Handle<T> for ModelHandle<T> {
3806    type Weak = WeakModelHandle<T>;
3807
3808    fn id(&self) -> usize {
3809        self.model_id
3810    }
3811
3812    fn location(&self) -> EntityLocation {
3813        EntityLocation::Model(self.model_id)
3814    }
3815
3816    fn downgrade(&self) -> Self::Weak {
3817        self.downgrade()
3818    }
3819
3820    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
3821    where
3822        Self: Sized,
3823    {
3824        weak.upgrade(cx)
3825    }
3826}
3827
3828pub struct WeakModelHandle<T> {
3829    model_id: usize,
3830    model_type: PhantomData<T>,
3831}
3832
3833impl<T> WeakHandle for WeakModelHandle<T> {
3834    fn id(&self) -> usize {
3835        self.model_id
3836    }
3837}
3838
3839unsafe impl<T> Send for WeakModelHandle<T> {}
3840unsafe impl<T> Sync for WeakModelHandle<T> {}
3841
3842impl<T: Entity> WeakModelHandle<T> {
3843    fn new(model_id: usize) -> Self {
3844        Self {
3845            model_id,
3846            model_type: PhantomData,
3847        }
3848    }
3849
3850    pub fn id(&self) -> usize {
3851        self.model_id
3852    }
3853
3854    pub fn is_upgradable(&self, cx: &impl UpgradeModelHandle) -> bool {
3855        cx.model_handle_is_upgradable(self)
3856    }
3857
3858    pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<ModelHandle<T>> {
3859        cx.upgrade_model_handle(self)
3860    }
3861}
3862
3863impl<T> Hash for WeakModelHandle<T> {
3864    fn hash<H: Hasher>(&self, state: &mut H) {
3865        self.model_id.hash(state)
3866    }
3867}
3868
3869impl<T> PartialEq for WeakModelHandle<T> {
3870    fn eq(&self, other: &Self) -> bool {
3871        self.model_id == other.model_id
3872    }
3873}
3874
3875impl<T> Eq for WeakModelHandle<T> {}
3876
3877impl<T> Clone for WeakModelHandle<T> {
3878    fn clone(&self) -> Self {
3879        Self {
3880            model_id: self.model_id,
3881            model_type: PhantomData,
3882        }
3883    }
3884}
3885
3886impl<T> Copy for WeakModelHandle<T> {}
3887
3888pub struct ViewHandle<T> {
3889    window_id: usize,
3890    view_id: usize,
3891    view_type: PhantomData<T>,
3892    ref_counts: Arc<Mutex<RefCounts>>,
3893    #[cfg(any(test, feature = "test-support"))]
3894    handle_id: usize,
3895}
3896
3897impl<T: View> ViewHandle<T> {
3898    fn new(window_id: usize, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
3899        ref_counts.lock().inc_view(window_id, view_id);
3900        #[cfg(any(test, feature = "test-support"))]
3901        let handle_id = ref_counts
3902            .lock()
3903            .leak_detector
3904            .lock()
3905            .handle_created(Some(type_name::<T>()), view_id);
3906
3907        Self {
3908            window_id,
3909            view_id,
3910            view_type: PhantomData,
3911            ref_counts: ref_counts.clone(),
3912
3913            #[cfg(any(test, feature = "test-support"))]
3914            handle_id,
3915        }
3916    }
3917
3918    pub fn downgrade(&self) -> WeakViewHandle<T> {
3919        WeakViewHandle::new(self.window_id, self.view_id)
3920    }
3921
3922    pub fn window_id(&self) -> usize {
3923        self.window_id
3924    }
3925
3926    pub fn id(&self) -> usize {
3927        self.view_id
3928    }
3929
3930    pub fn read<'a, C: ReadView>(&self, cx: &'a C) -> &'a T {
3931        cx.read_view(self)
3932    }
3933
3934    pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> S
3935    where
3936        C: ReadViewWith,
3937        F: FnOnce(&T, &AppContext) -> S,
3938    {
3939        let mut read = Some(read);
3940        cx.read_view_with(self, &mut |view, cx| {
3941            let read = read.take().unwrap();
3942            read(view, cx)
3943        })
3944    }
3945
3946    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
3947    where
3948        C: UpdateView,
3949        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
3950    {
3951        let mut update = Some(update);
3952        cx.update_view(self, &mut |view, cx| {
3953            let update = update.take().unwrap();
3954            update(view, cx)
3955        })
3956    }
3957
3958    pub fn defer<C, F>(&self, cx: &mut C, update: F)
3959    where
3960        C: AsMut<MutableAppContext>,
3961        F: 'static + FnOnce(&mut T, &mut ViewContext<T>),
3962    {
3963        let this = self.clone();
3964        cx.as_mut().defer(move |cx| {
3965            this.update(cx, |view, cx| update(view, cx));
3966        });
3967    }
3968
3969    pub fn is_focused(&self, cx: &AppContext) -> bool {
3970        cx.focused_view_id(self.window_id)
3971            .map_or(false, |focused_id| focused_id == self.view_id)
3972    }
3973
3974    #[cfg(any(test, feature = "test-support"))]
3975    pub fn next_notification(&self, cx: &TestAppContext) -> impl Future<Output = ()> {
3976        use postage::prelude::{Sink as _, Stream as _};
3977
3978        let (mut tx, mut rx) = postage::mpsc::channel(1);
3979        let mut cx = cx.cx.borrow_mut();
3980        let subscription = cx.observe(self, move |_, _| {
3981            tx.try_send(()).ok();
3982        });
3983
3984        let duration = if std::env::var("CI").is_ok() {
3985            Duration::from_secs(5)
3986        } else {
3987            Duration::from_secs(1)
3988        };
3989
3990        async move {
3991            let notification = crate::util::timeout(duration, rx.recv())
3992                .await
3993                .expect("next notification timed out");
3994            drop(subscription);
3995            notification.expect("model dropped while test was waiting for its next notification")
3996        }
3997    }
3998
3999    #[cfg(any(test, feature = "test-support"))]
4000    pub fn condition(
4001        &self,
4002        cx: &TestAppContext,
4003        mut predicate: impl FnMut(&T, &AppContext) -> bool,
4004    ) -> impl Future<Output = ()> {
4005        use postage::prelude::{Sink as _, Stream as _};
4006
4007        let (tx, mut rx) = postage::mpsc::channel(1024);
4008
4009        let mut cx = cx.cx.borrow_mut();
4010        let subscriptions = self.update(&mut *cx, |_, cx| {
4011            (
4012                cx.observe(self, {
4013                    let mut tx = tx.clone();
4014                    move |_, _, _| {
4015                        tx.blocking_send(()).ok();
4016                    }
4017                }),
4018                cx.subscribe(self, {
4019                    let mut tx = tx.clone();
4020                    move |_, _, _, _| {
4021                        tx.blocking_send(()).ok();
4022                    }
4023                }),
4024            )
4025        });
4026
4027        let cx = cx.weak_self.as_ref().unwrap().upgrade().unwrap();
4028        let handle = self.downgrade();
4029        let duration = if std::env::var("CI").is_ok() {
4030            Duration::from_secs(2)
4031        } else {
4032            Duration::from_millis(500)
4033        };
4034
4035        async move {
4036            crate::util::timeout(duration, async move {
4037                loop {
4038                    {
4039                        let cx = cx.borrow();
4040                        let cx = cx.as_ref();
4041                        if predicate(
4042                            handle
4043                                .upgrade(cx)
4044                                .expect("view dropped with pending condition")
4045                                .read(cx),
4046                            cx,
4047                        ) {
4048                            break;
4049                        }
4050                    }
4051
4052                    cx.borrow().foreground().start_waiting();
4053                    rx.recv()
4054                        .await
4055                        .expect("view dropped with pending condition");
4056                    cx.borrow().foreground().finish_waiting();
4057                }
4058            })
4059            .await
4060            .expect("condition timed out");
4061            drop(subscriptions);
4062        }
4063    }
4064}
4065
4066impl<T: View> Clone for ViewHandle<T> {
4067    fn clone(&self) -> Self {
4068        ViewHandle::new(self.window_id, self.view_id, &self.ref_counts)
4069    }
4070}
4071
4072impl<T> PartialEq for ViewHandle<T> {
4073    fn eq(&self, other: &Self) -> bool {
4074        self.window_id == other.window_id && self.view_id == other.view_id
4075    }
4076}
4077
4078impl<T> PartialEq<WeakViewHandle<T>> for ViewHandle<T> {
4079    fn eq(&self, other: &WeakViewHandle<T>) -> bool {
4080        self.window_id == other.window_id && self.view_id == other.view_id
4081    }
4082}
4083
4084impl<T> PartialEq<ViewHandle<T>> for WeakViewHandle<T> {
4085    fn eq(&self, other: &ViewHandle<T>) -> bool {
4086        self.window_id == other.window_id && self.view_id == other.view_id
4087    }
4088}
4089
4090impl<T> Eq for ViewHandle<T> {}
4091
4092impl<T> Hash for ViewHandle<T> {
4093    fn hash<H: Hasher>(&self, state: &mut H) {
4094        self.window_id.hash(state);
4095        self.view_id.hash(state);
4096    }
4097}
4098
4099impl<T> Debug for ViewHandle<T> {
4100    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4101        f.debug_struct(&format!("ViewHandle<{}>", type_name::<T>()))
4102            .field("window_id", &self.window_id)
4103            .field("view_id", &self.view_id)
4104            .finish()
4105    }
4106}
4107
4108impl<T> Drop for ViewHandle<T> {
4109    fn drop(&mut self) {
4110        self.ref_counts
4111            .lock()
4112            .dec_view(self.window_id, self.view_id);
4113        #[cfg(any(test, feature = "test-support"))]
4114        self.ref_counts
4115            .lock()
4116            .leak_detector
4117            .lock()
4118            .handle_dropped(self.view_id, self.handle_id);
4119    }
4120}
4121
4122impl<T: View> Handle<T> for ViewHandle<T> {
4123    type Weak = WeakViewHandle<T>;
4124
4125    fn id(&self) -> usize {
4126        self.view_id
4127    }
4128
4129    fn location(&self) -> EntityLocation {
4130        EntityLocation::View(self.window_id, self.view_id)
4131    }
4132
4133    fn downgrade(&self) -> Self::Weak {
4134        self.downgrade()
4135    }
4136
4137    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
4138    where
4139        Self: Sized,
4140    {
4141        weak.upgrade(cx)
4142    }
4143}
4144
4145pub struct AnyViewHandle {
4146    window_id: usize,
4147    view_id: usize,
4148    view_type: TypeId,
4149    ref_counts: Arc<Mutex<RefCounts>>,
4150
4151    #[cfg(any(test, feature = "test-support"))]
4152    handle_id: usize,
4153}
4154
4155impl AnyViewHandle {
4156    fn new(
4157        window_id: usize,
4158        view_id: usize,
4159        view_type: TypeId,
4160        ref_counts: Arc<Mutex<RefCounts>>,
4161    ) -> Self {
4162        ref_counts.lock().inc_view(window_id, view_id);
4163
4164        #[cfg(any(test, feature = "test-support"))]
4165        let handle_id = ref_counts
4166            .lock()
4167            .leak_detector
4168            .lock()
4169            .handle_created(None, view_id);
4170
4171        Self {
4172            window_id,
4173            view_id,
4174            view_type,
4175            ref_counts,
4176            #[cfg(any(test, feature = "test-support"))]
4177            handle_id,
4178        }
4179    }
4180
4181    pub fn id(&self) -> usize {
4182        self.view_id
4183    }
4184
4185    pub fn is<T: 'static>(&self) -> bool {
4186        TypeId::of::<T>() == self.view_type
4187    }
4188
4189    pub fn is_focused(&self, cx: &AppContext) -> bool {
4190        cx.focused_view_id(self.window_id)
4191            .map_or(false, |focused_id| focused_id == self.view_id)
4192    }
4193
4194    pub fn downcast<T: View>(self) -> Option<ViewHandle<T>> {
4195        if self.is::<T>() {
4196            let result = Some(ViewHandle {
4197                window_id: self.window_id,
4198                view_id: self.view_id,
4199                ref_counts: self.ref_counts.clone(),
4200                view_type: PhantomData,
4201                #[cfg(any(test, feature = "test-support"))]
4202                handle_id: self.handle_id,
4203            });
4204            unsafe {
4205                Arc::decrement_strong_count(&self.ref_counts);
4206            }
4207            std::mem::forget(self);
4208            result
4209        } else {
4210            None
4211        }
4212    }
4213
4214    pub fn downgrade(&self) -> AnyWeakViewHandle {
4215        AnyWeakViewHandle {
4216            window_id: self.window_id,
4217            view_id: self.view_id,
4218            view_type: self.view_type,
4219        }
4220    }
4221
4222    pub fn view_type(&self) -> TypeId {
4223        self.view_type
4224    }
4225
4226    pub fn debug_json(&self, cx: &AppContext) -> serde_json::Value {
4227        cx.views
4228            .get(&(self.window_id, self.view_id))
4229            .map_or_else(|| serde_json::Value::Null, |view| view.debug_json(cx))
4230    }
4231}
4232
4233impl Clone for AnyViewHandle {
4234    fn clone(&self) -> Self {
4235        Self::new(
4236            self.window_id,
4237            self.view_id,
4238            self.view_type,
4239            self.ref_counts.clone(),
4240        )
4241    }
4242}
4243
4244impl From<&AnyViewHandle> for AnyViewHandle {
4245    fn from(handle: &AnyViewHandle) -> Self {
4246        handle.clone()
4247    }
4248}
4249
4250impl<T: View> From<&ViewHandle<T>> for AnyViewHandle {
4251    fn from(handle: &ViewHandle<T>) -> Self {
4252        Self::new(
4253            handle.window_id,
4254            handle.view_id,
4255            TypeId::of::<T>(),
4256            handle.ref_counts.clone(),
4257        )
4258    }
4259}
4260
4261impl<T: View> From<ViewHandle<T>> for AnyViewHandle {
4262    fn from(handle: ViewHandle<T>) -> Self {
4263        let any_handle = AnyViewHandle {
4264            window_id: handle.window_id,
4265            view_id: handle.view_id,
4266            view_type: TypeId::of::<T>(),
4267            ref_counts: handle.ref_counts.clone(),
4268            #[cfg(any(test, feature = "test-support"))]
4269            handle_id: handle.handle_id,
4270        };
4271        unsafe {
4272            Arc::decrement_strong_count(&handle.ref_counts);
4273        }
4274        std::mem::forget(handle);
4275        any_handle
4276    }
4277}
4278
4279impl Drop for AnyViewHandle {
4280    fn drop(&mut self) {
4281        self.ref_counts
4282            .lock()
4283            .dec_view(self.window_id, self.view_id);
4284        #[cfg(any(test, feature = "test-support"))]
4285        self.ref_counts
4286            .lock()
4287            .leak_detector
4288            .lock()
4289            .handle_dropped(self.view_id, self.handle_id);
4290    }
4291}
4292
4293pub struct AnyModelHandle {
4294    model_id: usize,
4295    model_type: TypeId,
4296    ref_counts: Arc<Mutex<RefCounts>>,
4297
4298    #[cfg(any(test, feature = "test-support"))]
4299    handle_id: usize,
4300}
4301
4302impl AnyModelHandle {
4303    fn new(model_id: usize, model_type: TypeId, ref_counts: Arc<Mutex<RefCounts>>) -> Self {
4304        ref_counts.lock().inc_model(model_id);
4305
4306        #[cfg(any(test, feature = "test-support"))]
4307        let handle_id = ref_counts
4308            .lock()
4309            .leak_detector
4310            .lock()
4311            .handle_created(None, model_id);
4312
4313        Self {
4314            model_id,
4315            model_type,
4316            ref_counts,
4317
4318            #[cfg(any(test, feature = "test-support"))]
4319            handle_id,
4320        }
4321    }
4322
4323    pub fn downcast<T: Entity>(self) -> Option<ModelHandle<T>> {
4324        if self.is::<T>() {
4325            let result = Some(ModelHandle {
4326                model_id: self.model_id,
4327                model_type: PhantomData,
4328                ref_counts: self.ref_counts.clone(),
4329
4330                #[cfg(any(test, feature = "test-support"))]
4331                handle_id: self.handle_id,
4332            });
4333            unsafe {
4334                Arc::decrement_strong_count(&self.ref_counts);
4335            }
4336            std::mem::forget(self);
4337            result
4338        } else {
4339            None
4340        }
4341    }
4342
4343    pub fn downgrade(&self) -> AnyWeakModelHandle {
4344        AnyWeakModelHandle {
4345            model_id: self.model_id,
4346            model_type: self.model_type,
4347        }
4348    }
4349
4350    pub fn is<T: Entity>(&self) -> bool {
4351        self.model_type == TypeId::of::<T>()
4352    }
4353
4354    pub fn model_type(&self) -> TypeId {
4355        self.model_type
4356    }
4357}
4358
4359impl<T: Entity> From<ModelHandle<T>> for AnyModelHandle {
4360    fn from(handle: ModelHandle<T>) -> Self {
4361        Self::new(
4362            handle.model_id,
4363            TypeId::of::<T>(),
4364            handle.ref_counts.clone(),
4365        )
4366    }
4367}
4368
4369impl Clone for AnyModelHandle {
4370    fn clone(&self) -> Self {
4371        Self::new(self.model_id, self.model_type, self.ref_counts.clone())
4372    }
4373}
4374
4375impl Drop for AnyModelHandle {
4376    fn drop(&mut self) {
4377        let mut ref_counts = self.ref_counts.lock();
4378        ref_counts.dec_model(self.model_id);
4379
4380        #[cfg(any(test, feature = "test-support"))]
4381        ref_counts
4382            .leak_detector
4383            .lock()
4384            .handle_dropped(self.model_id, self.handle_id);
4385    }
4386}
4387
4388pub struct AnyWeakModelHandle {
4389    model_id: usize,
4390    model_type: TypeId,
4391}
4392
4393impl AnyWeakModelHandle {
4394    pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<AnyModelHandle> {
4395        cx.upgrade_any_model_handle(self)
4396    }
4397}
4398
4399impl<T: Entity> From<WeakModelHandle<T>> for AnyWeakModelHandle {
4400    fn from(handle: WeakModelHandle<T>) -> Self {
4401        AnyWeakModelHandle {
4402            model_id: handle.model_id,
4403            model_type: TypeId::of::<T>(),
4404        }
4405    }
4406}
4407
4408pub struct WeakViewHandle<T> {
4409    window_id: usize,
4410    view_id: usize,
4411    view_type: PhantomData<T>,
4412}
4413
4414impl<T> WeakHandle for WeakViewHandle<T> {
4415    fn id(&self) -> usize {
4416        self.view_id
4417    }
4418}
4419
4420impl<T: View> WeakViewHandle<T> {
4421    fn new(window_id: usize, view_id: usize) -> Self {
4422        Self {
4423            window_id,
4424            view_id,
4425            view_type: PhantomData,
4426        }
4427    }
4428
4429    pub fn id(&self) -> usize {
4430        self.view_id
4431    }
4432
4433    pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<ViewHandle<T>> {
4434        cx.upgrade_view_handle(self)
4435    }
4436}
4437
4438impl<T> Clone for WeakViewHandle<T> {
4439    fn clone(&self) -> Self {
4440        Self {
4441            window_id: self.window_id,
4442            view_id: self.view_id,
4443            view_type: PhantomData,
4444        }
4445    }
4446}
4447
4448impl<T> PartialEq for WeakViewHandle<T> {
4449    fn eq(&self, other: &Self) -> bool {
4450        self.window_id == other.window_id && self.view_id == other.view_id
4451    }
4452}
4453
4454impl<T> Eq for WeakViewHandle<T> {}
4455
4456impl<T> Hash for WeakViewHandle<T> {
4457    fn hash<H: Hasher>(&self, state: &mut H) {
4458        self.window_id.hash(state);
4459        self.view_id.hash(state);
4460    }
4461}
4462
4463pub struct AnyWeakViewHandle {
4464    window_id: usize,
4465    view_id: usize,
4466    view_type: TypeId,
4467}
4468
4469impl AnyWeakViewHandle {
4470    pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<AnyViewHandle> {
4471        cx.upgrade_any_view_handle(self)
4472    }
4473}
4474
4475impl<T: View> From<WeakViewHandle<T>> for AnyWeakViewHandle {
4476    fn from(handle: WeakViewHandle<T>) -> Self {
4477        AnyWeakViewHandle {
4478            window_id: handle.window_id,
4479            view_id: handle.view_id,
4480            view_type: TypeId::of::<T>(),
4481        }
4482    }
4483}
4484
4485#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4486pub struct ElementStateId {
4487    view_id: usize,
4488    element_id: usize,
4489    tag: TypeId,
4490}
4491
4492pub struct ElementStateHandle<T> {
4493    value_type: PhantomData<T>,
4494    id: ElementStateId,
4495    ref_counts: Weak<Mutex<RefCounts>>,
4496}
4497
4498impl<T: 'static> ElementStateHandle<T> {
4499    fn new(id: ElementStateId, frame_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
4500        ref_counts.lock().inc_element_state(id, frame_id);
4501        Self {
4502            value_type: PhantomData,
4503            id,
4504            ref_counts: Arc::downgrade(ref_counts),
4505        }
4506    }
4507
4508    pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
4509        cx.element_states
4510            .get(&self.id)
4511            .unwrap()
4512            .downcast_ref()
4513            .unwrap()
4514    }
4515
4516    pub fn update<C, R>(&self, cx: &mut C, f: impl FnOnce(&mut T, &mut C) -> R) -> R
4517    where
4518        C: DerefMut<Target = MutableAppContext>,
4519    {
4520        let mut element_state = cx.deref_mut().cx.element_states.remove(&self.id).unwrap();
4521        let result = f(element_state.downcast_mut().unwrap(), cx);
4522        cx.deref_mut()
4523            .cx
4524            .element_states
4525            .insert(self.id, element_state);
4526        result
4527    }
4528}
4529
4530impl<T> Drop for ElementStateHandle<T> {
4531    fn drop(&mut self) {
4532        if let Some(ref_counts) = self.ref_counts.upgrade() {
4533            ref_counts.lock().dec_element_state(self.id);
4534        }
4535    }
4536}
4537
4538#[must_use]
4539pub enum Subscription {
4540    Subscription {
4541        id: usize,
4542        entity_id: usize,
4543        subscriptions:
4544            Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, Option<SubscriptionCallback>>>>>>,
4545    },
4546    GlobalSubscription {
4547        id: usize,
4548        type_id: TypeId,
4549        subscriptions: Option<
4550            Weak<Mutex<HashMap<TypeId, BTreeMap<usize, Option<GlobalSubscriptionCallback>>>>>,
4551        >,
4552    },
4553    Observation {
4554        id: usize,
4555        entity_id: usize,
4556        observations:
4557            Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, Option<ObservationCallback>>>>>>,
4558    },
4559    GlobalObservation {
4560        id: usize,
4561        type_id: TypeId,
4562        observations: Option<
4563            Weak<Mutex<HashMap<TypeId, BTreeMap<usize, Option<GlobalObservationCallback>>>>>,
4564        >,
4565    },
4566    FocusObservation {
4567        id: usize,
4568        view_id: usize,
4569        observations:
4570            Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, Option<FocusObservationCallback>>>>>>,
4571    },
4572    ReleaseObservation {
4573        id: usize,
4574        entity_id: usize,
4575        observations:
4576            Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, ReleaseObservationCallback>>>>>,
4577    },
4578}
4579
4580impl Subscription {
4581    pub fn detach(&mut self) {
4582        match self {
4583            Subscription::Subscription { subscriptions, .. } => {
4584                subscriptions.take();
4585            }
4586            Subscription::GlobalSubscription { subscriptions, .. } => {
4587                subscriptions.take();
4588            }
4589            Subscription::Observation { observations, .. } => {
4590                observations.take();
4591            }
4592            Subscription::GlobalObservation { observations, .. } => {
4593                observations.take();
4594            }
4595            Subscription::ReleaseObservation { observations, .. } => {
4596                observations.take();
4597            }
4598            Subscription::FocusObservation { observations, .. } => {
4599                observations.take();
4600            }
4601        }
4602    }
4603}
4604
4605impl Drop for Subscription {
4606    fn drop(&mut self) {
4607        match self {
4608            Subscription::Subscription {
4609                id,
4610                entity_id,
4611                subscriptions,
4612            } => {
4613                if let Some(subscriptions) = subscriptions.as_ref().and_then(Weak::upgrade) {
4614                    match subscriptions
4615                        .lock()
4616                        .entry(*entity_id)
4617                        .or_default()
4618                        .entry(*id)
4619                    {
4620                        btree_map::Entry::Vacant(entry) => {
4621                            entry.insert(None);
4622                        }
4623                        btree_map::Entry::Occupied(entry) => {
4624                            entry.remove();
4625                        }
4626                    }
4627                }
4628            }
4629            Subscription::GlobalSubscription {
4630                id,
4631                type_id,
4632                subscriptions,
4633            } => {
4634                if let Some(subscriptions) = subscriptions.as_ref().and_then(Weak::upgrade) {
4635                    match subscriptions.lock().entry(*type_id).or_default().entry(*id) {
4636                        btree_map::Entry::Vacant(entry) => {
4637                            entry.insert(None);
4638                        }
4639                        btree_map::Entry::Occupied(entry) => {
4640                            entry.remove();
4641                        }
4642                    }
4643                }
4644            }
4645            Subscription::Observation {
4646                id,
4647                entity_id,
4648                observations,
4649            } => {
4650                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4651                    match observations
4652                        .lock()
4653                        .entry(*entity_id)
4654                        .or_default()
4655                        .entry(*id)
4656                    {
4657                        btree_map::Entry::Vacant(entry) => {
4658                            entry.insert(None);
4659                        }
4660                        btree_map::Entry::Occupied(entry) => {
4661                            entry.remove();
4662                        }
4663                    }
4664                }
4665            }
4666            Subscription::GlobalObservation {
4667                id,
4668                type_id,
4669                observations,
4670            } => {
4671                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4672                    match observations.lock().entry(*type_id).or_default().entry(*id) {
4673                        collections::btree_map::Entry::Vacant(entry) => {
4674                            entry.insert(None);
4675                        }
4676                        collections::btree_map::Entry::Occupied(entry) => {
4677                            entry.remove();
4678                        }
4679                    }
4680                }
4681            }
4682            Subscription::ReleaseObservation {
4683                id,
4684                entity_id,
4685                observations,
4686            } => {
4687                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4688                    if let Some(observations) = observations.lock().get_mut(entity_id) {
4689                        observations.remove(id);
4690                    }
4691                }
4692            }
4693            Subscription::FocusObservation {
4694                id,
4695                view_id,
4696                observations,
4697            } => {
4698                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4699                    match observations.lock().entry(*view_id).or_default().entry(*id) {
4700                        btree_map::Entry::Vacant(entry) => {
4701                            entry.insert(None);
4702                        }
4703                        btree_map::Entry::Occupied(entry) => {
4704                            entry.remove();
4705                        }
4706                    }
4707                }
4708            }
4709        }
4710    }
4711}
4712
4713lazy_static! {
4714    static ref LEAK_BACKTRACE: bool =
4715        std::env::var("LEAK_BACKTRACE").map_or(false, |b| !b.is_empty());
4716}
4717
4718#[cfg(any(test, feature = "test-support"))]
4719#[derive(Default)]
4720pub struct LeakDetector {
4721    next_handle_id: usize,
4722    handle_backtraces: HashMap<
4723        usize,
4724        (
4725            Option<&'static str>,
4726            HashMap<usize, Option<backtrace::Backtrace>>,
4727        ),
4728    >,
4729}
4730
4731#[cfg(any(test, feature = "test-support"))]
4732impl LeakDetector {
4733    fn handle_created(&mut self, type_name: Option<&'static str>, entity_id: usize) -> usize {
4734        let handle_id = post_inc(&mut self.next_handle_id);
4735        let entry = self.handle_backtraces.entry(entity_id).or_default();
4736        let backtrace = if *LEAK_BACKTRACE {
4737            Some(backtrace::Backtrace::new_unresolved())
4738        } else {
4739            None
4740        };
4741        if let Some(type_name) = type_name {
4742            entry.0.get_or_insert(type_name);
4743        }
4744        entry.1.insert(handle_id, backtrace);
4745        handle_id
4746    }
4747
4748    fn handle_dropped(&mut self, entity_id: usize, handle_id: usize) {
4749        if let Some((_, backtraces)) = self.handle_backtraces.get_mut(&entity_id) {
4750            assert!(backtraces.remove(&handle_id).is_some());
4751            if backtraces.is_empty() {
4752                self.handle_backtraces.remove(&entity_id);
4753            }
4754        }
4755    }
4756
4757    pub fn assert_dropped(&mut self, entity_id: usize) {
4758        if let Some((type_name, backtraces)) = self.handle_backtraces.get_mut(&entity_id) {
4759            for trace in backtraces.values_mut() {
4760                if let Some(trace) = trace {
4761                    trace.resolve();
4762                    eprintln!("{:?}", crate::util::CwdBacktrace(trace));
4763                }
4764            }
4765
4766            let hint = if *LEAK_BACKTRACE {
4767                ""
4768            } else {
4769                " – set LEAK_BACKTRACE=1 for more information"
4770            };
4771
4772            panic!(
4773                "{} handles to {} {} still exist{}",
4774                backtraces.len(),
4775                type_name.unwrap_or("entity"),
4776                entity_id,
4777                hint
4778            );
4779        }
4780    }
4781
4782    pub fn detect(&mut self) {
4783        let mut found_leaks = false;
4784        for (id, (type_name, backtraces)) in self.handle_backtraces.iter_mut() {
4785            eprintln!(
4786                "leaked {} handles to {} {}",
4787                backtraces.len(),
4788                type_name.unwrap_or("entity"),
4789                id
4790            );
4791            for trace in backtraces.values_mut() {
4792                if let Some(trace) = trace {
4793                    trace.resolve();
4794                    eprintln!("{:?}", crate::util::CwdBacktrace(trace));
4795                }
4796            }
4797            found_leaks = true;
4798        }
4799
4800        let hint = if *LEAK_BACKTRACE {
4801            ""
4802        } else {
4803            " – set LEAK_BACKTRACE=1 for more information"
4804        };
4805        assert!(!found_leaks, "detected leaked handles{}", hint);
4806    }
4807}
4808
4809#[derive(Default)]
4810struct RefCounts {
4811    entity_counts: HashMap<usize, usize>,
4812    element_state_counts: HashMap<ElementStateId, ElementStateRefCount>,
4813    dropped_models: HashSet<usize>,
4814    dropped_views: HashSet<(usize, usize)>,
4815    dropped_element_states: HashSet<ElementStateId>,
4816
4817    #[cfg(any(test, feature = "test-support"))]
4818    leak_detector: Arc<Mutex<LeakDetector>>,
4819}
4820
4821struct ElementStateRefCount {
4822    ref_count: usize,
4823    frame_id: usize,
4824}
4825
4826impl RefCounts {
4827    fn inc_model(&mut self, model_id: usize) {
4828        match self.entity_counts.entry(model_id) {
4829            Entry::Occupied(mut entry) => {
4830                *entry.get_mut() += 1;
4831            }
4832            Entry::Vacant(entry) => {
4833                entry.insert(1);
4834                self.dropped_models.remove(&model_id);
4835            }
4836        }
4837    }
4838
4839    fn inc_view(&mut self, window_id: usize, view_id: usize) {
4840        match self.entity_counts.entry(view_id) {
4841            Entry::Occupied(mut entry) => *entry.get_mut() += 1,
4842            Entry::Vacant(entry) => {
4843                entry.insert(1);
4844                self.dropped_views.remove(&(window_id, view_id));
4845            }
4846        }
4847    }
4848
4849    fn inc_element_state(&mut self, id: ElementStateId, frame_id: usize) {
4850        match self.element_state_counts.entry(id) {
4851            Entry::Occupied(mut entry) => {
4852                let entry = entry.get_mut();
4853                if entry.frame_id == frame_id || entry.ref_count >= 2 {
4854                    panic!("used the same element state more than once in the same frame");
4855                }
4856                entry.ref_count += 1;
4857                entry.frame_id = frame_id;
4858            }
4859            Entry::Vacant(entry) => {
4860                entry.insert(ElementStateRefCount {
4861                    ref_count: 1,
4862                    frame_id,
4863                });
4864                self.dropped_element_states.remove(&id);
4865            }
4866        }
4867    }
4868
4869    fn dec_model(&mut self, model_id: usize) {
4870        let count = self.entity_counts.get_mut(&model_id).unwrap();
4871        *count -= 1;
4872        if *count == 0 {
4873            self.entity_counts.remove(&model_id);
4874            self.dropped_models.insert(model_id);
4875        }
4876    }
4877
4878    fn dec_view(&mut self, window_id: usize, view_id: usize) {
4879        let count = self.entity_counts.get_mut(&view_id).unwrap();
4880        *count -= 1;
4881        if *count == 0 {
4882            self.entity_counts.remove(&view_id);
4883            self.dropped_views.insert((window_id, view_id));
4884        }
4885    }
4886
4887    fn dec_element_state(&mut self, id: ElementStateId) {
4888        let entry = self.element_state_counts.get_mut(&id).unwrap();
4889        entry.ref_count -= 1;
4890        if entry.ref_count == 0 {
4891            self.element_state_counts.remove(&id);
4892            self.dropped_element_states.insert(id);
4893        }
4894    }
4895
4896    fn is_entity_alive(&self, entity_id: usize) -> bool {
4897        self.entity_counts.contains_key(&entity_id)
4898    }
4899
4900    fn take_dropped(
4901        &mut self,
4902    ) -> (
4903        HashSet<usize>,
4904        HashSet<(usize, usize)>,
4905        HashSet<ElementStateId>,
4906    ) {
4907        (
4908            std::mem::take(&mut self.dropped_models),
4909            std::mem::take(&mut self.dropped_views),
4910            std::mem::take(&mut self.dropped_element_states),
4911        )
4912    }
4913}
4914
4915#[cfg(test)]
4916mod tests {
4917    use super::*;
4918    use crate::{actions, elements::*, impl_actions};
4919    use serde::Deserialize;
4920    use smol::future::poll_once;
4921    use std::{
4922        cell::Cell,
4923        sync::atomic::{AtomicBool, AtomicUsize, Ordering::SeqCst},
4924    };
4925
4926    #[crate::test(self)]
4927    fn test_model_handles(cx: &mut MutableAppContext) {
4928        struct Model {
4929            other: Option<ModelHandle<Model>>,
4930            events: Vec<String>,
4931        }
4932
4933        impl Entity for Model {
4934            type Event = usize;
4935        }
4936
4937        impl Model {
4938            fn new(other: Option<ModelHandle<Self>>, cx: &mut ModelContext<Self>) -> Self {
4939                if let Some(other) = other.as_ref() {
4940                    cx.observe(other, |me, _, _| {
4941                        me.events.push("notified".into());
4942                    })
4943                    .detach();
4944                    cx.subscribe(other, |me, _, event, _| {
4945                        me.events.push(format!("observed event {}", event));
4946                    })
4947                    .detach();
4948                }
4949
4950                Self {
4951                    other,
4952                    events: Vec::new(),
4953                }
4954            }
4955        }
4956
4957        let handle_1 = cx.add_model(|cx| Model::new(None, cx));
4958        let handle_2 = cx.add_model(|cx| Model::new(Some(handle_1.clone()), cx));
4959        assert_eq!(cx.cx.models.len(), 2);
4960
4961        handle_1.update(cx, |model, cx| {
4962            model.events.push("updated".into());
4963            cx.emit(1);
4964            cx.notify();
4965            cx.emit(2);
4966        });
4967        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
4968        assert_eq!(
4969            handle_2.read(cx).events,
4970            vec![
4971                "observed event 1".to_string(),
4972                "notified".to_string(),
4973                "observed event 2".to_string(),
4974            ]
4975        );
4976
4977        handle_2.update(cx, |model, _| {
4978            drop(handle_1);
4979            model.other.take();
4980        });
4981
4982        assert_eq!(cx.cx.models.len(), 1);
4983        assert!(cx.subscriptions.lock().is_empty());
4984        assert!(cx.observations.lock().is_empty());
4985    }
4986
4987    #[crate::test(self)]
4988    fn test_model_events(cx: &mut MutableAppContext) {
4989        #[derive(Default)]
4990        struct Model {
4991            events: Vec<usize>,
4992        }
4993
4994        impl Entity for Model {
4995            type Event = usize;
4996        }
4997
4998        let handle_1 = cx.add_model(|_| Model::default());
4999        let handle_2 = cx.add_model(|_| Model::default());
5000
5001        handle_1.update(cx, |_, cx| {
5002            cx.subscribe(&handle_2, move |model: &mut Model, emitter, event, cx| {
5003                model.events.push(*event);
5004
5005                cx.subscribe(&emitter, |model, _, event, _| {
5006                    model.events.push(*event * 2);
5007                })
5008                .detach();
5009            })
5010            .detach();
5011        });
5012
5013        handle_2.update(cx, |_, c| c.emit(7));
5014        assert_eq!(handle_1.read(cx).events, vec![7]);
5015
5016        handle_2.update(cx, |_, c| c.emit(5));
5017        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
5018    }
5019
5020    #[crate::test(self)]
5021    fn test_model_emit_before_subscribe_in_same_update_cycle(cx: &mut MutableAppContext) {
5022        #[derive(Default)]
5023        struct Model;
5024
5025        impl Entity for Model {
5026            type Event = ();
5027        }
5028
5029        let events = Rc::new(RefCell::new(Vec::new()));
5030        cx.add_model(|cx| {
5031            drop(cx.subscribe(&cx.handle(), {
5032                let events = events.clone();
5033                move |_, _, _, _| events.borrow_mut().push("dropped before flush")
5034            }));
5035            cx.subscribe(&cx.handle(), {
5036                let events = events.clone();
5037                move |_, _, _, _| events.borrow_mut().push("before emit")
5038            })
5039            .detach();
5040            cx.emit(());
5041            cx.subscribe(&cx.handle(), {
5042                let events = events.clone();
5043                move |_, _, _, _| events.borrow_mut().push("after emit")
5044            })
5045            .detach();
5046            Model
5047        });
5048        assert_eq!(*events.borrow(), ["before emit"]);
5049    }
5050
5051    #[crate::test(self)]
5052    fn test_observe_and_notify_from_model(cx: &mut MutableAppContext) {
5053        #[derive(Default)]
5054        struct Model {
5055            count: usize,
5056            events: Vec<usize>,
5057        }
5058
5059        impl Entity for Model {
5060            type Event = ();
5061        }
5062
5063        let handle_1 = cx.add_model(|_| Model::default());
5064        let handle_2 = cx.add_model(|_| Model::default());
5065
5066        handle_1.update(cx, |_, c| {
5067            c.observe(&handle_2, move |model, observed, c| {
5068                model.events.push(observed.read(c).count);
5069                c.observe(&observed, |model, observed, c| {
5070                    model.events.push(observed.read(c).count * 2);
5071                })
5072                .detach();
5073            })
5074            .detach();
5075        });
5076
5077        handle_2.update(cx, |model, c| {
5078            model.count = 7;
5079            c.notify()
5080        });
5081        assert_eq!(handle_1.read(cx).events, vec![7]);
5082
5083        handle_2.update(cx, |model, c| {
5084            model.count = 5;
5085            c.notify()
5086        });
5087        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10])
5088    }
5089
5090    #[crate::test(self)]
5091    fn test_model_notify_before_observe_in_same_update_cycle(cx: &mut MutableAppContext) {
5092        #[derive(Default)]
5093        struct Model;
5094
5095        impl Entity for Model {
5096            type Event = ();
5097        }
5098
5099        let events = Rc::new(RefCell::new(Vec::new()));
5100        cx.add_model(|cx| {
5101            drop(cx.observe(&cx.handle(), {
5102                let events = events.clone();
5103                move |_, _, _| events.borrow_mut().push("dropped before flush")
5104            }));
5105            cx.observe(&cx.handle(), {
5106                let events = events.clone();
5107                move |_, _, _| events.borrow_mut().push("before notify")
5108            })
5109            .detach();
5110            cx.notify();
5111            cx.observe(&cx.handle(), {
5112                let events = events.clone();
5113                move |_, _, _| events.borrow_mut().push("after notify")
5114            })
5115            .detach();
5116            Model
5117        });
5118        assert_eq!(*events.borrow(), ["before notify"]);
5119    }
5120
5121    #[crate::test(self)]
5122    fn test_defer_and_after_window_update(cx: &mut MutableAppContext) {
5123        struct View {
5124            render_count: usize,
5125        }
5126
5127        impl Entity for View {
5128            type Event = usize;
5129        }
5130
5131        impl super::View for View {
5132            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5133                post_inc(&mut self.render_count);
5134                Empty::new().boxed()
5135            }
5136
5137            fn ui_name() -> &'static str {
5138                "View"
5139            }
5140        }
5141
5142        let (_, view) = cx.add_window(Default::default(), |_| View { render_count: 0 });
5143        let called_defer = Rc::new(AtomicBool::new(false));
5144        let called_after_window_update = Rc::new(AtomicBool::new(false));
5145
5146        view.update(cx, |this, cx| {
5147            assert_eq!(this.render_count, 1);
5148            cx.defer({
5149                let called_defer = called_defer.clone();
5150                move |this, _| {
5151                    assert_eq!(this.render_count, 1);
5152                    called_defer.store(true, SeqCst);
5153                }
5154            });
5155            cx.after_window_update({
5156                let called_after_window_update = called_after_window_update.clone();
5157                move |this, cx| {
5158                    assert_eq!(this.render_count, 2);
5159                    called_after_window_update.store(true, SeqCst);
5160                    cx.notify();
5161                }
5162            });
5163            assert!(!called_defer.load(SeqCst));
5164            assert!(!called_after_window_update.load(SeqCst));
5165            cx.notify();
5166        });
5167
5168        assert!(called_defer.load(SeqCst));
5169        assert!(called_after_window_update.load(SeqCst));
5170        assert_eq!(view.read(cx).render_count, 3);
5171    }
5172
5173    #[crate::test(self)]
5174    fn test_view_handles(cx: &mut MutableAppContext) {
5175        struct View {
5176            other: Option<ViewHandle<View>>,
5177            events: Vec<String>,
5178        }
5179
5180        impl Entity for View {
5181            type Event = usize;
5182        }
5183
5184        impl super::View for View {
5185            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5186                Empty::new().boxed()
5187            }
5188
5189            fn ui_name() -> &'static str {
5190                "View"
5191            }
5192        }
5193
5194        impl View {
5195            fn new(other: Option<ViewHandle<View>>, cx: &mut ViewContext<Self>) -> Self {
5196                if let Some(other) = other.as_ref() {
5197                    cx.subscribe(other, |me, _, event, _| {
5198                        me.events.push(format!("observed event {}", event));
5199                    })
5200                    .detach();
5201                }
5202                Self {
5203                    other,
5204                    events: Vec::new(),
5205                }
5206            }
5207        }
5208
5209        let (window_id, _) = cx.add_window(Default::default(), |cx| View::new(None, cx));
5210        let handle_1 = cx.add_view(window_id, |cx| View::new(None, cx));
5211        let handle_2 = cx.add_view(window_id, |cx| View::new(Some(handle_1.clone()), cx));
5212        assert_eq!(cx.cx.views.len(), 3);
5213
5214        handle_1.update(cx, |view, cx| {
5215            view.events.push("updated".into());
5216            cx.emit(1);
5217            cx.emit(2);
5218        });
5219        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
5220        assert_eq!(
5221            handle_2.read(cx).events,
5222            vec![
5223                "observed event 1".to_string(),
5224                "observed event 2".to_string(),
5225            ]
5226        );
5227
5228        handle_2.update(cx, |view, _| {
5229            drop(handle_1);
5230            view.other.take();
5231        });
5232
5233        assert_eq!(cx.cx.views.len(), 2);
5234        assert!(cx.subscriptions.lock().is_empty());
5235        assert!(cx.observations.lock().is_empty());
5236    }
5237
5238    #[crate::test(self)]
5239    fn test_add_window(cx: &mut MutableAppContext) {
5240        struct View {
5241            mouse_down_count: Arc<AtomicUsize>,
5242        }
5243
5244        impl Entity for View {
5245            type Event = ();
5246        }
5247
5248        impl super::View for View {
5249            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5250                let mouse_down_count = self.mouse_down_count.clone();
5251                EventHandler::new(Empty::new().boxed())
5252                    .on_mouse_down(move |_| {
5253                        mouse_down_count.fetch_add(1, SeqCst);
5254                        true
5255                    })
5256                    .boxed()
5257            }
5258
5259            fn ui_name() -> &'static str {
5260                "View"
5261            }
5262        }
5263
5264        let mouse_down_count = Arc::new(AtomicUsize::new(0));
5265        let (window_id, _) = cx.add_window(Default::default(), |_| View {
5266            mouse_down_count: mouse_down_count.clone(),
5267        });
5268        let presenter = cx.presenters_and_platform_windows[&window_id].0.clone();
5269        // Ensure window's root element is in a valid lifecycle state.
5270        presenter.borrow_mut().dispatch_event(
5271            Event::LeftMouseDown {
5272                position: Default::default(),
5273                ctrl: false,
5274                alt: false,
5275                shift: false,
5276                cmd: false,
5277                click_count: 1,
5278            },
5279            cx,
5280        );
5281        assert_eq!(mouse_down_count.load(SeqCst), 1);
5282    }
5283
5284    #[crate::test(self)]
5285    fn test_entity_release_hooks(cx: &mut MutableAppContext) {
5286        struct Model {
5287            released: Rc<Cell<bool>>,
5288        }
5289
5290        struct View {
5291            released: Rc<Cell<bool>>,
5292        }
5293
5294        impl Entity for Model {
5295            type Event = ();
5296
5297            fn release(&mut self, _: &mut MutableAppContext) {
5298                self.released.set(true);
5299            }
5300        }
5301
5302        impl Entity for View {
5303            type Event = ();
5304
5305            fn release(&mut self, _: &mut MutableAppContext) {
5306                self.released.set(true);
5307            }
5308        }
5309
5310        impl super::View for View {
5311            fn ui_name() -> &'static str {
5312                "View"
5313            }
5314
5315            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5316                Empty::new().boxed()
5317            }
5318        }
5319
5320        let model_released = Rc::new(Cell::new(false));
5321        let model_release_observed = Rc::new(Cell::new(false));
5322        let view_released = Rc::new(Cell::new(false));
5323        let view_release_observed = Rc::new(Cell::new(false));
5324
5325        let model = cx.add_model(|_| Model {
5326            released: model_released.clone(),
5327        });
5328        let (window_id, view) = cx.add_window(Default::default(), |_| View {
5329            released: view_released.clone(),
5330        });
5331        assert!(!model_released.get());
5332        assert!(!view_released.get());
5333
5334        cx.observe_release(&model, {
5335            let model_release_observed = model_release_observed.clone();
5336            move |_, _| model_release_observed.set(true)
5337        })
5338        .detach();
5339        cx.observe_release(&view, {
5340            let view_release_observed = view_release_observed.clone();
5341            move |_, _| view_release_observed.set(true)
5342        })
5343        .detach();
5344
5345        cx.update(move |_| {
5346            drop(model);
5347        });
5348        assert!(model_released.get());
5349        assert!(model_release_observed.get());
5350
5351        drop(view);
5352        cx.remove_window(window_id);
5353        assert!(view_released.get());
5354        assert!(view_release_observed.get());
5355    }
5356
5357    #[crate::test(self)]
5358    fn test_view_events(cx: &mut MutableAppContext) {
5359        #[derive(Default)]
5360        struct View {
5361            events: Vec<usize>,
5362        }
5363
5364        impl Entity for View {
5365            type Event = usize;
5366        }
5367
5368        impl super::View for View {
5369            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5370                Empty::new().boxed()
5371            }
5372
5373            fn ui_name() -> &'static str {
5374                "View"
5375            }
5376        }
5377
5378        struct Model;
5379
5380        impl Entity for Model {
5381            type Event = usize;
5382        }
5383
5384        let (window_id, handle_1) = cx.add_window(Default::default(), |_| View::default());
5385        let handle_2 = cx.add_view(window_id, |_| View::default());
5386        let handle_3 = cx.add_model(|_| Model);
5387
5388        handle_1.update(cx, |_, cx| {
5389            cx.subscribe(&handle_2, move |me, emitter, event, cx| {
5390                me.events.push(*event);
5391
5392                cx.subscribe(&emitter, |me, _, event, _| {
5393                    me.events.push(*event * 2);
5394                })
5395                .detach();
5396            })
5397            .detach();
5398
5399            cx.subscribe(&handle_3, |me, _, event, _| {
5400                me.events.push(*event);
5401            })
5402            .detach();
5403        });
5404
5405        handle_2.update(cx, |_, c| c.emit(7));
5406        assert_eq!(handle_1.read(cx).events, vec![7]);
5407
5408        handle_2.update(cx, |_, c| c.emit(5));
5409        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
5410
5411        handle_3.update(cx, |_, c| c.emit(9));
5412        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10, 9]);
5413    }
5414
5415    #[crate::test(self)]
5416    fn test_global_events(cx: &mut MutableAppContext) {
5417        #[derive(Clone, Debug, Eq, PartialEq)]
5418        struct GlobalEvent(u64);
5419
5420        let events = Rc::new(RefCell::new(Vec::new()));
5421        let first_subscription;
5422        let second_subscription;
5423
5424        {
5425            let events = events.clone();
5426            first_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
5427                events.borrow_mut().push(("First", e.clone()));
5428            });
5429        }
5430
5431        {
5432            let events = events.clone();
5433            second_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
5434                events.borrow_mut().push(("Second", e.clone()));
5435            });
5436        }
5437
5438        cx.update(|cx| {
5439            cx.emit_global(GlobalEvent(1));
5440            cx.emit_global(GlobalEvent(2));
5441        });
5442
5443        drop(first_subscription);
5444
5445        cx.update(|cx| {
5446            cx.emit_global(GlobalEvent(3));
5447        });
5448
5449        drop(second_subscription);
5450
5451        cx.update(|cx| {
5452            cx.emit_global(GlobalEvent(4));
5453        });
5454
5455        assert_eq!(
5456            &*events.borrow(),
5457            &[
5458                ("First", GlobalEvent(1)),
5459                ("Second", GlobalEvent(1)),
5460                ("First", GlobalEvent(2)),
5461                ("Second", GlobalEvent(2)),
5462                ("Second", GlobalEvent(3)),
5463            ]
5464        );
5465    }
5466
5467    #[crate::test(self)]
5468    fn test_global_events_emitted_before_subscription_in_same_update_cycle(
5469        cx: &mut MutableAppContext,
5470    ) {
5471        let events = Rc::new(RefCell::new(Vec::new()));
5472        cx.update(|cx| {
5473            {
5474                let events = events.clone();
5475                drop(cx.subscribe_global(move |_: &(), _| {
5476                    events.borrow_mut().push("dropped before emit");
5477                }));
5478            }
5479
5480            {
5481                let events = events.clone();
5482                cx.subscribe_global(move |_: &(), _| {
5483                    events.borrow_mut().push("before emit");
5484                })
5485                .detach();
5486            }
5487
5488            cx.emit_global(());
5489
5490            {
5491                let events = events.clone();
5492                cx.subscribe_global(move |_: &(), _| {
5493                    events.borrow_mut().push("after emit");
5494                })
5495                .detach();
5496            }
5497        });
5498
5499        assert_eq!(*events.borrow(), ["before emit"]);
5500    }
5501
5502    #[crate::test(self)]
5503    fn test_global_nested_events(cx: &mut MutableAppContext) {
5504        #[derive(Clone, Debug, Eq, PartialEq)]
5505        struct GlobalEvent(u64);
5506
5507        let events = Rc::new(RefCell::new(Vec::new()));
5508
5509        {
5510            let events = events.clone();
5511            cx.subscribe_global(move |e: &GlobalEvent, cx| {
5512                events.borrow_mut().push(("Outer", e.clone()));
5513
5514                if e.0 == 1 {
5515                    let events = events.clone();
5516                    cx.subscribe_global(move |e: &GlobalEvent, _| {
5517                        events.borrow_mut().push(("Inner", e.clone()));
5518                    })
5519                    .detach();
5520                }
5521            })
5522            .detach();
5523        }
5524
5525        cx.update(|cx| {
5526            cx.emit_global(GlobalEvent(1));
5527            cx.emit_global(GlobalEvent(2));
5528            cx.emit_global(GlobalEvent(3));
5529        });
5530        cx.update(|cx| {
5531            cx.emit_global(GlobalEvent(4));
5532        });
5533
5534        assert_eq!(
5535            &*events.borrow(),
5536            &[
5537                ("Outer", GlobalEvent(1)),
5538                ("Outer", GlobalEvent(2)),
5539                ("Outer", GlobalEvent(3)),
5540                ("Outer", GlobalEvent(4)),
5541                ("Inner", GlobalEvent(4)),
5542            ]
5543        );
5544    }
5545
5546    #[crate::test(self)]
5547    fn test_global(cx: &mut MutableAppContext) {
5548        type Global = usize;
5549
5550        let observation_count = Rc::new(RefCell::new(0));
5551        let subscription = cx.observe_global::<Global, _>({
5552            let observation_count = observation_count.clone();
5553            move |_, _| {
5554                *observation_count.borrow_mut() += 1;
5555            }
5556        });
5557
5558        assert!(!cx.has_global::<Global>());
5559        assert_eq!(cx.default_global::<Global>(), &0);
5560        assert_eq!(*observation_count.borrow(), 1);
5561        assert!(cx.has_global::<Global>());
5562        assert_eq!(
5563            cx.update_global::<Global, _, _>(|global, _| {
5564                *global = 1;
5565                "Update Result"
5566            }),
5567            "Update Result"
5568        );
5569        assert_eq!(*observation_count.borrow(), 2);
5570        assert_eq!(cx.global::<Global>(), &1);
5571
5572        drop(subscription);
5573        cx.update_global::<Global, _, _>(|global, _| {
5574            *global = 2;
5575        });
5576        assert_eq!(*observation_count.borrow(), 2);
5577
5578        type OtherGlobal = f32;
5579
5580        let observation_count = Rc::new(RefCell::new(0));
5581        cx.observe_global::<OtherGlobal, _>({
5582            let observation_count = observation_count.clone();
5583            move |_, _| {
5584                *observation_count.borrow_mut() += 1;
5585            }
5586        })
5587        .detach();
5588
5589        assert_eq!(
5590            cx.update_default_global::<OtherGlobal, _, _>(|global, _| {
5591                assert_eq!(global, &0.0);
5592                *global = 2.0;
5593                "Default update result"
5594            }),
5595            "Default update result"
5596        );
5597        assert_eq!(cx.global::<OtherGlobal>(), &2.0);
5598        assert_eq!(*observation_count.borrow(), 1);
5599    }
5600
5601    #[crate::test(self)]
5602    fn test_dropping_subscribers(cx: &mut MutableAppContext) {
5603        struct View;
5604
5605        impl Entity for View {
5606            type Event = ();
5607        }
5608
5609        impl super::View for View {
5610            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5611                Empty::new().boxed()
5612            }
5613
5614            fn ui_name() -> &'static str {
5615                "View"
5616            }
5617        }
5618
5619        struct Model;
5620
5621        impl Entity for Model {
5622            type Event = ();
5623        }
5624
5625        let (window_id, _) = cx.add_window(Default::default(), |_| View);
5626        let observing_view = cx.add_view(window_id, |_| View);
5627        let emitting_view = cx.add_view(window_id, |_| View);
5628        let observing_model = cx.add_model(|_| Model);
5629        let observed_model = cx.add_model(|_| Model);
5630
5631        observing_view.update(cx, |_, cx| {
5632            cx.subscribe(&emitting_view, |_, _, _, _| {}).detach();
5633            cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
5634        });
5635        observing_model.update(cx, |_, cx| {
5636            cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
5637        });
5638
5639        cx.update(|_| {
5640            drop(observing_view);
5641            drop(observing_model);
5642        });
5643
5644        emitting_view.update(cx, |_, cx| cx.emit(()));
5645        observed_model.update(cx, |_, cx| cx.emit(()));
5646    }
5647
5648    #[crate::test(self)]
5649    fn test_view_emit_before_subscribe_in_same_update_cycle(cx: &mut MutableAppContext) {
5650        #[derive(Default)]
5651        struct TestView;
5652
5653        impl Entity for TestView {
5654            type Event = ();
5655        }
5656
5657        impl View for TestView {
5658            fn ui_name() -> &'static str {
5659                "TestView"
5660            }
5661
5662            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5663                Empty::new().boxed()
5664            }
5665        }
5666
5667        let events = Rc::new(RefCell::new(Vec::new()));
5668        cx.add_window(Default::default(), |cx| {
5669            drop(cx.subscribe(&cx.handle(), {
5670                let events = events.clone();
5671                move |_, _, _, _| events.borrow_mut().push("dropped before flush")
5672            }));
5673            cx.subscribe(&cx.handle(), {
5674                let events = events.clone();
5675                move |_, _, _, _| events.borrow_mut().push("before emit")
5676            })
5677            .detach();
5678            cx.emit(());
5679            cx.subscribe(&cx.handle(), {
5680                let events = events.clone();
5681                move |_, _, _, _| events.borrow_mut().push("after emit")
5682            })
5683            .detach();
5684            TestView
5685        });
5686        assert_eq!(*events.borrow(), ["before emit"]);
5687    }
5688
5689    #[crate::test(self)]
5690    fn test_observe_and_notify_from_view(cx: &mut MutableAppContext) {
5691        #[derive(Default)]
5692        struct View {
5693            events: Vec<usize>,
5694        }
5695
5696        impl Entity for View {
5697            type Event = usize;
5698        }
5699
5700        impl super::View for View {
5701            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5702                Empty::new().boxed()
5703            }
5704
5705            fn ui_name() -> &'static str {
5706                "View"
5707            }
5708        }
5709
5710        #[derive(Default)]
5711        struct Model {
5712            count: usize,
5713        }
5714
5715        impl Entity for Model {
5716            type Event = ();
5717        }
5718
5719        let (_, view) = cx.add_window(Default::default(), |_| View::default());
5720        let model = cx.add_model(|_| Model::default());
5721
5722        view.update(cx, |_, c| {
5723            c.observe(&model, |me, observed, c| {
5724                me.events.push(observed.read(c).count)
5725            })
5726            .detach();
5727        });
5728
5729        model.update(cx, |model, c| {
5730            model.count = 11;
5731            c.notify();
5732        });
5733        assert_eq!(view.read(cx).events, vec![11]);
5734    }
5735
5736    #[crate::test(self)]
5737    fn test_view_notify_before_observe_in_same_update_cycle(cx: &mut MutableAppContext) {
5738        #[derive(Default)]
5739        struct TestView;
5740
5741        impl Entity for TestView {
5742            type Event = ();
5743        }
5744
5745        impl View for TestView {
5746            fn ui_name() -> &'static str {
5747                "TestView"
5748            }
5749
5750            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5751                Empty::new().boxed()
5752            }
5753        }
5754
5755        let events = Rc::new(RefCell::new(Vec::new()));
5756        cx.add_window(Default::default(), |cx| {
5757            drop(cx.observe(&cx.handle(), {
5758                let events = events.clone();
5759                move |_, _, _| events.borrow_mut().push("dropped before flush")
5760            }));
5761            cx.observe(&cx.handle(), {
5762                let events = events.clone();
5763                move |_, _, _| events.borrow_mut().push("before notify")
5764            })
5765            .detach();
5766            cx.notify();
5767            cx.observe(&cx.handle(), {
5768                let events = events.clone();
5769                move |_, _, _| events.borrow_mut().push("after notify")
5770            })
5771            .detach();
5772            TestView
5773        });
5774        assert_eq!(*events.borrow(), ["before notify"]);
5775    }
5776
5777    #[crate::test(self)]
5778    fn test_dropping_observers(cx: &mut MutableAppContext) {
5779        struct View;
5780
5781        impl Entity for View {
5782            type Event = ();
5783        }
5784
5785        impl super::View for View {
5786            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5787                Empty::new().boxed()
5788            }
5789
5790            fn ui_name() -> &'static str {
5791                "View"
5792            }
5793        }
5794
5795        struct Model;
5796
5797        impl Entity for Model {
5798            type Event = ();
5799        }
5800
5801        let (window_id, _) = cx.add_window(Default::default(), |_| View);
5802        let observing_view = cx.add_view(window_id, |_| View);
5803        let observing_model = cx.add_model(|_| Model);
5804        let observed_model = cx.add_model(|_| Model);
5805
5806        observing_view.update(cx, |_, cx| {
5807            cx.observe(&observed_model, |_, _, _| {}).detach();
5808        });
5809        observing_model.update(cx, |_, cx| {
5810            cx.observe(&observed_model, |_, _, _| {}).detach();
5811        });
5812
5813        cx.update(|_| {
5814            drop(observing_view);
5815            drop(observing_model);
5816        });
5817
5818        observed_model.update(cx, |_, cx| cx.notify());
5819    }
5820
5821    #[crate::test(self)]
5822    fn test_dropping_subscriptions_during_callback(cx: &mut MutableAppContext) {
5823        struct Model;
5824
5825        impl Entity for Model {
5826            type Event = u64;
5827        }
5828
5829        // Events
5830        let observing_model = cx.add_model(|_| Model);
5831        let observed_model = cx.add_model(|_| Model);
5832
5833        let events = Rc::new(RefCell::new(Vec::new()));
5834
5835        observing_model.update(cx, |_, cx| {
5836            let events = events.clone();
5837            let subscription = Rc::new(RefCell::new(None));
5838            *subscription.borrow_mut() = Some(cx.subscribe(&observed_model, {
5839                let subscription = subscription.clone();
5840                move |_, _, e, _| {
5841                    subscription.borrow_mut().take();
5842                    events.borrow_mut().push(e.clone());
5843                }
5844            }));
5845        });
5846
5847        observed_model.update(cx, |_, cx| {
5848            cx.emit(1);
5849            cx.emit(2);
5850        });
5851
5852        assert_eq!(*events.borrow(), [1]);
5853
5854        // Global Events
5855        #[derive(Clone, Debug, Eq, PartialEq)]
5856        struct GlobalEvent(u64);
5857
5858        let events = Rc::new(RefCell::new(Vec::new()));
5859
5860        {
5861            let events = events.clone();
5862            let subscription = Rc::new(RefCell::new(None));
5863            *subscription.borrow_mut() = Some(cx.subscribe_global({
5864                let subscription = subscription.clone();
5865                move |e: &GlobalEvent, _| {
5866                    subscription.borrow_mut().take();
5867                    events.borrow_mut().push(e.clone());
5868                }
5869            }));
5870        }
5871
5872        cx.update(|cx| {
5873            cx.emit_global(GlobalEvent(1));
5874            cx.emit_global(GlobalEvent(2));
5875        });
5876
5877        assert_eq!(*events.borrow(), [GlobalEvent(1)]);
5878
5879        // Model Observation
5880        let observing_model = cx.add_model(|_| Model);
5881        let observed_model = cx.add_model(|_| Model);
5882
5883        let observation_count = Rc::new(RefCell::new(0));
5884
5885        observing_model.update(cx, |_, cx| {
5886            let observation_count = observation_count.clone();
5887            let subscription = Rc::new(RefCell::new(None));
5888            *subscription.borrow_mut() = Some(cx.observe(&observed_model, {
5889                let subscription = subscription.clone();
5890                move |_, _, _| {
5891                    subscription.borrow_mut().take();
5892                    *observation_count.borrow_mut() += 1;
5893                }
5894            }));
5895        });
5896
5897        observed_model.update(cx, |_, cx| {
5898            cx.notify();
5899        });
5900
5901        observed_model.update(cx, |_, cx| {
5902            cx.notify();
5903        });
5904
5905        assert_eq!(*observation_count.borrow(), 1);
5906
5907        // View Observation
5908        struct View;
5909
5910        impl Entity for View {
5911            type Event = ();
5912        }
5913
5914        impl super::View for View {
5915            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5916                Empty::new().boxed()
5917            }
5918
5919            fn ui_name() -> &'static str {
5920                "View"
5921            }
5922        }
5923
5924        let (window_id, _) = cx.add_window(Default::default(), |_| View);
5925        let observing_view = cx.add_view(window_id, |_| View);
5926        let observed_view = cx.add_view(window_id, |_| View);
5927
5928        let observation_count = Rc::new(RefCell::new(0));
5929        observing_view.update(cx, |_, cx| {
5930            let observation_count = observation_count.clone();
5931            let subscription = Rc::new(RefCell::new(None));
5932            *subscription.borrow_mut() = Some(cx.observe(&observed_view, {
5933                let subscription = subscription.clone();
5934                move |_, _, _| {
5935                    subscription.borrow_mut().take();
5936                    *observation_count.borrow_mut() += 1;
5937                }
5938            }));
5939        });
5940
5941        observed_view.update(cx, |_, cx| {
5942            cx.notify();
5943        });
5944
5945        observed_view.update(cx, |_, cx| {
5946            cx.notify();
5947        });
5948
5949        assert_eq!(*observation_count.borrow(), 1);
5950
5951        // Global Observation
5952        let observation_count = Rc::new(RefCell::new(0));
5953        let subscription = Rc::new(RefCell::new(None));
5954        *subscription.borrow_mut() = Some(cx.observe_global::<(), _>({
5955            let observation_count = observation_count.clone();
5956            let subscription = subscription.clone();
5957            move |_, _| {
5958                subscription.borrow_mut().take();
5959                *observation_count.borrow_mut() += 1;
5960            }
5961        }));
5962
5963        cx.default_global::<()>();
5964        cx.set_global(());
5965        assert_eq!(*observation_count.borrow(), 1);
5966    }
5967
5968    #[crate::test(self)]
5969    fn test_focus(cx: &mut MutableAppContext) {
5970        struct View {
5971            name: String,
5972            events: Arc<Mutex<Vec<String>>>,
5973        }
5974
5975        impl Entity for View {
5976            type Event = ();
5977        }
5978
5979        impl super::View for View {
5980            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5981                Empty::new().boxed()
5982            }
5983
5984            fn ui_name() -> &'static str {
5985                "View"
5986            }
5987
5988            fn on_focus(&mut self, _: &mut ViewContext<Self>) {
5989                self.events.lock().push(format!("{} focused", &self.name));
5990            }
5991
5992            fn on_blur(&mut self, _: &mut ViewContext<Self>) {
5993                self.events.lock().push(format!("{} blurred", &self.name));
5994            }
5995        }
5996
5997        let view_events: Arc<Mutex<Vec<String>>> = Default::default();
5998        let (window_id, view_1) = cx.add_window(Default::default(), |_| View {
5999            events: view_events.clone(),
6000            name: "view 1".to_string(),
6001        });
6002        let view_2 = cx.add_view(window_id, |_| View {
6003            events: view_events.clone(),
6004            name: "view 2".to_string(),
6005        });
6006
6007        let observed_events: Arc<Mutex<Vec<String>>> = Default::default();
6008        view_1.update(cx, |_, cx| {
6009            cx.observe_focus(&view_2, {
6010                let observed_events = observed_events.clone();
6011                move |this, view, cx| {
6012                    observed_events.lock().push(format!(
6013                        "{} observed {}'s focus",
6014                        this.name,
6015                        view.read(cx).name
6016                    ))
6017                }
6018            })
6019            .detach();
6020        });
6021        view_2.update(cx, |_, cx| {
6022            cx.observe_focus(&view_1, {
6023                let observed_events = observed_events.clone();
6024                move |this, view, cx| {
6025                    observed_events.lock().push(format!(
6026                        "{} observed {}'s focus",
6027                        this.name,
6028                        view.read(cx).name
6029                    ))
6030                }
6031            })
6032            .detach();
6033        });
6034
6035        view_1.update(cx, |_, cx| {
6036            // Ensure only the latest focus is honored.
6037            cx.focus(&view_2);
6038            cx.focus(&view_1);
6039            cx.focus(&view_2);
6040        });
6041        view_1.update(cx, |_, cx| cx.focus(&view_1));
6042        view_1.update(cx, |_, cx| cx.focus(&view_2));
6043        view_1.update(cx, |_, _| drop(view_2));
6044
6045        assert_eq!(
6046            *view_events.lock(),
6047            [
6048                "view 1 focused".to_string(),
6049                "view 1 blurred".to_string(),
6050                "view 2 focused".to_string(),
6051                "view 2 blurred".to_string(),
6052                "view 1 focused".to_string(),
6053                "view 1 blurred".to_string(),
6054                "view 2 focused".to_string(),
6055                "view 1 focused".to_string(),
6056            ],
6057        );
6058        assert_eq!(
6059            *observed_events.lock(),
6060            [
6061                "view 1 observed view 2's focus".to_string(),
6062                "view 2 observed view 1's focus".to_string(),
6063                "view 1 observed view 2's focus".to_string(),
6064            ]
6065        );
6066    }
6067
6068    #[crate::test(self)]
6069    fn test_deserialize_actions(cx: &mut MutableAppContext) {
6070        #[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
6071        pub struct ComplexAction {
6072            arg: String,
6073            count: usize,
6074        }
6075
6076        actions!(test::something, [SimpleAction]);
6077        impl_actions!(test::something, [ComplexAction]);
6078
6079        cx.add_global_action(move |_: &SimpleAction, _: &mut MutableAppContext| {});
6080        cx.add_global_action(move |_: &ComplexAction, _: &mut MutableAppContext| {});
6081
6082        let action1 = cx
6083            .deserialize_action(
6084                "test::something::ComplexAction",
6085                Some(r#"{"arg": "a", "count": 5}"#),
6086            )
6087            .unwrap();
6088        let action2 = cx
6089            .deserialize_action("test::something::SimpleAction", None)
6090            .unwrap();
6091        assert_eq!(
6092            action1.as_any().downcast_ref::<ComplexAction>().unwrap(),
6093            &ComplexAction {
6094                arg: "a".to_string(),
6095                count: 5,
6096            }
6097        );
6098        assert_eq!(
6099            action2.as_any().downcast_ref::<SimpleAction>().unwrap(),
6100            &SimpleAction
6101        );
6102    }
6103
6104    #[crate::test(self)]
6105    fn test_dispatch_action(cx: &mut MutableAppContext) {
6106        struct ViewA {
6107            id: usize,
6108        }
6109
6110        impl Entity for ViewA {
6111            type Event = ();
6112        }
6113
6114        impl View for ViewA {
6115            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6116                Empty::new().boxed()
6117            }
6118
6119            fn ui_name() -> &'static str {
6120                "View"
6121            }
6122        }
6123
6124        struct ViewB {
6125            id: usize,
6126        }
6127
6128        impl Entity for ViewB {
6129            type Event = ();
6130        }
6131
6132        impl View for ViewB {
6133            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6134                Empty::new().boxed()
6135            }
6136
6137            fn ui_name() -> &'static str {
6138                "View"
6139            }
6140        }
6141
6142        #[derive(Clone, Deserialize)]
6143        pub struct Action(pub String);
6144
6145        impl_actions!(test, [Action]);
6146
6147        let actions = Rc::new(RefCell::new(Vec::new()));
6148
6149        cx.add_global_action({
6150            let actions = actions.clone();
6151            move |_: &Action, _: &mut MutableAppContext| {
6152                actions.borrow_mut().push("global".to_string());
6153            }
6154        });
6155
6156        cx.add_action({
6157            let actions = actions.clone();
6158            move |view: &mut ViewA, action: &Action, cx| {
6159                assert_eq!(action.0, "bar");
6160                cx.propagate_action();
6161                actions.borrow_mut().push(format!("{} a", view.id));
6162            }
6163        });
6164
6165        cx.add_action({
6166            let actions = actions.clone();
6167            move |view: &mut ViewA, _: &Action, cx| {
6168                if view.id != 1 {
6169                    cx.add_view(|cx| {
6170                        cx.propagate_action(); // Still works on a nested ViewContext
6171                        ViewB { id: 5 }
6172                    });
6173                }
6174                actions.borrow_mut().push(format!("{} b", view.id));
6175            }
6176        });
6177
6178        cx.add_action({
6179            let actions = actions.clone();
6180            move |view: &mut ViewB, _: &Action, cx| {
6181                cx.propagate_action();
6182                actions.borrow_mut().push(format!("{} c", view.id));
6183            }
6184        });
6185
6186        cx.add_action({
6187            let actions = actions.clone();
6188            move |view: &mut ViewB, _: &Action, cx| {
6189                cx.propagate_action();
6190                actions.borrow_mut().push(format!("{} d", view.id));
6191            }
6192        });
6193
6194        cx.capture_action({
6195            let actions = actions.clone();
6196            move |view: &mut ViewA, _: &Action, cx| {
6197                cx.propagate_action();
6198                actions.borrow_mut().push(format!("{} capture", view.id));
6199            }
6200        });
6201
6202        let (window_id, view_1) = cx.add_window(Default::default(), |_| ViewA { id: 1 });
6203        let view_2 = cx.add_view(window_id, |_| ViewB { id: 2 });
6204        let view_3 = cx.add_view(window_id, |_| ViewA { id: 3 });
6205        let view_4 = cx.add_view(window_id, |_| ViewB { id: 4 });
6206
6207        cx.dispatch_action(
6208            window_id,
6209            vec![view_1.id(), view_2.id(), view_3.id(), view_4.id()],
6210            &Action("bar".to_string()),
6211        );
6212
6213        assert_eq!(
6214            *actions.borrow(),
6215            vec![
6216                "1 capture",
6217                "3 capture",
6218                "4 d",
6219                "4 c",
6220                "3 b",
6221                "3 a",
6222                "2 d",
6223                "2 c",
6224                "1 b"
6225            ]
6226        );
6227
6228        // Remove view_1, which doesn't propagate the action
6229        actions.borrow_mut().clear();
6230        cx.dispatch_action(
6231            window_id,
6232            vec![view_2.id(), view_3.id(), view_4.id()],
6233            &Action("bar".to_string()),
6234        );
6235
6236        assert_eq!(
6237            *actions.borrow(),
6238            vec![
6239                "3 capture",
6240                "4 d",
6241                "4 c",
6242                "3 b",
6243                "3 a",
6244                "2 d",
6245                "2 c",
6246                "global"
6247            ]
6248        );
6249    }
6250
6251    #[crate::test(self)]
6252    fn test_dispatch_keystroke(cx: &mut MutableAppContext) {
6253        #[derive(Clone, Deserialize)]
6254        pub struct Action(String);
6255
6256        impl_actions!(test, [Action]);
6257
6258        struct View {
6259            id: usize,
6260            keymap_context: keymap::Context,
6261        }
6262
6263        impl Entity for View {
6264            type Event = ();
6265        }
6266
6267        impl super::View for View {
6268            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6269                Empty::new().boxed()
6270            }
6271
6272            fn ui_name() -> &'static str {
6273                "View"
6274            }
6275
6276            fn keymap_context(&self, _: &AppContext) -> keymap::Context {
6277                self.keymap_context.clone()
6278            }
6279        }
6280
6281        impl View {
6282            fn new(id: usize) -> Self {
6283                View {
6284                    id,
6285                    keymap_context: keymap::Context::default(),
6286                }
6287            }
6288        }
6289
6290        let mut view_1 = View::new(1);
6291        let mut view_2 = View::new(2);
6292        let mut view_3 = View::new(3);
6293        view_1.keymap_context.set.insert("a".into());
6294        view_2.keymap_context.set.insert("a".into());
6295        view_2.keymap_context.set.insert("b".into());
6296        view_3.keymap_context.set.insert("a".into());
6297        view_3.keymap_context.set.insert("b".into());
6298        view_3.keymap_context.set.insert("c".into());
6299
6300        let (window_id, view_1) = cx.add_window(Default::default(), |_| view_1);
6301        let view_2 = cx.add_view(window_id, |_| view_2);
6302        let view_3 = cx.add_view(window_id, |_| view_3);
6303
6304        // This keymap's only binding dispatches an action on view 2 because that view will have
6305        // "a" and "b" in its context, but not "c".
6306        cx.add_bindings(vec![keymap::Binding::new(
6307            "a",
6308            Action("a".to_string()),
6309            Some("a && b && !c"),
6310        )]);
6311
6312        cx.add_bindings(vec![keymap::Binding::new(
6313            "b",
6314            Action("b".to_string()),
6315            None,
6316        )]);
6317
6318        let actions = Rc::new(RefCell::new(Vec::new()));
6319        cx.add_action({
6320            let actions = actions.clone();
6321            move |view: &mut View, action: &Action, cx| {
6322                if action.0 == "a" {
6323                    actions.borrow_mut().push(format!("{} a", view.id));
6324                } else {
6325                    actions
6326                        .borrow_mut()
6327                        .push(format!("{} {}", view.id, action.0));
6328                    cx.propagate_action();
6329                }
6330            }
6331        });
6332
6333        cx.add_global_action({
6334            let actions = actions.clone();
6335            move |action: &Action, _| {
6336                actions.borrow_mut().push(format!("global {}", action.0));
6337            }
6338        });
6339
6340        cx.dispatch_keystroke(
6341            window_id,
6342            vec![view_1.id(), view_2.id(), view_3.id()],
6343            &Keystroke::parse("a").unwrap(),
6344        );
6345
6346        assert_eq!(&*actions.borrow(), &["2 a"]);
6347
6348        actions.borrow_mut().clear();
6349        cx.dispatch_keystroke(
6350            window_id,
6351            vec![view_1.id(), view_2.id(), view_3.id()],
6352            &Keystroke::parse("b").unwrap(),
6353        );
6354
6355        assert_eq!(&*actions.borrow(), &["3 b", "2 b", "1 b", "global b"]);
6356    }
6357
6358    #[crate::test(self)]
6359    async fn test_model_condition(cx: &mut TestAppContext) {
6360        struct Counter(usize);
6361
6362        impl super::Entity for Counter {
6363            type Event = ();
6364        }
6365
6366        impl Counter {
6367            fn inc(&mut self, cx: &mut ModelContext<Self>) {
6368                self.0 += 1;
6369                cx.notify();
6370            }
6371        }
6372
6373        let model = cx.add_model(|_| Counter(0));
6374
6375        let condition1 = model.condition(&cx, |model, _| model.0 == 2);
6376        let condition2 = model.condition(&cx, |model, _| model.0 == 3);
6377        smol::pin!(condition1, condition2);
6378
6379        model.update(cx, |model, cx| model.inc(cx));
6380        assert_eq!(poll_once(&mut condition1).await, None);
6381        assert_eq!(poll_once(&mut condition2).await, None);
6382
6383        model.update(cx, |model, cx| model.inc(cx));
6384        assert_eq!(poll_once(&mut condition1).await, Some(()));
6385        assert_eq!(poll_once(&mut condition2).await, None);
6386
6387        model.update(cx, |model, cx| model.inc(cx));
6388        assert_eq!(poll_once(&mut condition2).await, Some(()));
6389
6390        model.update(cx, |_, cx| cx.notify());
6391    }
6392
6393    #[crate::test(self)]
6394    #[should_panic]
6395    async fn test_model_condition_timeout(cx: &mut TestAppContext) {
6396        struct Model;
6397
6398        impl super::Entity for Model {
6399            type Event = ();
6400        }
6401
6402        let model = cx.add_model(|_| Model);
6403        model.condition(&cx, |_, _| false).await;
6404    }
6405
6406    #[crate::test(self)]
6407    #[should_panic(expected = "model dropped with pending condition")]
6408    async fn test_model_condition_panic_on_drop(cx: &mut TestAppContext) {
6409        struct Model;
6410
6411        impl super::Entity for Model {
6412            type Event = ();
6413        }
6414
6415        let model = cx.add_model(|_| Model);
6416        let condition = model.condition(&cx, |_, _| false);
6417        cx.update(|_| drop(model));
6418        condition.await;
6419    }
6420
6421    #[crate::test(self)]
6422    async fn test_view_condition(cx: &mut TestAppContext) {
6423        struct Counter(usize);
6424
6425        impl super::Entity for Counter {
6426            type Event = ();
6427        }
6428
6429        impl super::View for Counter {
6430            fn ui_name() -> &'static str {
6431                "test view"
6432            }
6433
6434            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6435                Empty::new().boxed()
6436            }
6437        }
6438
6439        impl Counter {
6440            fn inc(&mut self, cx: &mut ViewContext<Self>) {
6441                self.0 += 1;
6442                cx.notify();
6443            }
6444        }
6445
6446        let (_, view) = cx.add_window(|_| Counter(0));
6447
6448        let condition1 = view.condition(&cx, |view, _| view.0 == 2);
6449        let condition2 = view.condition(&cx, |view, _| view.0 == 3);
6450        smol::pin!(condition1, condition2);
6451
6452        view.update(cx, |view, cx| view.inc(cx));
6453        assert_eq!(poll_once(&mut condition1).await, None);
6454        assert_eq!(poll_once(&mut condition2).await, None);
6455
6456        view.update(cx, |view, cx| view.inc(cx));
6457        assert_eq!(poll_once(&mut condition1).await, Some(()));
6458        assert_eq!(poll_once(&mut condition2).await, None);
6459
6460        view.update(cx, |view, cx| view.inc(cx));
6461        assert_eq!(poll_once(&mut condition2).await, Some(()));
6462        view.update(cx, |_, cx| cx.notify());
6463    }
6464
6465    #[crate::test(self)]
6466    #[should_panic]
6467    async fn test_view_condition_timeout(cx: &mut TestAppContext) {
6468        struct View;
6469
6470        impl super::Entity for View {
6471            type Event = ();
6472        }
6473
6474        impl super::View for View {
6475            fn ui_name() -> &'static str {
6476                "test view"
6477            }
6478
6479            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6480                Empty::new().boxed()
6481            }
6482        }
6483
6484        let (_, view) = cx.add_window(|_| View);
6485        view.condition(&cx, |_, _| false).await;
6486    }
6487
6488    #[crate::test(self)]
6489    #[should_panic(expected = "view dropped with pending condition")]
6490    async fn test_view_condition_panic_on_drop(cx: &mut TestAppContext) {
6491        struct View;
6492
6493        impl super::Entity for View {
6494            type Event = ();
6495        }
6496
6497        impl super::View for View {
6498            fn ui_name() -> &'static str {
6499                "test view"
6500            }
6501
6502            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6503                Empty::new().boxed()
6504            }
6505        }
6506
6507        let window_id = cx.add_window(|_| View).0;
6508        let view = cx.add_view(window_id, |_| View);
6509
6510        let condition = view.condition(&cx, |_, _| false);
6511        cx.update(|_| drop(view));
6512        condition.await;
6513    }
6514
6515    #[crate::test(self)]
6516    fn test_refresh_windows(cx: &mut MutableAppContext) {
6517        struct View(usize);
6518
6519        impl super::Entity for View {
6520            type Event = ();
6521        }
6522
6523        impl super::View for View {
6524            fn ui_name() -> &'static str {
6525                "test view"
6526            }
6527
6528            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6529                Empty::new().named(format!("render count: {}", post_inc(&mut self.0)))
6530            }
6531        }
6532
6533        let (window_id, root_view) = cx.add_window(Default::default(), |_| View(0));
6534        let presenter = cx.presenters_and_platform_windows[&window_id].0.clone();
6535
6536        assert_eq!(
6537            presenter.borrow().rendered_views[&root_view.id()].name(),
6538            Some("render count: 0")
6539        );
6540
6541        let view = cx.add_view(window_id, |cx| {
6542            cx.refresh_windows();
6543            View(0)
6544        });
6545
6546        assert_eq!(
6547            presenter.borrow().rendered_views[&root_view.id()].name(),
6548            Some("render count: 1")
6549        );
6550        assert_eq!(
6551            presenter.borrow().rendered_views[&view.id()].name(),
6552            Some("render count: 0")
6553        );
6554
6555        cx.update(|cx| cx.refresh_windows());
6556        assert_eq!(
6557            presenter.borrow().rendered_views[&root_view.id()].name(),
6558            Some("render count: 2")
6559        );
6560        assert_eq!(
6561            presenter.borrow().rendered_views[&view.id()].name(),
6562            Some("render count: 1")
6563        );
6564
6565        cx.update(|cx| {
6566            cx.refresh_windows();
6567            drop(view);
6568        });
6569        assert_eq!(
6570            presenter.borrow().rendered_views[&root_view.id()].name(),
6571            Some("render count: 3")
6572        );
6573        assert_eq!(presenter.borrow().rendered_views.len(), 1);
6574    }
6575}