app.rs

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