app.rs

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