app.rs

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