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