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