app.rs

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