app.rs

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