app.rs

   1use crate::{
   2    elements::ElementBox,
   3    executor,
   4    keymap::{self, Keystroke},
   5    platform::{self, Platform, PromptLevel, WindowOptions},
   6    presenter::Presenter,
   7    util::{post_inc, timeout},
   8    AssetCache, AssetSource, ClipboardItem, FontCache, PathPromptOptions, TextLayoutCache,
   9};
  10use anyhow::{anyhow, Result};
  11use async_task::Task;
  12use keymap::MatchResult;
  13use parking_lot::Mutex;
  14use platform::Event;
  15use postage::{mpsc, sink::Sink as _, stream::Stream as _};
  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    rc::{self, Rc},
  28    sync::{Arc, Weak},
  29    time::Duration,
  30};
  31
  32pub trait Entity: 'static {
  33    type Event;
  34
  35    fn release(&mut self, _: &mut MutableAppContext) {}
  36}
  37
  38pub trait View: Entity + Sized {
  39    fn ui_name() -> &'static str;
  40    fn render(&self, cx: &mut RenderContext<'_, Self>) -> ElementBox;
  41    fn on_focus(&mut self, _: &mut ViewContext<Self>) {}
  42    fn on_blur(&mut self, _: &mut ViewContext<Self>) {}
  43    fn keymap_context(&self, _: &AppContext) -> keymap::Context {
  44        Self::default_keymap_context()
  45    }
  46    fn default_keymap_context() -> keymap::Context {
  47        let mut cx = keymap::Context::default();
  48        cx.set.insert(Self::ui_name().into());
  49        cx
  50    }
  51}
  52
  53pub trait ReadModel {
  54    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T;
  55}
  56
  57pub trait ReadModelWith {
  58    fn read_model_with<E: Entity, F: FnOnce(&E, &AppContext) -> T, T>(
  59        &self,
  60        handle: &ModelHandle<E>,
  61        read: F,
  62    ) -> T;
  63}
  64
  65pub trait UpdateModel {
  66    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
  67    where
  68        T: Entity,
  69        F: FnOnce(&mut T, &mut ModelContext<T>) -> S;
  70}
  71
  72pub trait UpgradeModelHandle {
  73    fn upgrade_model_handle<T: Entity>(&self, handle: WeakModelHandle<T>)
  74        -> Option<ModelHandle<T>>;
  75}
  76
  77pub trait ReadView {
  78    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T;
  79}
  80
  81pub trait ReadViewWith {
  82    fn read_view_with<V, F, T>(&self, handle: &ViewHandle<V>, read: F) -> T
  83    where
  84        V: View,
  85        F: FnOnce(&V, &AppContext) -> T;
  86}
  87
  88pub trait UpdateView {
  89    fn update_view<T, F, S>(&mut self, handle: &ViewHandle<T>, update: F) -> S
  90    where
  91        T: View,
  92        F: FnOnce(&mut T, &mut ViewContext<T>) -> S;
  93}
  94
  95pub trait Action: 'static + AnyAction {
  96    type Argument: 'static + Clone;
  97}
  98
  99pub trait AnyAction {
 100    fn id(&self) -> TypeId;
 101    fn name(&self) -> &'static str;
 102    fn as_any(&self) -> &dyn Any;
 103    fn boxed_clone(&self) -> Box<dyn AnyAction>;
 104    fn boxed_clone_as_any(&self) -> Box<dyn Any>;
 105}
 106
 107#[macro_export]
 108macro_rules! action {
 109    ($name:ident, $arg:ty) => {
 110        #[derive(Clone)]
 111        pub struct $name(pub $arg);
 112
 113        impl $crate::Action for $name {
 114            type Argument = $arg;
 115        }
 116
 117        impl $crate::AnyAction for $name {
 118            fn id(&self) -> std::any::TypeId {
 119                std::any::TypeId::of::<$name>()
 120            }
 121
 122            fn name(&self) -> &'static str {
 123                stringify!($name)
 124            }
 125
 126            fn as_any(&self) -> &dyn std::any::Any {
 127                self
 128            }
 129
 130            fn boxed_clone(&self) -> Box<dyn $crate::AnyAction> {
 131                Box::new(self.clone())
 132            }
 133
 134            fn boxed_clone_as_any(&self) -> Box<dyn std::any::Any> {
 135                Box::new(self.clone())
 136            }
 137        }
 138    };
 139
 140    ($name:ident) => {
 141        #[derive(Clone, Debug, Eq, PartialEq)]
 142        pub struct $name;
 143
 144        impl $crate::Action for $name {
 145            type Argument = ();
 146        }
 147
 148        impl $crate::AnyAction for $name {
 149            fn id(&self) -> std::any::TypeId {
 150                std::any::TypeId::of::<$name>()
 151            }
 152
 153            fn name(&self) -> &'static str {
 154                stringify!($name)
 155            }
 156
 157            fn as_any(&self) -> &dyn std::any::Any {
 158                self
 159            }
 160
 161            fn boxed_clone(&self) -> Box<dyn $crate::AnyAction> {
 162                Box::new(self.clone())
 163            }
 164
 165            fn boxed_clone_as_any(&self) -> Box<dyn std::any::Any> {
 166                Box::new(self.clone())
 167            }
 168        }
 169    };
 170}
 171
 172pub struct Menu<'a> {
 173    pub name: &'a str,
 174    pub items: Vec<MenuItem<'a>>,
 175}
 176
 177pub enum MenuItem<'a> {
 178    Action {
 179        name: &'a str,
 180        keystroke: Option<&'a str>,
 181        action: Box<dyn AnyAction>,
 182    },
 183    Separator,
 184}
 185
 186#[derive(Clone)]
 187pub struct App(Rc<RefCell<MutableAppContext>>);
 188
 189#[derive(Clone)]
 190pub struct AsyncAppContext(Rc<RefCell<MutableAppContext>>);
 191
 192pub struct BackgroundAppContext(*const RefCell<MutableAppContext>);
 193
 194#[derive(Clone)]
 195pub struct TestAppContext {
 196    cx: Rc<RefCell<MutableAppContext>>,
 197    foreground_platform: Rc<platform::test::ForegroundPlatform>,
 198}
 199
 200impl App {
 201    pub fn new(asset_source: impl AssetSource) -> Result<Self> {
 202        let platform = platform::current::platform();
 203        let foreground_platform = platform::current::foreground_platform();
 204        let foreground = Rc::new(executor::Foreground::platform(platform.dispatcher())?);
 205        let app = Self(Rc::new(RefCell::new(MutableAppContext::new(
 206            foreground,
 207            Arc::new(executor::Background::new()),
 208            platform.clone(),
 209            foreground_platform.clone(),
 210            Arc::new(FontCache::new(platform.fonts())),
 211            asset_source,
 212        ))));
 213
 214        let cx = app.0.clone();
 215        foreground_platform.on_menu_command(Box::new(move |action| {
 216            let mut cx = cx.borrow_mut();
 217            if let Some(key_window_id) = cx.cx.platform.key_window_id() {
 218                if let Some((presenter, _)) = cx.presenters_and_platform_windows.get(&key_window_id)
 219                {
 220                    let presenter = presenter.clone();
 221                    let path = presenter.borrow().dispatch_path(cx.as_ref());
 222                    cx.dispatch_action_any(key_window_id, &path, action);
 223                } else {
 224                    cx.dispatch_global_action_any(action);
 225                }
 226            } else {
 227                cx.dispatch_global_action_any(action);
 228            }
 229        }));
 230
 231        app.0.borrow_mut().weak_self = Some(Rc::downgrade(&app.0));
 232        Ok(app)
 233    }
 234
 235    pub fn on_become_active<F>(self, mut callback: F) -> Self
 236    where
 237        F: 'static + FnMut(&mut MutableAppContext),
 238    {
 239        let cx = self.0.clone();
 240        self.0
 241            .borrow_mut()
 242            .foreground_platform
 243            .on_become_active(Box::new(move || callback(&mut *cx.borrow_mut())));
 244        self
 245    }
 246
 247    pub fn on_resign_active<F>(self, mut callback: F) -> Self
 248    where
 249        F: 'static + FnMut(&mut MutableAppContext),
 250    {
 251        let cx = self.0.clone();
 252        self.0
 253            .borrow_mut()
 254            .foreground_platform
 255            .on_resign_active(Box::new(move || callback(&mut *cx.borrow_mut())));
 256        self
 257    }
 258
 259    pub fn on_event<F>(self, mut callback: F) -> Self
 260    where
 261        F: 'static + FnMut(Event, &mut MutableAppContext) -> bool,
 262    {
 263        let cx = self.0.clone();
 264        self.0
 265            .borrow_mut()
 266            .foreground_platform
 267            .on_event(Box::new(move |event| {
 268                callback(event, &mut *cx.borrow_mut())
 269            }));
 270        self
 271    }
 272
 273    pub fn on_open_files<F>(self, mut callback: F) -> Self
 274    where
 275        F: 'static + FnMut(Vec<PathBuf>, &mut MutableAppContext),
 276    {
 277        let cx = self.0.clone();
 278        self.0
 279            .borrow_mut()
 280            .foreground_platform
 281            .on_open_files(Box::new(move |paths| {
 282                callback(paths, &mut *cx.borrow_mut())
 283            }));
 284        self
 285    }
 286
 287    pub fn run<F>(self, on_finish_launching: F)
 288    where
 289        F: 'static + FnOnce(&mut MutableAppContext),
 290    {
 291        let platform = self.0.borrow().foreground_platform.clone();
 292        platform.run(Box::new(move || {
 293            let mut cx = self.0.borrow_mut();
 294            on_finish_launching(&mut *cx);
 295        }))
 296    }
 297
 298    pub fn font_cache(&self) -> Arc<FontCache> {
 299        self.0.borrow().cx.font_cache.clone()
 300    }
 301
 302    fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 303        let mut state = self.0.borrow_mut();
 304        state.pending_flushes += 1;
 305        let result = callback(&mut *state);
 306        state.flush_effects();
 307        result
 308    }
 309}
 310
 311impl TestAppContext {
 312    pub fn new(
 313        foreground_platform: Rc<platform::test::ForegroundPlatform>,
 314        platform: Arc<dyn Platform>,
 315        foreground: Rc<executor::Foreground>,
 316        background: Arc<executor::Background>,
 317        font_cache: Arc<FontCache>,
 318        first_entity_id: usize,
 319    ) -> Self {
 320        let mut cx = MutableAppContext::new(
 321            foreground.clone(),
 322            background,
 323            platform,
 324            foreground_platform.clone(),
 325            font_cache,
 326            (),
 327        );
 328        cx.next_entity_id = first_entity_id;
 329        let cx = TestAppContext {
 330            cx: Rc::new(RefCell::new(cx)),
 331            foreground_platform,
 332        };
 333        cx.cx.borrow_mut().weak_self = Some(Rc::downgrade(&cx.cx));
 334        cx
 335    }
 336
 337    pub fn dispatch_action<A: Action>(
 338        &self,
 339        window_id: usize,
 340        responder_chain: Vec<usize>,
 341        action: A,
 342    ) {
 343        self.cx
 344            .borrow_mut()
 345            .dispatch_action_any(window_id, &responder_chain, &action);
 346    }
 347
 348    pub fn dispatch_global_action<A: Action>(&self, action: A) {
 349        self.cx.borrow_mut().dispatch_global_action(action);
 350    }
 351
 352    pub fn dispatch_keystroke(
 353        &self,
 354        window_id: usize,
 355        responder_chain: Vec<usize>,
 356        keystroke: &Keystroke,
 357    ) -> Result<bool> {
 358        let mut state = self.cx.borrow_mut();
 359        state.dispatch_keystroke(window_id, responder_chain, keystroke)
 360    }
 361
 362    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
 363    where
 364        T: Entity,
 365        F: FnOnce(&mut ModelContext<T>) -> T,
 366    {
 367        let mut state = self.cx.borrow_mut();
 368        state.pending_flushes += 1;
 369        let handle = state.add_model(build_model);
 370        state.flush_effects();
 371        handle
 372    }
 373
 374    pub fn add_window<T, F>(&mut self, build_root_view: F) -> (usize, ViewHandle<T>)
 375    where
 376        T: View,
 377        F: FnOnce(&mut ViewContext<T>) -> T,
 378    {
 379        self.cx
 380            .borrow_mut()
 381            .add_window(Default::default(), build_root_view)
 382    }
 383
 384    pub fn window_ids(&self) -> Vec<usize> {
 385        self.cx.borrow().window_ids().collect()
 386    }
 387
 388    pub fn root_view<T: View>(&self, window_id: usize) -> Option<ViewHandle<T>> {
 389        self.cx.borrow().root_view(window_id)
 390    }
 391
 392    pub fn add_view<T, F>(&mut self, window_id: usize, build_view: F) -> ViewHandle<T>
 393    where
 394        T: View,
 395        F: FnOnce(&mut ViewContext<T>) -> T,
 396    {
 397        let mut state = self.cx.borrow_mut();
 398        state.pending_flushes += 1;
 399        let handle = state.add_view(window_id, build_view);
 400        state.flush_effects();
 401        handle
 402    }
 403
 404    pub fn add_option_view<T, F>(
 405        &mut self,
 406        window_id: usize,
 407        build_view: F,
 408    ) -> Option<ViewHandle<T>>
 409    where
 410        T: View,
 411        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
 412    {
 413        let mut state = self.cx.borrow_mut();
 414        state.pending_flushes += 1;
 415        let handle = state.add_option_view(window_id, build_view);
 416        state.flush_effects();
 417        handle
 418    }
 419
 420    pub fn read<T, F: FnOnce(&AppContext) -> T>(&self, callback: F) -> T {
 421        callback(self.cx.borrow().as_ref())
 422    }
 423
 424    pub fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 425        let mut state = self.cx.borrow_mut();
 426        // Don't increment pending flushes in order to effects to be flushed before the callback
 427        // completes, which is helpful in tests.
 428        let result = callback(&mut *state);
 429        // Flush effects after the callback just in case there are any. This can happen in edge
 430        // cases such as the closure dropping handles.
 431        state.flush_effects();
 432        result
 433    }
 434
 435    pub fn to_async(&self) -> AsyncAppContext {
 436        AsyncAppContext(self.cx.clone())
 437    }
 438
 439    pub fn font_cache(&self) -> Arc<FontCache> {
 440        self.cx.borrow().cx.font_cache.clone()
 441    }
 442
 443    pub fn platform(&self) -> Arc<dyn platform::Platform> {
 444        self.cx.borrow().cx.platform.clone()
 445    }
 446
 447    pub fn foreground(&self) -> Rc<executor::Foreground> {
 448        self.cx.borrow().foreground().clone()
 449    }
 450
 451    pub fn background(&self) -> Arc<executor::Background> {
 452        self.cx.borrow().background().clone()
 453    }
 454
 455    pub fn simulate_new_path_selection(&self, result: impl FnOnce(PathBuf) -> Option<PathBuf>) {
 456        self.foreground_platform.simulate_new_path_selection(result);
 457    }
 458
 459    pub fn did_prompt_for_new_path(&self) -> bool {
 460        self.foreground_platform.as_ref().did_prompt_for_new_path()
 461    }
 462
 463    pub fn simulate_prompt_answer(&self, window_id: usize, answer: usize) {
 464        let mut state = self.cx.borrow_mut();
 465        let (_, window) = state
 466            .presenters_and_platform_windows
 467            .get_mut(&window_id)
 468            .unwrap();
 469        let test_window = window
 470            .as_any_mut()
 471            .downcast_mut::<platform::test::Window>()
 472            .unwrap();
 473        let callback = test_window
 474            .last_prompt
 475            .take()
 476            .expect("prompt was not called");
 477        (callback)(answer);
 478    }
 479}
 480
 481impl AsyncAppContext {
 482    pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
 483    where
 484        F: FnOnce(AsyncAppContext) -> Fut,
 485        Fut: 'static + Future<Output = T>,
 486        T: 'static,
 487    {
 488        self.0.borrow().foreground.spawn(f(self.clone()))
 489    }
 490
 491    pub fn read<T, F: FnOnce(&AppContext) -> T>(&mut self, callback: F) -> T {
 492        callback(self.0.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.0.borrow_mut();
 497        state.pending_flushes += 1;
 498        let result = callback(&mut *state);
 499        state.flush_effects();
 500        result
 501    }
 502
 503    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
 504    where
 505        T: Entity,
 506        F: FnOnce(&mut ModelContext<T>) -> T,
 507    {
 508        self.update(|cx| cx.add_model(build_model))
 509    }
 510
 511    pub fn platform(&self) -> Arc<dyn Platform> {
 512        self.0.borrow().platform()
 513    }
 514
 515    pub fn foreground(&self) -> Rc<executor::Foreground> {
 516        self.0.borrow().foreground.clone()
 517    }
 518
 519    pub fn background(&self) -> Arc<executor::Background> {
 520        self.0.borrow().cx.background.clone()
 521    }
 522}
 523
 524impl UpdateModel for AsyncAppContext {
 525    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
 526    where
 527        T: Entity,
 528        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
 529    {
 530        let mut state = self.0.borrow_mut();
 531        state.pending_flushes += 1;
 532        let result = state.update_model(handle, update);
 533        state.flush_effects();
 534        result
 535    }
 536}
 537
 538impl UpgradeModelHandle for AsyncAppContext {
 539    fn upgrade_model_handle<T: Entity>(
 540        &self,
 541        handle: WeakModelHandle<T>,
 542    ) -> Option<ModelHandle<T>> {
 543        self.0.borrow_mut().upgrade_model_handle(handle)
 544    }
 545}
 546
 547impl ReadModelWith for AsyncAppContext {
 548    fn read_model_with<E: Entity, F: FnOnce(&E, &AppContext) -> T, T>(
 549        &self,
 550        handle: &ModelHandle<E>,
 551        read: F,
 552    ) -> T {
 553        let cx = self.0.borrow();
 554        let cx = cx.as_ref();
 555        read(handle.read(cx), cx)
 556    }
 557}
 558
 559impl UpdateView for AsyncAppContext {
 560    fn update_view<T, F, S>(&mut self, handle: &ViewHandle<T>, update: F) -> S
 561    where
 562        T: View,
 563        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
 564    {
 565        let mut state = self.0.borrow_mut();
 566        state.pending_flushes += 1;
 567        let result = state.update_view(handle, update);
 568        state.flush_effects();
 569        result
 570    }
 571}
 572
 573impl ReadViewWith for AsyncAppContext {
 574    fn read_view_with<V, F, T>(&self, handle: &ViewHandle<V>, read: F) -> T
 575    where
 576        V: View,
 577        F: FnOnce(&V, &AppContext) -> T,
 578    {
 579        let cx = self.0.borrow();
 580        let cx = cx.as_ref();
 581        read(handle.read(cx), cx)
 582    }
 583}
 584
 585impl UpdateModel for TestAppContext {
 586    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
 587    where
 588        T: Entity,
 589        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
 590    {
 591        let mut state = self.cx.borrow_mut();
 592        state.pending_flushes += 1;
 593        let result = state.update_model(handle, update);
 594        state.flush_effects();
 595        result
 596    }
 597}
 598
 599impl ReadModelWith for TestAppContext {
 600    fn read_model_with<E: Entity, F: FnOnce(&E, &AppContext) -> T, T>(
 601        &self,
 602        handle: &ModelHandle<E>,
 603        read: F,
 604    ) -> T {
 605        let cx = self.cx.borrow();
 606        let cx = cx.as_ref();
 607        read(handle.read(cx), cx)
 608    }
 609}
 610
 611impl UpdateView for TestAppContext {
 612    fn update_view<T, F, S>(&mut self, handle: &ViewHandle<T>, update: F) -> S
 613    where
 614        T: View,
 615        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
 616    {
 617        let mut state = self.cx.borrow_mut();
 618        state.pending_flushes += 1;
 619        let result = state.update_view(handle, update);
 620        state.flush_effects();
 621        result
 622    }
 623}
 624
 625impl ReadViewWith for TestAppContext {
 626    fn read_view_with<V, F, T>(&self, handle: &ViewHandle<V>, read: F) -> T
 627    where
 628        V: View,
 629        F: FnOnce(&V, &AppContext) -> T,
 630    {
 631        let cx = self.cx.borrow();
 632        let cx = cx.as_ref();
 633        read(handle.read(cx), cx)
 634    }
 635}
 636
 637type ActionCallback =
 638    dyn FnMut(&mut dyn AnyView, &dyn AnyAction, &mut MutableAppContext, usize, usize) -> bool;
 639type GlobalActionCallback = dyn FnMut(&dyn AnyAction, &mut MutableAppContext);
 640
 641type SubscriptionCallback = Box<dyn FnMut(&dyn Any, &mut MutableAppContext) -> bool>;
 642type ObservationCallback = Box<dyn FnMut(&mut MutableAppContext) -> bool>;
 643
 644pub struct MutableAppContext {
 645    weak_self: Option<rc::Weak<RefCell<Self>>>,
 646    foreground_platform: Rc<dyn platform::ForegroundPlatform>,
 647    assets: Arc<AssetCache>,
 648    cx: AppContext,
 649    actions: HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>>,
 650    global_actions: HashMap<TypeId, Vec<Box<GlobalActionCallback>>>,
 651    keystroke_matcher: keymap::Matcher,
 652    next_entity_id: usize,
 653    next_window_id: usize,
 654    next_subscription_id: usize,
 655    subscriptions: Arc<Mutex<HashMap<usize, BTreeMap<usize, SubscriptionCallback>>>>,
 656    observations: Arc<Mutex<HashMap<usize, BTreeMap<usize, ObservationCallback>>>>,
 657    presenters_and_platform_windows:
 658        HashMap<usize, (Rc<RefCell<Presenter>>, Box<dyn platform::Window>)>,
 659    debug_elements_callbacks: HashMap<usize, Box<dyn Fn(&AppContext) -> crate::json::Value>>,
 660    foreground: Rc<executor::Foreground>,
 661    pending_effects: VecDeque<Effect>,
 662    pending_flushes: usize,
 663    flushing_effects: bool,
 664}
 665
 666impl MutableAppContext {
 667    fn new(
 668        foreground: Rc<executor::Foreground>,
 669        background: Arc<executor::Background>,
 670        platform: Arc<dyn platform::Platform>,
 671        foreground_platform: Rc<dyn platform::ForegroundPlatform>,
 672        font_cache: Arc<FontCache>,
 673        asset_source: impl AssetSource,
 674    ) -> Self {
 675        Self {
 676            weak_self: None,
 677            foreground_platform,
 678            assets: Arc::new(AssetCache::new(asset_source)),
 679            cx: AppContext {
 680                models: Default::default(),
 681                views: Default::default(),
 682                windows: Default::default(),
 683                element_states: Default::default(),
 684                ref_counts: Arc::new(Mutex::new(RefCounts::default())),
 685                background,
 686                font_cache,
 687                platform,
 688            },
 689            actions: HashMap::new(),
 690            global_actions: HashMap::new(),
 691            keystroke_matcher: keymap::Matcher::default(),
 692            next_entity_id: 0,
 693            next_window_id: 0,
 694            next_subscription_id: 0,
 695            subscriptions: Default::default(),
 696            observations: Default::default(),
 697            presenters_and_platform_windows: HashMap::new(),
 698            debug_elements_callbacks: HashMap::new(),
 699            foreground,
 700            pending_effects: VecDeque::new(),
 701            pending_flushes: 0,
 702            flushing_effects: false,
 703        }
 704    }
 705
 706    pub fn upgrade(&self) -> App {
 707        App(self.weak_self.as_ref().unwrap().upgrade().unwrap())
 708    }
 709
 710    pub fn platform(&self) -> Arc<dyn platform::Platform> {
 711        self.cx.platform.clone()
 712    }
 713
 714    pub fn font_cache(&self) -> &Arc<FontCache> {
 715        &self.cx.font_cache
 716    }
 717
 718    pub fn foreground(&self) -> &Rc<executor::Foreground> {
 719        &self.foreground
 720    }
 721
 722    pub fn background(&self) -> &Arc<executor::Background> {
 723        &self.cx.background
 724    }
 725
 726    pub fn on_debug_elements<F>(&mut self, window_id: usize, callback: F)
 727    where
 728        F: 'static + Fn(&AppContext) -> crate::json::Value,
 729    {
 730        self.debug_elements_callbacks
 731            .insert(window_id, Box::new(callback));
 732    }
 733
 734    pub fn debug_elements(&self, window_id: usize) -> Option<crate::json::Value> {
 735        self.debug_elements_callbacks
 736            .get(&window_id)
 737            .map(|debug_elements| debug_elements(&self.cx))
 738    }
 739
 740    pub fn add_action<A, V, F>(&mut self, mut handler: F)
 741    where
 742        A: Action,
 743        V: View,
 744        F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>),
 745    {
 746        let handler = Box::new(
 747            move |view: &mut dyn AnyView,
 748                  action: &dyn AnyAction,
 749                  cx: &mut MutableAppContext,
 750                  window_id: usize,
 751                  view_id: usize| {
 752                let action = action.as_any().downcast_ref().unwrap();
 753                let mut cx = ViewContext::new(cx, window_id, view_id);
 754                handler(
 755                    view.as_any_mut()
 756                        .downcast_mut()
 757                        .expect("downcast is type safe"),
 758                    action,
 759                    &mut cx,
 760                );
 761                cx.halt_action_dispatch
 762            },
 763        );
 764
 765        self.actions
 766            .entry(TypeId::of::<V>())
 767            .or_default()
 768            .entry(TypeId::of::<A>())
 769            .or_default()
 770            .push(handler);
 771    }
 772
 773    pub fn add_global_action<A, F>(&mut self, mut handler: F)
 774    where
 775        A: Action,
 776        F: 'static + FnMut(&A, &mut MutableAppContext),
 777    {
 778        let handler = Box::new(move |action: &dyn AnyAction, cx: &mut MutableAppContext| {
 779            let action = action.as_any().downcast_ref().unwrap();
 780            handler(action, cx);
 781        });
 782
 783        self.global_actions
 784            .entry(TypeId::of::<A>())
 785            .or_default()
 786            .push(handler);
 787    }
 788
 789    pub fn window_ids(&self) -> impl Iterator<Item = usize> + '_ {
 790        self.cx.windows.keys().cloned()
 791    }
 792
 793    pub fn root_view<T: View>(&self, window_id: usize) -> Option<ViewHandle<T>> {
 794        self.cx
 795            .windows
 796            .get(&window_id)
 797            .and_then(|window| window.root_view.clone().downcast::<T>())
 798    }
 799
 800    pub fn root_view_id(&self, window_id: usize) -> Option<usize> {
 801        self.cx.root_view_id(window_id)
 802    }
 803
 804    pub fn focused_view_id(&self, window_id: usize) -> Option<usize> {
 805        self.cx.focused_view_id(window_id)
 806    }
 807
 808    pub fn render_view(
 809        &mut self,
 810        window_id: usize,
 811        view_id: usize,
 812        titlebar_height: f32,
 813        refreshing: bool,
 814    ) -> Result<ElementBox> {
 815        let view = self
 816            .cx
 817            .views
 818            .remove(&(window_id, view_id))
 819            .ok_or(anyhow!("view not found"))?;
 820        let element = view.render(window_id, view_id, titlebar_height, refreshing, self);
 821        self.cx.views.insert((window_id, view_id), view);
 822        Ok(element)
 823    }
 824
 825    pub fn render_views(
 826        &mut self,
 827        window_id: usize,
 828        titlebar_height: f32,
 829    ) -> HashMap<usize, ElementBox> {
 830        let view_ids = self
 831            .views
 832            .keys()
 833            .filter_map(|(win_id, view_id)| {
 834                if *win_id == window_id {
 835                    Some(*view_id)
 836                } else {
 837                    None
 838                }
 839            })
 840            .collect::<Vec<_>>();
 841        view_ids
 842            .into_iter()
 843            .map(|view_id| {
 844                (
 845                    view_id,
 846                    self.render_view(window_id, view_id, titlebar_height, false)
 847                        .unwrap(),
 848                )
 849            })
 850            .collect()
 851    }
 852
 853    pub fn update<T, F: FnOnce() -> T>(&mut self, callback: F) -> T {
 854        self.pending_flushes += 1;
 855        let result = callback();
 856        self.flush_effects();
 857        result
 858    }
 859
 860    pub fn set_menus(&mut self, menus: Vec<Menu>) {
 861        self.foreground_platform.set_menus(menus);
 862    }
 863
 864    fn prompt<F>(
 865        &self,
 866        window_id: usize,
 867        level: PromptLevel,
 868        msg: &str,
 869        answers: &[&str],
 870        done_fn: F,
 871    ) where
 872        F: 'static + FnOnce(usize, &mut MutableAppContext),
 873    {
 874        let app = self.weak_self.as_ref().unwrap().upgrade().unwrap();
 875        let foreground = self.foreground.clone();
 876        let (_, window) = &self.presenters_and_platform_windows[&window_id];
 877        window.prompt(
 878            level,
 879            msg,
 880            answers,
 881            Box::new(move |answer| {
 882                foreground
 883                    .spawn(async move { (done_fn)(answer, &mut *app.borrow_mut()) })
 884                    .detach();
 885            }),
 886        );
 887    }
 888
 889    pub fn prompt_for_paths<F>(&self, options: PathPromptOptions, done_fn: F)
 890    where
 891        F: 'static + FnOnce(Option<Vec<PathBuf>>, &mut MutableAppContext),
 892    {
 893        let app = self.weak_self.as_ref().unwrap().upgrade().unwrap();
 894        let foreground = self.foreground.clone();
 895        self.foreground_platform.prompt_for_paths(
 896            options,
 897            Box::new(move |paths| {
 898                foreground
 899                    .spawn(async move { (done_fn)(paths, &mut *app.borrow_mut()) })
 900                    .detach();
 901            }),
 902        );
 903    }
 904
 905    pub fn prompt_for_new_path<F>(&self, directory: &Path, done_fn: F)
 906    where
 907        F: 'static + FnOnce(Option<PathBuf>, &mut MutableAppContext),
 908    {
 909        let app = self.weak_self.as_ref().unwrap().upgrade().unwrap();
 910        let foreground = self.foreground.clone();
 911        self.foreground_platform.prompt_for_new_path(
 912            directory,
 913            Box::new(move |path| {
 914                foreground
 915                    .spawn(async move { (done_fn)(path, &mut *app.borrow_mut()) })
 916                    .detach();
 917            }),
 918        );
 919    }
 920
 921    pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
 922    where
 923        E: Entity,
 924        E::Event: 'static,
 925        H: Handle<E>,
 926        F: 'static + FnMut(H, &E::Event, &mut Self),
 927    {
 928        self.subscribe_internal(handle, move |handle, event, cx| {
 929            callback(handle, event, cx);
 930            true
 931        })
 932    }
 933
 934    fn observe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
 935    where
 936        E: Entity,
 937        E::Event: 'static,
 938        H: Handle<E>,
 939        F: 'static + FnMut(H, &mut Self),
 940    {
 941        self.observe_internal(handle, move |handle, cx| {
 942            callback(handle, cx);
 943            true
 944        })
 945    }
 946
 947    pub fn subscribe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
 948    where
 949        E: Entity,
 950        E::Event: 'static,
 951        H: Handle<E>,
 952        F: 'static + FnMut(H, &E::Event, &mut Self) -> bool,
 953    {
 954        let id = post_inc(&mut self.next_subscription_id);
 955        let emitter = handle.downgrade();
 956        self.subscriptions
 957            .lock()
 958            .entry(handle.id())
 959            .or_default()
 960            .insert(
 961                id,
 962                Box::new(move |payload, cx| {
 963                    if let Some(emitter) = H::upgrade_from(&emitter, cx.as_ref()) {
 964                        let payload = payload.downcast_ref().expect("downcast is type safe");
 965                        callback(emitter, payload, cx)
 966                    } else {
 967                        false
 968                    }
 969                }),
 970            );
 971        Subscription::Subscription {
 972            id,
 973            entity_id: handle.id(),
 974            subscriptions: Some(Arc::downgrade(&self.subscriptions)),
 975        }
 976    }
 977
 978    fn observe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
 979    where
 980        E: Entity,
 981        E::Event: 'static,
 982        H: Handle<E>,
 983        F: 'static + FnMut(H, &mut Self) -> bool,
 984    {
 985        let id = post_inc(&mut self.next_subscription_id);
 986        let observed = handle.downgrade();
 987        self.observations
 988            .lock()
 989            .entry(handle.id())
 990            .or_default()
 991            .insert(
 992                id,
 993                Box::new(move |cx| {
 994                    if let Some(observed) = H::upgrade_from(&observed, cx) {
 995                        callback(observed, cx)
 996                    } else {
 997                        false
 998                    }
 999                }),
1000            );
1001        Subscription::Observation {
1002            id,
1003            entity_id: handle.id(),
1004            observations: Some(Arc::downgrade(&self.observations)),
1005        }
1006    }
1007
1008    pub(crate) fn notify_view(&mut self, window_id: usize, view_id: usize) {
1009        self.pending_effects
1010            .push_back(Effect::ViewNotification { window_id, view_id });
1011    }
1012
1013    pub fn dispatch_action<A: Action>(
1014        &mut self,
1015        window_id: usize,
1016        responder_chain: Vec<usize>,
1017        action: &A,
1018    ) {
1019        self.dispatch_action_any(window_id, &responder_chain, action);
1020    }
1021
1022    pub(crate) fn dispatch_action_any(
1023        &mut self,
1024        window_id: usize,
1025        path: &[usize],
1026        action: &dyn AnyAction,
1027    ) -> bool {
1028        self.pending_flushes += 1;
1029        let mut halted_dispatch = false;
1030
1031        for view_id in path.iter().rev() {
1032            if let Some(mut view) = self.cx.views.remove(&(window_id, *view_id)) {
1033                let type_id = view.as_any().type_id();
1034
1035                if let Some((name, mut handlers)) = self
1036                    .actions
1037                    .get_mut(&type_id)
1038                    .and_then(|h| h.remove_entry(&action.id()))
1039                {
1040                    for handler in handlers.iter_mut().rev() {
1041                        let halt_dispatch =
1042                            handler(view.as_mut(), action, self, window_id, *view_id);
1043                        if halt_dispatch {
1044                            halted_dispatch = true;
1045                            break;
1046                        }
1047                    }
1048                    self.actions
1049                        .get_mut(&type_id)
1050                        .unwrap()
1051                        .insert(name, handlers);
1052                }
1053
1054                self.cx.views.insert((window_id, *view_id), view);
1055
1056                if halted_dispatch {
1057                    break;
1058                }
1059            }
1060        }
1061
1062        if !halted_dispatch {
1063            self.dispatch_global_action_any(action);
1064        }
1065
1066        self.flush_effects();
1067        halted_dispatch
1068    }
1069
1070    pub fn dispatch_global_action<A: Action>(&mut self, action: A) {
1071        self.dispatch_global_action_any(&action);
1072    }
1073
1074    fn dispatch_global_action_any(&mut self, action: &dyn AnyAction) {
1075        if let Some((name, mut handlers)) = self.global_actions.remove_entry(&action.id()) {
1076            self.pending_flushes += 1;
1077            for handler in handlers.iter_mut().rev() {
1078                handler(action, self);
1079            }
1080            self.global_actions.insert(name, handlers);
1081            self.flush_effects();
1082        }
1083    }
1084
1085    pub fn add_bindings<T: IntoIterator<Item = keymap::Binding>>(&mut self, bindings: T) {
1086        self.keystroke_matcher.add_bindings(bindings);
1087    }
1088
1089    pub fn dispatch_keystroke(
1090        &mut self,
1091        window_id: usize,
1092        responder_chain: Vec<usize>,
1093        keystroke: &Keystroke,
1094    ) -> Result<bool> {
1095        let mut context_chain = Vec::new();
1096        let mut context = keymap::Context::default();
1097        for view_id in &responder_chain {
1098            if let Some(view) = self.cx.views.get(&(window_id, *view_id)) {
1099                context.extend(view.keymap_context(self.as_ref()));
1100                context_chain.push(context.clone());
1101            } else {
1102                return Err(anyhow!(
1103                    "View {} in responder chain does not exist",
1104                    view_id
1105                ));
1106            }
1107        }
1108
1109        let mut pending = false;
1110        for (i, cx) in context_chain.iter().enumerate().rev() {
1111            match self
1112                .keystroke_matcher
1113                .push_keystroke(keystroke.clone(), responder_chain[i], cx)
1114            {
1115                MatchResult::None => {}
1116                MatchResult::Pending => pending = true,
1117                MatchResult::Action(action) => {
1118                    if self.dispatch_action_any(window_id, &responder_chain[0..=i], action.as_ref())
1119                    {
1120                        return Ok(true);
1121                    }
1122                }
1123            }
1124        }
1125
1126        Ok(pending)
1127    }
1128
1129    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
1130    where
1131        T: Entity,
1132        F: FnOnce(&mut ModelContext<T>) -> T,
1133    {
1134        self.pending_flushes += 1;
1135        let model_id = post_inc(&mut self.next_entity_id);
1136        let handle = ModelHandle::new(model_id, &self.cx.ref_counts);
1137        let mut cx = ModelContext::new(self, model_id);
1138        let model = build_model(&mut cx);
1139        self.cx.models.insert(model_id, Box::new(model));
1140        self.flush_effects();
1141        handle
1142    }
1143
1144    pub fn add_window<T, F>(
1145        &mut self,
1146        window_options: WindowOptions,
1147        build_root_view: F,
1148    ) -> (usize, ViewHandle<T>)
1149    where
1150        T: View,
1151        F: FnOnce(&mut ViewContext<T>) -> T,
1152    {
1153        self.pending_flushes += 1;
1154        let window_id = post_inc(&mut self.next_window_id);
1155        let root_view = self.add_view(window_id, build_root_view);
1156
1157        self.cx.windows.insert(
1158            window_id,
1159            Window {
1160                root_view: root_view.clone().into(),
1161                focused_view_id: root_view.id(),
1162                invalidation: None,
1163            },
1164        );
1165        self.open_platform_window(window_id, window_options);
1166        root_view.update(self, |view, cx| {
1167            view.on_focus(cx);
1168            cx.notify();
1169        });
1170        self.flush_effects();
1171
1172        (window_id, root_view)
1173    }
1174
1175    pub fn remove_window(&mut self, window_id: usize) {
1176        self.cx.windows.remove(&window_id);
1177        self.presenters_and_platform_windows.remove(&window_id);
1178        self.remove_dropped_entities();
1179    }
1180
1181    fn open_platform_window(&mut self, window_id: usize, window_options: WindowOptions) {
1182        let mut window =
1183            self.cx
1184                .platform
1185                .open_window(window_id, window_options, self.foreground.clone());
1186        let presenter = Rc::new(RefCell::new(
1187            self.build_presenter(window_id, window.titlebar_height()),
1188        ));
1189
1190        {
1191            let mut app = self.upgrade();
1192            let presenter = presenter.clone();
1193            window.on_event(Box::new(move |event| {
1194                app.update(|cx| {
1195                    if let Event::KeyDown { keystroke, .. } = &event {
1196                        if cx
1197                            .dispatch_keystroke(
1198                                window_id,
1199                                presenter.borrow().dispatch_path(cx.as_ref()),
1200                                keystroke,
1201                            )
1202                            .unwrap()
1203                        {
1204                            return;
1205                        }
1206                    }
1207
1208                    presenter.borrow_mut().dispatch_event(event, cx);
1209                })
1210            }));
1211        }
1212
1213        {
1214            let mut app = self.upgrade();
1215            let presenter = presenter.clone();
1216            window.on_resize(Box::new(move |window| {
1217                app.update(|cx| {
1218                    let scene = presenter.borrow_mut().build_scene(
1219                        window.size(),
1220                        window.scale_factor(),
1221                        cx,
1222                    );
1223                    window.present_scene(scene);
1224                })
1225            }));
1226        }
1227
1228        {
1229            let mut app = self.upgrade();
1230            window.on_close(Box::new(move || {
1231                app.update(|cx| cx.remove_window(window_id));
1232            }));
1233        }
1234
1235        self.presenters_and_platform_windows
1236            .insert(window_id, (presenter.clone(), window));
1237
1238        self.on_debug_elements(window_id, move |cx| {
1239            presenter.borrow().debug_elements(cx).unwrap()
1240        });
1241    }
1242
1243    pub fn build_presenter(&mut self, window_id: usize, titlebar_height: f32) -> Presenter {
1244        Presenter::new(
1245            window_id,
1246            titlebar_height,
1247            self.cx.font_cache.clone(),
1248            TextLayoutCache::new(self.cx.platform.fonts()),
1249            self.assets.clone(),
1250            self,
1251        )
1252    }
1253
1254    pub fn render_cx<V: View>(
1255        &mut self,
1256        window_id: usize,
1257        view_id: usize,
1258        titlebar_height: f32,
1259        refreshing: bool,
1260    ) -> RenderContext<V> {
1261        RenderContext {
1262            app: self,
1263            titlebar_height,
1264            refreshing,
1265            window_id,
1266            view_id,
1267            view_type: PhantomData,
1268        }
1269    }
1270
1271    pub fn add_view<T, F>(&mut self, window_id: usize, build_view: F) -> ViewHandle<T>
1272    where
1273        T: View,
1274        F: FnOnce(&mut ViewContext<T>) -> T,
1275    {
1276        self.add_option_view(window_id, |cx| Some(build_view(cx)))
1277            .unwrap()
1278    }
1279
1280    pub fn add_option_view<T, F>(
1281        &mut self,
1282        window_id: usize,
1283        build_view: F,
1284    ) -> Option<ViewHandle<T>>
1285    where
1286        T: View,
1287        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
1288    {
1289        let view_id = post_inc(&mut self.next_entity_id);
1290        self.pending_flushes += 1;
1291        let handle = ViewHandle::new(window_id, view_id, &self.cx.ref_counts);
1292        let mut cx = ViewContext::new(self, window_id, view_id);
1293        let handle = if let Some(view) = build_view(&mut cx) {
1294            self.cx.views.insert((window_id, view_id), Box::new(view));
1295            if let Some(window) = self.cx.windows.get_mut(&window_id) {
1296                window
1297                    .invalidation
1298                    .get_or_insert_with(Default::default)
1299                    .updated
1300                    .insert(view_id);
1301            }
1302            Some(handle)
1303        } else {
1304            None
1305        };
1306        self.flush_effects();
1307        handle
1308    }
1309
1310    pub fn element_state<Tag: 'static, T: 'static + Default>(
1311        &mut self,
1312        id: usize,
1313    ) -> ElementStateHandle<T> {
1314        let key = (TypeId::of::<Tag>(), id);
1315        self.cx
1316            .element_states
1317            .entry(key)
1318            .or_insert_with(|| Box::new(T::default()));
1319        ElementStateHandle::new(TypeId::of::<Tag>(), id, &self.cx.ref_counts)
1320    }
1321
1322    fn remove_dropped_entities(&mut self) {
1323        loop {
1324            let (dropped_models, dropped_views, dropped_element_states) =
1325                self.cx.ref_counts.lock().take_dropped();
1326            if dropped_models.is_empty()
1327                && dropped_views.is_empty()
1328                && dropped_element_states.is_empty()
1329            {
1330                break;
1331            }
1332
1333            for model_id in dropped_models {
1334                self.subscriptions.lock().remove(&model_id);
1335                self.observations.lock().remove(&model_id);
1336                let mut model = self.cx.models.remove(&model_id).unwrap();
1337                model.release(self);
1338            }
1339
1340            for (window_id, view_id) in dropped_views {
1341                self.subscriptions.lock().remove(&view_id);
1342                self.observations.lock().remove(&view_id);
1343                let mut view = self.cx.views.remove(&(window_id, view_id)).unwrap();
1344                view.release(self);
1345                let change_focus_to = self.cx.windows.get_mut(&window_id).and_then(|window| {
1346                    window
1347                        .invalidation
1348                        .get_or_insert_with(Default::default)
1349                        .removed
1350                        .push(view_id);
1351                    if window.focused_view_id == view_id {
1352                        Some(window.root_view.id())
1353                    } else {
1354                        None
1355                    }
1356                });
1357
1358                if let Some(view_id) = change_focus_to {
1359                    self.focus(window_id, view_id);
1360                }
1361            }
1362
1363            for key in dropped_element_states {
1364                self.cx.element_states.remove(&key);
1365            }
1366        }
1367    }
1368
1369    fn flush_effects(&mut self) {
1370        self.pending_flushes = self.pending_flushes.saturating_sub(1);
1371
1372        if !self.flushing_effects && self.pending_flushes == 0 {
1373            self.flushing_effects = true;
1374
1375            let mut refreshing = false;
1376            loop {
1377                if let Some(effect) = self.pending_effects.pop_front() {
1378                    match effect {
1379                        Effect::Event { entity_id, payload } => self.emit_event(entity_id, payload),
1380                        Effect::ModelNotification { model_id } => {
1381                            self.notify_model_observers(model_id)
1382                        }
1383                        Effect::ViewNotification { window_id, view_id } => {
1384                            self.notify_view_observers(window_id, view_id)
1385                        }
1386                        Effect::Focus { window_id, view_id } => {
1387                            self.focus(window_id, view_id);
1388                        }
1389                        Effect::RefreshWindows => {
1390                            refreshing = true;
1391                        }
1392                    }
1393                    self.remove_dropped_entities();
1394                } else {
1395                    self.remove_dropped_entities();
1396                    if refreshing {
1397                        self.perform_window_refresh();
1398                    } else {
1399                        self.update_windows();
1400                    }
1401
1402                    if self.pending_effects.is_empty() {
1403                        self.flushing_effects = false;
1404                        break;
1405                    } else {
1406                        refreshing = false;
1407                    }
1408                }
1409            }
1410        }
1411    }
1412
1413    fn update_windows(&mut self) {
1414        let mut invalidations = HashMap::new();
1415        for (window_id, window) in &mut self.cx.windows {
1416            if let Some(invalidation) = window.invalidation.take() {
1417                invalidations.insert(*window_id, invalidation);
1418            }
1419        }
1420
1421        for (window_id, invalidation) in invalidations {
1422            if let Some((presenter, mut window)) =
1423                self.presenters_and_platform_windows.remove(&window_id)
1424            {
1425                {
1426                    let mut presenter = presenter.borrow_mut();
1427                    presenter.invalidate(invalidation, self);
1428                    let scene = presenter.build_scene(window.size(), window.scale_factor(), self);
1429                    window.present_scene(scene);
1430                }
1431                self.presenters_and_platform_windows
1432                    .insert(window_id, (presenter, window));
1433            }
1434        }
1435    }
1436
1437    pub fn refresh_windows(&mut self) {
1438        self.pending_effects.push_back(Effect::RefreshWindows);
1439    }
1440
1441    fn perform_window_refresh(&mut self) {
1442        let mut presenters = mem::take(&mut self.presenters_and_platform_windows);
1443        for (window_id, (presenter, window)) in &mut presenters {
1444            let invalidation = self
1445                .cx
1446                .windows
1447                .get_mut(&window_id)
1448                .unwrap()
1449                .invalidation
1450                .take();
1451            let mut presenter = presenter.borrow_mut();
1452            presenter.refresh(invalidation, self);
1453            let scene = presenter.build_scene(window.size(), window.scale_factor(), self);
1454            window.present_scene(scene);
1455        }
1456        self.presenters_and_platform_windows = presenters;
1457    }
1458
1459    fn emit_event(&mut self, entity_id: usize, payload: Box<dyn Any>) {
1460        let callbacks = self.subscriptions.lock().remove(&entity_id);
1461        if let Some(callbacks) = callbacks {
1462            for (id, mut callback) in callbacks {
1463                let alive = callback(payload.as_ref(), self);
1464                if alive {
1465                    self.subscriptions
1466                        .lock()
1467                        .entry(entity_id)
1468                        .or_default()
1469                        .insert(id, callback);
1470                }
1471            }
1472        }
1473    }
1474
1475    fn notify_model_observers(&mut self, observed_id: usize) {
1476        let callbacks = self.observations.lock().remove(&observed_id);
1477        if let Some(callbacks) = callbacks {
1478            if self.cx.models.contains_key(&observed_id) {
1479                for (id, mut callback) in callbacks {
1480                    let alive = callback(self);
1481                    if alive {
1482                        self.observations
1483                            .lock()
1484                            .entry(observed_id)
1485                            .or_default()
1486                            .insert(id, callback);
1487                    }
1488                }
1489            }
1490        }
1491    }
1492
1493    fn notify_view_observers(&mut self, observed_window_id: usize, observed_view_id: usize) {
1494        if let Some(window) = self.cx.windows.get_mut(&observed_window_id) {
1495            window
1496                .invalidation
1497                .get_or_insert_with(Default::default)
1498                .updated
1499                .insert(observed_view_id);
1500        }
1501
1502        let callbacks = self.observations.lock().remove(&observed_view_id);
1503        if let Some(callbacks) = callbacks {
1504            if self
1505                .cx
1506                .views
1507                .contains_key(&(observed_window_id, observed_view_id))
1508            {
1509                for (id, mut callback) in callbacks {
1510                    let alive = callback(self);
1511                    if alive {
1512                        self.observations
1513                            .lock()
1514                            .entry(observed_view_id)
1515                            .or_default()
1516                            .insert(id, callback);
1517                    }
1518                }
1519            }
1520        }
1521    }
1522
1523    fn focus(&mut self, window_id: usize, focused_id: usize) {
1524        if self
1525            .cx
1526            .windows
1527            .get(&window_id)
1528            .map(|w| w.focused_view_id)
1529            .map_or(false, |cur_focused| cur_focused == focused_id)
1530        {
1531            return;
1532        }
1533
1534        self.pending_flushes += 1;
1535
1536        let blurred_id = self.cx.windows.get_mut(&window_id).map(|window| {
1537            let blurred_id = window.focused_view_id;
1538            window.focused_view_id = focused_id;
1539            blurred_id
1540        });
1541
1542        if let Some(blurred_id) = blurred_id {
1543            if let Some(mut blurred_view) = self.cx.views.remove(&(window_id, blurred_id)) {
1544                blurred_view.on_blur(self, window_id, blurred_id);
1545                self.cx.views.insert((window_id, blurred_id), blurred_view);
1546            }
1547        }
1548
1549        if let Some(mut focused_view) = self.cx.views.remove(&(window_id, focused_id)) {
1550            focused_view.on_focus(self, window_id, focused_id);
1551            self.cx.views.insert((window_id, focused_id), focused_view);
1552        }
1553
1554        self.flush_effects();
1555    }
1556
1557    pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
1558    where
1559        F: FnOnce(AsyncAppContext) -> Fut,
1560        Fut: 'static + Future<Output = T>,
1561        T: 'static,
1562    {
1563        let cx = self.to_async();
1564        self.foreground.spawn(f(cx))
1565    }
1566
1567    pub fn to_async(&self) -> AsyncAppContext {
1568        AsyncAppContext(self.weak_self.as_ref().unwrap().upgrade().unwrap())
1569    }
1570
1571    pub fn write_to_clipboard(&self, item: ClipboardItem) {
1572        self.cx.platform.write_to_clipboard(item);
1573    }
1574
1575    pub fn read_from_clipboard(&self) -> Option<ClipboardItem> {
1576        self.cx.platform.read_from_clipboard()
1577    }
1578}
1579
1580impl ReadModel for MutableAppContext {
1581    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1582        if let Some(model) = self.cx.models.get(&handle.model_id) {
1583            model
1584                .as_any()
1585                .downcast_ref()
1586                .expect("downcast is type safe")
1587        } else {
1588            panic!("circular model reference");
1589        }
1590    }
1591}
1592
1593impl UpdateModel for MutableAppContext {
1594    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
1595    where
1596        T: Entity,
1597        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
1598    {
1599        if let Some(mut model) = self.cx.models.remove(&handle.model_id) {
1600            self.pending_flushes += 1;
1601            let mut cx = ModelContext::new(self, handle.model_id);
1602            let result = update(
1603                model
1604                    .as_any_mut()
1605                    .downcast_mut()
1606                    .expect("downcast is type safe"),
1607                &mut cx,
1608            );
1609            self.cx.models.insert(handle.model_id, model);
1610            self.flush_effects();
1611            result
1612        } else {
1613            panic!("circular model update");
1614        }
1615    }
1616}
1617
1618impl UpgradeModelHandle for MutableAppContext {
1619    fn upgrade_model_handle<T: Entity>(
1620        &self,
1621        handle: WeakModelHandle<T>,
1622    ) -> Option<ModelHandle<T>> {
1623        self.cx.upgrade_model_handle(handle)
1624    }
1625}
1626
1627impl ReadView for MutableAppContext {
1628    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
1629        if let Some(view) = self.cx.views.get(&(handle.window_id, handle.view_id)) {
1630            view.as_any().downcast_ref().expect("downcast is type safe")
1631        } else {
1632            panic!("circular view reference");
1633        }
1634    }
1635}
1636
1637impl UpdateView for MutableAppContext {
1638    fn update_view<T, F, S>(&mut self, handle: &ViewHandle<T>, update: F) -> S
1639    where
1640        T: View,
1641        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
1642    {
1643        self.pending_flushes += 1;
1644        let mut view = self
1645            .cx
1646            .views
1647            .remove(&(handle.window_id, handle.view_id))
1648            .expect("circular view update");
1649
1650        let mut cx = ViewContext::new(self, handle.window_id, handle.view_id);
1651        let result = update(
1652            view.as_any_mut()
1653                .downcast_mut()
1654                .expect("downcast is type safe"),
1655            &mut cx,
1656        );
1657        self.cx
1658            .views
1659            .insert((handle.window_id, handle.view_id), view);
1660        self.flush_effects();
1661        result
1662    }
1663}
1664
1665impl AsRef<AppContext> for MutableAppContext {
1666    fn as_ref(&self) -> &AppContext {
1667        &self.cx
1668    }
1669}
1670
1671impl Deref for MutableAppContext {
1672    type Target = AppContext;
1673
1674    fn deref(&self) -> &Self::Target {
1675        &self.cx
1676    }
1677}
1678
1679pub struct AppContext {
1680    models: HashMap<usize, Box<dyn AnyModel>>,
1681    views: HashMap<(usize, usize), Box<dyn AnyView>>,
1682    windows: HashMap<usize, Window>,
1683    element_states: HashMap<(TypeId, usize), Box<dyn Any>>,
1684    background: Arc<executor::Background>,
1685    ref_counts: Arc<Mutex<RefCounts>>,
1686    font_cache: Arc<FontCache>,
1687    platform: Arc<dyn Platform>,
1688}
1689
1690impl AppContext {
1691    pub fn root_view_id(&self, window_id: usize) -> Option<usize> {
1692        self.windows
1693            .get(&window_id)
1694            .map(|window| window.root_view.id())
1695    }
1696
1697    pub fn focused_view_id(&self, window_id: usize) -> Option<usize> {
1698        self.windows
1699            .get(&window_id)
1700            .map(|window| window.focused_view_id)
1701    }
1702
1703    pub fn background(&self) -> &Arc<executor::Background> {
1704        &self.background
1705    }
1706
1707    pub fn font_cache(&self) -> &Arc<FontCache> {
1708        &self.font_cache
1709    }
1710
1711    pub fn platform(&self) -> &Arc<dyn Platform> {
1712        &self.platform
1713    }
1714}
1715
1716impl ReadModel for AppContext {
1717    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1718        if let Some(model) = self.models.get(&handle.model_id) {
1719            model
1720                .as_any()
1721                .downcast_ref()
1722                .expect("downcast should be type safe")
1723        } else {
1724            panic!("circular model reference");
1725        }
1726    }
1727}
1728
1729impl UpgradeModelHandle for AppContext {
1730    fn upgrade_model_handle<T: Entity>(
1731        &self,
1732        handle: WeakModelHandle<T>,
1733    ) -> Option<ModelHandle<T>> {
1734        if self.models.contains_key(&handle.model_id) {
1735            Some(ModelHandle::new(handle.model_id, &self.ref_counts))
1736        } else {
1737            None
1738        }
1739    }
1740}
1741
1742impl ReadView for AppContext {
1743    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
1744        if let Some(view) = self.views.get(&(handle.window_id, handle.view_id)) {
1745            view.as_any()
1746                .downcast_ref()
1747                .expect("downcast should be type safe")
1748        } else {
1749            panic!("circular view reference");
1750        }
1751    }
1752}
1753
1754struct Window {
1755    root_view: AnyViewHandle,
1756    focused_view_id: usize,
1757    invalidation: Option<WindowInvalidation>,
1758}
1759
1760#[derive(Default, Clone)]
1761pub struct WindowInvalidation {
1762    pub updated: HashSet<usize>,
1763    pub removed: Vec<usize>,
1764}
1765
1766pub enum Effect {
1767    Event {
1768        entity_id: usize,
1769        payload: Box<dyn Any>,
1770    },
1771    ModelNotification {
1772        model_id: usize,
1773    },
1774    ViewNotification {
1775        window_id: usize,
1776        view_id: usize,
1777    },
1778    Focus {
1779        window_id: usize,
1780        view_id: usize,
1781    },
1782    RefreshWindows,
1783}
1784
1785impl Debug for Effect {
1786    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1787        match self {
1788            Effect::Event { entity_id, .. } => f
1789                .debug_struct("Effect::Event")
1790                .field("entity_id", entity_id)
1791                .finish(),
1792            Effect::ModelNotification { model_id } => f
1793                .debug_struct("Effect::ModelNotification")
1794                .field("model_id", model_id)
1795                .finish(),
1796            Effect::ViewNotification { window_id, view_id } => f
1797                .debug_struct("Effect::ViewNotification")
1798                .field("window_id", window_id)
1799                .field("view_id", view_id)
1800                .finish(),
1801            Effect::Focus { window_id, view_id } => f
1802                .debug_struct("Effect::Focus")
1803                .field("window_id", window_id)
1804                .field("view_id", view_id)
1805                .finish(),
1806            Effect::RefreshWindows => f.debug_struct("Effect::FullViewRefresh").finish(),
1807        }
1808    }
1809}
1810
1811pub trait AnyModel {
1812    fn as_any(&self) -> &dyn Any;
1813    fn as_any_mut(&mut self) -> &mut dyn Any;
1814    fn release(&mut self, cx: &mut MutableAppContext);
1815}
1816
1817impl<T> AnyModel for T
1818where
1819    T: Entity,
1820{
1821    fn as_any(&self) -> &dyn Any {
1822        self
1823    }
1824
1825    fn as_any_mut(&mut self) -> &mut dyn Any {
1826        self
1827    }
1828
1829    fn release(&mut self, cx: &mut MutableAppContext) {
1830        self.release(cx);
1831    }
1832}
1833
1834pub trait AnyView {
1835    fn as_any(&self) -> &dyn Any;
1836    fn as_any_mut(&mut self) -> &mut dyn Any;
1837    fn release(&mut self, cx: &mut MutableAppContext);
1838    fn ui_name(&self) -> &'static str;
1839    fn render<'a>(
1840        &self,
1841        window_id: usize,
1842        view_id: usize,
1843        titlebar_height: f32,
1844        refreshing: bool,
1845        cx: &mut MutableAppContext,
1846    ) -> ElementBox;
1847    fn on_focus(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize);
1848    fn on_blur(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize);
1849    fn keymap_context(&self, cx: &AppContext) -> keymap::Context;
1850}
1851
1852impl<T> AnyView for T
1853where
1854    T: View,
1855{
1856    fn as_any(&self) -> &dyn Any {
1857        self
1858    }
1859
1860    fn as_any_mut(&mut self) -> &mut dyn Any {
1861        self
1862    }
1863
1864    fn release(&mut self, cx: &mut MutableAppContext) {
1865        self.release(cx);
1866    }
1867
1868    fn ui_name(&self) -> &'static str {
1869        T::ui_name()
1870    }
1871
1872    fn render<'a>(
1873        &self,
1874        window_id: usize,
1875        view_id: usize,
1876        titlebar_height: f32,
1877        refreshing: bool,
1878        cx: &mut MutableAppContext,
1879    ) -> ElementBox {
1880        View::render(
1881            self,
1882            &mut RenderContext {
1883                window_id,
1884                view_id,
1885                app: cx,
1886                view_type: PhantomData::<T>,
1887                titlebar_height,
1888                refreshing,
1889            },
1890        )
1891    }
1892
1893    fn on_focus(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize) {
1894        let mut cx = ViewContext::new(cx, window_id, view_id);
1895        View::on_focus(self, &mut cx);
1896    }
1897
1898    fn on_blur(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize) {
1899        let mut cx = ViewContext::new(cx, window_id, view_id);
1900        View::on_blur(self, &mut cx);
1901    }
1902
1903    fn keymap_context(&self, cx: &AppContext) -> keymap::Context {
1904        View::keymap_context(self, cx)
1905    }
1906}
1907
1908pub struct ModelContext<'a, T: ?Sized> {
1909    app: &'a mut MutableAppContext,
1910    model_id: usize,
1911    model_type: PhantomData<T>,
1912    halt_stream: bool,
1913}
1914
1915impl<'a, T: Entity> ModelContext<'a, T> {
1916    fn new(app: &'a mut MutableAppContext, model_id: usize) -> Self {
1917        Self {
1918            app,
1919            model_id,
1920            model_type: PhantomData,
1921            halt_stream: false,
1922        }
1923    }
1924
1925    pub fn background(&self) -> &Arc<executor::Background> {
1926        &self.app.cx.background
1927    }
1928
1929    pub fn halt_stream(&mut self) {
1930        self.halt_stream = true;
1931    }
1932
1933    pub fn model_id(&self) -> usize {
1934        self.model_id
1935    }
1936
1937    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
1938    where
1939        S: Entity,
1940        F: FnOnce(&mut ModelContext<S>) -> S,
1941    {
1942        self.app.add_model(build_model)
1943    }
1944
1945    pub fn emit(&mut self, payload: T::Event) {
1946        self.app.pending_effects.push_back(Effect::Event {
1947            entity_id: self.model_id,
1948            payload: Box::new(payload),
1949        });
1950    }
1951
1952    pub fn notify(&mut self) {
1953        self.app
1954            .pending_effects
1955            .push_back(Effect::ModelNotification {
1956                model_id: self.model_id,
1957            });
1958    }
1959
1960    pub fn subscribe<S: Entity, F>(
1961        &mut self,
1962        handle: &ModelHandle<S>,
1963        mut callback: F,
1964    ) -> Subscription
1965    where
1966        S::Event: 'static,
1967        F: 'static + FnMut(&mut T, ModelHandle<S>, &S::Event, &mut ModelContext<T>),
1968    {
1969        let subscriber = self.handle().downgrade();
1970        self.app
1971            .subscribe_internal(handle, move |emitter, event, cx| {
1972                if let Some(subscriber) = subscriber.upgrade(cx) {
1973                    subscriber.update(cx, |subscriber, cx| {
1974                        callback(subscriber, emitter, event, cx);
1975                    });
1976                    true
1977                } else {
1978                    false
1979                }
1980            })
1981    }
1982
1983    pub fn observe<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F) -> Subscription
1984    where
1985        S: Entity,
1986        F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ModelContext<T>),
1987    {
1988        let observer = self.handle().downgrade();
1989        self.app.observe_internal(handle, move |observed, cx| {
1990            if let Some(observer) = observer.upgrade(cx) {
1991                observer.update(cx, |observer, cx| {
1992                    callback(observer, observed, cx);
1993                });
1994                true
1995            } else {
1996                false
1997            }
1998        })
1999    }
2000
2001    pub fn handle(&self) -> ModelHandle<T> {
2002        ModelHandle::new(self.model_id, &self.app.cx.ref_counts)
2003    }
2004
2005    pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
2006    where
2007        F: FnOnce(ModelHandle<T>, AsyncAppContext) -> Fut,
2008        Fut: 'static + Future<Output = S>,
2009        S: 'static,
2010    {
2011        let handle = self.handle();
2012        self.app.spawn(|cx| f(handle, cx))
2013    }
2014
2015    pub fn spawn_weak<F, Fut, S>(&self, f: F) -> Task<S>
2016    where
2017        F: FnOnce(WeakModelHandle<T>, AsyncAppContext) -> Fut,
2018        Fut: 'static + Future<Output = S>,
2019        S: 'static,
2020    {
2021        let handle = self.handle().downgrade();
2022        self.app.spawn(|cx| f(handle, cx))
2023    }
2024}
2025
2026impl<M> AsRef<AppContext> for ModelContext<'_, M> {
2027    fn as_ref(&self) -> &AppContext {
2028        &self.app.cx
2029    }
2030}
2031
2032impl<M> AsMut<MutableAppContext> for ModelContext<'_, M> {
2033    fn as_mut(&mut self) -> &mut MutableAppContext {
2034        self.app
2035    }
2036}
2037
2038impl<M> ReadModel for ModelContext<'_, M> {
2039    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2040        self.app.read_model(handle)
2041    }
2042}
2043
2044impl<M> UpdateModel for ModelContext<'_, M> {
2045    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
2046    where
2047        T: Entity,
2048        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
2049    {
2050        self.app.update_model(handle, update)
2051    }
2052}
2053
2054impl<M> UpgradeModelHandle for ModelContext<'_, M> {
2055    fn upgrade_model_handle<T: Entity>(
2056        &self,
2057        handle: WeakModelHandle<T>,
2058    ) -> Option<ModelHandle<T>> {
2059        self.cx.upgrade_model_handle(handle)
2060    }
2061}
2062
2063impl<M> Deref for ModelContext<'_, M> {
2064    type Target = MutableAppContext;
2065
2066    fn deref(&self) -> &Self::Target {
2067        &self.app
2068    }
2069}
2070
2071impl<M> DerefMut for ModelContext<'_, M> {
2072    fn deref_mut(&mut self) -> &mut Self::Target {
2073        &mut self.app
2074    }
2075}
2076
2077pub struct ViewContext<'a, T: ?Sized> {
2078    app: &'a mut MutableAppContext,
2079    window_id: usize,
2080    view_id: usize,
2081    view_type: PhantomData<T>,
2082    halt_action_dispatch: bool,
2083}
2084
2085impl<'a, T: View> ViewContext<'a, T> {
2086    fn new(app: &'a mut MutableAppContext, window_id: usize, view_id: usize) -> Self {
2087        Self {
2088            app,
2089            window_id,
2090            view_id,
2091            view_type: PhantomData,
2092            halt_action_dispatch: true,
2093        }
2094    }
2095
2096    pub fn handle(&self) -> ViewHandle<T> {
2097        ViewHandle::new(self.window_id, self.view_id, &self.app.cx.ref_counts)
2098    }
2099
2100    pub fn window_id(&self) -> usize {
2101        self.window_id
2102    }
2103
2104    pub fn view_id(&self) -> usize {
2105        self.view_id
2106    }
2107
2108    pub fn foreground(&self) -> &Rc<executor::Foreground> {
2109        self.app.foreground()
2110    }
2111
2112    pub fn background_executor(&self) -> &Arc<executor::Background> {
2113        &self.app.cx.background
2114    }
2115
2116    pub fn platform(&self) -> Arc<dyn Platform> {
2117        self.app.platform()
2118    }
2119
2120    pub fn prompt<F>(&self, level: PromptLevel, msg: &str, answers: &[&str], done_fn: F)
2121    where
2122        F: 'static + FnOnce(usize, &mut MutableAppContext),
2123    {
2124        self.app
2125            .prompt(self.window_id, level, msg, answers, done_fn)
2126    }
2127
2128    pub fn prompt_for_paths<F>(&self, options: PathPromptOptions, done_fn: F)
2129    where
2130        F: 'static + FnOnce(Option<Vec<PathBuf>>, &mut MutableAppContext),
2131    {
2132        self.app.prompt_for_paths(options, done_fn)
2133    }
2134
2135    pub fn prompt_for_new_path<F>(&self, directory: &Path, done_fn: F)
2136    where
2137        F: 'static + FnOnce(Option<PathBuf>, &mut MutableAppContext),
2138    {
2139        self.app.prompt_for_new_path(directory, done_fn)
2140    }
2141
2142    pub fn debug_elements(&self) -> crate::json::Value {
2143        self.app.debug_elements(self.window_id).unwrap()
2144    }
2145
2146    pub fn focus<S>(&mut self, handle: S)
2147    where
2148        S: Into<AnyViewHandle>,
2149    {
2150        let handle = handle.into();
2151        self.app.pending_effects.push_back(Effect::Focus {
2152            window_id: handle.window_id,
2153            view_id: handle.view_id,
2154        });
2155    }
2156
2157    pub fn focus_self(&mut self) {
2158        self.app.pending_effects.push_back(Effect::Focus {
2159            window_id: self.window_id,
2160            view_id: self.view_id,
2161        });
2162    }
2163
2164    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
2165    where
2166        S: Entity,
2167        F: FnOnce(&mut ModelContext<S>) -> S,
2168    {
2169        self.app.add_model(build_model)
2170    }
2171
2172    pub fn add_view<S, F>(&mut self, build_view: F) -> ViewHandle<S>
2173    where
2174        S: View,
2175        F: FnOnce(&mut ViewContext<S>) -> S,
2176    {
2177        self.app.add_view(self.window_id, build_view)
2178    }
2179
2180    pub fn add_option_view<S, F>(&mut self, build_view: F) -> Option<ViewHandle<S>>
2181    where
2182        S: View,
2183        F: FnOnce(&mut ViewContext<S>) -> Option<S>,
2184    {
2185        self.app.add_option_view(self.window_id, build_view)
2186    }
2187
2188    pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
2189    where
2190        E: Entity,
2191        E::Event: 'static,
2192        H: Handle<E>,
2193        F: 'static + FnMut(&mut T, H, &E::Event, &mut ViewContext<T>),
2194    {
2195        let subscriber = self.handle().downgrade();
2196        self.app
2197            .subscribe_internal(handle, move |emitter, event, cx| {
2198                if let Some(subscriber) = subscriber.upgrade(cx) {
2199                    subscriber.update(cx, |subscriber, cx| {
2200                        callback(subscriber, emitter, event, cx);
2201                    });
2202                    true
2203                } else {
2204                    false
2205                }
2206            })
2207    }
2208
2209    pub fn observe<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
2210    where
2211        E: Entity,
2212        H: Handle<E>,
2213        F: 'static + FnMut(&mut T, H, &mut ViewContext<T>),
2214    {
2215        let observer = self.handle().downgrade();
2216        self.app.observe_internal(handle, move |observed, cx| {
2217            if let Some(observer) = observer.upgrade(cx) {
2218                observer.update(cx, |observer, cx| {
2219                    callback(observer, observed, cx);
2220                });
2221                true
2222            } else {
2223                false
2224            }
2225        })
2226    }
2227
2228    pub fn emit(&mut self, payload: T::Event) {
2229        self.app.pending_effects.push_back(Effect::Event {
2230            entity_id: self.view_id,
2231            payload: Box::new(payload),
2232        });
2233    }
2234
2235    pub fn notify(&mut self) {
2236        self.app.notify_view(self.window_id, self.view_id);
2237    }
2238
2239    pub fn propagate_action(&mut self) {
2240        self.halt_action_dispatch = false;
2241    }
2242
2243    pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
2244    where
2245        F: FnOnce(ViewHandle<T>, AsyncAppContext) -> Fut,
2246        Fut: 'static + Future<Output = S>,
2247        S: 'static,
2248    {
2249        let handle = self.handle();
2250        self.app.spawn(|cx| f(handle, cx))
2251    }
2252}
2253
2254pub struct RenderContext<'a, T: View> {
2255    pub app: &'a mut MutableAppContext,
2256    pub titlebar_height: f32,
2257    pub refreshing: bool,
2258    window_id: usize,
2259    view_id: usize,
2260    view_type: PhantomData<T>,
2261}
2262
2263impl<'a, T: View> RenderContext<'a, T> {
2264    pub fn handle(&self) -> WeakViewHandle<T> {
2265        WeakViewHandle::new(self.window_id, self.view_id)
2266    }
2267}
2268
2269impl AsRef<AppContext> for &AppContext {
2270    fn as_ref(&self) -> &AppContext {
2271        self
2272    }
2273}
2274
2275impl<V: View> Deref for RenderContext<'_, V> {
2276    type Target = MutableAppContext;
2277
2278    fn deref(&self) -> &Self::Target {
2279        self.app
2280    }
2281}
2282
2283impl<V: View> DerefMut for RenderContext<'_, V> {
2284    fn deref_mut(&mut self) -> &mut Self::Target {
2285        self.app
2286    }
2287}
2288
2289impl<V: View> ReadModel for RenderContext<'_, V> {
2290    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2291        self.app.read_model(handle)
2292    }
2293}
2294
2295impl<M> AsRef<AppContext> for ViewContext<'_, M> {
2296    fn as_ref(&self) -> &AppContext {
2297        &self.app.cx
2298    }
2299}
2300
2301impl<M> Deref for ViewContext<'_, M> {
2302    type Target = MutableAppContext;
2303
2304    fn deref(&self) -> &Self::Target {
2305        &self.app
2306    }
2307}
2308
2309impl<M> DerefMut for ViewContext<'_, M> {
2310    fn deref_mut(&mut self) -> &mut Self::Target {
2311        &mut self.app
2312    }
2313}
2314
2315impl<M> AsMut<MutableAppContext> for ViewContext<'_, M> {
2316    fn as_mut(&mut self) -> &mut MutableAppContext {
2317        self.app
2318    }
2319}
2320
2321impl<V> ReadModel for ViewContext<'_, V> {
2322    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2323        self.app.read_model(handle)
2324    }
2325}
2326
2327impl<V> UpgradeModelHandle for ViewContext<'_, V> {
2328    fn upgrade_model_handle<T: Entity>(
2329        &self,
2330        handle: WeakModelHandle<T>,
2331    ) -> Option<ModelHandle<T>> {
2332        self.cx.upgrade_model_handle(handle)
2333    }
2334}
2335
2336impl<V: View> UpdateModel for ViewContext<'_, V> {
2337    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
2338    where
2339        T: Entity,
2340        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
2341    {
2342        self.app.update_model(handle, update)
2343    }
2344}
2345
2346impl<V: View> ReadView for ViewContext<'_, V> {
2347    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
2348        self.app.read_view(handle)
2349    }
2350}
2351
2352impl<V: View> UpdateView for ViewContext<'_, V> {
2353    fn update_view<T, F, S>(&mut self, handle: &ViewHandle<T>, update: F) -> S
2354    where
2355        T: View,
2356        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
2357    {
2358        self.app.update_view(handle, update)
2359    }
2360}
2361
2362pub trait Handle<T> {
2363    type Weak: 'static;
2364    fn id(&self) -> usize;
2365    fn location(&self) -> EntityLocation;
2366    fn downgrade(&self) -> Self::Weak;
2367    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
2368    where
2369        Self: Sized;
2370}
2371
2372#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
2373pub enum EntityLocation {
2374    Model(usize),
2375    View(usize, usize),
2376}
2377
2378pub struct ModelHandle<T> {
2379    model_id: usize,
2380    model_type: PhantomData<T>,
2381    ref_counts: Arc<Mutex<RefCounts>>,
2382}
2383
2384impl<T: Entity> ModelHandle<T> {
2385    fn new(model_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
2386        ref_counts.lock().inc_model(model_id);
2387        Self {
2388            model_id,
2389            model_type: PhantomData,
2390            ref_counts: ref_counts.clone(),
2391        }
2392    }
2393
2394    pub fn downgrade(&self) -> WeakModelHandle<T> {
2395        WeakModelHandle::new(self.model_id)
2396    }
2397
2398    pub fn id(&self) -> usize {
2399        self.model_id
2400    }
2401
2402    pub fn read<'a, C: ReadModel>(&self, cx: &'a C) -> &'a T {
2403        cx.read_model(self)
2404    }
2405
2406    pub fn read_with<'a, C, F, S>(&self, cx: &C, read: F) -> S
2407    where
2408        C: ReadModelWith,
2409        F: FnOnce(&T, &AppContext) -> S,
2410    {
2411        cx.read_model_with(self, read)
2412    }
2413
2414    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
2415    where
2416        C: UpdateModel,
2417        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
2418    {
2419        cx.update_model(self, update)
2420    }
2421
2422    pub fn next_notification(&self, cx: &TestAppContext) -> impl Future<Output = ()> {
2423        let (mut tx, mut rx) = mpsc::channel(1);
2424        let mut cx = cx.cx.borrow_mut();
2425        let subscription = cx.observe(self, move |_, _| {
2426            tx.blocking_send(()).ok();
2427        });
2428
2429        let duration = if std::env::var("CI").is_ok() {
2430            Duration::from_secs(5)
2431        } else {
2432            Duration::from_secs(1)
2433        };
2434
2435        async move {
2436            let notification = timeout(duration, rx.recv())
2437                .await
2438                .expect("next notification timed out");
2439            drop(subscription);
2440            notification.expect("model dropped while test was waiting for its next notification")
2441        }
2442    }
2443
2444    pub fn next_event(&self, cx: &TestAppContext) -> impl Future<Output = T::Event>
2445    where
2446        T::Event: Clone,
2447    {
2448        let (mut tx, mut rx) = mpsc::channel(1);
2449        let mut cx = cx.cx.borrow_mut();
2450        let subscription = cx.subscribe(self, move |_, event, _| {
2451            tx.blocking_send(event.clone()).ok();
2452        });
2453
2454        let duration = if std::env::var("CI").is_ok() {
2455            Duration::from_secs(5)
2456        } else {
2457            Duration::from_secs(1)
2458        };
2459
2460        async move {
2461            let event = timeout(duration, rx.recv())
2462                .await
2463                .expect("next event timed out");
2464            drop(subscription);
2465            event.expect("model dropped while test was waiting for its next event")
2466        }
2467    }
2468
2469    pub fn condition(
2470        &self,
2471        cx: &TestAppContext,
2472        mut predicate: impl FnMut(&T, &AppContext) -> bool,
2473    ) -> impl Future<Output = ()> {
2474        let (tx, mut rx) = mpsc::channel(1024);
2475
2476        let mut cx = cx.cx.borrow_mut();
2477        let subscriptions = (
2478            cx.observe(self, {
2479                let mut tx = tx.clone();
2480                move |_, _| {
2481                    tx.blocking_send(()).ok();
2482                }
2483            }),
2484            cx.subscribe(self, {
2485                let mut tx = tx.clone();
2486                move |_, _, _| {
2487                    tx.blocking_send(()).ok();
2488                }
2489            }),
2490        );
2491
2492        let cx = cx.weak_self.as_ref().unwrap().upgrade().unwrap();
2493        let handle = self.downgrade();
2494        let duration = if std::env::var("CI").is_ok() {
2495            Duration::from_secs(5)
2496        } else {
2497            Duration::from_secs(1)
2498        };
2499
2500        async move {
2501            timeout(duration, async move {
2502                loop {
2503                    {
2504                        let cx = cx.borrow();
2505                        let cx = cx.as_ref();
2506                        if predicate(
2507                            handle
2508                                .upgrade(cx)
2509                                .expect("model dropped with pending condition")
2510                                .read(cx),
2511                            cx,
2512                        ) {
2513                            break;
2514                        }
2515                    }
2516
2517                    rx.recv()
2518                        .await
2519                        .expect("model dropped with pending condition");
2520                }
2521            })
2522            .await
2523            .expect("condition timed out");
2524            drop(subscriptions);
2525        }
2526    }
2527}
2528
2529impl<T> Clone for ModelHandle<T> {
2530    fn clone(&self) -> Self {
2531        self.ref_counts.lock().inc_model(self.model_id);
2532        Self {
2533            model_id: self.model_id,
2534            model_type: PhantomData,
2535            ref_counts: self.ref_counts.clone(),
2536        }
2537    }
2538}
2539
2540impl<T> PartialEq for ModelHandle<T> {
2541    fn eq(&self, other: &Self) -> bool {
2542        self.model_id == other.model_id
2543    }
2544}
2545
2546impl<T> Eq for ModelHandle<T> {}
2547
2548impl<T> Hash for ModelHandle<T> {
2549    fn hash<H: Hasher>(&self, state: &mut H) {
2550        self.model_id.hash(state);
2551    }
2552}
2553
2554impl<T> std::borrow::Borrow<usize> for ModelHandle<T> {
2555    fn borrow(&self) -> &usize {
2556        &self.model_id
2557    }
2558}
2559
2560impl<T> Debug for ModelHandle<T> {
2561    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2562        f.debug_tuple(&format!("ModelHandle<{}>", type_name::<T>()))
2563            .field(&self.model_id)
2564            .finish()
2565    }
2566}
2567
2568unsafe impl<T> Send for ModelHandle<T> {}
2569unsafe impl<T> Sync for ModelHandle<T> {}
2570
2571impl<T> Drop for ModelHandle<T> {
2572    fn drop(&mut self) {
2573        self.ref_counts.lock().dec_model(self.model_id);
2574    }
2575}
2576
2577impl<T: Entity> Handle<T> for ModelHandle<T> {
2578    type Weak = WeakModelHandle<T>;
2579
2580    fn id(&self) -> usize {
2581        self.model_id
2582    }
2583
2584    fn location(&self) -> EntityLocation {
2585        EntityLocation::Model(self.model_id)
2586    }
2587
2588    fn downgrade(&self) -> Self::Weak {
2589        self.downgrade()
2590    }
2591
2592    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
2593    where
2594        Self: Sized,
2595    {
2596        weak.upgrade(cx)
2597    }
2598}
2599
2600pub struct WeakModelHandle<T> {
2601    model_id: usize,
2602    model_type: PhantomData<T>,
2603}
2604
2605unsafe impl<T> Send for WeakModelHandle<T> {}
2606unsafe impl<T> Sync for WeakModelHandle<T> {}
2607
2608impl<T: Entity> WeakModelHandle<T> {
2609    fn new(model_id: usize) -> Self {
2610        Self {
2611            model_id,
2612            model_type: PhantomData,
2613        }
2614    }
2615
2616    pub fn upgrade(self, cx: &impl UpgradeModelHandle) -> Option<ModelHandle<T>> {
2617        cx.upgrade_model_handle(self)
2618    }
2619}
2620
2621impl<T> Hash for WeakModelHandle<T> {
2622    fn hash<H: Hasher>(&self, state: &mut H) {
2623        self.model_id.hash(state)
2624    }
2625}
2626
2627impl<T> PartialEq for WeakModelHandle<T> {
2628    fn eq(&self, other: &Self) -> bool {
2629        self.model_id == other.model_id
2630    }
2631}
2632
2633impl<T> Eq for WeakModelHandle<T> {}
2634
2635impl<T> Clone for WeakModelHandle<T> {
2636    fn clone(&self) -> Self {
2637        Self {
2638            model_id: self.model_id,
2639            model_type: PhantomData,
2640        }
2641    }
2642}
2643
2644impl<T> Copy for WeakModelHandle<T> {}
2645
2646pub struct ViewHandle<T> {
2647    window_id: usize,
2648    view_id: usize,
2649    view_type: PhantomData<T>,
2650    ref_counts: Arc<Mutex<RefCounts>>,
2651}
2652
2653impl<T: View> ViewHandle<T> {
2654    fn new(window_id: usize, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
2655        ref_counts.lock().inc_view(window_id, view_id);
2656        Self {
2657            window_id,
2658            view_id,
2659            view_type: PhantomData,
2660            ref_counts: ref_counts.clone(),
2661        }
2662    }
2663
2664    pub fn downgrade(&self) -> WeakViewHandle<T> {
2665        WeakViewHandle::new(self.window_id, self.view_id)
2666    }
2667
2668    pub fn window_id(&self) -> usize {
2669        self.window_id
2670    }
2671
2672    pub fn id(&self) -> usize {
2673        self.view_id
2674    }
2675
2676    pub fn read<'a, C: ReadView>(&self, cx: &'a C) -> &'a T {
2677        cx.read_view(self)
2678    }
2679
2680    pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> S
2681    where
2682        C: ReadViewWith,
2683        F: FnOnce(&T, &AppContext) -> S,
2684    {
2685        cx.read_view_with(self, read)
2686    }
2687
2688    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
2689    where
2690        C: UpdateView,
2691        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
2692    {
2693        cx.update_view(self, update)
2694    }
2695
2696    pub fn is_focused(&self, cx: &AppContext) -> bool {
2697        cx.focused_view_id(self.window_id)
2698            .map_or(false, |focused_id| focused_id == self.view_id)
2699    }
2700
2701    pub fn condition(
2702        &self,
2703        cx: &TestAppContext,
2704        mut predicate: impl FnMut(&T, &AppContext) -> bool,
2705    ) -> impl Future<Output = ()> {
2706        let (tx, mut rx) = mpsc::channel(1024);
2707
2708        let mut cx = cx.cx.borrow_mut();
2709        let subscriptions = self.update(&mut *cx, |_, cx| {
2710            (
2711                cx.observe(self, {
2712                    let mut tx = tx.clone();
2713                    move |_, _, _| {
2714                        tx.blocking_send(()).ok();
2715                    }
2716                }),
2717                cx.subscribe(self, {
2718                    let mut tx = tx.clone();
2719                    move |_, _, _, _| {
2720                        tx.blocking_send(()).ok();
2721                    }
2722                }),
2723            )
2724        });
2725
2726        let cx = cx.weak_self.as_ref().unwrap().upgrade().unwrap();
2727        let handle = self.downgrade();
2728        let duration = if std::env::var("CI").is_ok() {
2729            Duration::from_secs(2)
2730        } else {
2731            Duration::from_millis(500)
2732        };
2733
2734        async move {
2735            timeout(duration, async move {
2736                loop {
2737                    {
2738                        let cx = cx.borrow();
2739                        let cx = cx.as_ref();
2740                        if predicate(
2741                            handle
2742                                .upgrade(cx)
2743                                .expect("view dropped with pending condition")
2744                                .read(cx),
2745                            cx,
2746                        ) {
2747                            break;
2748                        }
2749                    }
2750
2751                    rx.recv()
2752                        .await
2753                        .expect("view dropped with pending condition");
2754                }
2755            })
2756            .await
2757            .expect("condition timed out");
2758            drop(subscriptions);
2759        }
2760    }
2761}
2762
2763impl<T> Clone for ViewHandle<T> {
2764    fn clone(&self) -> Self {
2765        self.ref_counts
2766            .lock()
2767            .inc_view(self.window_id, self.view_id);
2768        Self {
2769            window_id: self.window_id,
2770            view_id: self.view_id,
2771            view_type: PhantomData,
2772            ref_counts: self.ref_counts.clone(),
2773        }
2774    }
2775}
2776
2777impl<T> PartialEq for ViewHandle<T> {
2778    fn eq(&self, other: &Self) -> bool {
2779        self.window_id == other.window_id && self.view_id == other.view_id
2780    }
2781}
2782
2783impl<T> Eq for ViewHandle<T> {}
2784
2785impl<T> Debug for ViewHandle<T> {
2786    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2787        f.debug_struct(&format!("ViewHandle<{}>", type_name::<T>()))
2788            .field("window_id", &self.window_id)
2789            .field("view_id", &self.view_id)
2790            .finish()
2791    }
2792}
2793
2794impl<T> Drop for ViewHandle<T> {
2795    fn drop(&mut self) {
2796        self.ref_counts
2797            .lock()
2798            .dec_view(self.window_id, self.view_id);
2799    }
2800}
2801
2802impl<T: View> Handle<T> for ViewHandle<T> {
2803    type Weak = WeakViewHandle<T>;
2804
2805    fn id(&self) -> usize {
2806        self.view_id
2807    }
2808
2809    fn location(&self) -> EntityLocation {
2810        EntityLocation::View(self.window_id, self.view_id)
2811    }
2812
2813    fn downgrade(&self) -> Self::Weak {
2814        self.downgrade()
2815    }
2816
2817    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
2818    where
2819        Self: Sized,
2820    {
2821        weak.upgrade(cx)
2822    }
2823}
2824
2825pub struct AnyViewHandle {
2826    window_id: usize,
2827    view_id: usize,
2828    view_type: TypeId,
2829    ref_counts: Arc<Mutex<RefCounts>>,
2830}
2831
2832impl AnyViewHandle {
2833    pub fn id(&self) -> usize {
2834        self.view_id
2835    }
2836
2837    pub fn is<T: 'static>(&self) -> bool {
2838        TypeId::of::<T>() == self.view_type
2839    }
2840
2841    pub fn downcast<T: View>(self) -> Option<ViewHandle<T>> {
2842        if self.is::<T>() {
2843            let result = Some(ViewHandle {
2844                window_id: self.window_id,
2845                view_id: self.view_id,
2846                ref_counts: self.ref_counts.clone(),
2847                view_type: PhantomData,
2848            });
2849            unsafe {
2850                Arc::decrement_strong_count(&self.ref_counts);
2851            }
2852            std::mem::forget(self);
2853            result
2854        } else {
2855            None
2856        }
2857    }
2858}
2859
2860impl Clone for AnyViewHandle {
2861    fn clone(&self) -> Self {
2862        self.ref_counts
2863            .lock()
2864            .inc_view(self.window_id, self.view_id);
2865        Self {
2866            window_id: self.window_id,
2867            view_id: self.view_id,
2868            view_type: self.view_type,
2869            ref_counts: self.ref_counts.clone(),
2870        }
2871    }
2872}
2873
2874impl From<&AnyViewHandle> for AnyViewHandle {
2875    fn from(handle: &AnyViewHandle) -> Self {
2876        handle.clone()
2877    }
2878}
2879
2880impl<T: View> From<&ViewHandle<T>> for AnyViewHandle {
2881    fn from(handle: &ViewHandle<T>) -> Self {
2882        handle
2883            .ref_counts
2884            .lock()
2885            .inc_view(handle.window_id, handle.view_id);
2886        AnyViewHandle {
2887            window_id: handle.window_id,
2888            view_id: handle.view_id,
2889            view_type: TypeId::of::<T>(),
2890            ref_counts: handle.ref_counts.clone(),
2891        }
2892    }
2893}
2894
2895impl<T: View> From<ViewHandle<T>> for AnyViewHandle {
2896    fn from(handle: ViewHandle<T>) -> Self {
2897        let any_handle = AnyViewHandle {
2898            window_id: handle.window_id,
2899            view_id: handle.view_id,
2900            view_type: TypeId::of::<T>(),
2901            ref_counts: handle.ref_counts.clone(),
2902        };
2903        unsafe {
2904            Arc::decrement_strong_count(&handle.ref_counts);
2905        }
2906        std::mem::forget(handle);
2907        any_handle
2908    }
2909}
2910
2911impl Drop for AnyViewHandle {
2912    fn drop(&mut self) {
2913        self.ref_counts
2914            .lock()
2915            .dec_view(self.window_id, self.view_id);
2916    }
2917}
2918
2919pub struct AnyModelHandle {
2920    model_id: usize,
2921    ref_counts: Arc<Mutex<RefCounts>>,
2922}
2923
2924impl<T: Entity> From<ModelHandle<T>> for AnyModelHandle {
2925    fn from(handle: ModelHandle<T>) -> Self {
2926        handle.ref_counts.lock().inc_model(handle.model_id);
2927        Self {
2928            model_id: handle.model_id,
2929            ref_counts: handle.ref_counts.clone(),
2930        }
2931    }
2932}
2933
2934impl Drop for AnyModelHandle {
2935    fn drop(&mut self) {
2936        self.ref_counts.lock().dec_model(self.model_id);
2937    }
2938}
2939pub struct WeakViewHandle<T> {
2940    window_id: usize,
2941    view_id: usize,
2942    view_type: PhantomData<T>,
2943}
2944
2945impl<T: View> WeakViewHandle<T> {
2946    fn new(window_id: usize, view_id: usize) -> Self {
2947        Self {
2948            window_id,
2949            view_id,
2950            view_type: PhantomData,
2951        }
2952    }
2953
2954    pub fn upgrade(&self, cx: &AppContext) -> Option<ViewHandle<T>> {
2955        if cx.ref_counts.lock().is_entity_alive(self.view_id) {
2956            Some(ViewHandle::new(
2957                self.window_id,
2958                self.view_id,
2959                &cx.ref_counts,
2960            ))
2961        } else {
2962            None
2963        }
2964    }
2965}
2966
2967impl<T> Clone for WeakViewHandle<T> {
2968    fn clone(&self) -> Self {
2969        Self {
2970            window_id: self.window_id,
2971            view_id: self.view_id,
2972            view_type: PhantomData,
2973        }
2974    }
2975}
2976
2977pub struct ElementStateHandle<T> {
2978    value_type: PhantomData<T>,
2979    tag_type_id: TypeId,
2980    id: usize,
2981    ref_counts: Weak<Mutex<RefCounts>>,
2982}
2983
2984impl<T: 'static> ElementStateHandle<T> {
2985    fn new(tag_type_id: TypeId, id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
2986        ref_counts.lock().inc_element_state(tag_type_id, id);
2987        Self {
2988            value_type: PhantomData,
2989            tag_type_id,
2990            id,
2991            ref_counts: Arc::downgrade(ref_counts),
2992        }
2993    }
2994
2995    pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
2996        cx.element_states
2997            .get(&(self.tag_type_id, self.id))
2998            .unwrap()
2999            .downcast_ref()
3000            .unwrap()
3001    }
3002
3003    pub fn update<C, R>(&self, cx: &mut C, f: impl FnOnce(&mut T, &mut C) -> R) -> R
3004    where
3005        C: DerefMut<Target = MutableAppContext>,
3006    {
3007        let mut element_state = cx
3008            .deref_mut()
3009            .cx
3010            .element_states
3011            .remove(&(self.tag_type_id, self.id))
3012            .unwrap();
3013        let result = f(element_state.downcast_mut().unwrap(), cx);
3014        cx.deref_mut()
3015            .cx
3016            .element_states
3017            .insert((self.tag_type_id, self.id), element_state);
3018        result
3019    }
3020}
3021
3022impl<T> Drop for ElementStateHandle<T> {
3023    fn drop(&mut self) {
3024        if let Some(ref_counts) = self.ref_counts.upgrade() {
3025            ref_counts
3026                .lock()
3027                .dec_element_state(self.tag_type_id, self.id);
3028        }
3029    }
3030}
3031
3032#[must_use]
3033pub enum Subscription {
3034    Subscription {
3035        id: usize,
3036        entity_id: usize,
3037        subscriptions: Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, SubscriptionCallback>>>>>,
3038    },
3039    Observation {
3040        id: usize,
3041        entity_id: usize,
3042        observations: Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, ObservationCallback>>>>>,
3043    },
3044}
3045
3046impl Subscription {
3047    pub fn detach(&mut self) {
3048        match self {
3049            Subscription::Subscription { subscriptions, .. } => {
3050                subscriptions.take();
3051            }
3052            Subscription::Observation { observations, .. } => {
3053                observations.take();
3054            }
3055        }
3056    }
3057}
3058
3059impl Drop for Subscription {
3060    fn drop(&mut self) {
3061        match self {
3062            Subscription::Observation {
3063                id,
3064                entity_id,
3065                observations,
3066            } => {
3067                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
3068                    if let Some(observations) = observations.lock().get_mut(entity_id) {
3069                        observations.remove(id);
3070                    }
3071                }
3072            }
3073            Subscription::Subscription {
3074                id,
3075                entity_id,
3076                subscriptions,
3077            } => {
3078                if let Some(subscriptions) = subscriptions.as_ref().and_then(Weak::upgrade) {
3079                    if let Some(subscriptions) = subscriptions.lock().get_mut(entity_id) {
3080                        subscriptions.remove(id);
3081                    }
3082                }
3083            }
3084        }
3085    }
3086}
3087
3088#[derive(Default)]
3089struct RefCounts {
3090    entity_counts: HashMap<usize, usize>,
3091    element_state_counts: HashMap<(TypeId, usize), usize>,
3092    dropped_models: HashSet<usize>,
3093    dropped_views: HashSet<(usize, usize)>,
3094    dropped_element_states: HashSet<(TypeId, usize)>,
3095}
3096
3097impl RefCounts {
3098    fn inc_model(&mut self, model_id: usize) {
3099        match self.entity_counts.entry(model_id) {
3100            Entry::Occupied(mut entry) => *entry.get_mut() += 1,
3101            Entry::Vacant(entry) => {
3102                entry.insert(1);
3103                self.dropped_models.remove(&model_id);
3104            }
3105        }
3106    }
3107
3108    fn inc_view(&mut self, window_id: usize, view_id: usize) {
3109        match self.entity_counts.entry(view_id) {
3110            Entry::Occupied(mut entry) => *entry.get_mut() += 1,
3111            Entry::Vacant(entry) => {
3112                entry.insert(1);
3113                self.dropped_views.remove(&(window_id, view_id));
3114            }
3115        }
3116    }
3117
3118    fn inc_element_state(&mut self, tag_type_id: TypeId, id: usize) {
3119        *self
3120            .element_state_counts
3121            .entry((tag_type_id, id))
3122            .or_insert(0) += 1;
3123    }
3124
3125    fn dec_model(&mut self, model_id: usize) {
3126        let count = self.entity_counts.get_mut(&model_id).unwrap();
3127        *count -= 1;
3128        if *count == 0 {
3129            self.entity_counts.remove(&model_id);
3130            self.dropped_models.insert(model_id);
3131        }
3132    }
3133
3134    fn dec_view(&mut self, window_id: usize, view_id: usize) {
3135        let count = self.entity_counts.get_mut(&view_id).unwrap();
3136        *count -= 1;
3137        if *count == 0 {
3138            self.entity_counts.remove(&view_id);
3139            self.dropped_views.insert((window_id, view_id));
3140        }
3141    }
3142
3143    fn dec_element_state(&mut self, tag_type_id: TypeId, id: usize) {
3144        let key = (tag_type_id, id);
3145        let count = self.element_state_counts.get_mut(&key).unwrap();
3146        *count -= 1;
3147        if *count == 0 {
3148            self.element_state_counts.remove(&key);
3149            self.dropped_element_states.insert(key);
3150        }
3151    }
3152
3153    fn is_entity_alive(&self, entity_id: usize) -> bool {
3154        self.entity_counts.contains_key(&entity_id)
3155    }
3156
3157    fn take_dropped(
3158        &mut self,
3159    ) -> (
3160        HashSet<usize>,
3161        HashSet<(usize, usize)>,
3162        HashSet<(TypeId, usize)>,
3163    ) {
3164        let mut dropped_models = HashSet::new();
3165        let mut dropped_views = HashSet::new();
3166        let mut dropped_element_states = HashSet::new();
3167        std::mem::swap(&mut self.dropped_models, &mut dropped_models);
3168        std::mem::swap(&mut self.dropped_views, &mut dropped_views);
3169        std::mem::swap(
3170            &mut self.dropped_element_states,
3171            &mut dropped_element_states,
3172        );
3173        (dropped_models, dropped_views, dropped_element_states)
3174    }
3175}
3176
3177#[cfg(test)]
3178mod tests {
3179    use super::*;
3180    use crate::elements::*;
3181    use smol::future::poll_once;
3182    use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
3183
3184    #[crate::test(self)]
3185    fn test_model_handles(cx: &mut MutableAppContext) {
3186        struct Model {
3187            other: Option<ModelHandle<Model>>,
3188            events: Vec<String>,
3189        }
3190
3191        impl Entity for Model {
3192            type Event = usize;
3193        }
3194
3195        impl Model {
3196            fn new(other: Option<ModelHandle<Self>>, cx: &mut ModelContext<Self>) -> Self {
3197                if let Some(other) = other.as_ref() {
3198                    cx.observe(other, |me, _, _| {
3199                        me.events.push("notified".into());
3200                    })
3201                    .detach();
3202                    cx.subscribe(other, |me, _, event, _| {
3203                        me.events.push(format!("observed event {}", event));
3204                    })
3205                    .detach();
3206                }
3207
3208                Self {
3209                    other,
3210                    events: Vec::new(),
3211                }
3212            }
3213        }
3214
3215        let handle_1 = cx.add_model(|cx| Model::new(None, cx));
3216        let handle_2 = cx.add_model(|cx| Model::new(Some(handle_1.clone()), cx));
3217        assert_eq!(cx.cx.models.len(), 2);
3218
3219        handle_1.update(cx, |model, cx| {
3220            model.events.push("updated".into());
3221            cx.emit(1);
3222            cx.notify();
3223            cx.emit(2);
3224        });
3225        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
3226        assert_eq!(
3227            handle_2.read(cx).events,
3228            vec![
3229                "observed event 1".to_string(),
3230                "notified".to_string(),
3231                "observed event 2".to_string(),
3232            ]
3233        );
3234
3235        handle_2.update(cx, |model, _| {
3236            drop(handle_1);
3237            model.other.take();
3238        });
3239
3240        assert_eq!(cx.cx.models.len(), 1);
3241        assert!(cx.subscriptions.lock().is_empty());
3242        assert!(cx.observations.lock().is_empty());
3243    }
3244
3245    #[crate::test(self)]
3246    fn test_subscribe_and_emit_from_model(cx: &mut MutableAppContext) {
3247        #[derive(Default)]
3248        struct Model {
3249            events: Vec<usize>,
3250        }
3251
3252        impl Entity for Model {
3253            type Event = usize;
3254        }
3255
3256        let handle_1 = cx.add_model(|_| Model::default());
3257        let handle_2 = cx.add_model(|_| Model::default());
3258        let handle_2b = handle_2.clone();
3259
3260        handle_1.update(cx, |_, c| {
3261            c.subscribe(&handle_2, move |model: &mut Model, _, event, c| {
3262                model.events.push(*event);
3263
3264                c.subscribe(&handle_2b, |model, _, event, _| {
3265                    model.events.push(*event * 2);
3266                })
3267                .detach();
3268            })
3269            .detach();
3270        });
3271
3272        handle_2.update(cx, |_, c| c.emit(7));
3273        assert_eq!(handle_1.read(cx).events, vec![7]);
3274
3275        handle_2.update(cx, |_, c| c.emit(5));
3276        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
3277    }
3278
3279    #[crate::test(self)]
3280    fn test_observe_and_notify_from_model(cx: &mut MutableAppContext) {
3281        #[derive(Default)]
3282        struct Model {
3283            count: usize,
3284            events: Vec<usize>,
3285        }
3286
3287        impl Entity for Model {
3288            type Event = ();
3289        }
3290
3291        let handle_1 = cx.add_model(|_| Model::default());
3292        let handle_2 = cx.add_model(|_| Model::default());
3293        let handle_2b = handle_2.clone();
3294
3295        handle_1.update(cx, |_, c| {
3296            c.observe(&handle_2, move |model, observed, c| {
3297                model.events.push(observed.read(c).count);
3298                c.observe(&handle_2b, |model, observed, c| {
3299                    model.events.push(observed.read(c).count * 2);
3300                })
3301                .detach();
3302            })
3303            .detach();
3304        });
3305
3306        handle_2.update(cx, |model, c| {
3307            model.count = 7;
3308            c.notify()
3309        });
3310        assert_eq!(handle_1.read(cx).events, vec![7]);
3311
3312        handle_2.update(cx, |model, c| {
3313            model.count = 5;
3314            c.notify()
3315        });
3316        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10])
3317    }
3318
3319    #[crate::test(self)]
3320    fn test_view_handles(cx: &mut MutableAppContext) {
3321        struct View {
3322            other: Option<ViewHandle<View>>,
3323            events: Vec<String>,
3324        }
3325
3326        impl Entity for View {
3327            type Event = usize;
3328        }
3329
3330        impl super::View for View {
3331            fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
3332                Empty::new().boxed()
3333            }
3334
3335            fn ui_name() -> &'static str {
3336                "View"
3337            }
3338        }
3339
3340        impl View {
3341            fn new(other: Option<ViewHandle<View>>, cx: &mut ViewContext<Self>) -> Self {
3342                if let Some(other) = other.as_ref() {
3343                    cx.subscribe(other, |me, _, event, _| {
3344                        me.events.push(format!("observed event {}", event));
3345                    })
3346                    .detach();
3347                }
3348                Self {
3349                    other,
3350                    events: Vec::new(),
3351                }
3352            }
3353        }
3354
3355        let (window_id, _) = cx.add_window(Default::default(), |cx| View::new(None, cx));
3356        let handle_1 = cx.add_view(window_id, |cx| View::new(None, cx));
3357        let handle_2 = cx.add_view(window_id, |cx| View::new(Some(handle_1.clone()), cx));
3358        assert_eq!(cx.cx.views.len(), 3);
3359
3360        handle_1.update(cx, |view, cx| {
3361            view.events.push("updated".into());
3362            cx.emit(1);
3363            cx.emit(2);
3364        });
3365        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
3366        assert_eq!(
3367            handle_2.read(cx).events,
3368            vec![
3369                "observed event 1".to_string(),
3370                "observed event 2".to_string(),
3371            ]
3372        );
3373
3374        handle_2.update(cx, |view, _| {
3375            drop(handle_1);
3376            view.other.take();
3377        });
3378
3379        assert_eq!(cx.cx.views.len(), 2);
3380        assert!(cx.subscriptions.lock().is_empty());
3381        assert!(cx.observations.lock().is_empty());
3382    }
3383
3384    #[crate::test(self)]
3385    fn test_add_window(cx: &mut MutableAppContext) {
3386        struct View {
3387            mouse_down_count: Arc<AtomicUsize>,
3388        }
3389
3390        impl Entity for View {
3391            type Event = ();
3392        }
3393
3394        impl super::View for View {
3395            fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
3396                let mouse_down_count = self.mouse_down_count.clone();
3397                EventHandler::new(Empty::new().boxed())
3398                    .on_mouse_down(move |_| {
3399                        mouse_down_count.fetch_add(1, SeqCst);
3400                        true
3401                    })
3402                    .boxed()
3403            }
3404
3405            fn ui_name() -> &'static str {
3406                "View"
3407            }
3408        }
3409
3410        let mouse_down_count = Arc::new(AtomicUsize::new(0));
3411        let (window_id, _) = cx.add_window(Default::default(), |_| View {
3412            mouse_down_count: mouse_down_count.clone(),
3413        });
3414        let presenter = cx.presenters_and_platform_windows[&window_id].0.clone();
3415        // Ensure window's root element is in a valid lifecycle state.
3416        presenter.borrow_mut().dispatch_event(
3417            Event::LeftMouseDown {
3418                position: Default::default(),
3419                cmd: false,
3420            },
3421            cx,
3422        );
3423        assert_eq!(mouse_down_count.load(SeqCst), 1);
3424    }
3425
3426    #[crate::test(self)]
3427    fn test_entity_release_hooks(cx: &mut MutableAppContext) {
3428        struct Model {
3429            released: Arc<Mutex<bool>>,
3430        }
3431
3432        struct View {
3433            released: Arc<Mutex<bool>>,
3434        }
3435
3436        impl Entity for Model {
3437            type Event = ();
3438
3439            fn release(&mut self, _: &mut MutableAppContext) {
3440                *self.released.lock() = true;
3441            }
3442        }
3443
3444        impl Entity for View {
3445            type Event = ();
3446
3447            fn release(&mut self, _: &mut MutableAppContext) {
3448                *self.released.lock() = true;
3449            }
3450        }
3451
3452        impl super::View for View {
3453            fn ui_name() -> &'static str {
3454                "View"
3455            }
3456
3457            fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
3458                Empty::new().boxed()
3459            }
3460        }
3461
3462        let model_released = Arc::new(Mutex::new(false));
3463        let view_released = Arc::new(Mutex::new(false));
3464
3465        let model = cx.add_model(|_| Model {
3466            released: model_released.clone(),
3467        });
3468
3469        let (window_id, _) = cx.add_window(Default::default(), |_| View {
3470            released: view_released.clone(),
3471        });
3472
3473        assert!(!*model_released.lock());
3474        assert!(!*view_released.lock());
3475
3476        cx.update(move || {
3477            drop(model);
3478        });
3479        assert!(*model_released.lock());
3480
3481        drop(cx.remove_window(window_id));
3482        assert!(*view_released.lock());
3483    }
3484
3485    #[crate::test(self)]
3486    fn test_subscribe_and_emit_from_view(cx: &mut MutableAppContext) {
3487        #[derive(Default)]
3488        struct View {
3489            events: Vec<usize>,
3490        }
3491
3492        impl Entity for View {
3493            type Event = usize;
3494        }
3495
3496        impl super::View for View {
3497            fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
3498                Empty::new().boxed()
3499            }
3500
3501            fn ui_name() -> &'static str {
3502                "View"
3503            }
3504        }
3505
3506        struct Model;
3507
3508        impl Entity for Model {
3509            type Event = usize;
3510        }
3511
3512        let (window_id, handle_1) = cx.add_window(Default::default(), |_| View::default());
3513        let handle_2 = cx.add_view(window_id, |_| View::default());
3514        let handle_2b = handle_2.clone();
3515        let handle_3 = cx.add_model(|_| Model);
3516
3517        handle_1.update(cx, |_, c| {
3518            c.subscribe(&handle_2, move |me, _, event, c| {
3519                me.events.push(*event);
3520
3521                c.subscribe(&handle_2b, |me, _, event, _| {
3522                    me.events.push(*event * 2);
3523                })
3524                .detach();
3525            })
3526            .detach();
3527
3528            c.subscribe(&handle_3, |me, _, event, _| {
3529                me.events.push(*event);
3530            })
3531            .detach();
3532        });
3533
3534        handle_2.update(cx, |_, c| c.emit(7));
3535        assert_eq!(handle_1.read(cx).events, vec![7]);
3536
3537        handle_2.update(cx, |_, c| c.emit(5));
3538        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
3539
3540        handle_3.update(cx, |_, c| c.emit(9));
3541        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10, 9]);
3542    }
3543
3544    #[crate::test(self)]
3545    fn test_dropping_subscribers(cx: &mut MutableAppContext) {
3546        struct View;
3547
3548        impl Entity for View {
3549            type Event = ();
3550        }
3551
3552        impl super::View for View {
3553            fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
3554                Empty::new().boxed()
3555            }
3556
3557            fn ui_name() -> &'static str {
3558                "View"
3559            }
3560        }
3561
3562        struct Model;
3563
3564        impl Entity for Model {
3565            type Event = ();
3566        }
3567
3568        let (window_id, _) = cx.add_window(Default::default(), |_| View);
3569        let observing_view = cx.add_view(window_id, |_| View);
3570        let emitting_view = cx.add_view(window_id, |_| View);
3571        let observing_model = cx.add_model(|_| Model);
3572        let observed_model = cx.add_model(|_| Model);
3573
3574        observing_view.update(cx, |_, cx| {
3575            cx.subscribe(&emitting_view, |_, _, _, _| {}).detach();
3576            cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
3577        });
3578        observing_model.update(cx, |_, cx| {
3579            cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
3580        });
3581
3582        cx.update(|| {
3583            drop(observing_view);
3584            drop(observing_model);
3585        });
3586
3587        emitting_view.update(cx, |_, cx| cx.emit(()));
3588        observed_model.update(cx, |_, cx| cx.emit(()));
3589    }
3590
3591    #[crate::test(self)]
3592    fn test_observe_and_notify_from_view(cx: &mut MutableAppContext) {
3593        #[derive(Default)]
3594        struct View {
3595            events: Vec<usize>,
3596        }
3597
3598        impl Entity for View {
3599            type Event = usize;
3600        }
3601
3602        impl super::View for View {
3603            fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
3604                Empty::new().boxed()
3605            }
3606
3607            fn ui_name() -> &'static str {
3608                "View"
3609            }
3610        }
3611
3612        #[derive(Default)]
3613        struct Model {
3614            count: usize,
3615        }
3616
3617        impl Entity for Model {
3618            type Event = ();
3619        }
3620
3621        let (_, view) = cx.add_window(Default::default(), |_| View::default());
3622        let model = cx.add_model(|_| Model::default());
3623
3624        view.update(cx, |_, c| {
3625            c.observe(&model, |me, observed, c| {
3626                me.events.push(observed.read(c).count)
3627            })
3628            .detach();
3629        });
3630
3631        model.update(cx, |model, c| {
3632            model.count = 11;
3633            c.notify();
3634        });
3635        assert_eq!(view.read(cx).events, vec![11]);
3636    }
3637
3638    #[crate::test(self)]
3639    fn test_dropping_observers(cx: &mut MutableAppContext) {
3640        struct View;
3641
3642        impl Entity for View {
3643            type Event = ();
3644        }
3645
3646        impl super::View for View {
3647            fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
3648                Empty::new().boxed()
3649            }
3650
3651            fn ui_name() -> &'static str {
3652                "View"
3653            }
3654        }
3655
3656        struct Model;
3657
3658        impl Entity for Model {
3659            type Event = ();
3660        }
3661
3662        let (window_id, _) = cx.add_window(Default::default(), |_| View);
3663        let observing_view = cx.add_view(window_id, |_| View);
3664        let observing_model = cx.add_model(|_| Model);
3665        let observed_model = cx.add_model(|_| Model);
3666
3667        observing_view.update(cx, |_, cx| {
3668            cx.observe(&observed_model, |_, _, _| {}).detach();
3669        });
3670        observing_model.update(cx, |_, cx| {
3671            cx.observe(&observed_model, |_, _, _| {}).detach();
3672        });
3673
3674        cx.update(|| {
3675            drop(observing_view);
3676            drop(observing_model);
3677        });
3678
3679        observed_model.update(cx, |_, cx| cx.notify());
3680    }
3681
3682    #[crate::test(self)]
3683    fn test_focus(cx: &mut MutableAppContext) {
3684        struct View {
3685            name: String,
3686            events: Arc<Mutex<Vec<String>>>,
3687        }
3688
3689        impl Entity for View {
3690            type Event = ();
3691        }
3692
3693        impl super::View for View {
3694            fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
3695                Empty::new().boxed()
3696            }
3697
3698            fn ui_name() -> &'static str {
3699                "View"
3700            }
3701
3702            fn on_focus(&mut self, _: &mut ViewContext<Self>) {
3703                self.events.lock().push(format!("{} focused", &self.name));
3704            }
3705
3706            fn on_blur(&mut self, _: &mut ViewContext<Self>) {
3707                self.events.lock().push(format!("{} blurred", &self.name));
3708            }
3709        }
3710
3711        let events: Arc<Mutex<Vec<String>>> = Default::default();
3712        let (window_id, view_1) = cx.add_window(Default::default(), |_| View {
3713            events: events.clone(),
3714            name: "view 1".to_string(),
3715        });
3716        let view_2 = cx.add_view(window_id, |_| View {
3717            events: events.clone(),
3718            name: "view 2".to_string(),
3719        });
3720
3721        view_1.update(cx, |_, cx| cx.focus(&view_2));
3722        view_1.update(cx, |_, cx| cx.focus(&view_1));
3723        view_1.update(cx, |_, cx| cx.focus(&view_2));
3724        view_1.update(cx, |_, _| drop(view_2));
3725
3726        assert_eq!(
3727            *events.lock(),
3728            [
3729                "view 1 focused".to_string(),
3730                "view 1 blurred".to_string(),
3731                "view 2 focused".to_string(),
3732                "view 2 blurred".to_string(),
3733                "view 1 focused".to_string(),
3734                "view 1 blurred".to_string(),
3735                "view 2 focused".to_string(),
3736                "view 1 focused".to_string(),
3737            ],
3738        );
3739    }
3740
3741    #[crate::test(self)]
3742    fn test_dispatch_action(cx: &mut MutableAppContext) {
3743        struct ViewA {
3744            id: usize,
3745        }
3746
3747        impl Entity for ViewA {
3748            type Event = ();
3749        }
3750
3751        impl View for ViewA {
3752            fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
3753                Empty::new().boxed()
3754            }
3755
3756            fn ui_name() -> &'static str {
3757                "View"
3758            }
3759        }
3760
3761        struct ViewB {
3762            id: usize,
3763        }
3764
3765        impl Entity for ViewB {
3766            type Event = ();
3767        }
3768
3769        impl View for ViewB {
3770            fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
3771                Empty::new().boxed()
3772            }
3773
3774            fn ui_name() -> &'static str {
3775                "View"
3776            }
3777        }
3778
3779        action!(Action, &'static str);
3780
3781        let actions = Rc::new(RefCell::new(Vec::new()));
3782
3783        let actions_clone = actions.clone();
3784        cx.add_global_action(move |_: &Action, _: &mut MutableAppContext| {
3785            actions_clone.borrow_mut().push("global a".to_string());
3786        });
3787
3788        let actions_clone = actions.clone();
3789        cx.add_global_action(move |_: &Action, _: &mut MutableAppContext| {
3790            actions_clone.borrow_mut().push("global b".to_string());
3791        });
3792
3793        let actions_clone = actions.clone();
3794        cx.add_action(move |view: &mut ViewA, action: &Action, cx| {
3795            assert_eq!(action.0, "bar");
3796            cx.propagate_action();
3797            actions_clone.borrow_mut().push(format!("{} a", view.id));
3798        });
3799
3800        let actions_clone = actions.clone();
3801        cx.add_action(move |view: &mut ViewA, _: &Action, cx| {
3802            if view.id != 1 {
3803                cx.propagate_action();
3804            }
3805            actions_clone.borrow_mut().push(format!("{} b", view.id));
3806        });
3807
3808        let actions_clone = actions.clone();
3809        cx.add_action(move |view: &mut ViewB, _: &Action, cx| {
3810            cx.propagate_action();
3811            actions_clone.borrow_mut().push(format!("{} c", view.id));
3812        });
3813
3814        let actions_clone = actions.clone();
3815        cx.add_action(move |view: &mut ViewB, _: &Action, cx| {
3816            cx.propagate_action();
3817            actions_clone.borrow_mut().push(format!("{} d", view.id));
3818        });
3819
3820        let (window_id, view_1) = cx.add_window(Default::default(), |_| ViewA { id: 1 });
3821        let view_2 = cx.add_view(window_id, |_| ViewB { id: 2 });
3822        let view_3 = cx.add_view(window_id, |_| ViewA { id: 3 });
3823        let view_4 = cx.add_view(window_id, |_| ViewB { id: 4 });
3824
3825        cx.dispatch_action(
3826            window_id,
3827            vec![view_1.id(), view_2.id(), view_3.id(), view_4.id()],
3828            &Action("bar"),
3829        );
3830
3831        assert_eq!(
3832            *actions.borrow(),
3833            vec!["4 d", "4 c", "3 b", "3 a", "2 d", "2 c", "1 b"]
3834        );
3835
3836        // Remove view_1, which doesn't propagate the action
3837        actions.borrow_mut().clear();
3838        cx.dispatch_action(
3839            window_id,
3840            vec![view_2.id(), view_3.id(), view_4.id()],
3841            &Action("bar"),
3842        );
3843
3844        assert_eq!(
3845            *actions.borrow(),
3846            vec!["4 d", "4 c", "3 b", "3 a", "2 d", "2 c", "global b", "global a"]
3847        );
3848    }
3849
3850    #[crate::test(self)]
3851    fn test_dispatch_keystroke(cx: &mut MutableAppContext) {
3852        use std::cell::Cell;
3853
3854        action!(Action, &'static str);
3855
3856        struct View {
3857            id: usize,
3858            keymap_context: keymap::Context,
3859        }
3860
3861        impl Entity for View {
3862            type Event = ();
3863        }
3864
3865        impl super::View for View {
3866            fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
3867                Empty::new().boxed()
3868            }
3869
3870            fn ui_name() -> &'static str {
3871                "View"
3872            }
3873
3874            fn keymap_context(&self, _: &AppContext) -> keymap::Context {
3875                self.keymap_context.clone()
3876            }
3877        }
3878
3879        impl View {
3880            fn new(id: usize) -> Self {
3881                View {
3882                    id,
3883                    keymap_context: keymap::Context::default(),
3884                }
3885            }
3886        }
3887
3888        let mut view_1 = View::new(1);
3889        let mut view_2 = View::new(2);
3890        let mut view_3 = View::new(3);
3891        view_1.keymap_context.set.insert("a".into());
3892        view_2.keymap_context.set.insert("b".into());
3893        view_3.keymap_context.set.insert("c".into());
3894
3895        let (window_id, view_1) = cx.add_window(Default::default(), |_| view_1);
3896        let view_2 = cx.add_view(window_id, |_| view_2);
3897        let view_3 = cx.add_view(window_id, |_| view_3);
3898
3899        // This keymap's only binding dispatches an action on view 2 because that view will have
3900        // "a" and "b" in its context, but not "c".
3901        cx.add_bindings(vec![keymap::Binding::new(
3902            "a",
3903            Action("a"),
3904            Some("a && b && !c"),
3905        )]);
3906
3907        let handled_action = Rc::new(Cell::new(false));
3908        let handled_action_clone = handled_action.clone();
3909        cx.add_action(move |view: &mut View, action: &Action, _| {
3910            handled_action_clone.set(true);
3911            assert_eq!(view.id, 2);
3912            assert_eq!(action.0, "a");
3913        });
3914
3915        cx.dispatch_keystroke(
3916            window_id,
3917            vec![view_1.id(), view_2.id(), view_3.id()],
3918            &Keystroke::parse("a").unwrap(),
3919        )
3920        .unwrap();
3921
3922        assert!(handled_action.get());
3923    }
3924
3925    #[crate::test(self)]
3926    async fn test_model_condition(mut cx: TestAppContext) {
3927        struct Counter(usize);
3928
3929        impl super::Entity for Counter {
3930            type Event = ();
3931        }
3932
3933        impl Counter {
3934            fn inc(&mut self, cx: &mut ModelContext<Self>) {
3935                self.0 += 1;
3936                cx.notify();
3937            }
3938        }
3939
3940        let model = cx.add_model(|_| Counter(0));
3941
3942        let condition1 = model.condition(&cx, |model, _| model.0 == 2);
3943        let condition2 = model.condition(&cx, |model, _| model.0 == 3);
3944        smol::pin!(condition1, condition2);
3945
3946        model.update(&mut cx, |model, cx| model.inc(cx));
3947        assert_eq!(poll_once(&mut condition1).await, None);
3948        assert_eq!(poll_once(&mut condition2).await, None);
3949
3950        model.update(&mut cx, |model, cx| model.inc(cx));
3951        assert_eq!(poll_once(&mut condition1).await, Some(()));
3952        assert_eq!(poll_once(&mut condition2).await, None);
3953
3954        model.update(&mut cx, |model, cx| model.inc(cx));
3955        assert_eq!(poll_once(&mut condition2).await, Some(()));
3956
3957        model.update(&mut cx, |_, cx| cx.notify());
3958    }
3959
3960    #[crate::test(self)]
3961    #[should_panic]
3962    async fn test_model_condition_timeout(mut cx: TestAppContext) {
3963        struct Model;
3964
3965        impl super::Entity for Model {
3966            type Event = ();
3967        }
3968
3969        let model = cx.add_model(|_| Model);
3970        model.condition(&cx, |_, _| false).await;
3971    }
3972
3973    #[crate::test(self)]
3974    #[should_panic(expected = "model dropped with pending condition")]
3975    async fn test_model_condition_panic_on_drop(mut cx: TestAppContext) {
3976        struct Model;
3977
3978        impl super::Entity for Model {
3979            type Event = ();
3980        }
3981
3982        let model = cx.add_model(|_| Model);
3983        let condition = model.condition(&cx, |_, _| false);
3984        cx.update(|_| drop(model));
3985        condition.await;
3986    }
3987
3988    #[crate::test(self)]
3989    async fn test_view_condition(mut cx: TestAppContext) {
3990        struct Counter(usize);
3991
3992        impl super::Entity for Counter {
3993            type Event = ();
3994        }
3995
3996        impl super::View for Counter {
3997            fn ui_name() -> &'static str {
3998                "test view"
3999            }
4000
4001            fn render(&self, _: &mut RenderContext<Self>) -> ElementBox {
4002                Empty::new().boxed()
4003            }
4004        }
4005
4006        impl Counter {
4007            fn inc(&mut self, cx: &mut ViewContext<Self>) {
4008                self.0 += 1;
4009                cx.notify();
4010            }
4011        }
4012
4013        let (_, view) = cx.add_window(|_| Counter(0));
4014
4015        let condition1 = view.condition(&cx, |view, _| view.0 == 2);
4016        let condition2 = view.condition(&cx, |view, _| view.0 == 3);
4017        smol::pin!(condition1, condition2);
4018
4019        view.update(&mut cx, |view, cx| view.inc(cx));
4020        assert_eq!(poll_once(&mut condition1).await, None);
4021        assert_eq!(poll_once(&mut condition2).await, None);
4022
4023        view.update(&mut cx, |view, cx| view.inc(cx));
4024        assert_eq!(poll_once(&mut condition1).await, Some(()));
4025        assert_eq!(poll_once(&mut condition2).await, None);
4026
4027        view.update(&mut cx, |view, cx| view.inc(cx));
4028        assert_eq!(poll_once(&mut condition2).await, Some(()));
4029        view.update(&mut cx, |_, cx| cx.notify());
4030    }
4031
4032    #[crate::test(self)]
4033    #[should_panic]
4034    async fn test_view_condition_timeout(mut cx: TestAppContext) {
4035        struct View;
4036
4037        impl super::Entity for View {
4038            type Event = ();
4039        }
4040
4041        impl super::View for View {
4042            fn ui_name() -> &'static str {
4043                "test view"
4044            }
4045
4046            fn render(&self, _: &mut RenderContext<Self>) -> ElementBox {
4047                Empty::new().boxed()
4048            }
4049        }
4050
4051        let (_, view) = cx.add_window(|_| View);
4052        view.condition(&cx, |_, _| false).await;
4053    }
4054
4055    #[crate::test(self)]
4056    #[should_panic(expected = "view dropped with pending condition")]
4057    async fn test_view_condition_panic_on_drop(mut cx: TestAppContext) {
4058        struct View;
4059
4060        impl super::Entity for View {
4061            type Event = ();
4062        }
4063
4064        impl super::View for View {
4065            fn ui_name() -> &'static str {
4066                "test view"
4067            }
4068
4069            fn render(&self, _: &mut RenderContext<Self>) -> ElementBox {
4070                Empty::new().boxed()
4071            }
4072        }
4073
4074        let window_id = cx.add_window(|_| View).0;
4075        let view = cx.add_view(window_id, |_| View);
4076
4077        let condition = view.condition(&cx, |_, _| false);
4078        cx.update(|_| drop(view));
4079        condition.await;
4080    }
4081}