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