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