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