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