app.rs

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