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    pub fn paste(&self) -> Option<String> {
1220        self.platform.paste()
1221    }
1222}
1223
1224impl ReadModel for MutableAppContext {
1225    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1226        if let Some(model) = self.ctx.models.get(&handle.model_id) {
1227            model
1228                .as_any()
1229                .downcast_ref()
1230                .expect("Downcast is type safe")
1231        } else {
1232            panic!("Circular model reference");
1233        }
1234    }
1235}
1236
1237impl UpdateModel for MutableAppContext {
1238    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
1239    where
1240        T: Entity,
1241        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
1242    {
1243        if let Some(mut model) = self.ctx.models.remove(&handle.model_id) {
1244            self.pending_flushes += 1;
1245            let mut ctx = ModelContext::new(self, handle.model_id);
1246            let result = update(
1247                model
1248                    .as_any_mut()
1249                    .downcast_mut()
1250                    .expect("Downcast is type safe"),
1251                &mut ctx,
1252            );
1253            self.ctx.models.insert(handle.model_id, model);
1254            self.flush_effects();
1255            result
1256        } else {
1257            panic!("Circular model update");
1258        }
1259    }
1260}
1261
1262impl ReadView for MutableAppContext {
1263    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
1264        if let Some(window) = self.ctx.windows.get(&handle.window_id) {
1265            if let Some(view) = window.views.get(&handle.view_id) {
1266                view.as_any().downcast_ref().expect("Downcast is type safe")
1267            } else {
1268                panic!("Circular view reference");
1269            }
1270        } else {
1271            panic!("Window does not exist");
1272        }
1273    }
1274}
1275
1276impl UpdateView for MutableAppContext {
1277    fn update_view<T, F, S>(&mut self, handle: &ViewHandle<T>, update: F) -> S
1278    where
1279        T: View,
1280        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
1281    {
1282        self.pending_flushes += 1;
1283        let mut view = if let Some(window) = self.ctx.windows.get_mut(&handle.window_id) {
1284            if let Some(view) = window.views.remove(&handle.view_id) {
1285                view
1286            } else {
1287                panic!("Circular view update");
1288            }
1289        } else {
1290            panic!("Window does not exist");
1291        };
1292
1293        let mut ctx = ViewContext::new(self, handle.window_id, handle.view_id);
1294        let result = update(
1295            view.as_any_mut()
1296                .downcast_mut()
1297                .expect("Downcast is type safe"),
1298            &mut ctx,
1299        );
1300        self.ctx
1301            .windows
1302            .get_mut(&handle.window_id)
1303            .unwrap()
1304            .views
1305            .insert(handle.view_id, view);
1306        self.flush_effects();
1307        result
1308    }
1309}
1310
1311impl AsRef<AppContext> for MutableAppContext {
1312    fn as_ref(&self) -> &AppContext {
1313        &self.ctx
1314    }
1315}
1316
1317pub struct AppContext {
1318    models: HashMap<usize, Box<dyn AnyModel>>,
1319    windows: HashMap<usize, Window>,
1320    background: Arc<executor::Background>,
1321    ref_counts: Arc<Mutex<RefCounts>>,
1322}
1323
1324impl AppContext {
1325    pub fn root_view_id(&self, window_id: usize) -> Option<usize> {
1326        self.windows
1327            .get(&window_id)
1328            .and_then(|window| window.root_view.as_ref().map(|v| v.id()))
1329    }
1330
1331    pub fn focused_view_id(&self, window_id: usize) -> Option<usize> {
1332        self.windows
1333            .get(&window_id)
1334            .and_then(|window| window.focused_view)
1335    }
1336
1337    pub fn render_view(&self, window_id: usize, view_id: usize) -> Result<ElementBox> {
1338        self.windows
1339            .get(&window_id)
1340            .and_then(|w| w.views.get(&view_id))
1341            .map(|v| v.render(self))
1342            .ok_or(anyhow!("view not found"))
1343    }
1344
1345    pub fn render_views(&self, window_id: usize) -> Result<HashMap<usize, ElementBox>> {
1346        self.windows
1347            .get(&window_id)
1348            .map(|w| {
1349                w.views
1350                    .iter()
1351                    .map(|(id, view)| (*id, view.render(self)))
1352                    .collect::<HashMap<_, ElementBox>>()
1353            })
1354            .ok_or(anyhow!("window not found"))
1355    }
1356
1357    pub fn background_executor(&self) -> &Arc<executor::Background> {
1358        &self.background
1359    }
1360}
1361
1362impl ReadModel for AppContext {
1363    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1364        if let Some(model) = self.models.get(&handle.model_id) {
1365            model
1366                .as_any()
1367                .downcast_ref()
1368                .expect("downcast should be type safe")
1369        } else {
1370            panic!("circular model reference");
1371        }
1372    }
1373}
1374
1375impl ReadView for AppContext {
1376    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
1377        if let Some(window) = self.windows.get(&handle.window_id) {
1378            if let Some(view) = window.views.get(&handle.view_id) {
1379                view.as_any()
1380                    .downcast_ref()
1381                    .expect("downcast should be type safe")
1382            } else {
1383                panic!("circular view reference");
1384            }
1385        } else {
1386            panic!("window does not exist");
1387        }
1388    }
1389}
1390
1391#[derive(Default)]
1392struct Window {
1393    views: HashMap<usize, Box<dyn AnyView>>,
1394    root_view: Option<AnyViewHandle>,
1395    focused_view: Option<usize>,
1396}
1397
1398#[derive(Default, Clone)]
1399pub struct WindowInvalidation {
1400    pub updated: HashSet<usize>,
1401    pub removed: Vec<usize>,
1402}
1403
1404pub enum Effect {
1405    Event {
1406        entity_id: usize,
1407        payload: Box<dyn Any>,
1408    },
1409    ModelNotification {
1410        model_id: usize,
1411    },
1412    ViewNotification {
1413        window_id: usize,
1414        view_id: usize,
1415    },
1416    Focus {
1417        window_id: usize,
1418        view_id: usize,
1419    },
1420}
1421
1422pub trait AnyModel: Send + Sync {
1423    fn as_any(&self) -> &dyn Any;
1424    fn as_any_mut(&mut self) -> &mut dyn Any;
1425}
1426
1427impl<T> AnyModel for T
1428where
1429    T: Entity,
1430{
1431    fn as_any(&self) -> &dyn Any {
1432        self
1433    }
1434
1435    fn as_any_mut(&mut self) -> &mut dyn Any {
1436        self
1437    }
1438}
1439
1440pub trait AnyView: Send + Sync {
1441    fn as_any(&self) -> &dyn Any;
1442    fn as_any_mut(&mut self) -> &mut dyn Any;
1443    fn ui_name(&self) -> &'static str;
1444    fn render<'a>(&self, app: &AppContext) -> ElementBox;
1445    fn on_focus(&mut self, app: &mut MutableAppContext, window_id: usize, view_id: usize);
1446    fn on_blur(&mut self, app: &mut MutableAppContext, window_id: usize, view_id: usize);
1447    fn keymap_context(&self, app: &AppContext) -> keymap::Context;
1448}
1449
1450impl<T> AnyView for T
1451where
1452    T: View,
1453{
1454    fn as_any(&self) -> &dyn Any {
1455        self
1456    }
1457
1458    fn as_any_mut(&mut self) -> &mut dyn Any {
1459        self
1460    }
1461
1462    fn ui_name(&self) -> &'static str {
1463        T::ui_name()
1464    }
1465
1466    fn render<'a>(&self, app: &AppContext) -> ElementBox {
1467        View::render(self, app)
1468    }
1469
1470    fn on_focus(&mut self, app: &mut MutableAppContext, window_id: usize, view_id: usize) {
1471        let mut ctx = ViewContext::new(app, window_id, view_id);
1472        View::on_focus(self, &mut ctx);
1473    }
1474
1475    fn on_blur(&mut self, app: &mut MutableAppContext, window_id: usize, view_id: usize) {
1476        let mut ctx = ViewContext::new(app, window_id, view_id);
1477        View::on_blur(self, &mut ctx);
1478    }
1479
1480    fn keymap_context(&self, app: &AppContext) -> keymap::Context {
1481        View::keymap_context(self, app)
1482    }
1483}
1484
1485pub struct ModelContext<'a, T: ?Sized> {
1486    app: &'a mut MutableAppContext,
1487    model_id: usize,
1488    model_type: PhantomData<T>,
1489    halt_stream: bool,
1490}
1491
1492impl<'a, T: Entity> ModelContext<'a, T> {
1493    fn new(app: &'a mut MutableAppContext, model_id: usize) -> Self {
1494        Self {
1495            app,
1496            model_id,
1497            model_type: PhantomData,
1498            halt_stream: false,
1499        }
1500    }
1501
1502    pub fn app(&self) -> &AppContext {
1503        &self.app.ctx
1504    }
1505
1506    pub fn app_mut(&mut self) -> &mut MutableAppContext {
1507        self.app
1508    }
1509
1510    pub fn background_executor(&self) -> &Arc<executor::Background> {
1511        &self.app.ctx.background
1512    }
1513
1514    pub fn halt_stream(&mut self) {
1515        self.halt_stream = true;
1516    }
1517
1518    pub fn model_id(&self) -> usize {
1519        self.model_id
1520    }
1521
1522    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
1523    where
1524        S: Entity,
1525        F: FnOnce(&mut ModelContext<S>) -> S,
1526    {
1527        self.app.add_model(build_model)
1528    }
1529
1530    pub fn subscribe<S: Entity, F>(&mut self, handle: &ModelHandle<S>, mut callback: F)
1531    where
1532        S::Event: 'static,
1533        F: 'static + FnMut(&mut T, &S::Event, &mut ModelContext<T>),
1534    {
1535        self.app
1536            .subscriptions
1537            .entry(handle.model_id)
1538            .or_default()
1539            .push(Subscription::FromModel {
1540                model_id: self.model_id,
1541                callback: Box::new(move |model, payload, app, model_id| {
1542                    let model = model.downcast_mut().expect("downcast is type safe");
1543                    let payload = payload.downcast_ref().expect("downcast is type safe");
1544                    let mut ctx = ModelContext::new(app, model_id);
1545                    callback(model, payload, &mut ctx);
1546                }),
1547            });
1548    }
1549
1550    pub fn emit(&mut self, payload: T::Event) {
1551        self.app.pending_effects.push_back(Effect::Event {
1552            entity_id: self.model_id,
1553            payload: Box::new(payload),
1554        });
1555    }
1556
1557    pub fn observe<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F)
1558    where
1559        S: Entity,
1560        F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ModelContext<T>),
1561    {
1562        self.app
1563            .observations
1564            .entry(handle.model_id)
1565            .or_default()
1566            .push(Observation::FromModel {
1567                model_id: self.model_id,
1568                callback: Box::new(move |model, observed_id, app, model_id| {
1569                    let model = model.downcast_mut().expect("downcast is type safe");
1570                    let observed = ModelHandle::new(observed_id, &app.ctx.ref_counts);
1571                    let mut ctx = ModelContext::new(app, model_id);
1572                    callback(model, observed, &mut ctx);
1573                }),
1574            });
1575    }
1576
1577    pub fn notify(&mut self) {
1578        self.app
1579            .pending_effects
1580            .push_back(Effect::ModelNotification {
1581                model_id: self.model_id,
1582            });
1583    }
1584
1585    fn handle(&self) -> ModelHandle<T> {
1586        ModelHandle::new(self.model_id, &self.app.ctx.ref_counts)
1587    }
1588
1589    pub fn spawn<S, F, U>(&mut self, future: S, callback: F) -> EntityTask<U>
1590    where
1591        S: 'static + Future,
1592        F: 'static + FnOnce(&mut T, S::Output, &mut ModelContext<T>) -> U,
1593        U: 'static,
1594    {
1595        let handle = self.handle();
1596        let task = self.app.spawn::<S, U>(future);
1597
1598        self.app.future_handlers.borrow_mut().insert(
1599            task.id,
1600            Box::new(move |output, ctx| {
1601                let output = *output.downcast().unwrap();
1602                handle.update(ctx, |model, ctx| Box::new(callback(model, output, ctx)))
1603            }),
1604        );
1605
1606        task
1607    }
1608
1609    pub fn spawn_stream<S, F, G, U>(
1610        &mut self,
1611        stream: S,
1612        mut item_callback: F,
1613        done_callback: G,
1614    ) -> EntityTask<U>
1615    where
1616        S: 'static + Stream + Unpin,
1617        F: 'static + FnMut(&mut T, S::Item, &mut ModelContext<T>),
1618        G: 'static + FnOnce(&mut T, &mut ModelContext<T>) -> U,
1619        U: 'static + Any,
1620    {
1621        let handle = self.handle();
1622        let task = self.app.spawn_stream(stream);
1623
1624        self.app.stream_handlers.borrow_mut().insert(
1625            task.id,
1626            StreamHandler {
1627                item_callback: {
1628                    let handle = handle.clone();
1629                    Box::new(move |output, app| {
1630                        let output = *output.downcast().unwrap();
1631                        handle.update(app, |model, ctx| {
1632                            item_callback(model, output, ctx);
1633                            ctx.halt_stream
1634                        })
1635                    })
1636                },
1637                done_callback: Box::new(move |app| {
1638                    handle.update(app, |model, ctx| Box::new(done_callback(model, ctx)))
1639                }),
1640            },
1641        );
1642
1643        task
1644    }
1645}
1646
1647impl<M> ReadModel for ModelContext<'_, M> {
1648    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1649        self.app.read_model(handle)
1650    }
1651}
1652
1653impl<M> UpdateModel for ModelContext<'_, M> {
1654    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
1655    where
1656        T: Entity,
1657        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
1658    {
1659        self.app.update_model(handle, update)
1660    }
1661}
1662
1663pub struct ViewContext<'a, T: ?Sized> {
1664    app: &'a mut MutableAppContext,
1665    window_id: usize,
1666    view_id: usize,
1667    view_type: PhantomData<T>,
1668    halt_action_dispatch: bool,
1669    halt_stream: bool,
1670}
1671
1672impl<'a, T: View> ViewContext<'a, T> {
1673    fn new(app: &'a mut MutableAppContext, window_id: usize, view_id: usize) -> Self {
1674        Self {
1675            app,
1676            window_id,
1677            view_id,
1678            view_type: PhantomData,
1679            halt_action_dispatch: true,
1680            halt_stream: false,
1681        }
1682    }
1683
1684    pub fn handle(&self) -> ViewHandle<T> {
1685        ViewHandle::new(self.window_id, self.view_id, &self.app.ctx.ref_counts)
1686    }
1687
1688    pub fn window_id(&self) -> usize {
1689        self.window_id
1690    }
1691
1692    pub fn app(&self) -> &AppContext {
1693        &self.app.ctx
1694    }
1695
1696    pub fn app_mut(&mut self) -> &mut MutableAppContext {
1697        self.app
1698    }
1699
1700    pub fn background_executor(&self) -> &Arc<executor::Background> {
1701        &self.app.ctx.background
1702    }
1703
1704    pub fn debug_elements(&self) -> crate::json::Value {
1705        self.app.debug_elements(self.window_id).unwrap()
1706    }
1707
1708    pub fn focus<S>(&mut self, handle: S)
1709    where
1710        S: Into<AnyViewHandle>,
1711    {
1712        let handle = handle.into();
1713        self.app.pending_effects.push_back(Effect::Focus {
1714            window_id: handle.window_id,
1715            view_id: handle.view_id,
1716        });
1717    }
1718
1719    pub fn focus_self(&mut self) {
1720        self.app.pending_effects.push_back(Effect::Focus {
1721            window_id: self.window_id,
1722            view_id: self.view_id,
1723        });
1724    }
1725
1726    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
1727    where
1728        S: Entity,
1729        F: FnOnce(&mut ModelContext<S>) -> S,
1730    {
1731        self.app.add_model(build_model)
1732    }
1733
1734    pub fn add_view<S, F>(&mut self, build_view: F) -> ViewHandle<S>
1735    where
1736        S: View,
1737        F: FnOnce(&mut ViewContext<S>) -> S,
1738    {
1739        self.app.add_view(self.window_id, build_view)
1740    }
1741
1742    pub fn add_option_view<S, F>(&mut self, build_view: F) -> Option<ViewHandle<S>>
1743    where
1744        S: View,
1745        F: FnOnce(&mut ViewContext<S>) -> Option<S>,
1746    {
1747        self.app.add_option_view(self.window_id, build_view)
1748    }
1749
1750    pub fn subscribe_to_model<E, F>(&mut self, handle: &ModelHandle<E>, mut callback: F)
1751    where
1752        E: Entity,
1753        E::Event: 'static,
1754        F: 'static + FnMut(&mut T, ModelHandle<E>, &E::Event, &mut ViewContext<T>),
1755    {
1756        let emitter_handle = handle.downgrade();
1757        self.app
1758            .subscriptions
1759            .entry(handle.id())
1760            .or_default()
1761            .push(Subscription::FromView {
1762                window_id: self.window_id,
1763                view_id: self.view_id,
1764                callback: Box::new(move |view, payload, app, window_id, view_id| {
1765                    if let Some(emitter_handle) = emitter_handle.upgrade(app.as_ref()) {
1766                        let model = view.downcast_mut().expect("downcast is type safe");
1767                        let payload = payload.downcast_ref().expect("downcast is type safe");
1768                        let mut ctx = ViewContext::new(app, window_id, view_id);
1769                        callback(model, emitter_handle, payload, &mut ctx);
1770                    }
1771                }),
1772            });
1773    }
1774
1775    pub fn subscribe_to_view<V, F>(&mut self, handle: &ViewHandle<V>, mut callback: F)
1776    where
1777        V: View,
1778        V::Event: 'static,
1779        F: 'static + FnMut(&mut T, ViewHandle<V>, &V::Event, &mut ViewContext<T>),
1780    {
1781        let emitter_handle = handle.downgrade();
1782
1783        self.app
1784            .subscriptions
1785            .entry(handle.id())
1786            .or_default()
1787            .push(Subscription::FromView {
1788                window_id: self.window_id,
1789                view_id: self.view_id,
1790                callback: Box::new(move |view, payload, app, window_id, view_id| {
1791                    if let Some(emitter_handle) = emitter_handle.upgrade(app.as_ref()) {
1792                        let model = view.downcast_mut().expect("downcast is type safe");
1793                        let payload = payload.downcast_ref().expect("downcast is type safe");
1794                        let mut ctx = ViewContext::new(app, window_id, view_id);
1795                        callback(model, emitter_handle, payload, &mut ctx);
1796                    }
1797                }),
1798            });
1799    }
1800
1801    pub fn emit(&mut self, payload: T::Event) {
1802        self.app.pending_effects.push_back(Effect::Event {
1803            entity_id: self.view_id,
1804            payload: Box::new(payload),
1805        });
1806    }
1807
1808    pub fn observe<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F)
1809    where
1810        S: Entity,
1811        F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ViewContext<T>),
1812    {
1813        self.app
1814            .observations
1815            .entry(handle.id())
1816            .or_default()
1817            .push(Observation::FromView {
1818                window_id: self.window_id,
1819                view_id: self.view_id,
1820                callback: Box::new(move |view, observed_id, app, window_id, view_id| {
1821                    let view = view.downcast_mut().expect("downcast is type safe");
1822                    let observed = ModelHandle::new(observed_id, &app.ctx.ref_counts);
1823                    let mut ctx = ViewContext::new(app, window_id, view_id);
1824                    callback(view, observed, &mut ctx);
1825                }),
1826            });
1827    }
1828
1829    pub fn notify(&mut self) {
1830        self.app
1831            .pending_effects
1832            .push_back(Effect::ViewNotification {
1833                window_id: self.window_id,
1834                view_id: self.view_id,
1835            });
1836    }
1837
1838    pub fn propagate_action(&mut self) {
1839        self.halt_action_dispatch = false;
1840    }
1841
1842    pub fn halt_stream(&mut self) {
1843        self.halt_stream = true;
1844    }
1845
1846    pub fn spawn<S, F, U>(&mut self, future: S, callback: F) -> EntityTask<U>
1847    where
1848        S: 'static + Future,
1849        F: 'static + FnOnce(&mut T, S::Output, &mut ViewContext<T>) -> U,
1850        U: 'static,
1851    {
1852        let handle = self.handle();
1853        let task = self.app.spawn(future);
1854
1855        self.app.future_handlers.borrow_mut().insert(
1856            task.id,
1857            Box::new(move |output, app| {
1858                let output = *output.downcast().unwrap();
1859                handle.update(app, |view, ctx| Box::new(callback(view, output, ctx)))
1860            }),
1861        );
1862
1863        task
1864    }
1865
1866    pub fn spawn_stream<S, F, G, U>(
1867        &mut self,
1868        stream: S,
1869        mut item_callback: F,
1870        done_callback: G,
1871    ) -> EntityTask<U>
1872    where
1873        S: 'static + Stream + Unpin,
1874        F: 'static + FnMut(&mut T, S::Item, &mut ViewContext<T>),
1875        G: 'static + FnOnce(&mut T, &mut ViewContext<T>) -> U,
1876        U: 'static + Any,
1877    {
1878        let handle = self.handle();
1879        let task = self.app.spawn_stream(stream);
1880        self.app.stream_handlers.borrow_mut().insert(
1881            task.id,
1882            StreamHandler {
1883                item_callback: {
1884                    let handle = handle.clone();
1885                    Box::new(move |output, app| {
1886                        let output = *output.downcast().unwrap();
1887                        handle.update(app, |view, ctx| {
1888                            item_callback(view, output, ctx);
1889                            ctx.halt_stream
1890                        })
1891                    })
1892                },
1893                done_callback: Box::new(move |app| {
1894                    handle.update(app, |view, ctx| Box::new(done_callback(view, ctx)))
1895                }),
1896            },
1897        );
1898        task
1899    }
1900}
1901
1902impl<V> ReadModel for ViewContext<'_, V> {
1903    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1904        self.app.read_model(handle)
1905    }
1906}
1907
1908impl<V: View> UpdateModel for ViewContext<'_, V> {
1909    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
1910    where
1911        T: Entity,
1912        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
1913    {
1914        self.app.update_model(handle, update)
1915    }
1916}
1917
1918impl<V: View> ReadView for ViewContext<'_, V> {
1919    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
1920        self.app.read_view(handle)
1921    }
1922}
1923
1924impl<V: View> UpdateView for ViewContext<'_, V> {
1925    fn update_view<T, F, S>(&mut self, handle: &ViewHandle<T>, update: F) -> S
1926    where
1927        T: View,
1928        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
1929    {
1930        self.app.update_view(handle, update)
1931    }
1932}
1933
1934pub trait Handle<T> {
1935    fn id(&self) -> usize;
1936    fn location(&self) -> EntityLocation;
1937}
1938
1939#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
1940pub enum EntityLocation {
1941    Model(usize),
1942    View(usize, usize),
1943}
1944
1945pub struct ModelHandle<T> {
1946    model_id: usize,
1947    model_type: PhantomData<T>,
1948    ref_counts: Weak<Mutex<RefCounts>>,
1949}
1950
1951impl<T: Entity> ModelHandle<T> {
1952    fn new(model_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
1953        ref_counts.lock().inc(model_id);
1954        Self {
1955            model_id,
1956            model_type: PhantomData,
1957            ref_counts: Arc::downgrade(ref_counts),
1958        }
1959    }
1960
1961    fn downgrade(&self) -> WeakModelHandle<T> {
1962        WeakModelHandle::new(self.model_id)
1963    }
1964
1965    pub fn id(&self) -> usize {
1966        self.model_id
1967    }
1968
1969    pub fn read<'a, A: ReadModel>(&self, app: &'a A) -> &'a T {
1970        app.read_model(self)
1971    }
1972
1973    pub fn update<A, F, S>(&self, app: &mut A, update: F) -> S
1974    where
1975        A: UpdateModel,
1976        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
1977    {
1978        app.update_model(self, update)
1979    }
1980}
1981
1982impl<T> Clone for ModelHandle<T> {
1983    fn clone(&self) -> Self {
1984        if let Some(ref_counts) = self.ref_counts.upgrade() {
1985            ref_counts.lock().inc(self.model_id);
1986        }
1987
1988        Self {
1989            model_id: self.model_id,
1990            model_type: PhantomData,
1991            ref_counts: self.ref_counts.clone(),
1992        }
1993    }
1994}
1995
1996impl<T> PartialEq for ModelHandle<T> {
1997    fn eq(&self, other: &Self) -> bool {
1998        self.model_id == other.model_id
1999    }
2000}
2001
2002impl<T> Eq for ModelHandle<T> {}
2003
2004impl<T> Hash for ModelHandle<T> {
2005    fn hash<H: Hasher>(&self, state: &mut H) {
2006        self.model_id.hash(state);
2007    }
2008}
2009
2010impl<T> std::borrow::Borrow<usize> for ModelHandle<T> {
2011    fn borrow(&self) -> &usize {
2012        &self.model_id
2013    }
2014}
2015
2016impl<T> Debug for ModelHandle<T> {
2017    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2018        f.debug_tuple(&format!("ModelHandle<{}>", type_name::<T>()))
2019            .field(&self.model_id)
2020            .finish()
2021    }
2022}
2023
2024unsafe impl<T> Send for ModelHandle<T> {}
2025unsafe impl<T> Sync for ModelHandle<T> {}
2026
2027impl<T> Drop for ModelHandle<T> {
2028    fn drop(&mut self) {
2029        if let Some(ref_counts) = self.ref_counts.upgrade() {
2030            ref_counts.lock().dec_model(self.model_id);
2031        }
2032    }
2033}
2034
2035impl<T> Handle<T> for ModelHandle<T> {
2036    fn id(&self) -> usize {
2037        self.model_id
2038    }
2039
2040    fn location(&self) -> EntityLocation {
2041        EntityLocation::Model(self.model_id)
2042    }
2043}
2044
2045pub struct WeakModelHandle<T> {
2046    model_id: usize,
2047    model_type: PhantomData<T>,
2048}
2049
2050impl<T: Entity> WeakModelHandle<T> {
2051    fn new(model_id: usize) -> Self {
2052        Self {
2053            model_id,
2054            model_type: PhantomData,
2055        }
2056    }
2057
2058    pub fn upgrade(&self, app: &AppContext) -> Option<ModelHandle<T>> {
2059        if app.models.contains_key(&self.model_id) {
2060            Some(ModelHandle::new(self.model_id, &app.ref_counts))
2061        } else {
2062            None
2063        }
2064    }
2065}
2066
2067pub struct ViewHandle<T> {
2068    window_id: usize,
2069    view_id: usize,
2070    view_type: PhantomData<T>,
2071    ref_counts: Weak<Mutex<RefCounts>>,
2072}
2073
2074impl<T: View> ViewHandle<T> {
2075    fn new(window_id: usize, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
2076        ref_counts.lock().inc(view_id);
2077        Self {
2078            window_id,
2079            view_id,
2080            view_type: PhantomData,
2081            ref_counts: Arc::downgrade(ref_counts),
2082        }
2083    }
2084
2085    pub fn downgrade(&self) -> WeakViewHandle<T> {
2086        WeakViewHandle::new(self.window_id, self.view_id)
2087    }
2088
2089    pub fn window_id(&self) -> usize {
2090        self.window_id
2091    }
2092
2093    pub fn id(&self) -> usize {
2094        self.view_id
2095    }
2096
2097    pub fn read<'a, A: ReadView>(&self, app: &'a A) -> &'a T {
2098        app.read_view(self)
2099    }
2100
2101    pub fn update<A, F, S>(&self, app: &mut A, update: F) -> S
2102    where
2103        A: UpdateView,
2104        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
2105    {
2106        app.update_view(self, update)
2107    }
2108
2109    pub fn is_focused(&self, app: &AppContext) -> bool {
2110        app.focused_view_id(self.window_id)
2111            .map_or(false, |focused_id| focused_id == self.view_id)
2112    }
2113}
2114
2115impl<T> Clone for ViewHandle<T> {
2116    fn clone(&self) -> Self {
2117        if let Some(ref_counts) = self.ref_counts.upgrade() {
2118            ref_counts.lock().inc(self.view_id);
2119        }
2120
2121        Self {
2122            window_id: self.window_id,
2123            view_id: self.view_id,
2124            view_type: PhantomData,
2125            ref_counts: self.ref_counts.clone(),
2126        }
2127    }
2128}
2129
2130impl<T> PartialEq for ViewHandle<T> {
2131    fn eq(&self, other: &Self) -> bool {
2132        self.window_id == other.window_id && self.view_id == other.view_id
2133    }
2134}
2135
2136impl<T> Eq for ViewHandle<T> {}
2137
2138impl<T> Debug for ViewHandle<T> {
2139    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2140        f.debug_struct(&format!("ViewHandle<{}>", type_name::<T>()))
2141            .field("window_id", &self.window_id)
2142            .field("view_id", &self.view_id)
2143            .finish()
2144    }
2145}
2146
2147impl<T> Drop for ViewHandle<T> {
2148    fn drop(&mut self) {
2149        if let Some(ref_counts) = self.ref_counts.upgrade() {
2150            ref_counts.lock().dec_view(self.window_id, self.view_id);
2151        }
2152    }
2153}
2154
2155impl<T> Handle<T> for ViewHandle<T> {
2156    fn id(&self) -> usize {
2157        self.view_id
2158    }
2159
2160    fn location(&self) -> EntityLocation {
2161        EntityLocation::View(self.window_id, self.view_id)
2162    }
2163}
2164
2165#[derive(Clone)]
2166pub struct AnyViewHandle {
2167    window_id: usize,
2168    view_id: usize,
2169    view_type: TypeId,
2170    ref_counts: Weak<Mutex<RefCounts>>,
2171}
2172
2173impl AnyViewHandle {
2174    pub fn id(&self) -> usize {
2175        self.view_id
2176    }
2177
2178    pub fn is<T: 'static>(&self) -> bool {
2179        TypeId::of::<T>() == self.view_type
2180    }
2181
2182    pub fn downcast<T: View>(self) -> Option<ViewHandle<T>> {
2183        if self.is::<T>() {
2184            if let Some(ref_counts) = self.ref_counts.upgrade() {
2185                return Some(ViewHandle::new(self.window_id, self.view_id, &ref_counts));
2186            }
2187        }
2188        None
2189    }
2190}
2191
2192impl<T: View> From<&ViewHandle<T>> for AnyViewHandle {
2193    fn from(handle: &ViewHandle<T>) -> Self {
2194        if let Some(ref_counts) = handle.ref_counts.upgrade() {
2195            ref_counts.lock().inc(handle.view_id);
2196        }
2197        AnyViewHandle {
2198            window_id: handle.window_id,
2199            view_id: handle.view_id,
2200            view_type: TypeId::of::<T>(),
2201            ref_counts: handle.ref_counts.clone(),
2202        }
2203    }
2204}
2205
2206impl<T: View> From<ViewHandle<T>> for AnyViewHandle {
2207    fn from(handle: ViewHandle<T>) -> Self {
2208        (&handle).into()
2209    }
2210}
2211
2212pub struct WeakViewHandle<T> {
2213    window_id: usize,
2214    view_id: usize,
2215    view_type: PhantomData<T>,
2216}
2217
2218impl<T: View> WeakViewHandle<T> {
2219    fn new(window_id: usize, view_id: usize) -> Self {
2220        Self {
2221            window_id,
2222            view_id,
2223            view_type: PhantomData,
2224        }
2225    }
2226
2227    pub fn upgrade(&self, app: &AppContext) -> Option<ViewHandle<T>> {
2228        if app
2229            .windows
2230            .get(&self.window_id)
2231            .and_then(|w| w.views.get(&self.view_id))
2232            .is_some()
2233        {
2234            Some(ViewHandle::new(
2235                self.window_id,
2236                self.view_id,
2237                &app.ref_counts,
2238            ))
2239        } else {
2240            None
2241        }
2242    }
2243}
2244
2245impl<T> Clone for WeakViewHandle<T> {
2246    fn clone(&self) -> Self {
2247        Self {
2248            window_id: self.window_id,
2249            view_id: self.view_id,
2250            view_type: PhantomData,
2251        }
2252    }
2253}
2254
2255#[derive(Default)]
2256struct RefCounts {
2257    counts: HashMap<usize, usize>,
2258    dropped_models: HashSet<usize>,
2259    dropped_views: HashSet<(usize, usize)>,
2260}
2261
2262impl RefCounts {
2263    fn inc(&mut self, model_id: usize) {
2264        *self.counts.entry(model_id).or_insert(0) += 1;
2265    }
2266
2267    fn dec_model(&mut self, model_id: usize) {
2268        if let Some(count) = self.counts.get_mut(&model_id) {
2269            *count -= 1;
2270            if *count == 0 {
2271                self.counts.remove(&model_id);
2272                self.dropped_models.insert(model_id);
2273            }
2274        } else {
2275            panic!("Expected ref count to be positive")
2276        }
2277    }
2278
2279    fn dec_view(&mut self, window_id: usize, view_id: usize) {
2280        if let Some(count) = self.counts.get_mut(&view_id) {
2281            *count -= 1;
2282            if *count == 0 {
2283                self.counts.remove(&view_id);
2284                self.dropped_views.insert((window_id, view_id));
2285            }
2286        } else {
2287            panic!("Expected ref count to be positive")
2288        }
2289    }
2290
2291    fn take_dropped(&mut self) -> (HashSet<usize>, HashSet<(usize, usize)>) {
2292        let mut dropped_models = HashSet::new();
2293        let mut dropped_views = HashSet::new();
2294        std::mem::swap(&mut self.dropped_models, &mut dropped_models);
2295        std::mem::swap(&mut self.dropped_views, &mut dropped_views);
2296        (dropped_models, dropped_views)
2297    }
2298}
2299
2300enum Subscription {
2301    FromModel {
2302        model_id: usize,
2303        callback: Box<dyn FnMut(&mut dyn Any, &dyn Any, &mut MutableAppContext, usize)>,
2304    },
2305    FromView {
2306        window_id: usize,
2307        view_id: usize,
2308        callback: Box<dyn FnMut(&mut dyn Any, &dyn Any, &mut MutableAppContext, usize, usize)>,
2309    },
2310}
2311
2312enum Observation {
2313    FromModel {
2314        model_id: usize,
2315        callback: Box<dyn FnMut(&mut dyn Any, usize, &mut MutableAppContext, usize)>,
2316    },
2317    FromView {
2318        window_id: usize,
2319        view_id: usize,
2320        callback: Box<dyn FnMut(&mut dyn Any, usize, &mut MutableAppContext, usize, usize)>,
2321    },
2322}
2323
2324type FutureHandler = Box<dyn FnOnce(Box<dyn Any>, &mut MutableAppContext) -> Box<dyn Any>>;
2325
2326struct StreamHandler {
2327    item_callback: Box<dyn FnMut(Box<dyn Any>, &mut MutableAppContext) -> bool>,
2328    done_callback: Box<dyn FnOnce(&mut MutableAppContext) -> Box<dyn Any>>,
2329}
2330
2331#[must_use]
2332pub struct EntityTask<T> {
2333    id: usize,
2334    task: Option<executor::Task<T>>,
2335    handler_map: TaskHandlerMap,
2336    task_done: Arc<Condvar>,
2337}
2338
2339enum TaskHandlerMap {
2340    Detached,
2341    Future(Rc<RefCell<HashMap<usize, FutureHandler>>>),
2342    Stream(Rc<RefCell<HashMap<usize, StreamHandler>>>),
2343}
2344
2345impl<T> EntityTask<T> {
2346    fn new(
2347        id: usize,
2348        task: executor::Task<T>,
2349        handler_map: TaskHandlerMap,
2350        task_done: Arc<Condvar>,
2351    ) -> Self {
2352        Self {
2353            id,
2354            task: Some(task),
2355            handler_map,
2356            task_done,
2357        }
2358    }
2359
2360    pub fn detach(mut self) {
2361        self.handler_map = TaskHandlerMap::Detached;
2362        self.task.take().unwrap().detach();
2363    }
2364
2365    pub async fn cancel(mut self) -> Option<T> {
2366        let task = self.task.take().unwrap();
2367        task.cancel().await
2368    }
2369}
2370
2371impl<T> Future for EntityTask<T> {
2372    type Output = T;
2373
2374    fn poll(
2375        self: std::pin::Pin<&mut Self>,
2376        ctx: &mut std::task::Context<'_>,
2377    ) -> std::task::Poll<Self::Output> {
2378        let task = unsafe { self.map_unchecked_mut(|task| task.task.as_mut().unwrap()) };
2379        task.poll(ctx)
2380    }
2381}
2382
2383impl<T> Drop for EntityTask<T> {
2384    fn drop(self: &mut Self) {
2385        match &self.handler_map {
2386            TaskHandlerMap::Detached => {
2387                return;
2388            }
2389            TaskHandlerMap::Future(map) => {
2390                map.borrow_mut().remove(&self.id);
2391            }
2392            TaskHandlerMap::Stream(map) => {
2393                map.borrow_mut().remove(&self.id);
2394            }
2395        }
2396        self.task_done.notify_all();
2397    }
2398}
2399
2400#[cfg(test)]
2401mod tests {
2402    use super::*;
2403    use crate::elements::*;
2404
2405    #[test]
2406    fn test_model_handles() {
2407        struct Model {
2408            other: Option<ModelHandle<Model>>,
2409            events: Vec<String>,
2410        }
2411
2412        impl Entity for Model {
2413            type Event = usize;
2414        }
2415
2416        impl Model {
2417            fn new(other: Option<ModelHandle<Self>>, ctx: &mut ModelContext<Self>) -> Self {
2418                if let Some(other) = other.as_ref() {
2419                    ctx.observe(other, |me, _, _| {
2420                        me.events.push("notified".into());
2421                    });
2422                    ctx.subscribe(other, |me, event, _| {
2423                        me.events.push(format!("observed event {}", event));
2424                    });
2425                }
2426
2427                Self {
2428                    other,
2429                    events: Vec::new(),
2430                }
2431            }
2432        }
2433
2434        App::test((), |app| {
2435            let handle_1 = app.add_model(|ctx| Model::new(None, ctx));
2436            let handle_2 = app.add_model(|ctx| Model::new(Some(handle_1.clone()), ctx));
2437            assert_eq!(app.ctx.models.len(), 2);
2438
2439            handle_1.update(app, |model, ctx| {
2440                model.events.push("updated".into());
2441                ctx.emit(1);
2442                ctx.notify();
2443                ctx.emit(2);
2444            });
2445            assert_eq!(handle_1.read(app).events, vec!["updated".to_string()]);
2446            assert_eq!(
2447                handle_2.read(app).events,
2448                vec![
2449                    "observed event 1".to_string(),
2450                    "notified".to_string(),
2451                    "observed event 2".to_string(),
2452                ]
2453            );
2454
2455            handle_2.update(app, |model, _| {
2456                drop(handle_1);
2457                model.other.take();
2458            });
2459
2460            assert_eq!(app.ctx.models.len(), 1);
2461            assert!(app.subscriptions.is_empty());
2462            assert!(app.observations.is_empty());
2463        });
2464    }
2465
2466    #[test]
2467    fn test_subscribe_and_emit_from_model() {
2468        #[derive(Default)]
2469        struct Model {
2470            events: Vec<usize>,
2471        }
2472
2473        impl Entity for Model {
2474            type Event = usize;
2475        }
2476
2477        App::test((), |app| {
2478            let handle_1 = app.add_model(|_| Model::default());
2479            let handle_2 = app.add_model(|_| Model::default());
2480            let handle_2b = handle_2.clone();
2481
2482            handle_1.update(app, |_, c| {
2483                c.subscribe(&handle_2, move |model: &mut Model, event, c| {
2484                    model.events.push(*event);
2485
2486                    c.subscribe(&handle_2b, |model, event, _| {
2487                        model.events.push(*event * 2);
2488                    });
2489                });
2490            });
2491
2492            handle_2.update(app, |_, c| c.emit(7));
2493            assert_eq!(handle_1.read(app).events, vec![7]);
2494
2495            handle_2.update(app, |_, c| c.emit(5));
2496            assert_eq!(handle_1.read(app).events, vec![7, 10, 5]);
2497        })
2498    }
2499
2500    #[test]
2501    fn test_observe_and_notify_from_model() {
2502        #[derive(Default)]
2503        struct Model {
2504            count: usize,
2505            events: Vec<usize>,
2506        }
2507
2508        impl Entity for Model {
2509            type Event = ();
2510        }
2511
2512        App::test((), |app| {
2513            let handle_1 = app.add_model(|_| Model::default());
2514            let handle_2 = app.add_model(|_| Model::default());
2515            let handle_2b = handle_2.clone();
2516
2517            handle_1.update(app, |_, c| {
2518                c.observe(&handle_2, move |model, observed, c| {
2519                    model.events.push(observed.read(c).count);
2520                    c.observe(&handle_2b, |model, observed, c| {
2521                        model.events.push(observed.read(c).count * 2);
2522                    });
2523                });
2524            });
2525
2526            handle_2.update(app, |model, c| {
2527                model.count = 7;
2528                c.notify()
2529            });
2530            assert_eq!(handle_1.read(app).events, vec![7]);
2531
2532            handle_2.update(app, |model, c| {
2533                model.count = 5;
2534                c.notify()
2535            });
2536            assert_eq!(handle_1.read(app).events, vec![7, 10, 5])
2537        })
2538    }
2539
2540    #[test]
2541    fn test_spawn_from_model() {
2542        #[derive(Default)]
2543        struct Model {
2544            count: usize,
2545        }
2546
2547        impl Entity for Model {
2548            type Event = ();
2549        }
2550
2551        App::test_async((), |mut app| async move {
2552            let handle = app.add_model(|_| Model::default());
2553            handle
2554                .update(&mut app, |_, c| {
2555                    c.spawn(async { 7 }, |model, output, _| {
2556                        model.count = output;
2557                    })
2558                })
2559                .await;
2560            app.read(|ctx| assert_eq!(handle.read(ctx).count, 7));
2561
2562            handle
2563                .update(&mut app, |_, c| {
2564                    c.spawn(async { 14 }, |model, output, _| {
2565                        model.count = output;
2566                    })
2567                })
2568                .await;
2569            app.read(|ctx| assert_eq!(handle.read(ctx).count, 14));
2570        });
2571    }
2572
2573    #[test]
2574    fn test_spawn_stream_local_from_model() {
2575        #[derive(Default)]
2576        struct Model {
2577            events: Vec<Option<usize>>,
2578        }
2579
2580        impl Entity for Model {
2581            type Event = ();
2582        }
2583
2584        App::test_async((), |mut app| async move {
2585            let handle = app.add_model(|_| Model::default());
2586            handle
2587                .update(&mut app, |_, c| {
2588                    c.spawn_stream(
2589                        smol::stream::iter(vec![1, 2, 3]),
2590                        |model, output, _| {
2591                            model.events.push(Some(output));
2592                        },
2593                        |model, _| {
2594                            model.events.push(None);
2595                        },
2596                    )
2597                })
2598                .await;
2599            app.read(|ctx| assert_eq!(handle.read(ctx).events, [Some(1), Some(2), Some(3), None]));
2600        })
2601    }
2602
2603    #[test]
2604    fn test_view_handles() {
2605        struct View {
2606            other: Option<ViewHandle<View>>,
2607            events: Vec<String>,
2608        }
2609
2610        impl Entity for View {
2611            type Event = usize;
2612        }
2613
2614        impl super::View for View {
2615            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2616                Empty::new().boxed()
2617            }
2618
2619            fn ui_name() -> &'static str {
2620                "View"
2621            }
2622        }
2623
2624        impl View {
2625            fn new(other: Option<ViewHandle<View>>, ctx: &mut ViewContext<Self>) -> Self {
2626                if let Some(other) = other.as_ref() {
2627                    ctx.subscribe_to_view(other, |me, _, event, _| {
2628                        me.events.push(format!("observed event {}", event));
2629                    });
2630                }
2631                Self {
2632                    other,
2633                    events: Vec::new(),
2634                }
2635            }
2636        }
2637
2638        App::test((), |app| {
2639            let (window_id, _) = app.add_window(|ctx| View::new(None, ctx));
2640            let handle_1 = app.add_view(window_id, |ctx| View::new(None, ctx));
2641            let handle_2 = app.add_view(window_id, |ctx| View::new(Some(handle_1.clone()), ctx));
2642            assert_eq!(app.ctx.windows[&window_id].views.len(), 3);
2643
2644            handle_1.update(app, |view, ctx| {
2645                view.events.push("updated".into());
2646                ctx.emit(1);
2647                ctx.emit(2);
2648            });
2649            assert_eq!(handle_1.read(app).events, vec!["updated".to_string()]);
2650            assert_eq!(
2651                handle_2.read(app).events,
2652                vec![
2653                    "observed event 1".to_string(),
2654                    "observed event 2".to_string(),
2655                ]
2656            );
2657
2658            handle_2.update(app, |view, _| {
2659                drop(handle_1);
2660                view.other.take();
2661            });
2662
2663            assert_eq!(app.ctx.windows[&window_id].views.len(), 2);
2664            assert!(app.subscriptions.is_empty());
2665            assert!(app.observations.is_empty());
2666        })
2667    }
2668
2669    #[test]
2670    fn test_subscribe_and_emit_from_view() {
2671        #[derive(Default)]
2672        struct View {
2673            events: Vec<usize>,
2674        }
2675
2676        impl Entity for View {
2677            type Event = usize;
2678        }
2679
2680        impl super::View for View {
2681            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2682                Empty::new().boxed()
2683            }
2684
2685            fn ui_name() -> &'static str {
2686                "View"
2687            }
2688        }
2689
2690        struct Model;
2691
2692        impl Entity for Model {
2693            type Event = usize;
2694        }
2695
2696        App::test((), |app| {
2697            let (window_id, handle_1) = app.add_window(|_| View::default());
2698            let handle_2 = app.add_view(window_id, |_| View::default());
2699            let handle_2b = handle_2.clone();
2700            let handle_3 = app.add_model(|_| Model);
2701
2702            handle_1.update(app, |_, c| {
2703                c.subscribe_to_view(&handle_2, move |me, _, event, c| {
2704                    me.events.push(*event);
2705
2706                    c.subscribe_to_view(&handle_2b, |me, _, event, _| {
2707                        me.events.push(*event * 2);
2708                    });
2709                });
2710
2711                c.subscribe_to_model(&handle_3, |me, _, event, _| {
2712                    me.events.push(*event);
2713                })
2714            });
2715
2716            handle_2.update(app, |_, c| c.emit(7));
2717            assert_eq!(handle_1.read(app).events, vec![7]);
2718
2719            handle_2.update(app, |_, c| c.emit(5));
2720            assert_eq!(handle_1.read(app).events, vec![7, 10, 5]);
2721
2722            handle_3.update(app, |_, c| c.emit(9));
2723            assert_eq!(handle_1.read(app).events, vec![7, 10, 5, 9]);
2724        })
2725    }
2726
2727    #[test]
2728    fn test_dropping_subscribers() {
2729        struct View;
2730
2731        impl Entity for View {
2732            type Event = ();
2733        }
2734
2735        impl super::View for View {
2736            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2737                Empty::new().boxed()
2738            }
2739
2740            fn ui_name() -> &'static str {
2741                "View"
2742            }
2743        }
2744
2745        struct Model;
2746
2747        impl Entity for Model {
2748            type Event = ();
2749        }
2750
2751        App::test((), |app| {
2752            let (window_id, _) = app.add_window(|_| View);
2753            let observing_view = app.add_view(window_id, |_| View);
2754            let emitting_view = app.add_view(window_id, |_| View);
2755            let observing_model = app.add_model(|_| Model);
2756            let observed_model = app.add_model(|_| Model);
2757
2758            observing_view.update(app, |_, ctx| {
2759                ctx.subscribe_to_view(&emitting_view, |_, _, _, _| {});
2760                ctx.subscribe_to_model(&observed_model, |_, _, _, _| {});
2761            });
2762            observing_model.update(app, |_, ctx| {
2763                ctx.subscribe(&observed_model, |_, _, _| {});
2764            });
2765
2766            app.update(|| {
2767                drop(observing_view);
2768                drop(observing_model);
2769            });
2770
2771            emitting_view.update(app, |_, ctx| ctx.emit(()));
2772            observed_model.update(app, |_, ctx| ctx.emit(()));
2773        })
2774    }
2775
2776    #[test]
2777    fn test_observe_and_notify_from_view() {
2778        #[derive(Default)]
2779        struct View {
2780            events: Vec<usize>,
2781        }
2782
2783        impl Entity for View {
2784            type Event = usize;
2785        }
2786
2787        impl super::View for View {
2788            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2789                Empty::new().boxed()
2790            }
2791
2792            fn ui_name() -> &'static str {
2793                "View"
2794            }
2795        }
2796
2797        #[derive(Default)]
2798        struct Model {
2799            count: usize,
2800        }
2801
2802        impl Entity for Model {
2803            type Event = ();
2804        }
2805
2806        App::test((), |app| {
2807            let (_, view) = app.add_window(|_| View::default());
2808            let model = app.add_model(|_| Model::default());
2809
2810            view.update(app, |_, c| {
2811                c.observe(&model, |me, observed, c| {
2812                    me.events.push(observed.read(c).count)
2813                });
2814            });
2815
2816            model.update(app, |model, c| {
2817                model.count = 11;
2818                c.notify();
2819            });
2820            assert_eq!(view.read(app).events, vec![11]);
2821        })
2822    }
2823
2824    #[test]
2825    fn test_dropping_observers() {
2826        struct View;
2827
2828        impl Entity for View {
2829            type Event = ();
2830        }
2831
2832        impl super::View for View {
2833            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2834                Empty::new().boxed()
2835            }
2836
2837            fn ui_name() -> &'static str {
2838                "View"
2839            }
2840        }
2841
2842        struct Model;
2843
2844        impl Entity for Model {
2845            type Event = ();
2846        }
2847
2848        App::test((), |app| {
2849            let (window_id, _) = app.add_window(|_| View);
2850            let observing_view = app.add_view(window_id, |_| View);
2851            let observing_model = app.add_model(|_| Model);
2852            let observed_model = app.add_model(|_| Model);
2853
2854            observing_view.update(app, |_, ctx| {
2855                ctx.observe(&observed_model, |_, _, _| {});
2856            });
2857            observing_model.update(app, |_, ctx| {
2858                ctx.observe(&observed_model, |_, _, _| {});
2859            });
2860
2861            app.update(|| {
2862                drop(observing_view);
2863                drop(observing_model);
2864            });
2865
2866            observed_model.update(app, |_, ctx| ctx.notify());
2867        })
2868    }
2869
2870    #[test]
2871    fn test_focus() {
2872        #[derive(Default)]
2873        struct View {
2874            events: Vec<String>,
2875        }
2876
2877        impl Entity for View {
2878            type Event = String;
2879        }
2880
2881        impl super::View for View {
2882            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2883                Empty::new().boxed()
2884            }
2885
2886            fn ui_name() -> &'static str {
2887                "View"
2888            }
2889
2890            fn on_focus(&mut self, ctx: &mut ViewContext<Self>) {
2891                self.events.push("self focused".into());
2892                ctx.emit("focused".into());
2893            }
2894
2895            fn on_blur(&mut self, ctx: &mut ViewContext<Self>) {
2896                self.events.push("self blurred".into());
2897                ctx.emit("blurred".into());
2898            }
2899        }
2900
2901        App::test((), |app| {
2902            let (window_id, view_1) = app.add_window(|_| View::default());
2903            let view_2 = app.add_view(window_id, |_| View::default());
2904
2905            view_1.update(app, |_, ctx| {
2906                ctx.subscribe_to_view(&view_2, |view_1, _, event, _| {
2907                    view_1.events.push(format!("view 2 {}", event));
2908                });
2909                ctx.focus(&view_2);
2910            });
2911
2912            view_1.update(app, |_, ctx| {
2913                ctx.focus(&view_1);
2914            });
2915
2916            assert_eq!(
2917                view_1.read(app).events,
2918                [
2919                    "self focused".to_string(),
2920                    "self blurred".to_string(),
2921                    "view 2 focused".to_string(),
2922                    "self focused".to_string(),
2923                    "view 2 blurred".to_string(),
2924                ],
2925            );
2926        })
2927    }
2928
2929    #[test]
2930    fn test_spawn_from_view() {
2931        #[derive(Default)]
2932        struct View {
2933            count: usize,
2934        }
2935
2936        impl Entity for View {
2937            type Event = ();
2938        }
2939
2940        impl super::View for View {
2941            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2942                Empty::new().boxed()
2943            }
2944
2945            fn ui_name() -> &'static str {
2946                "View"
2947            }
2948        }
2949
2950        App::test_async((), |mut app| async move {
2951            let handle = app.add_window(|_| View::default()).1;
2952            handle
2953                .update(&mut app, |_, c| {
2954                    c.spawn(async { 7 }, |me, output, _| {
2955                        me.count = output;
2956                    })
2957                })
2958                .await;
2959            app.read(|ctx| assert_eq!(handle.read(ctx).count, 7));
2960            handle
2961                .update(&mut app, |_, c| {
2962                    c.spawn(async { 14 }, |me, output, _| {
2963                        me.count = output;
2964                    })
2965                })
2966                .await;
2967            app.read(|ctx| assert_eq!(handle.read(ctx).count, 14));
2968        });
2969    }
2970
2971    #[test]
2972    fn test_spawn_stream_local_from_view() {
2973        #[derive(Default)]
2974        struct View {
2975            events: Vec<Option<usize>>,
2976        }
2977
2978        impl Entity for View {
2979            type Event = ();
2980        }
2981
2982        impl super::View for View {
2983            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2984                Empty::new().boxed()
2985            }
2986
2987            fn ui_name() -> &'static str {
2988                "View"
2989            }
2990        }
2991
2992        App::test_async((), |mut app| async move {
2993            let (_, handle) = app.add_window(|_| View::default());
2994            handle
2995                .update(&mut app, |_, c| {
2996                    c.spawn_stream(
2997                        smol::stream::iter(vec![1_usize, 2, 3]),
2998                        |me, output, _| {
2999                            me.events.push(Some(output));
3000                        },
3001                        |me, _| {
3002                            me.events.push(None);
3003                        },
3004                    )
3005                })
3006                .await;
3007
3008            app.read(|ctx| assert_eq!(handle.read(ctx).events, [Some(1), Some(2), Some(3), None]))
3009        });
3010    }
3011
3012    #[test]
3013    fn test_dispatch_action() {
3014        struct ViewA {
3015            id: usize,
3016        }
3017
3018        impl Entity for ViewA {
3019            type Event = ();
3020        }
3021
3022        impl View for ViewA {
3023            fn render<'a>(&self, _: &AppContext) -> ElementBox {
3024                Empty::new().boxed()
3025            }
3026
3027            fn ui_name() -> &'static str {
3028                "View"
3029            }
3030        }
3031
3032        struct ViewB {
3033            id: usize,
3034        }
3035
3036        impl Entity for ViewB {
3037            type Event = ();
3038        }
3039
3040        impl View for ViewB {
3041            fn render<'a>(&self, _: &AppContext) -> ElementBox {
3042                Empty::new().boxed()
3043            }
3044
3045            fn ui_name() -> &'static str {
3046                "View"
3047            }
3048        }
3049
3050        struct ActionArg {
3051            foo: String,
3052        }
3053
3054        App::test((), |app| {
3055            let actions = Rc::new(RefCell::new(Vec::new()));
3056
3057            let actions_clone = actions.clone();
3058            app.add_global_action("action", move |_: &ActionArg, _: &mut MutableAppContext| {
3059                actions_clone.borrow_mut().push("global a".to_string());
3060            });
3061
3062            let actions_clone = actions.clone();
3063            app.add_global_action("action", move |_: &ActionArg, _: &mut MutableAppContext| {
3064                actions_clone.borrow_mut().push("global b".to_string());
3065            });
3066
3067            let actions_clone = actions.clone();
3068            app.add_action("action", move |view: &mut ViewA, arg: &ActionArg, ctx| {
3069                assert_eq!(arg.foo, "bar");
3070                ctx.propagate_action();
3071                actions_clone.borrow_mut().push(format!("{} a", view.id));
3072            });
3073
3074            let actions_clone = actions.clone();
3075            app.add_action("action", move |view: &mut ViewA, _: &ActionArg, ctx| {
3076                if view.id != 1 {
3077                    ctx.propagate_action();
3078                }
3079                actions_clone.borrow_mut().push(format!("{} b", view.id));
3080            });
3081
3082            let actions_clone = actions.clone();
3083            app.add_action("action", move |view: &mut ViewB, _: &ActionArg, ctx| {
3084                ctx.propagate_action();
3085                actions_clone.borrow_mut().push(format!("{} c", view.id));
3086            });
3087
3088            let actions_clone = actions.clone();
3089            app.add_action("action", move |view: &mut ViewB, _: &ActionArg, ctx| {
3090                ctx.propagate_action();
3091                actions_clone.borrow_mut().push(format!("{} d", view.id));
3092            });
3093
3094            let (window_id, view_1) = app.add_window(|_| ViewA { id: 1 });
3095            let view_2 = app.add_view(window_id, |_| ViewB { id: 2 });
3096            let view_3 = app.add_view(window_id, |_| ViewA { id: 3 });
3097            let view_4 = app.add_view(window_id, |_| ViewB { id: 4 });
3098
3099            app.dispatch_action(
3100                window_id,
3101                vec![view_1.id(), view_2.id(), view_3.id(), view_4.id()],
3102                "action",
3103                ActionArg { foo: "bar".into() },
3104            );
3105
3106            assert_eq!(
3107                *actions.borrow(),
3108                vec!["4 d", "4 c", "3 b", "3 a", "2 d", "2 c", "1 b"]
3109            );
3110
3111            // Remove view_1, which doesn't propagate the action
3112            actions.borrow_mut().clear();
3113            app.dispatch_action(
3114                window_id,
3115                vec![view_2.id(), view_3.id(), view_4.id()],
3116                "action",
3117                ActionArg { foo: "bar".into() },
3118            );
3119
3120            assert_eq!(
3121                *actions.borrow(),
3122                vec!["4 d", "4 c", "3 b", "3 a", "2 d", "2 c", "global b", "global a"]
3123            );
3124        })
3125    }
3126
3127    #[test]
3128    fn test_dispatch_keystroke() {
3129        use std::cell::Cell;
3130
3131        #[derive(Clone)]
3132        struct ActionArg {
3133            key: String,
3134        }
3135
3136        struct View {
3137            id: usize,
3138            keymap_context: keymap::Context,
3139        }
3140
3141        impl Entity for View {
3142            type Event = ();
3143        }
3144
3145        impl super::View for View {
3146            fn render<'a>(&self, _: &AppContext) -> ElementBox {
3147                Empty::new().boxed()
3148            }
3149
3150            fn ui_name() -> &'static str {
3151                "View"
3152            }
3153
3154            fn keymap_context(&self, _: &AppContext) -> keymap::Context {
3155                self.keymap_context.clone()
3156            }
3157        }
3158
3159        impl View {
3160            fn new(id: usize) -> Self {
3161                View {
3162                    id,
3163                    keymap_context: keymap::Context::default(),
3164                }
3165            }
3166        }
3167
3168        App::test((), |app| {
3169            let mut view_1 = View::new(1);
3170            let mut view_2 = View::new(2);
3171            let mut view_3 = View::new(3);
3172            view_1.keymap_context.set.insert("a".into());
3173            view_2.keymap_context.set.insert("b".into());
3174            view_3.keymap_context.set.insert("c".into());
3175
3176            let (window_id, view_1) = app.add_window(|_| view_1);
3177            let view_2 = app.add_view(window_id, |_| view_2);
3178            let view_3 = app.add_view(window_id, |_| view_3);
3179
3180            // This keymap's only binding dispatches an action on view 2 because that view will have
3181            // "a" and "b" in its context, but not "c".
3182            let binding = keymap::Binding::new("a", "action", Some("a && b && !c"))
3183                .with_arg(ActionArg { key: "a".into() });
3184            app.add_bindings(vec![binding]);
3185
3186            let handled_action = Rc::new(Cell::new(false));
3187            let handled_action_clone = handled_action.clone();
3188            app.add_action("action", move |view: &mut View, arg: &ActionArg, _ctx| {
3189                handled_action_clone.set(true);
3190                assert_eq!(view.id, 2);
3191                assert_eq!(arg.key, "a");
3192            });
3193
3194            app.dispatch_keystroke(
3195                window_id,
3196                vec![view_1.id(), view_2.id(), view_3.id()],
3197                &Keystroke::parse("a").unwrap(),
3198            )
3199            .unwrap();
3200
3201            assert!(handled_action.get());
3202        });
3203    }
3204
3205    // #[test]
3206    // fn test_ui_and_window_updates() {
3207    //     struct View {
3208    //         count: usize,
3209    //     }
3210
3211    //     impl Entity for View {
3212    //         type Event = ();
3213    //     }
3214
3215    //     impl super::View for View {
3216    //         fn render<'a>(&self, _: &AppContext) -> ElementBox {
3217    //             Empty::new().boxed()
3218    //         }
3219
3220    //         fn ui_name() -> &'static str {
3221    //             "View"
3222    //         }
3223    //     }
3224
3225    //     App::test(|app| async move {
3226    //         let (window_id, _) = app.add_window(|_| View { count: 3 });
3227    //         let view_1 = app.add_view(window_id, |_| View { count: 1 });
3228    //         let view_2 = app.add_view(window_id, |_| View { count: 2 });
3229
3230    //         // Ensure that registering for UI updates after mutating the app still gives us all the
3231    //         // updates.
3232    //         let ui_updates = Rc::new(RefCell::new(Vec::new()));
3233    //         let ui_updates_ = ui_updates.clone();
3234    //         app.on_ui_update(move |update, _| ui_updates_.borrow_mut().push(update));
3235
3236    //         assert_eq!(
3237    //             ui_updates.borrow_mut().drain(..).collect::<Vec<_>>(),
3238    //             vec![UiUpdate::OpenWindow {
3239    //                 window_id,
3240    //                 width: 1024.0,
3241    //                 height: 768.0,
3242    //             }]
3243    //         );
3244
3245    //         let window_invalidations = Rc::new(RefCell::new(Vec::new()));
3246    //         let window_invalidations_ = window_invalidations.clone();
3247    //         app.on_window_invalidated(window_id, move |update, _| {
3248    //             window_invalidations_.borrow_mut().push(update)
3249    //         });
3250
3251    //         let view_2_id = view_2.id();
3252    //         view_1.update(app, |view, ctx| {
3253    //             view.count = 7;
3254    //             ctx.notify();
3255    //             drop(view_2);
3256    //         });
3257
3258    //         let invalidation = window_invalidations.borrow_mut().drain(..).next().unwrap();
3259    //         assert_eq!(invalidation.updated.len(), 1);
3260    //         assert!(invalidation.updated.contains(&view_1.id()));
3261    //         assert_eq!(invalidation.removed, vec![view_2_id]);
3262
3263    //         let view_3 = view_1.update(app, |_, ctx| ctx.add_view(|_| View { count: 8 }));
3264
3265    //         let invalidation = window_invalidations.borrow_mut().drain(..).next().unwrap();
3266    //         assert_eq!(invalidation.updated.len(), 1);
3267    //         assert!(invalidation.updated.contains(&view_3.id()));
3268    //         assert!(invalidation.removed.is_empty());
3269
3270    //         view_3
3271    //             .update(app, |_, ctx| {
3272    //                 ctx.spawn_local(async { 9 }, |me, output, ctx| {
3273    //                     me.count = output;
3274    //                     ctx.notify();
3275    //                 })
3276    //             })
3277    //             .await;
3278
3279    //         let invalidation = window_invalidations.borrow_mut().drain(..).next().unwrap();
3280    //         assert_eq!(invalidation.updated.len(), 1);
3281    //         assert!(invalidation.updated.contains(&view_3.id()));
3282    //         assert!(invalidation.removed.is_empty());
3283    //     });
3284    // }
3285
3286    #[test]
3287    fn test_finish_pending_tasks() {
3288        struct View;
3289
3290        impl Entity for View {
3291            type Event = ();
3292        }
3293
3294        impl super::View for View {
3295            fn render<'a>(&self, _: &AppContext) -> ElementBox {
3296                Empty::new().boxed()
3297            }
3298
3299            fn ui_name() -> &'static str {
3300                "View"
3301            }
3302        }
3303
3304        struct Model;
3305
3306        impl Entity for Model {
3307            type Event = ();
3308        }
3309
3310        App::test_async((), |mut app| async move {
3311            let model = app.add_model(|_| Model);
3312            let (_, view) = app.add_window(|_| View);
3313
3314            model.update(&mut app, |_, ctx| {
3315                ctx.spawn(async {}, |_, _, _| {}).detach();
3316                // Cancel this task
3317                drop(ctx.spawn(async {}, |_, _, _| {}));
3318            });
3319
3320            view.update(&mut app, |_, ctx| {
3321                ctx.spawn(async {}, |_, _, _| {}).detach();
3322                // Cancel this task
3323                drop(ctx.spawn(async {}, |_, _, _| {}));
3324            });
3325
3326            assert!(!app.0.borrow().future_handlers.borrow().is_empty());
3327            app.finish_pending_tasks().await;
3328            assert!(app.0.borrow().future_handlers.borrow().is_empty());
3329            app.finish_pending_tasks().await; // Don't block if there are no tasks
3330
3331            model.update(&mut app, |_, ctx| {
3332                ctx.spawn_stream(smol::stream::iter(vec![1, 2, 3]), |_, _, _| {}, |_, _| {})
3333                    .detach();
3334                // Cancel this task
3335                drop(ctx.spawn_stream(smol::stream::iter(vec![1, 2, 3]), |_, _, _| {}, |_, _| {}));
3336            });
3337
3338            view.update(&mut app, |_, ctx| {
3339                ctx.spawn_stream(smol::stream::iter(vec![1, 2, 3]), |_, _, _| {}, |_, _| {})
3340                    .detach();
3341                // Cancel this task
3342                drop(ctx.spawn_stream(smol::stream::iter(vec![1, 2, 3]), |_, _, _| {}, |_, _| {}));
3343            });
3344
3345            assert!(!app.0.borrow().stream_handlers.borrow().is_empty());
3346            app.finish_pending_tasks().await;
3347            assert!(app.0.borrow().stream_handlers.borrow().is_empty());
3348            app.finish_pending_tasks().await; // Don't block if there are no tasks
3349
3350            // Tasks are considered finished when we drop handles
3351            let mut tasks = Vec::new();
3352            model.update(&mut app, |_, ctx| {
3353                tasks.push(Box::new(ctx.spawn(async {}, |_, _, _| {})));
3354                tasks.push(Box::new(ctx.spawn_stream(
3355                    smol::stream::iter(vec![1, 2, 3]),
3356                    |_, _, _| {},
3357                    |_, _| {},
3358                )));
3359            });
3360
3361            view.update(&mut app, |_, ctx| {
3362                tasks.push(Box::new(ctx.spawn(async {}, |_, _, _| {})));
3363                tasks.push(Box::new(ctx.spawn_stream(
3364                    smol::stream::iter(vec![1, 2, 3]),
3365                    |_, _, _| {},
3366                    |_, _| {},
3367                )));
3368            });
3369
3370            assert!(!app.0.borrow().stream_handlers.borrow().is_empty());
3371
3372            let finish_pending_tasks = app.finish_pending_tasks();
3373            drop(tasks);
3374            finish_pending_tasks.await;
3375            assert!(app.0.borrow().stream_handlers.borrow().is_empty());
3376            app.finish_pending_tasks().await; // Don't block if there are no tasks
3377        });
3378    }
3379}