app.rs

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