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