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