app.rs

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