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