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