app.rs

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