app.rs

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