app.rs

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