app.rs

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