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