app.rs

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