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, FontCache, 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 smol::prelude::*;
  17use std::{
  18    any::{type_name, Any, TypeId},
  19    cell::RefCell,
  20    collections::{HashMap, HashSet, VecDeque},
  21    fmt::{self, Debug},
  22    hash::{Hash, Hasher},
  23    marker::PhantomData,
  24    path::PathBuf,
  25    rc::{self, Rc},
  26    sync::{Arc, Weak},
  27};
  28
  29pub trait Entity: 'static + Send + Sync {
  30    type Event;
  31}
  32
  33pub trait View: Entity {
  34    fn ui_name() -> &'static str;
  35    fn render<'a>(&self, app: &AppContext) -> ElementBox;
  36    fn on_focus(&mut self, _ctx: &mut ViewContext<Self>) {}
  37    fn on_blur(&mut self, _ctx: &mut ViewContext<Self>) {}
  38    fn keymap_context(&self, _: &AppContext) -> keymap::Context {
  39        Self::default_keymap_context()
  40    }
  41    fn default_keymap_context() -> keymap::Context {
  42        let mut ctx = keymap::Context::default();
  43        ctx.set.insert(Self::ui_name().into());
  44        ctx
  45    }
  46}
  47
  48pub trait ReadModel {
  49    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T;
  50}
  51
  52pub trait UpdateModel {
  53    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
  54    where
  55        T: Entity,
  56        F: FnOnce(&mut T, &mut ModelContext<T>) -> S;
  57}
  58
  59pub trait ReadView {
  60    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T;
  61}
  62
  63pub trait UpdateView {
  64    fn update_view<T, F, S>(&mut self, handle: &ViewHandle<T>, update: F) -> S
  65    where
  66        T: View,
  67        F: FnOnce(&mut T, &mut ViewContext<T>) -> S;
  68}
  69
  70pub struct Menu<'a> {
  71    pub name: &'a str,
  72    pub items: Vec<MenuItem<'a>>,
  73}
  74
  75pub enum MenuItem<'a> {
  76    Action {
  77        name: &'a str,
  78        keystroke: Option<&'a str>,
  79        action: &'a str,
  80        arg: Option<Box<dyn Any + 'static>>,
  81    },
  82    Separator,
  83}
  84
  85#[derive(Clone)]
  86pub struct App(Rc<RefCell<MutableAppContext>>);
  87
  88#[derive(Clone)]
  89pub struct TestAppContext(Rc<RefCell<MutableAppContext>>);
  90
  91impl App {
  92    pub fn test<T, A: AssetSource, F: FnOnce(&mut MutableAppContext) -> T>(
  93        asset_source: A,
  94        f: F,
  95    ) -> T {
  96        let platform = platform::test::platform();
  97        let foreground = Rc::new(executor::Foreground::test());
  98        let ctx = Rc::new(RefCell::new(MutableAppContext::new(
  99            foreground,
 100            Rc::new(platform),
 101            asset_source,
 102        )));
 103        ctx.borrow_mut().weak_self = Some(Rc::downgrade(&ctx));
 104        let mut ctx = ctx.borrow_mut();
 105        f(&mut *ctx)
 106    }
 107
 108    pub fn test_async<T, F, A: AssetSource, Fn>(asset_source: A, f: Fn) -> T
 109    where
 110        Fn: FnOnce(TestAppContext) -> F,
 111        F: Future<Output = T>,
 112    {
 113        let platform = platform::test::platform();
 114        let foreground = Rc::new(executor::Foreground::test());
 115        let ctx = TestAppContext(Rc::new(RefCell::new(MutableAppContext::new(
 116            foreground.clone(),
 117            Rc::new(platform),
 118            asset_source,
 119        ))));
 120        ctx.0.borrow_mut().weak_self = Some(Rc::downgrade(&ctx.0));
 121
 122        let future = f(ctx);
 123        smol::block_on(foreground.run(future))
 124    }
 125
 126    pub fn new(asset_source: impl AssetSource) -> Result<Self> {
 127        let platform = platform::current::platform();
 128        let foreground = Rc::new(executor::Foreground::platform(platform.dispatcher())?);
 129        let app = Self(Rc::new(RefCell::new(MutableAppContext::new(
 130            foreground,
 131            platform.clone(),
 132            asset_source,
 133        ))));
 134
 135        let ctx = app.0.clone();
 136        platform.on_menu_command(Box::new(move |command, arg| {
 137            let mut ctx = ctx.borrow_mut();
 138            if let Some(key_window_id) = ctx.platform.key_window_id() {
 139                if let Some((presenter, _)) =
 140                    ctx.presenters_and_platform_windows.get(&key_window_id)
 141                {
 142                    let presenter = presenter.clone();
 143                    let path = presenter.borrow().dispatch_path(ctx.as_ref());
 144                    if ctx.dispatch_action_any(key_window_id, &path, command, arg.unwrap_or(&())) {
 145                        return;
 146                    }
 147                }
 148            }
 149            ctx.dispatch_global_action_any(command, arg.unwrap_or(&()));
 150        }));
 151
 152        app.0.borrow_mut().weak_self = Some(Rc::downgrade(&app.0));
 153        Ok(app)
 154    }
 155
 156    pub fn on_become_active<F>(self, mut callback: F) -> Self
 157    where
 158        F: 'static + FnMut(&mut MutableAppContext),
 159    {
 160        let ctx = self.0.clone();
 161        self.0
 162            .borrow()
 163            .platform
 164            .on_become_active(Box::new(move || callback(&mut *ctx.borrow_mut())));
 165        self
 166    }
 167
 168    pub fn on_resign_active<F>(self, mut callback: F) -> Self
 169    where
 170        F: 'static + FnMut(&mut MutableAppContext),
 171    {
 172        let ctx = self.0.clone();
 173        self.0
 174            .borrow()
 175            .platform
 176            .on_resign_active(Box::new(move || callback(&mut *ctx.borrow_mut())));
 177        self
 178    }
 179
 180    pub fn on_event<F>(self, mut callback: F) -> Self
 181    where
 182        F: 'static + FnMut(Event, &mut MutableAppContext) -> bool,
 183    {
 184        let ctx = self.0.clone();
 185        self.0.borrow().platform.on_event(Box::new(move |event| {
 186            callback(event, &mut *ctx.borrow_mut())
 187        }));
 188        self
 189    }
 190
 191    pub fn on_open_files<F>(self, mut callback: F) -> Self
 192    where
 193        F: 'static + FnMut(Vec<PathBuf>, &mut MutableAppContext),
 194    {
 195        let ctx = self.0.clone();
 196        self.0
 197            .borrow()
 198            .platform
 199            .on_open_files(Box::new(move |paths| {
 200                callback(paths, &mut *ctx.borrow_mut())
 201            }));
 202        self
 203    }
 204
 205    pub fn run<F>(self, on_finish_launching: F)
 206    where
 207        F: 'static + FnOnce(&mut MutableAppContext),
 208    {
 209        let platform = self.0.borrow().platform.clone();
 210        platform.run(Box::new(move || {
 211            let mut ctx = self.0.borrow_mut();
 212            on_finish_launching(&mut *ctx);
 213        }))
 214    }
 215
 216    pub fn font_cache(&self) -> Arc<FontCache> {
 217        self.0.borrow().font_cache.clone()
 218    }
 219
 220    fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 221        let mut state = self.0.borrow_mut();
 222        state.pending_flushes += 1;
 223        let result = callback(&mut *state);
 224        state.flush_effects();
 225        result
 226    }
 227}
 228
 229impl TestAppContext {
 230    pub fn dispatch_action<T: 'static + Any>(
 231        &self,
 232        window_id: usize,
 233        responder_chain: Vec<usize>,
 234        name: &str,
 235        arg: T,
 236    ) {
 237        self.0.borrow_mut().dispatch_action_any(
 238            window_id,
 239            &responder_chain,
 240            name,
 241            Box::new(arg).as_ref(),
 242        );
 243    }
 244
 245    pub fn dispatch_keystroke(
 246        &self,
 247        window_id: usize,
 248        responder_chain: Vec<usize>,
 249        keystroke: &Keystroke,
 250    ) -> Result<bool> {
 251        let mut state = self.0.borrow_mut();
 252        state.dispatch_keystroke(window_id, responder_chain, keystroke)
 253    }
 254
 255    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
 256    where
 257        T: Entity,
 258        F: FnOnce(&mut ModelContext<T>) -> T,
 259    {
 260        let mut state = self.0.borrow_mut();
 261        state.pending_flushes += 1;
 262        let handle = state.add_model(build_model);
 263        state.flush_effects();
 264        handle
 265    }
 266
 267    pub fn add_window<T, F>(&mut self, build_root_view: F) -> (usize, ViewHandle<T>)
 268    where
 269        T: View,
 270        F: FnOnce(&mut ViewContext<T>) -> T,
 271    {
 272        self.0.borrow_mut().add_window(build_root_view)
 273    }
 274
 275    pub fn window_ids(&self) -> Vec<usize> {
 276        self.0.borrow().window_ids().collect()
 277    }
 278
 279    pub fn root_view<T: View>(&self, window_id: usize) -> Option<ViewHandle<T>> {
 280        self.0.borrow().root_view(window_id)
 281    }
 282
 283    pub fn add_view<T, F>(&mut self, window_id: usize, build_view: F) -> ViewHandle<T>
 284    where
 285        T: View,
 286        F: FnOnce(&mut ViewContext<T>) -> T,
 287    {
 288        let mut state = self.0.borrow_mut();
 289        state.pending_flushes += 1;
 290        let handle = state.add_view(window_id, build_view);
 291        state.flush_effects();
 292        handle
 293    }
 294
 295    pub fn add_option_view<T, F>(
 296        &mut self,
 297        window_id: usize,
 298        build_view: F,
 299    ) -> Option<ViewHandle<T>>
 300    where
 301        T: View,
 302        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
 303    {
 304        let mut state = self.0.borrow_mut();
 305        state.pending_flushes += 1;
 306        let handle = state.add_option_view(window_id, build_view);
 307        state.flush_effects();
 308        handle
 309    }
 310
 311    pub fn read<T, F: FnOnce(&AppContext) -> T>(&self, callback: F) -> T {
 312        callback(self.0.borrow().as_ref())
 313    }
 314
 315    pub fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 316        let mut state = self.0.borrow_mut();
 317        // Don't increment pending flushes in order to effects to be flushed before the callback
 318        // completes, which is helpful in tests.
 319        let result = callback(&mut *state);
 320        // Flush effects after the callback just in case there are any. This can happen in edge
 321        // cases such as the closure dropping handles.
 322        state.flush_effects();
 323        result
 324    }
 325
 326    pub fn finish_pending_tasks(&self) -> impl Future<Output = ()> {
 327        self.0.borrow().finish_pending_tasks()
 328    }
 329
 330    pub fn font_cache(&self) -> Arc<FontCache> {
 331        self.0.borrow().font_cache.clone()
 332    }
 333
 334    pub fn platform(&self) -> Rc<dyn platform::Platform> {
 335        self.0.borrow().platform.clone()
 336    }
 337}
 338
 339impl UpdateModel for TestAppContext {
 340    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
 341    where
 342        T: Entity,
 343        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
 344    {
 345        let mut state = self.0.borrow_mut();
 346        state.pending_flushes += 1;
 347        let result = state.update_model(handle, update);
 348        state.flush_effects();
 349        result
 350    }
 351}
 352
 353impl UpdateView for TestAppContext {
 354    fn update_view<T, F, S>(&mut self, handle: &ViewHandle<T>, update: F) -> S
 355    where
 356        T: View,
 357        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
 358    {
 359        let mut state = self.0.borrow_mut();
 360        state.pending_flushes += 1;
 361        let result = state.update_view(handle, update);
 362        state.flush_effects();
 363        result
 364    }
 365}
 366
 367type ActionCallback =
 368    dyn FnMut(&mut dyn AnyView, &dyn Any, &mut MutableAppContext, usize, usize) -> bool;
 369
 370type GlobalActionCallback = dyn FnMut(&dyn Any, &mut MutableAppContext);
 371
 372pub struct MutableAppContext {
 373    weak_self: Option<rc::Weak<RefCell<Self>>>,
 374    platform: Rc<dyn platform::Platform>,
 375    font_cache: Arc<FontCache>,
 376    assets: Arc<AssetCache>,
 377    ctx: AppContext,
 378    actions: HashMap<TypeId, HashMap<String, Vec<Box<ActionCallback>>>>,
 379    global_actions: HashMap<String, Vec<Box<GlobalActionCallback>>>,
 380    keystroke_matcher: keymap::Matcher,
 381    next_entity_id: usize,
 382    next_window_id: usize,
 383    next_task_id: usize,
 384    subscriptions: HashMap<usize, Vec<Subscription>>,
 385    observations: HashMap<usize, Vec<Observation>>,
 386    window_invalidations: HashMap<usize, WindowInvalidation>,
 387    presenters_and_platform_windows:
 388        HashMap<usize, (Rc<RefCell<Presenter>>, Box<dyn platform::Window>)>,
 389    debug_elements_callbacks: HashMap<usize, Box<dyn Fn(&AppContext) -> crate::json::Value>>,
 390    foreground: Rc<executor::Foreground>,
 391    future_handlers: Rc<RefCell<HashMap<usize, FutureHandler>>>,
 392    stream_handlers: Rc<RefCell<HashMap<usize, StreamHandler>>>,
 393    task_done: Arc<Condvar>,
 394    pending_effects: VecDeque<Effect>,
 395    pending_flushes: usize,
 396    flushing_effects: bool,
 397}
 398
 399impl MutableAppContext {
 400    pub fn new(
 401        foreground: Rc<executor::Foreground>,
 402        platform: Rc<dyn platform::Platform>,
 403        asset_source: impl AssetSource,
 404    ) -> Self {
 405        let fonts = platform.fonts();
 406        Self {
 407            weak_self: None,
 408            platform,
 409            font_cache: Arc::new(FontCache::new(fonts)),
 410            assets: Arc::new(AssetCache::new(asset_source)),
 411            ctx: AppContext {
 412                models: HashMap::new(),
 413                windows: HashMap::new(),
 414                ref_counts: Arc::new(Mutex::new(RefCounts::default())),
 415                background: Arc::new(executor::Background::new()),
 416                thread_pool: scoped_pool::Pool::new(num_cpus::get()),
 417            },
 418            actions: HashMap::new(),
 419            global_actions: HashMap::new(),
 420            keystroke_matcher: keymap::Matcher::default(),
 421            next_entity_id: 0,
 422            next_window_id: 0,
 423            next_task_id: 0,
 424            subscriptions: HashMap::new(),
 425            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 dispatch_action<T: 'static + Any>(
 574        &mut self,
 575        window_id: usize,
 576        responder_chain: Vec<usize>,
 577        name: &str,
 578        arg: T,
 579    ) {
 580        self.dispatch_action_any(window_id, &responder_chain, name, Box::new(arg).as_ref());
 581    }
 582
 583    fn dispatch_action_any(
 584        &mut self,
 585        window_id: usize,
 586        path: &[usize],
 587        name: &str,
 588        arg: &dyn Any,
 589    ) -> bool {
 590        self.pending_flushes += 1;
 591        let mut halted_dispatch = false;
 592
 593        for view_id in path.iter().rev() {
 594            if let Some(mut view) = self
 595                .ctx
 596                .windows
 597                .get_mut(&window_id)
 598                .and_then(|w| w.views.remove(view_id))
 599            {
 600                let type_id = view.as_any().type_id();
 601
 602                if let Some((name, mut handlers)) = self
 603                    .actions
 604                    .get_mut(&type_id)
 605                    .and_then(|h| h.remove_entry(name))
 606                {
 607                    for handler in handlers.iter_mut().rev() {
 608                        let halt_dispatch = handler(view.as_mut(), arg, self, window_id, *view_id);
 609                        if halt_dispatch {
 610                            halted_dispatch = true;
 611                            break;
 612                        }
 613                    }
 614                    self.actions
 615                        .get_mut(&type_id)
 616                        .unwrap()
 617                        .insert(name, handlers);
 618                }
 619
 620                self.ctx
 621                    .windows
 622                    .get_mut(&window_id)
 623                    .unwrap()
 624                    .views
 625                    .insert(*view_id, view);
 626
 627                if halted_dispatch {
 628                    break;
 629                }
 630            }
 631        }
 632
 633        if !halted_dispatch {
 634            self.dispatch_global_action_any(name, arg);
 635        }
 636
 637        self.flush_effects();
 638        halted_dispatch
 639    }
 640
 641    pub fn dispatch_global_action<T: 'static + Any>(&mut self, name: &str, arg: T) {
 642        self.dispatch_global_action_any(name, Box::new(arg).as_ref());
 643    }
 644
 645    fn dispatch_global_action_any(&mut self, name: &str, arg: &dyn Any) {
 646        if let Some((name, mut handlers)) = self.global_actions.remove_entry(name) {
 647            self.pending_flushes += 1;
 648            for handler in handlers.iter_mut().rev() {
 649                handler(arg, self);
 650            }
 651            self.global_actions.insert(name, handlers);
 652            self.flush_effects();
 653        }
 654    }
 655
 656    pub fn add_bindings<T: IntoIterator<Item = keymap::Binding>>(&mut self, bindings: T) {
 657        self.keystroke_matcher.add_bindings(bindings);
 658    }
 659
 660    pub fn dispatch_keystroke(
 661        &mut self,
 662        window_id: usize,
 663        responder_chain: Vec<usize>,
 664        keystroke: &Keystroke,
 665    ) -> Result<bool> {
 666        let mut context_chain = Vec::new();
 667        let mut context = keymap::Context::default();
 668        for view_id in &responder_chain {
 669            if let Some(view) = self
 670                .ctx
 671                .windows
 672                .get(&window_id)
 673                .and_then(|w| w.views.get(view_id))
 674            {
 675                context.extend(view.keymap_context(self.as_ref()));
 676                context_chain.push(context.clone());
 677            } else {
 678                return Err(anyhow!(
 679                    "View {} in responder chain does not exist",
 680                    view_id
 681                ));
 682            }
 683        }
 684
 685        let mut pending = false;
 686        for (i, ctx) in context_chain.iter().enumerate().rev() {
 687            match self
 688                .keystroke_matcher
 689                .push_keystroke(keystroke.clone(), responder_chain[i], ctx)
 690            {
 691                MatchResult::None => {}
 692                MatchResult::Pending => pending = true,
 693                MatchResult::Action { name, arg } => {
 694                    if self.dispatch_action_any(
 695                        window_id,
 696                        &responder_chain[0..=i],
 697                        &name,
 698                        arg.as_ref().map(|arg| arg.as_ref()).unwrap_or(&()),
 699                    ) {
 700                        return Ok(true);
 701                    }
 702                }
 703            }
 704        }
 705
 706        Ok(pending)
 707    }
 708
 709    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
 710    where
 711        T: Entity,
 712        F: FnOnce(&mut ModelContext<T>) -> T,
 713    {
 714        self.pending_flushes += 1;
 715        let model_id = post_inc(&mut self.next_entity_id);
 716        let mut ctx = ModelContext::new(self, model_id);
 717        let model = build_model(&mut ctx);
 718        self.ctx.models.insert(model_id, Box::new(model));
 719        self.flush_effects();
 720        ModelHandle::new(model_id, &self.ctx.ref_counts)
 721    }
 722
 723    pub fn add_window<T, F>(&mut self, build_root_view: F) -> (usize, ViewHandle<T>)
 724    where
 725        T: View,
 726        F: FnOnce(&mut ViewContext<T>) -> T,
 727    {
 728        self.pending_flushes += 1;
 729        let window_id = post_inc(&mut self.next_window_id);
 730        self.ctx.windows.insert(window_id, Window::default());
 731        self.open_platform_window(window_id);
 732        let root_handle = self.add_view(window_id, build_root_view);
 733        self.ctx.windows.get_mut(&window_id).unwrap().root_view = Some(root_handle.clone().into());
 734        self.focus(window_id, root_handle.id());
 735        self.flush_effects();
 736
 737        (window_id, root_handle)
 738    }
 739
 740    fn open_platform_window(&mut self, window_id: usize) {
 741        let mut window = self.platform.open_window(
 742            window_id,
 743            WindowOptions {
 744                bounds: RectF::new(vec2f(0., 0.), vec2f(1024., 768.)),
 745                title: "Zed".into(),
 746            },
 747            self.foreground.clone(),
 748        );
 749        let text_layout_cache = TextLayoutCache::new(self.platform.fonts());
 750        let presenter = Rc::new(RefCell::new(Presenter::new(
 751            window_id,
 752            self.font_cache.clone(),
 753            text_layout_cache,
 754            self.assets.clone(),
 755            self,
 756        )));
 757
 758        {
 759            let mut app = self.upgrade();
 760            let presenter = presenter.clone();
 761            window.on_event(Box::new(move |event| {
 762                app.update(|ctx| {
 763                    if let Event::KeyDown { keystroke, .. } = &event {
 764                        if ctx
 765                            .dispatch_keystroke(
 766                                window_id,
 767                                presenter.borrow().dispatch_path(ctx.as_ref()),
 768                                keystroke,
 769                            )
 770                            .unwrap()
 771                        {
 772                            return;
 773                        }
 774                    }
 775
 776                    let actions = presenter.borrow_mut().dispatch_event(event, ctx.as_ref());
 777                    for action in actions {
 778                        ctx.dispatch_action_any(
 779                            window_id,
 780                            &action.path,
 781                            action.name,
 782                            action.arg.as_ref(),
 783                        );
 784                    }
 785                })
 786            }));
 787        }
 788
 789        {
 790            let mut app = self.upgrade();
 791            let presenter = presenter.clone();
 792            window.on_resize(Box::new(move |window| {
 793                app.update(|ctx| {
 794                    let scene = presenter.borrow_mut().build_scene(
 795                        window.size(),
 796                        window.scale_factor(),
 797                        ctx,
 798                    );
 799                    window.present_scene(scene);
 800                })
 801            }));
 802        }
 803
 804        self.presenters_and_platform_windows
 805            .insert(window_id, (presenter.clone(), window));
 806
 807        self.on_debug_elements(window_id, move |ctx| {
 808            presenter.borrow().debug_elements(ctx).unwrap()
 809        });
 810    }
 811
 812    pub fn add_view<T, F>(&mut self, window_id: usize, build_view: F) -> ViewHandle<T>
 813    where
 814        T: View,
 815        F: FnOnce(&mut ViewContext<T>) -> T,
 816    {
 817        self.add_option_view(window_id, |ctx| Some(build_view(ctx)))
 818            .unwrap()
 819    }
 820
 821    pub fn add_option_view<T, F>(
 822        &mut self,
 823        window_id: usize,
 824        build_view: F,
 825    ) -> Option<ViewHandle<T>>
 826    where
 827        T: View,
 828        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
 829    {
 830        let view_id = post_inc(&mut self.next_entity_id);
 831        self.pending_flushes += 1;
 832        let mut ctx = ViewContext::new(self, window_id, view_id);
 833        let handle = if let Some(view) = build_view(&mut ctx) {
 834            if let Some(window) = self.ctx.windows.get_mut(&window_id) {
 835                window.views.insert(view_id, Box::new(view));
 836            } else {
 837                panic!("Window does not exist");
 838            }
 839            self.window_invalidations
 840                .entry(window_id)
 841                .or_default()
 842                .updated
 843                .insert(view_id);
 844            Some(ViewHandle::new(window_id, view_id, &self.ctx.ref_counts))
 845        } else {
 846            None
 847        };
 848        self.flush_effects();
 849        handle
 850    }
 851
 852    fn remove_dropped_entities(&mut self) {
 853        loop {
 854            let (dropped_models, dropped_views) = self.ctx.ref_counts.lock().take_dropped();
 855            if dropped_models.is_empty() && dropped_views.is_empty() {
 856                break;
 857            }
 858
 859            for model_id in dropped_models {
 860                self.ctx.models.remove(&model_id);
 861                self.subscriptions.remove(&model_id);
 862                self.observations.remove(&model_id);
 863            }
 864
 865            for (window_id, view_id) in dropped_views {
 866                self.subscriptions.remove(&view_id);
 867                self.observations.remove(&view_id);
 868                if let Some(window) = self.ctx.windows.get_mut(&window_id) {
 869                    self.window_invalidations
 870                        .entry(window_id)
 871                        .or_default()
 872                        .removed
 873                        .push(view_id);
 874                    window.views.remove(&view_id);
 875                }
 876            }
 877        }
 878    }
 879
 880    fn flush_effects(&mut self) {
 881        self.pending_flushes = self.pending_flushes.saturating_sub(1);
 882
 883        if !self.flushing_effects && self.pending_flushes == 0 {
 884            self.flushing_effects = true;
 885
 886            while let Some(effect) = self.pending_effects.pop_front() {
 887                match effect {
 888                    Effect::Event { entity_id, payload } => self.emit_event(entity_id, payload),
 889                    Effect::ModelNotification { model_id } => self.notify_model_observers(model_id),
 890                    Effect::ViewNotification { window_id, view_id } => {
 891                        self.notify_view_observers(window_id, view_id)
 892                    }
 893                    Effect::Focus { window_id, view_id } => {
 894                        self.focus(window_id, view_id);
 895                    }
 896                }
 897            }
 898
 899            self.flushing_effects = false;
 900            self.remove_dropped_entities();
 901            self.update_windows();
 902        }
 903    }
 904
 905    fn update_windows(&mut self) {
 906        let mut invalidations = HashMap::new();
 907        std::mem::swap(&mut invalidations, &mut self.window_invalidations);
 908
 909        for (window_id, invalidation) in invalidations {
 910            if let Some((presenter, mut window)) =
 911                self.presenters_and_platform_windows.remove(&window_id)
 912            {
 913                {
 914                    let mut presenter = presenter.borrow_mut();
 915                    presenter.invalidate(invalidation, self.as_ref());
 916                    let scene = presenter.build_scene(window.size(), window.scale_factor(), self);
 917                    window.present_scene(scene);
 918                }
 919                self.presenters_and_platform_windows
 920                    .insert(window_id, (presenter, window));
 921            }
 922        }
 923    }
 924
 925    fn emit_event(&mut self, entity_id: usize, payload: Box<dyn Any>) {
 926        if let Some(subscriptions) = self.subscriptions.remove(&entity_id) {
 927            for mut subscription in subscriptions {
 928                let alive = match &mut subscription {
 929                    Subscription::FromModel { model_id, callback } => {
 930                        if let Some(mut model) = self.ctx.models.remove(model_id) {
 931                            callback(model.as_any_mut(), payload.as_ref(), self, *model_id);
 932                            self.ctx.models.insert(*model_id, model);
 933                            true
 934                        } else {
 935                            false
 936                        }
 937                    }
 938                    Subscription::FromView {
 939                        window_id,
 940                        view_id,
 941                        callback,
 942                    } => {
 943                        if let Some(mut view) = self
 944                            .ctx
 945                            .windows
 946                            .get_mut(&window_id)
 947                            .and_then(|window| window.views.remove(view_id))
 948                        {
 949                            callback(
 950                                view.as_any_mut(),
 951                                payload.as_ref(),
 952                                self,
 953                                *window_id,
 954                                *view_id,
 955                            );
 956                            self.ctx
 957                                .windows
 958                                .get_mut(&window_id)
 959                                .unwrap()
 960                                .views
 961                                .insert(*view_id, view);
 962                            true
 963                        } else {
 964                            false
 965                        }
 966                    }
 967                };
 968
 969                if alive {
 970                    self.subscriptions
 971                        .entry(entity_id)
 972                        .or_default()
 973                        .push(subscription);
 974                }
 975            }
 976        }
 977    }
 978
 979    fn notify_model_observers(&mut self, observed_id: usize) {
 980        if let Some(observations) = self.observations.remove(&observed_id) {
 981            if self.ctx.models.contains_key(&observed_id) {
 982                for mut observation in observations {
 983                    let alive = match &mut observation {
 984                        Observation::FromModel { model_id, callback } => {
 985                            if let Some(mut model) = self.ctx.models.remove(model_id) {
 986                                callback(model.as_any_mut(), observed_id, self, *model_id);
 987                                self.ctx.models.insert(*model_id, model);
 988                                true
 989                            } else {
 990                                false
 991                            }
 992                        }
 993                        Observation::FromView {
 994                            window_id,
 995                            view_id,
 996                            callback,
 997                        } => {
 998                            if let Some(mut view) = self
 999                                .ctx
1000                                .windows
1001                                .get_mut(window_id)
1002                                .and_then(|w| w.views.remove(view_id))
1003                            {
1004                                callback(
1005                                    view.as_any_mut(),
1006                                    observed_id,
1007                                    self,
1008                                    *window_id,
1009                                    *view_id,
1010                                );
1011                                self.ctx
1012                                    .windows
1013                                    .get_mut(window_id)
1014                                    .unwrap()
1015                                    .views
1016                                    .insert(*view_id, view);
1017                                true
1018                            } else {
1019                                false
1020                            }
1021                        }
1022                    };
1023
1024                    if alive {
1025                        self.observations
1026                            .entry(observed_id)
1027                            .or_default()
1028                            .push(observation);
1029                    }
1030                }
1031            }
1032        }
1033    }
1034
1035    fn notify_view_observers(&mut self, window_id: usize, view_id: usize) {
1036        self.window_invalidations
1037            .entry(window_id)
1038            .or_default()
1039            .updated
1040            .insert(view_id);
1041    }
1042
1043    fn focus(&mut self, window_id: usize, focused_id: usize) {
1044        if self
1045            .ctx
1046            .windows
1047            .get(&window_id)
1048            .and_then(|w| w.focused_view)
1049            .map_or(false, |cur_focused| cur_focused == focused_id)
1050        {
1051            return;
1052        }
1053
1054        self.pending_flushes += 1;
1055
1056        if let Some((blurred_id, mut blurred)) =
1057            self.ctx.windows.get_mut(&window_id).and_then(|w| {
1058                let blurred_view = w.focused_view;
1059                w.focused_view = Some(focused_id);
1060                blurred_view.and_then(|id| w.views.remove(&id).map(|view| (id, view)))
1061            })
1062        {
1063            blurred.on_blur(self, window_id, blurred_id);
1064            self.ctx
1065                .windows
1066                .get_mut(&window_id)
1067                .unwrap()
1068                .views
1069                .insert(blurred_id, blurred);
1070        }
1071
1072        if let Some(mut focused) = self
1073            .ctx
1074            .windows
1075            .get_mut(&window_id)
1076            .and_then(|w| w.views.remove(&focused_id))
1077        {
1078            focused.on_focus(self, window_id, focused_id);
1079            self.ctx
1080                .windows
1081                .get_mut(&window_id)
1082                .unwrap()
1083                .views
1084                .insert(focused_id, focused);
1085        }
1086
1087        self.flush_effects();
1088    }
1089
1090    fn spawn<F, T>(&mut self, future: F) -> EntityTask<T>
1091    where
1092        F: 'static + Future,
1093        T: 'static,
1094    {
1095        let task_id = post_inc(&mut self.next_task_id);
1096        let app = self.weak_self.as_ref().unwrap().upgrade().unwrap();
1097        let task = {
1098            let app = app.clone();
1099            self.foreground.spawn(async move {
1100                let output = future.await;
1101                *app.borrow_mut()
1102                    .handle_future_output(task_id, Box::new(output))
1103                    .downcast::<T>()
1104                    .unwrap()
1105            })
1106        };
1107        EntityTask::new(
1108            task_id,
1109            task,
1110            TaskHandlerMap::Future(self.future_handlers.clone()),
1111            self.task_done.clone(),
1112        )
1113    }
1114
1115    fn spawn_stream<F, T>(&mut self, mut stream: F) -> EntityTask<T>
1116    where
1117        F: 'static + Stream + Unpin,
1118        T: 'static,
1119    {
1120        let task_id = post_inc(&mut self.next_task_id);
1121        let app = self.weak_self.as_ref().unwrap().upgrade().unwrap();
1122        let task = self.foreground.spawn(async move {
1123            loop {
1124                match stream.next().await {
1125                    Some(item) => {
1126                        let mut app = app.borrow_mut();
1127                        if app.handle_stream_item(task_id, Box::new(item)) {
1128                            break;
1129                        }
1130                    }
1131                    None => {
1132                        break;
1133                    }
1134                }
1135            }
1136
1137            *app.borrow_mut()
1138                .stream_completed(task_id)
1139                .downcast::<T>()
1140                .unwrap()
1141        });
1142
1143        EntityTask::new(
1144            task_id,
1145            task,
1146            TaskHandlerMap::Stream(self.stream_handlers.clone()),
1147            self.task_done.clone(),
1148        )
1149    }
1150
1151    fn handle_future_output(&mut self, task_id: usize, output: Box<dyn Any>) -> Box<dyn Any> {
1152        self.pending_flushes += 1;
1153        let future_callback = self.future_handlers.borrow_mut().remove(&task_id).unwrap();
1154        let result = future_callback(output, self);
1155        self.flush_effects();
1156        self.task_done.notify_all();
1157        result
1158    }
1159
1160    fn handle_stream_item(&mut self, task_id: usize, output: Box<dyn Any>) -> bool {
1161        self.pending_flushes += 1;
1162
1163        let mut handler = self.stream_handlers.borrow_mut().remove(&task_id).unwrap();
1164        let halt = (handler.item_callback)(output, self);
1165        self.stream_handlers.borrow_mut().insert(task_id, handler);
1166
1167        self.flush_effects();
1168        halt
1169    }
1170
1171    fn stream_completed(&mut self, task_id: usize) -> Box<dyn Any> {
1172        self.pending_flushes += 1;
1173
1174        let handler = self.stream_handlers.borrow_mut().remove(&task_id).unwrap();
1175        let result = (handler.done_callback)(self);
1176
1177        self.flush_effects();
1178        self.task_done.notify_all();
1179        result
1180    }
1181
1182    pub fn finish_pending_tasks(&self) -> impl Future<Output = ()> {
1183        let mut pending_tasks = self
1184            .future_handlers
1185            .borrow()
1186            .keys()
1187            .cloned()
1188            .collect::<HashSet<_>>();
1189        pending_tasks.extend(self.stream_handlers.borrow().keys());
1190
1191        let task_done = self.task_done.clone();
1192        let future_handlers = self.future_handlers.clone();
1193        let stream_handlers = self.stream_handlers.clone();
1194
1195        async move {
1196            // A Condvar expects the condition to be protected by a Mutex, but in this case we know
1197            // that this logic will always run on the main thread.
1198            let mutex = async_std::sync::Mutex::new(());
1199            loop {
1200                {
1201                    let future_handlers = future_handlers.borrow();
1202                    let stream_handlers = stream_handlers.borrow();
1203                    pending_tasks.retain(|task_id| {
1204                        future_handlers.contains_key(task_id)
1205                            || stream_handlers.contains_key(task_id)
1206                    });
1207                    if pending_tasks.is_empty() {
1208                        break;
1209                    }
1210                }
1211                task_done.wait(mutex.lock().await).await;
1212            }
1213        }
1214    }
1215
1216    pub fn copy(&self, text: &str) {
1217        self.platform.copy(text);
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
1996impl<T> Clone for ModelHandle<T> {
1997    fn clone(&self) -> Self {
1998        if let Some(ref_counts) = self.ref_counts.upgrade() {
1999            ref_counts.lock().inc(self.model_id);
2000        }
2001
2002        Self {
2003            model_id: self.model_id,
2004            model_type: PhantomData,
2005            ref_counts: self.ref_counts.clone(),
2006        }
2007    }
2008}
2009
2010impl<T> PartialEq for ModelHandle<T> {
2011    fn eq(&self, other: &Self) -> bool {
2012        self.model_id == other.model_id
2013    }
2014}
2015
2016impl<T> Eq for ModelHandle<T> {}
2017
2018impl<T> Hash for ModelHandle<T> {
2019    fn hash<H: Hasher>(&self, state: &mut H) {
2020        self.model_id.hash(state);
2021    }
2022}
2023
2024impl<T> std::borrow::Borrow<usize> for ModelHandle<T> {
2025    fn borrow(&self) -> &usize {
2026        &self.model_id
2027    }
2028}
2029
2030impl<T> Debug for ModelHandle<T> {
2031    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2032        f.debug_tuple(&format!("ModelHandle<{}>", type_name::<T>()))
2033            .field(&self.model_id)
2034            .finish()
2035    }
2036}
2037
2038unsafe impl<T> Send for ModelHandle<T> {}
2039unsafe impl<T> Sync for ModelHandle<T> {}
2040
2041impl<T> Drop for ModelHandle<T> {
2042    fn drop(&mut self) {
2043        if let Some(ref_counts) = self.ref_counts.upgrade() {
2044            ref_counts.lock().dec_model(self.model_id);
2045        }
2046    }
2047}
2048
2049impl<T> Handle<T> for ModelHandle<T> {
2050    fn id(&self) -> usize {
2051        self.model_id
2052    }
2053
2054    fn location(&self) -> EntityLocation {
2055        EntityLocation::Model(self.model_id)
2056    }
2057}
2058
2059pub struct WeakModelHandle<T> {
2060    model_id: usize,
2061    model_type: PhantomData<T>,
2062}
2063
2064impl<T: Entity> WeakModelHandle<T> {
2065    fn new(model_id: usize) -> Self {
2066        Self {
2067            model_id,
2068            model_type: PhantomData,
2069        }
2070    }
2071
2072    pub fn upgrade(&self, app: &AppContext) -> Option<ModelHandle<T>> {
2073        if app.models.contains_key(&self.model_id) {
2074            Some(ModelHandle::new(self.model_id, &app.ref_counts))
2075        } else {
2076            None
2077        }
2078    }
2079}
2080
2081pub struct ViewHandle<T> {
2082    window_id: usize,
2083    view_id: usize,
2084    view_type: PhantomData<T>,
2085    ref_counts: Weak<Mutex<RefCounts>>,
2086}
2087
2088impl<T: View> ViewHandle<T> {
2089    fn new(window_id: usize, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
2090        ref_counts.lock().inc(view_id);
2091        Self {
2092            window_id,
2093            view_id,
2094            view_type: PhantomData,
2095            ref_counts: Arc::downgrade(ref_counts),
2096        }
2097    }
2098
2099    pub fn downgrade(&self) -> WeakViewHandle<T> {
2100        WeakViewHandle::new(self.window_id, self.view_id)
2101    }
2102
2103    pub fn window_id(&self) -> usize {
2104        self.window_id
2105    }
2106
2107    pub fn id(&self) -> usize {
2108        self.view_id
2109    }
2110
2111    pub fn read<'a, A: ReadView>(&self, app: &'a A) -> &'a T {
2112        app.read_view(self)
2113    }
2114
2115    pub fn update<A, F, S>(&self, app: &mut A, update: F) -> S
2116    where
2117        A: UpdateView,
2118        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
2119    {
2120        app.update_view(self, update)
2121    }
2122
2123    pub fn is_focused(&self, app: &AppContext) -> bool {
2124        app.focused_view_id(self.window_id)
2125            .map_or(false, |focused_id| focused_id == self.view_id)
2126    }
2127}
2128
2129impl<T> Clone for ViewHandle<T> {
2130    fn clone(&self) -> Self {
2131        if let Some(ref_counts) = self.ref_counts.upgrade() {
2132            ref_counts.lock().inc(self.view_id);
2133        }
2134
2135        Self {
2136            window_id: self.window_id,
2137            view_id: self.view_id,
2138            view_type: PhantomData,
2139            ref_counts: self.ref_counts.clone(),
2140        }
2141    }
2142}
2143
2144impl<T> PartialEq for ViewHandle<T> {
2145    fn eq(&self, other: &Self) -> bool {
2146        self.window_id == other.window_id && self.view_id == other.view_id
2147    }
2148}
2149
2150impl<T> Eq for ViewHandle<T> {}
2151
2152impl<T> Debug for ViewHandle<T> {
2153    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2154        f.debug_struct(&format!("ViewHandle<{}>", type_name::<T>()))
2155            .field("window_id", &self.window_id)
2156            .field("view_id", &self.view_id)
2157            .finish()
2158    }
2159}
2160
2161impl<T> Drop for ViewHandle<T> {
2162    fn drop(&mut self) {
2163        if let Some(ref_counts) = self.ref_counts.upgrade() {
2164            ref_counts.lock().dec_view(self.window_id, self.view_id);
2165        }
2166    }
2167}
2168
2169impl<T> Handle<T> for ViewHandle<T> {
2170    fn id(&self) -> usize {
2171        self.view_id
2172    }
2173
2174    fn location(&self) -> EntityLocation {
2175        EntityLocation::View(self.window_id, self.view_id)
2176    }
2177}
2178
2179#[derive(Clone)]
2180pub struct AnyViewHandle {
2181    window_id: usize,
2182    view_id: usize,
2183    view_type: TypeId,
2184    ref_counts: Weak<Mutex<RefCounts>>,
2185}
2186
2187impl AnyViewHandle {
2188    pub fn id(&self) -> usize {
2189        self.view_id
2190    }
2191
2192    pub fn is<T: 'static>(&self) -> bool {
2193        TypeId::of::<T>() == self.view_type
2194    }
2195
2196    pub fn downcast<T: View>(self) -> Option<ViewHandle<T>> {
2197        if self.is::<T>() {
2198            if let Some(ref_counts) = self.ref_counts.upgrade() {
2199                return Some(ViewHandle::new(self.window_id, self.view_id, &ref_counts));
2200            }
2201        }
2202        None
2203    }
2204}
2205
2206impl<T: View> From<&ViewHandle<T>> for AnyViewHandle {
2207    fn from(handle: &ViewHandle<T>) -> Self {
2208        if let Some(ref_counts) = handle.ref_counts.upgrade() {
2209            ref_counts.lock().inc(handle.view_id);
2210        }
2211        AnyViewHandle {
2212            window_id: handle.window_id,
2213            view_id: handle.view_id,
2214            view_type: TypeId::of::<T>(),
2215            ref_counts: handle.ref_counts.clone(),
2216        }
2217    }
2218}
2219
2220impl<T: View> From<ViewHandle<T>> for AnyViewHandle {
2221    fn from(handle: ViewHandle<T>) -> Self {
2222        (&handle).into()
2223    }
2224}
2225
2226pub struct WeakViewHandle<T> {
2227    window_id: usize,
2228    view_id: usize,
2229    view_type: PhantomData<T>,
2230}
2231
2232impl<T: View> WeakViewHandle<T> {
2233    fn new(window_id: usize, view_id: usize) -> Self {
2234        Self {
2235            window_id,
2236            view_id,
2237            view_type: PhantomData,
2238        }
2239    }
2240
2241    pub fn upgrade(&self, app: &AppContext) -> Option<ViewHandle<T>> {
2242        if app
2243            .windows
2244            .get(&self.window_id)
2245            .and_then(|w| w.views.get(&self.view_id))
2246            .is_some()
2247        {
2248            Some(ViewHandle::new(
2249                self.window_id,
2250                self.view_id,
2251                &app.ref_counts,
2252            ))
2253        } else {
2254            None
2255        }
2256    }
2257}
2258
2259impl<T> Clone for WeakViewHandle<T> {
2260    fn clone(&self) -> Self {
2261        Self {
2262            window_id: self.window_id,
2263            view_id: self.view_id,
2264            view_type: PhantomData,
2265        }
2266    }
2267}
2268
2269#[derive(Default)]
2270struct RefCounts {
2271    counts: HashMap<usize, usize>,
2272    dropped_models: HashSet<usize>,
2273    dropped_views: HashSet<(usize, usize)>,
2274}
2275
2276impl RefCounts {
2277    fn inc(&mut self, model_id: usize) {
2278        *self.counts.entry(model_id).or_insert(0) += 1;
2279    }
2280
2281    fn dec_model(&mut self, model_id: usize) {
2282        if let Some(count) = self.counts.get_mut(&model_id) {
2283            *count -= 1;
2284            if *count == 0 {
2285                self.counts.remove(&model_id);
2286                self.dropped_models.insert(model_id);
2287            }
2288        } else {
2289            panic!("Expected ref count to be positive")
2290        }
2291    }
2292
2293    fn dec_view(&mut self, window_id: usize, view_id: usize) {
2294        if let Some(count) = self.counts.get_mut(&view_id) {
2295            *count -= 1;
2296            if *count == 0 {
2297                self.counts.remove(&view_id);
2298                self.dropped_views.insert((window_id, view_id));
2299            }
2300        } else {
2301            panic!("Expected ref count to be positive")
2302        }
2303    }
2304
2305    fn take_dropped(&mut self) -> (HashSet<usize>, HashSet<(usize, usize)>) {
2306        let mut dropped_models = HashSet::new();
2307        let mut dropped_views = HashSet::new();
2308        std::mem::swap(&mut self.dropped_models, &mut dropped_models);
2309        std::mem::swap(&mut self.dropped_views, &mut dropped_views);
2310        (dropped_models, dropped_views)
2311    }
2312}
2313
2314enum Subscription {
2315    FromModel {
2316        model_id: usize,
2317        callback: Box<dyn FnMut(&mut dyn Any, &dyn Any, &mut MutableAppContext, usize)>,
2318    },
2319    FromView {
2320        window_id: usize,
2321        view_id: usize,
2322        callback: Box<dyn FnMut(&mut dyn Any, &dyn Any, &mut MutableAppContext, usize, usize)>,
2323    },
2324}
2325
2326enum Observation {
2327    FromModel {
2328        model_id: usize,
2329        callback: Box<dyn FnMut(&mut dyn Any, usize, &mut MutableAppContext, usize)>,
2330    },
2331    FromView {
2332        window_id: usize,
2333        view_id: usize,
2334        callback: Box<dyn FnMut(&mut dyn Any, usize, &mut MutableAppContext, usize, usize)>,
2335    },
2336}
2337
2338type FutureHandler = Box<dyn FnOnce(Box<dyn Any>, &mut MutableAppContext) -> Box<dyn Any>>;
2339
2340struct StreamHandler {
2341    item_callback: Box<dyn FnMut(Box<dyn Any>, &mut MutableAppContext) -> bool>,
2342    done_callback: Box<dyn FnOnce(&mut MutableAppContext) -> Box<dyn Any>>,
2343}
2344
2345#[must_use]
2346pub struct EntityTask<T> {
2347    id: usize,
2348    task: Option<executor::Task<T>>,
2349    handler_map: TaskHandlerMap,
2350    task_done: Arc<Condvar>,
2351}
2352
2353enum TaskHandlerMap {
2354    Detached,
2355    Future(Rc<RefCell<HashMap<usize, FutureHandler>>>),
2356    Stream(Rc<RefCell<HashMap<usize, StreamHandler>>>),
2357}
2358
2359impl<T> EntityTask<T> {
2360    fn new(
2361        id: usize,
2362        task: executor::Task<T>,
2363        handler_map: TaskHandlerMap,
2364        task_done: Arc<Condvar>,
2365    ) -> Self {
2366        Self {
2367            id,
2368            task: Some(task),
2369            handler_map,
2370            task_done,
2371        }
2372    }
2373
2374    pub fn detach(mut self) {
2375        self.handler_map = TaskHandlerMap::Detached;
2376        self.task.take().unwrap().detach();
2377    }
2378
2379    pub async fn cancel(mut self) -> Option<T> {
2380        let task = self.task.take().unwrap();
2381        task.cancel().await
2382    }
2383}
2384
2385impl<T> Future for EntityTask<T> {
2386    type Output = T;
2387
2388    fn poll(
2389        self: std::pin::Pin<&mut Self>,
2390        ctx: &mut std::task::Context<'_>,
2391    ) -> std::task::Poll<Self::Output> {
2392        let task = unsafe { self.map_unchecked_mut(|task| task.task.as_mut().unwrap()) };
2393        task.poll(ctx)
2394    }
2395}
2396
2397impl<T> Drop for EntityTask<T> {
2398    fn drop(self: &mut Self) {
2399        match &self.handler_map {
2400            TaskHandlerMap::Detached => {
2401                return;
2402            }
2403            TaskHandlerMap::Future(map) => {
2404                map.borrow_mut().remove(&self.id);
2405            }
2406            TaskHandlerMap::Stream(map) => {
2407                map.borrow_mut().remove(&self.id);
2408            }
2409        }
2410        self.task_done.notify_all();
2411    }
2412}
2413
2414#[cfg(test)]
2415mod tests {
2416    use super::*;
2417    use crate::elements::*;
2418
2419    #[test]
2420    fn test_model_handles() {
2421        struct Model {
2422            other: Option<ModelHandle<Model>>,
2423            events: Vec<String>,
2424        }
2425
2426        impl Entity for Model {
2427            type Event = usize;
2428        }
2429
2430        impl Model {
2431            fn new(other: Option<ModelHandle<Self>>, ctx: &mut ModelContext<Self>) -> Self {
2432                if let Some(other) = other.as_ref() {
2433                    ctx.observe(other, |me, _, _| {
2434                        me.events.push("notified".into());
2435                    });
2436                    ctx.subscribe(other, |me, event, _| {
2437                        me.events.push(format!("observed event {}", event));
2438                    });
2439                }
2440
2441                Self {
2442                    other,
2443                    events: Vec::new(),
2444                }
2445            }
2446        }
2447
2448        App::test((), |app| {
2449            let handle_1 = app.add_model(|ctx| Model::new(None, ctx));
2450            let handle_2 = app.add_model(|ctx| Model::new(Some(handle_1.clone()), ctx));
2451            assert_eq!(app.ctx.models.len(), 2);
2452
2453            handle_1.update(app, |model, ctx| {
2454                model.events.push("updated".into());
2455                ctx.emit(1);
2456                ctx.notify();
2457                ctx.emit(2);
2458            });
2459            assert_eq!(handle_1.read(app).events, vec!["updated".to_string()]);
2460            assert_eq!(
2461                handle_2.read(app).events,
2462                vec![
2463                    "observed event 1".to_string(),
2464                    "notified".to_string(),
2465                    "observed event 2".to_string(),
2466                ]
2467            );
2468
2469            handle_2.update(app, |model, _| {
2470                drop(handle_1);
2471                model.other.take();
2472            });
2473
2474            assert_eq!(app.ctx.models.len(), 1);
2475            assert!(app.subscriptions.is_empty());
2476            assert!(app.observations.is_empty());
2477        });
2478    }
2479
2480    #[test]
2481    fn test_subscribe_and_emit_from_model() {
2482        #[derive(Default)]
2483        struct Model {
2484            events: Vec<usize>,
2485        }
2486
2487        impl Entity for Model {
2488            type Event = usize;
2489        }
2490
2491        App::test((), |app| {
2492            let handle_1 = app.add_model(|_| Model::default());
2493            let handle_2 = app.add_model(|_| Model::default());
2494            let handle_2b = handle_2.clone();
2495
2496            handle_1.update(app, |_, c| {
2497                c.subscribe(&handle_2, move |model: &mut Model, event, c| {
2498                    model.events.push(*event);
2499
2500                    c.subscribe(&handle_2b, |model, event, _| {
2501                        model.events.push(*event * 2);
2502                    });
2503                });
2504            });
2505
2506            handle_2.update(app, |_, c| c.emit(7));
2507            assert_eq!(handle_1.read(app).events, vec![7]);
2508
2509            handle_2.update(app, |_, c| c.emit(5));
2510            assert_eq!(handle_1.read(app).events, vec![7, 10, 5]);
2511        })
2512    }
2513
2514    #[test]
2515    fn test_observe_and_notify_from_model() {
2516        #[derive(Default)]
2517        struct Model {
2518            count: usize,
2519            events: Vec<usize>,
2520        }
2521
2522        impl Entity for Model {
2523            type Event = ();
2524        }
2525
2526        App::test((), |app| {
2527            let handle_1 = app.add_model(|_| Model::default());
2528            let handle_2 = app.add_model(|_| Model::default());
2529            let handle_2b = handle_2.clone();
2530
2531            handle_1.update(app, |_, c| {
2532                c.observe(&handle_2, move |model, observed, c| {
2533                    model.events.push(observed.read(c).count);
2534                    c.observe(&handle_2b, |model, observed, c| {
2535                        model.events.push(observed.read(c).count * 2);
2536                    });
2537                });
2538            });
2539
2540            handle_2.update(app, |model, c| {
2541                model.count = 7;
2542                c.notify()
2543            });
2544            assert_eq!(handle_1.read(app).events, vec![7]);
2545
2546            handle_2.update(app, |model, c| {
2547                model.count = 5;
2548                c.notify()
2549            });
2550            assert_eq!(handle_1.read(app).events, vec![7, 10, 5])
2551        })
2552    }
2553
2554    #[test]
2555    fn test_spawn_from_model() {
2556        #[derive(Default)]
2557        struct Model {
2558            count: usize,
2559        }
2560
2561        impl Entity for Model {
2562            type Event = ();
2563        }
2564
2565        App::test_async((), |mut app| async move {
2566            let handle = app.add_model(|_| Model::default());
2567            handle
2568                .update(&mut app, |_, c| {
2569                    c.spawn(async { 7 }, |model, output, _| {
2570                        model.count = output;
2571                    })
2572                })
2573                .await;
2574            app.read(|ctx| assert_eq!(handle.read(ctx).count, 7));
2575
2576            handle
2577                .update(&mut app, |_, c| {
2578                    c.spawn(async { 14 }, |model, output, _| {
2579                        model.count = output;
2580                    })
2581                })
2582                .await;
2583            app.read(|ctx| assert_eq!(handle.read(ctx).count, 14));
2584        });
2585    }
2586
2587    #[test]
2588    fn test_spawn_stream_local_from_model() {
2589        #[derive(Default)]
2590        struct Model {
2591            events: Vec<Option<usize>>,
2592        }
2593
2594        impl Entity for Model {
2595            type Event = ();
2596        }
2597
2598        App::test_async((), |mut app| async move {
2599            let handle = app.add_model(|_| Model::default());
2600            handle
2601                .update(&mut app, |_, c| {
2602                    c.spawn_stream(
2603                        smol::stream::iter(vec![1, 2, 3]),
2604                        |model, output, _| {
2605                            model.events.push(Some(output));
2606                        },
2607                        |model, _| {
2608                            model.events.push(None);
2609                        },
2610                    )
2611                })
2612                .await;
2613            app.read(|ctx| assert_eq!(handle.read(ctx).events, [Some(1), Some(2), Some(3), None]));
2614        })
2615    }
2616
2617    #[test]
2618    fn test_view_handles() {
2619        struct View {
2620            other: Option<ViewHandle<View>>,
2621            events: Vec<String>,
2622        }
2623
2624        impl Entity for View {
2625            type Event = usize;
2626        }
2627
2628        impl super::View for View {
2629            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2630                Empty::new().boxed()
2631            }
2632
2633            fn ui_name() -> &'static str {
2634                "View"
2635            }
2636        }
2637
2638        impl View {
2639            fn new(other: Option<ViewHandle<View>>, ctx: &mut ViewContext<Self>) -> Self {
2640                if let Some(other) = other.as_ref() {
2641                    ctx.subscribe_to_view(other, |me, _, event, _| {
2642                        me.events.push(format!("observed event {}", event));
2643                    });
2644                }
2645                Self {
2646                    other,
2647                    events: Vec::new(),
2648                }
2649            }
2650        }
2651
2652        App::test((), |app| {
2653            let (window_id, _) = app.add_window(|ctx| View::new(None, ctx));
2654            let handle_1 = app.add_view(window_id, |ctx| View::new(None, ctx));
2655            let handle_2 = app.add_view(window_id, |ctx| View::new(Some(handle_1.clone()), ctx));
2656            assert_eq!(app.ctx.windows[&window_id].views.len(), 3);
2657
2658            handle_1.update(app, |view, ctx| {
2659                view.events.push("updated".into());
2660                ctx.emit(1);
2661                ctx.emit(2);
2662            });
2663            assert_eq!(handle_1.read(app).events, vec!["updated".to_string()]);
2664            assert_eq!(
2665                handle_2.read(app).events,
2666                vec![
2667                    "observed event 1".to_string(),
2668                    "observed event 2".to_string(),
2669                ]
2670            );
2671
2672            handle_2.update(app, |view, _| {
2673                drop(handle_1);
2674                view.other.take();
2675            });
2676
2677            assert_eq!(app.ctx.windows[&window_id].views.len(), 2);
2678            assert!(app.subscriptions.is_empty());
2679            assert!(app.observations.is_empty());
2680        })
2681    }
2682
2683    #[test]
2684    fn test_subscribe_and_emit_from_view() {
2685        #[derive(Default)]
2686        struct View {
2687            events: Vec<usize>,
2688        }
2689
2690        impl Entity for View {
2691            type Event = usize;
2692        }
2693
2694        impl super::View for View {
2695            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2696                Empty::new().boxed()
2697            }
2698
2699            fn ui_name() -> &'static str {
2700                "View"
2701            }
2702        }
2703
2704        struct Model;
2705
2706        impl Entity for Model {
2707            type Event = usize;
2708        }
2709
2710        App::test((), |app| {
2711            let (window_id, handle_1) = app.add_window(|_| View::default());
2712            let handle_2 = app.add_view(window_id, |_| View::default());
2713            let handle_2b = handle_2.clone();
2714            let handle_3 = app.add_model(|_| Model);
2715
2716            handle_1.update(app, |_, c| {
2717                c.subscribe_to_view(&handle_2, move |me, _, event, c| {
2718                    me.events.push(*event);
2719
2720                    c.subscribe_to_view(&handle_2b, |me, _, event, _| {
2721                        me.events.push(*event * 2);
2722                    });
2723                });
2724
2725                c.subscribe_to_model(&handle_3, |me, _, event, _| {
2726                    me.events.push(*event);
2727                })
2728            });
2729
2730            handle_2.update(app, |_, c| c.emit(7));
2731            assert_eq!(handle_1.read(app).events, vec![7]);
2732
2733            handle_2.update(app, |_, c| c.emit(5));
2734            assert_eq!(handle_1.read(app).events, vec![7, 10, 5]);
2735
2736            handle_3.update(app, |_, c| c.emit(9));
2737            assert_eq!(handle_1.read(app).events, vec![7, 10, 5, 9]);
2738        })
2739    }
2740
2741    #[test]
2742    fn test_dropping_subscribers() {
2743        struct View;
2744
2745        impl Entity for View {
2746            type Event = ();
2747        }
2748
2749        impl super::View for View {
2750            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2751                Empty::new().boxed()
2752            }
2753
2754            fn ui_name() -> &'static str {
2755                "View"
2756            }
2757        }
2758
2759        struct Model;
2760
2761        impl Entity for Model {
2762            type Event = ();
2763        }
2764
2765        App::test((), |app| {
2766            let (window_id, _) = app.add_window(|_| View);
2767            let observing_view = app.add_view(window_id, |_| View);
2768            let emitting_view = app.add_view(window_id, |_| View);
2769            let observing_model = app.add_model(|_| Model);
2770            let observed_model = app.add_model(|_| Model);
2771
2772            observing_view.update(app, |_, ctx| {
2773                ctx.subscribe_to_view(&emitting_view, |_, _, _, _| {});
2774                ctx.subscribe_to_model(&observed_model, |_, _, _, _| {});
2775            });
2776            observing_model.update(app, |_, ctx| {
2777                ctx.subscribe(&observed_model, |_, _, _| {});
2778            });
2779
2780            app.update(|| {
2781                drop(observing_view);
2782                drop(observing_model);
2783            });
2784
2785            emitting_view.update(app, |_, ctx| ctx.emit(()));
2786            observed_model.update(app, |_, ctx| ctx.emit(()));
2787        })
2788    }
2789
2790    #[test]
2791    fn test_observe_and_notify_from_view() {
2792        #[derive(Default)]
2793        struct View {
2794            events: Vec<usize>,
2795        }
2796
2797        impl Entity for View {
2798            type Event = usize;
2799        }
2800
2801        impl super::View for View {
2802            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2803                Empty::new().boxed()
2804            }
2805
2806            fn ui_name() -> &'static str {
2807                "View"
2808            }
2809        }
2810
2811        #[derive(Default)]
2812        struct Model {
2813            count: usize,
2814        }
2815
2816        impl Entity for Model {
2817            type Event = ();
2818        }
2819
2820        App::test((), |app| {
2821            let (_, view) = app.add_window(|_| View::default());
2822            let model = app.add_model(|_| Model::default());
2823
2824            view.update(app, |_, c| {
2825                c.observe(&model, |me, observed, c| {
2826                    me.events.push(observed.read(c).count)
2827                });
2828            });
2829
2830            model.update(app, |model, c| {
2831                model.count = 11;
2832                c.notify();
2833            });
2834            assert_eq!(view.read(app).events, vec![11]);
2835        })
2836    }
2837
2838    #[test]
2839    fn test_dropping_observers() {
2840        struct View;
2841
2842        impl Entity for View {
2843            type Event = ();
2844        }
2845
2846        impl super::View for View {
2847            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2848                Empty::new().boxed()
2849            }
2850
2851            fn ui_name() -> &'static str {
2852                "View"
2853            }
2854        }
2855
2856        struct Model;
2857
2858        impl Entity for Model {
2859            type Event = ();
2860        }
2861
2862        App::test((), |app| {
2863            let (window_id, _) = app.add_window(|_| View);
2864            let observing_view = app.add_view(window_id, |_| View);
2865            let observing_model = app.add_model(|_| Model);
2866            let observed_model = app.add_model(|_| Model);
2867
2868            observing_view.update(app, |_, ctx| {
2869                ctx.observe(&observed_model, |_, _, _| {});
2870            });
2871            observing_model.update(app, |_, ctx| {
2872                ctx.observe(&observed_model, |_, _, _| {});
2873            });
2874
2875            app.update(|| {
2876                drop(observing_view);
2877                drop(observing_model);
2878            });
2879
2880            observed_model.update(app, |_, ctx| ctx.notify());
2881        })
2882    }
2883
2884    #[test]
2885    fn test_focus() {
2886        #[derive(Default)]
2887        struct View {
2888            events: Vec<String>,
2889        }
2890
2891        impl Entity for View {
2892            type Event = String;
2893        }
2894
2895        impl super::View for View {
2896            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2897                Empty::new().boxed()
2898            }
2899
2900            fn ui_name() -> &'static str {
2901                "View"
2902            }
2903
2904            fn on_focus(&mut self, ctx: &mut ViewContext<Self>) {
2905                self.events.push("self focused".into());
2906                ctx.emit("focused".into());
2907            }
2908
2909            fn on_blur(&mut self, ctx: &mut ViewContext<Self>) {
2910                self.events.push("self blurred".into());
2911                ctx.emit("blurred".into());
2912            }
2913        }
2914
2915        App::test((), |app| {
2916            let (window_id, view_1) = app.add_window(|_| View::default());
2917            let view_2 = app.add_view(window_id, |_| View::default());
2918
2919            view_1.update(app, |_, ctx| {
2920                ctx.subscribe_to_view(&view_2, |view_1, _, event, _| {
2921                    view_1.events.push(format!("view 2 {}", event));
2922                });
2923                ctx.focus(&view_2);
2924            });
2925
2926            view_1.update(app, |_, ctx| {
2927                ctx.focus(&view_1);
2928            });
2929
2930            assert_eq!(
2931                view_1.read(app).events,
2932                [
2933                    "self focused".to_string(),
2934                    "self blurred".to_string(),
2935                    "view 2 focused".to_string(),
2936                    "self focused".to_string(),
2937                    "view 2 blurred".to_string(),
2938                ],
2939            );
2940        })
2941    }
2942
2943    #[test]
2944    fn test_spawn_from_view() {
2945        #[derive(Default)]
2946        struct View {
2947            count: usize,
2948        }
2949
2950        impl Entity for View {
2951            type Event = ();
2952        }
2953
2954        impl super::View for View {
2955            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2956                Empty::new().boxed()
2957            }
2958
2959            fn ui_name() -> &'static str {
2960                "View"
2961            }
2962        }
2963
2964        App::test_async((), |mut app| async move {
2965            let handle = app.add_window(|_| View::default()).1;
2966            handle
2967                .update(&mut app, |_, c| {
2968                    c.spawn(async { 7 }, |me, output, _| {
2969                        me.count = output;
2970                    })
2971                })
2972                .await;
2973            app.read(|ctx| assert_eq!(handle.read(ctx).count, 7));
2974            handle
2975                .update(&mut app, |_, c| {
2976                    c.spawn(async { 14 }, |me, output, _| {
2977                        me.count = output;
2978                    })
2979                })
2980                .await;
2981            app.read(|ctx| assert_eq!(handle.read(ctx).count, 14));
2982        });
2983    }
2984
2985    #[test]
2986    fn test_spawn_stream_local_from_view() {
2987        #[derive(Default)]
2988        struct View {
2989            events: Vec<Option<usize>>,
2990        }
2991
2992        impl Entity for View {
2993            type Event = ();
2994        }
2995
2996        impl super::View for View {
2997            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2998                Empty::new().boxed()
2999            }
3000
3001            fn ui_name() -> &'static str {
3002                "View"
3003            }
3004        }
3005
3006        App::test_async((), |mut app| async move {
3007            let (_, handle) = app.add_window(|_| View::default());
3008            handle
3009                .update(&mut app, |_, c| {
3010                    c.spawn_stream(
3011                        smol::stream::iter(vec![1_usize, 2, 3]),
3012                        |me, output, _| {
3013                            me.events.push(Some(output));
3014                        },
3015                        |me, _| {
3016                            me.events.push(None);
3017                        },
3018                    )
3019                })
3020                .await;
3021
3022            app.read(|ctx| assert_eq!(handle.read(ctx).events, [Some(1), Some(2), Some(3), None]))
3023        });
3024    }
3025
3026    #[test]
3027    fn test_dispatch_action() {
3028        struct ViewA {
3029            id: usize,
3030        }
3031
3032        impl Entity for ViewA {
3033            type Event = ();
3034        }
3035
3036        impl View for ViewA {
3037            fn render<'a>(&self, _: &AppContext) -> ElementBox {
3038                Empty::new().boxed()
3039            }
3040
3041            fn ui_name() -> &'static str {
3042                "View"
3043            }
3044        }
3045
3046        struct ViewB {
3047            id: usize,
3048        }
3049
3050        impl Entity for ViewB {
3051            type Event = ();
3052        }
3053
3054        impl View for ViewB {
3055            fn render<'a>(&self, _: &AppContext) -> ElementBox {
3056                Empty::new().boxed()
3057            }
3058
3059            fn ui_name() -> &'static str {
3060                "View"
3061            }
3062        }
3063
3064        struct ActionArg {
3065            foo: String,
3066        }
3067
3068        App::test((), |app| {
3069            let actions = Rc::new(RefCell::new(Vec::new()));
3070
3071            let actions_clone = actions.clone();
3072            app.add_global_action("action", move |_: &ActionArg, _: &mut MutableAppContext| {
3073                actions_clone.borrow_mut().push("global a".to_string());
3074            });
3075
3076            let actions_clone = actions.clone();
3077            app.add_global_action("action", move |_: &ActionArg, _: &mut MutableAppContext| {
3078                actions_clone.borrow_mut().push("global b".to_string());
3079            });
3080
3081            let actions_clone = actions.clone();
3082            app.add_action("action", move |view: &mut ViewA, arg: &ActionArg, ctx| {
3083                assert_eq!(arg.foo, "bar");
3084                ctx.propagate_action();
3085                actions_clone.borrow_mut().push(format!("{} a", view.id));
3086            });
3087
3088            let actions_clone = actions.clone();
3089            app.add_action("action", move |view: &mut ViewA, _: &ActionArg, ctx| {
3090                if view.id != 1 {
3091                    ctx.propagate_action();
3092                }
3093                actions_clone.borrow_mut().push(format!("{} b", view.id));
3094            });
3095
3096            let actions_clone = actions.clone();
3097            app.add_action("action", move |view: &mut ViewB, _: &ActionArg, ctx| {
3098                ctx.propagate_action();
3099                actions_clone.borrow_mut().push(format!("{} c", view.id));
3100            });
3101
3102            let actions_clone = actions.clone();
3103            app.add_action("action", move |view: &mut ViewB, _: &ActionArg, ctx| {
3104                ctx.propagate_action();
3105                actions_clone.borrow_mut().push(format!("{} d", view.id));
3106            });
3107
3108            let (window_id, view_1) = app.add_window(|_| ViewA { id: 1 });
3109            let view_2 = app.add_view(window_id, |_| ViewB { id: 2 });
3110            let view_3 = app.add_view(window_id, |_| ViewA { id: 3 });
3111            let view_4 = app.add_view(window_id, |_| ViewB { id: 4 });
3112
3113            app.dispatch_action(
3114                window_id,
3115                vec![view_1.id(), view_2.id(), view_3.id(), view_4.id()],
3116                "action",
3117                ActionArg { foo: "bar".into() },
3118            );
3119
3120            assert_eq!(
3121                *actions.borrow(),
3122                vec!["4 d", "4 c", "3 b", "3 a", "2 d", "2 c", "1 b"]
3123            );
3124
3125            // Remove view_1, which doesn't propagate the action
3126            actions.borrow_mut().clear();
3127            app.dispatch_action(
3128                window_id,
3129                vec![view_2.id(), view_3.id(), view_4.id()],
3130                "action",
3131                ActionArg { foo: "bar".into() },
3132            );
3133
3134            assert_eq!(
3135                *actions.borrow(),
3136                vec!["4 d", "4 c", "3 b", "3 a", "2 d", "2 c", "global b", "global a"]
3137            );
3138        })
3139    }
3140
3141    #[test]
3142    fn test_dispatch_keystroke() {
3143        use std::cell::Cell;
3144
3145        #[derive(Clone)]
3146        struct ActionArg {
3147            key: String,
3148        }
3149
3150        struct View {
3151            id: usize,
3152            keymap_context: keymap::Context,
3153        }
3154
3155        impl Entity for View {
3156            type Event = ();
3157        }
3158
3159        impl super::View for View {
3160            fn render<'a>(&self, _: &AppContext) -> ElementBox {
3161                Empty::new().boxed()
3162            }
3163
3164            fn ui_name() -> &'static str {
3165                "View"
3166            }
3167
3168            fn keymap_context(&self, _: &AppContext) -> keymap::Context {
3169                self.keymap_context.clone()
3170            }
3171        }
3172
3173        impl View {
3174            fn new(id: usize) -> Self {
3175                View {
3176                    id,
3177                    keymap_context: keymap::Context::default(),
3178                }
3179            }
3180        }
3181
3182        App::test((), |app| {
3183            let mut view_1 = View::new(1);
3184            let mut view_2 = View::new(2);
3185            let mut view_3 = View::new(3);
3186            view_1.keymap_context.set.insert("a".into());
3187            view_2.keymap_context.set.insert("b".into());
3188            view_3.keymap_context.set.insert("c".into());
3189
3190            let (window_id, view_1) = app.add_window(|_| view_1);
3191            let view_2 = app.add_view(window_id, |_| view_2);
3192            let view_3 = app.add_view(window_id, |_| view_3);
3193
3194            // This keymap's only binding dispatches an action on view 2 because that view will have
3195            // "a" and "b" in its context, but not "c".
3196            let binding = keymap::Binding::new("a", "action", Some("a && b && !c"))
3197                .with_arg(ActionArg { key: "a".into() });
3198            app.add_bindings(vec![binding]);
3199
3200            let handled_action = Rc::new(Cell::new(false));
3201            let handled_action_clone = handled_action.clone();
3202            app.add_action("action", move |view: &mut View, arg: &ActionArg, _ctx| {
3203                handled_action_clone.set(true);
3204                assert_eq!(view.id, 2);
3205                assert_eq!(arg.key, "a");
3206            });
3207
3208            app.dispatch_keystroke(
3209                window_id,
3210                vec![view_1.id(), view_2.id(), view_3.id()],
3211                &Keystroke::parse("a").unwrap(),
3212            )
3213            .unwrap();
3214
3215            assert!(handled_action.get());
3216        });
3217    }
3218
3219    // #[test]
3220    // fn test_ui_and_window_updates() {
3221    //     struct View {
3222    //         count: usize,
3223    //     }
3224
3225    //     impl Entity for View {
3226    //         type Event = ();
3227    //     }
3228
3229    //     impl super::View for View {
3230    //         fn render<'a>(&self, _: &AppContext) -> ElementBox {
3231    //             Empty::new().boxed()
3232    //         }
3233
3234    //         fn ui_name() -> &'static str {
3235    //             "View"
3236    //         }
3237    //     }
3238
3239    //     App::test(|app| async move {
3240    //         let (window_id, _) = app.add_window(|_| View { count: 3 });
3241    //         let view_1 = app.add_view(window_id, |_| View { count: 1 });
3242    //         let view_2 = app.add_view(window_id, |_| View { count: 2 });
3243
3244    //         // Ensure that registering for UI updates after mutating the app still gives us all the
3245    //         // updates.
3246    //         let ui_updates = Rc::new(RefCell::new(Vec::new()));
3247    //         let ui_updates_ = ui_updates.clone();
3248    //         app.on_ui_update(move |update, _| ui_updates_.borrow_mut().push(update));
3249
3250    //         assert_eq!(
3251    //             ui_updates.borrow_mut().drain(..).collect::<Vec<_>>(),
3252    //             vec![UiUpdate::OpenWindow {
3253    //                 window_id,
3254    //                 width: 1024.0,
3255    //                 height: 768.0,
3256    //             }]
3257    //         );
3258
3259    //         let window_invalidations = Rc::new(RefCell::new(Vec::new()));
3260    //         let window_invalidations_ = window_invalidations.clone();
3261    //         app.on_window_invalidated(window_id, move |update, _| {
3262    //             window_invalidations_.borrow_mut().push(update)
3263    //         });
3264
3265    //         let view_2_id = view_2.id();
3266    //         view_1.update(app, |view, ctx| {
3267    //             view.count = 7;
3268    //             ctx.notify();
3269    //             drop(view_2);
3270    //         });
3271
3272    //         let invalidation = window_invalidations.borrow_mut().drain(..).next().unwrap();
3273    //         assert_eq!(invalidation.updated.len(), 1);
3274    //         assert!(invalidation.updated.contains(&view_1.id()));
3275    //         assert_eq!(invalidation.removed, vec![view_2_id]);
3276
3277    //         let view_3 = view_1.update(app, |_, ctx| ctx.add_view(|_| View { count: 8 }));
3278
3279    //         let invalidation = window_invalidations.borrow_mut().drain(..).next().unwrap();
3280    //         assert_eq!(invalidation.updated.len(), 1);
3281    //         assert!(invalidation.updated.contains(&view_3.id()));
3282    //         assert!(invalidation.removed.is_empty());
3283
3284    //         view_3
3285    //             .update(app, |_, ctx| {
3286    //                 ctx.spawn_local(async { 9 }, |me, output, ctx| {
3287    //                     me.count = output;
3288    //                     ctx.notify();
3289    //                 })
3290    //             })
3291    //             .await;
3292
3293    //         let invalidation = window_invalidations.borrow_mut().drain(..).next().unwrap();
3294    //         assert_eq!(invalidation.updated.len(), 1);
3295    //         assert!(invalidation.updated.contains(&view_3.id()));
3296    //         assert!(invalidation.removed.is_empty());
3297    //     });
3298    // }
3299
3300    #[test]
3301    fn test_finish_pending_tasks() {
3302        struct View;
3303
3304        impl Entity for View {
3305            type Event = ();
3306        }
3307
3308        impl super::View for View {
3309            fn render<'a>(&self, _: &AppContext) -> ElementBox {
3310                Empty::new().boxed()
3311            }
3312
3313            fn ui_name() -> &'static str {
3314                "View"
3315            }
3316        }
3317
3318        struct Model;
3319
3320        impl Entity for Model {
3321            type Event = ();
3322        }
3323
3324        App::test_async((), |mut app| async move {
3325            let model = app.add_model(|_| Model);
3326            let (_, view) = app.add_window(|_| View);
3327
3328            model.update(&mut app, |_, ctx| {
3329                ctx.spawn(async {}, |_, _, _| {}).detach();
3330                // Cancel this task
3331                drop(ctx.spawn(async {}, |_, _, _| {}));
3332            });
3333
3334            view.update(&mut app, |_, ctx| {
3335                ctx.spawn(async {}, |_, _, _| {}).detach();
3336                // Cancel this task
3337                drop(ctx.spawn(async {}, |_, _, _| {}));
3338            });
3339
3340            assert!(!app.0.borrow().future_handlers.borrow().is_empty());
3341            app.finish_pending_tasks().await;
3342            assert!(app.0.borrow().future_handlers.borrow().is_empty());
3343            app.finish_pending_tasks().await; // Don't block if there are no tasks
3344
3345            model.update(&mut app, |_, ctx| {
3346                ctx.spawn_stream(smol::stream::iter(vec![1, 2, 3]), |_, _, _| {}, |_, _| {})
3347                    .detach();
3348                // Cancel this task
3349                drop(ctx.spawn_stream(smol::stream::iter(vec![1, 2, 3]), |_, _, _| {}, |_, _| {}));
3350            });
3351
3352            view.update(&mut app, |_, ctx| {
3353                ctx.spawn_stream(smol::stream::iter(vec![1, 2, 3]), |_, _, _| {}, |_, _| {})
3354                    .detach();
3355                // Cancel this task
3356                drop(ctx.spawn_stream(smol::stream::iter(vec![1, 2, 3]), |_, _, _| {}, |_, _| {}));
3357            });
3358
3359            assert!(!app.0.borrow().stream_handlers.borrow().is_empty());
3360            app.finish_pending_tasks().await;
3361            assert!(app.0.borrow().stream_handlers.borrow().is_empty());
3362            app.finish_pending_tasks().await; // Don't block if there are no tasks
3363
3364            // Tasks are considered finished when we drop handles
3365            let mut tasks = Vec::new();
3366            model.update(&mut app, |_, ctx| {
3367                tasks.push(Box::new(ctx.spawn(async {}, |_, _, _| {})));
3368                tasks.push(Box::new(ctx.spawn_stream(
3369                    smol::stream::iter(vec![1, 2, 3]),
3370                    |_, _, _| {},
3371                    |_, _| {},
3372                )));
3373            });
3374
3375            view.update(&mut app, |_, ctx| {
3376                tasks.push(Box::new(ctx.spawn(async {}, |_, _, _| {})));
3377                tasks.push(Box::new(ctx.spawn_stream(
3378                    smol::stream::iter(vec![1, 2, 3]),
3379                    |_, _, _| {},
3380                    |_, _| {},
3381                )));
3382            });
3383
3384            assert!(!app.0.borrow().stream_handlers.borrow().is_empty());
3385
3386            let finish_pending_tasks = app.finish_pending_tasks();
3387            drop(tasks);
3388            finish_pending_tasks.await;
3389            assert!(app.0.borrow().stream_handlers.borrow().is_empty());
3390            app.finish_pending_tasks().await; // Don't block if there are no tasks
3391        });
3392    }
3393}