app.rs

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