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