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