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