app.rs

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