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