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