app.rs

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