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