app.rs

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