app.rs

   1use crate::{
   2    elements::ElementBox,
   3    executor::{self, Task},
   4    keymap::{self, Keystroke},
   5    platform::{self, CursorStyle, Platform, PromptLevel, WindowOptions},
   6    presenter::Presenter,
   7    util::{post_inc, timeout},
   8    AssetCache, AssetSource, ClipboardItem, FontCache, PathPromptOptions, TextLayoutCache,
   9};
  10use anyhow::{anyhow, Result};
  11use keymap::MatchResult;
  12use parking_lot::Mutex;
  13use platform::Event;
  14use postage::{mpsc, oneshot, sink::Sink as _, stream::Stream as _};
  15use smol::prelude::*;
  16use std::{
  17    any::{type_name, Any, TypeId},
  18    cell::RefCell,
  19    collections::{hash_map::Entry, BTreeMap, HashMap, HashSet, VecDeque},
  20    fmt::{self, Debug},
  21    hash::{Hash, Hasher},
  22    marker::PhantomData,
  23    mem,
  24    ops::{Deref, DerefMut},
  25    path::{Path, PathBuf},
  26    pin::Pin,
  27    rc::{self, Rc},
  28    sync::{
  29        atomic::{AtomicUsize, Ordering::SeqCst},
  30        Arc, Weak,
  31    },
  32    time::Duration,
  33};
  34
  35pub trait Entity: 'static {
  36    type Event;
  37
  38    fn release(&mut self, _: &mut MutableAppContext) {}
  39    fn app_will_quit(
  40        &mut self,
  41        _: &mut MutableAppContext,
  42    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
  43        None
  44    }
  45}
  46
  47pub trait View: Entity + Sized {
  48    fn ui_name() -> &'static str;
  49    fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox;
  50    fn on_focus(&mut self, _: &mut ViewContext<Self>) {}
  51    fn on_blur(&mut self, _: &mut ViewContext<Self>) {}
  52    fn keymap_context(&self, _: &AppContext) -> keymap::Context {
  53        Self::default_keymap_context()
  54    }
  55    fn default_keymap_context() -> keymap::Context {
  56        let mut cx = keymap::Context::default();
  57        cx.set.insert(Self::ui_name().into());
  58        cx
  59    }
  60}
  61
  62pub trait ReadModel {
  63    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T;
  64}
  65
  66pub trait ReadModelWith {
  67    fn read_model_with<E: Entity, T>(
  68        &self,
  69        handle: &ModelHandle<E>,
  70        read: &mut dyn FnMut(&E, &AppContext) -> T,
  71    ) -> T;
  72}
  73
  74pub trait UpdateModel {
  75    fn update_model<T: Entity, O>(
  76        &mut self,
  77        handle: &ModelHandle<T>,
  78        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
  79    ) -> O;
  80}
  81
  82pub trait UpgradeModelHandle {
  83    fn upgrade_model_handle<T: Entity>(
  84        &self,
  85        handle: &WeakModelHandle<T>,
  86    ) -> Option<ModelHandle<T>>;
  87
  88    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle>;
  89}
  90
  91pub trait UpgradeViewHandle {
  92    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>>;
  93}
  94
  95pub trait ReadView {
  96    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T;
  97}
  98
  99pub trait ReadViewWith {
 100    fn read_view_with<V, T>(
 101        &self,
 102        handle: &ViewHandle<V>,
 103        read: &mut dyn FnMut(&V, &AppContext) -> T,
 104    ) -> T
 105    where
 106        V: View;
 107}
 108
 109pub trait UpdateView {
 110    fn update_view<T, S>(
 111        &mut self,
 112        handle: &ViewHandle<T>,
 113        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
 114    ) -> S
 115    where
 116        T: View;
 117}
 118
 119pub trait Action: 'static + AnyAction {
 120    type Argument: 'static + Clone;
 121}
 122
 123pub trait AnyAction {
 124    fn id(&self) -> TypeId;
 125    fn name(&self) -> &'static str;
 126    fn as_any(&self) -> &dyn Any;
 127    fn boxed_clone(&self) -> Box<dyn AnyAction>;
 128    fn boxed_clone_as_any(&self) -> Box<dyn Any>;
 129}
 130
 131#[macro_export]
 132macro_rules! action {
 133    ($name:ident, $arg:ty) => {
 134        #[derive(Clone)]
 135        pub struct $name(pub $arg);
 136
 137        impl $crate::Action for $name {
 138            type Argument = $arg;
 139        }
 140
 141        impl $crate::AnyAction for $name {
 142            fn id(&self) -> std::any::TypeId {
 143                std::any::TypeId::of::<$name>()
 144            }
 145
 146            fn name(&self) -> &'static str {
 147                stringify!($name)
 148            }
 149
 150            fn as_any(&self) -> &dyn std::any::Any {
 151                self
 152            }
 153
 154            fn boxed_clone(&self) -> Box<dyn $crate::AnyAction> {
 155                Box::new(self.clone())
 156            }
 157
 158            fn boxed_clone_as_any(&self) -> Box<dyn std::any::Any> {
 159                Box::new(self.clone())
 160            }
 161        }
 162    };
 163
 164    ($name:ident) => {
 165        #[derive(Clone, Debug, Eq, PartialEq)]
 166        pub struct $name;
 167
 168        impl $crate::Action for $name {
 169            type Argument = ();
 170        }
 171
 172        impl $crate::AnyAction for $name {
 173            fn id(&self) -> std::any::TypeId {
 174                std::any::TypeId::of::<$name>()
 175            }
 176
 177            fn name(&self) -> &'static str {
 178                stringify!($name)
 179            }
 180
 181            fn as_any(&self) -> &dyn std::any::Any {
 182                self
 183            }
 184
 185            fn boxed_clone(&self) -> Box<dyn $crate::AnyAction> {
 186                Box::new(self.clone())
 187            }
 188
 189            fn boxed_clone_as_any(&self) -> Box<dyn std::any::Any> {
 190                Box::new(self.clone())
 191            }
 192        }
 193    };
 194}
 195
 196pub struct Menu<'a> {
 197    pub name: &'a str,
 198    pub items: Vec<MenuItem<'a>>,
 199}
 200
 201pub enum MenuItem<'a> {
 202    Action {
 203        name: &'a str,
 204        keystroke: Option<&'a str>,
 205        action: Box<dyn AnyAction>,
 206    },
 207    Separator,
 208}
 209
 210#[derive(Clone)]
 211pub struct App(Rc<RefCell<MutableAppContext>>);
 212
 213#[derive(Clone)]
 214pub struct AsyncAppContext(Rc<RefCell<MutableAppContext>>);
 215
 216#[derive(Clone)]
 217pub struct TestAppContext {
 218    cx: Rc<RefCell<MutableAppContext>>,
 219    foreground_platform: Rc<platform::test::ForegroundPlatform>,
 220}
 221
 222impl App {
 223    pub fn new(asset_source: impl AssetSource) -> Result<Self> {
 224        let platform = platform::current::platform();
 225        let foreground_platform = platform::current::foreground_platform();
 226        let foreground = Rc::new(executor::Foreground::platform(platform.dispatcher())?);
 227        let app = Self(Rc::new(RefCell::new(MutableAppContext::new(
 228            foreground,
 229            Arc::new(executor::Background::new()),
 230            platform.clone(),
 231            foreground_platform.clone(),
 232            Arc::new(FontCache::new(platform.fonts())),
 233            asset_source,
 234        ))));
 235
 236        foreground_platform.on_quit(Box::new({
 237            let cx = app.0.clone();
 238            move || {
 239                cx.borrow_mut().quit();
 240            }
 241        }));
 242        foreground_platform.on_menu_command(Box::new({
 243            let cx = app.0.clone();
 244            move |action| {
 245                let mut cx = cx.borrow_mut();
 246                if let Some(key_window_id) = cx.cx.platform.key_window_id() {
 247                    if let Some((presenter, _)) =
 248                        cx.presenters_and_platform_windows.get(&key_window_id)
 249                    {
 250                        let presenter = presenter.clone();
 251                        let path = presenter.borrow().dispatch_path(cx.as_ref());
 252                        cx.dispatch_action_any(key_window_id, &path, action);
 253                    } else {
 254                        cx.dispatch_global_action_any(action);
 255                    }
 256                } else {
 257                    cx.dispatch_global_action_any(action);
 258                }
 259            }
 260        }));
 261
 262        app.0.borrow_mut().weak_self = Some(Rc::downgrade(&app.0));
 263        Ok(app)
 264    }
 265
 266    pub fn on_become_active<F>(self, mut callback: F) -> Self
 267    where
 268        F: 'static + FnMut(&mut MutableAppContext),
 269    {
 270        let cx = self.0.clone();
 271        self.0
 272            .borrow_mut()
 273            .foreground_platform
 274            .on_become_active(Box::new(move || callback(&mut *cx.borrow_mut())));
 275        self
 276    }
 277
 278    pub fn on_resign_active<F>(self, mut callback: F) -> Self
 279    where
 280        F: 'static + FnMut(&mut MutableAppContext),
 281    {
 282        let cx = self.0.clone();
 283        self.0
 284            .borrow_mut()
 285            .foreground_platform
 286            .on_resign_active(Box::new(move || callback(&mut *cx.borrow_mut())));
 287        self
 288    }
 289
 290    pub fn on_quit<F>(self, mut callback: F) -> Self
 291    where
 292        F: 'static + FnMut(&mut MutableAppContext),
 293    {
 294        let cx = self.0.clone();
 295        self.0
 296            .borrow_mut()
 297            .foreground_platform
 298            .on_quit(Box::new(move || callback(&mut *cx.borrow_mut())));
 299        self
 300    }
 301
 302    pub fn on_event<F>(self, mut callback: F) -> Self
 303    where
 304        F: 'static + FnMut(Event, &mut MutableAppContext) -> bool,
 305    {
 306        let cx = self.0.clone();
 307        self.0
 308            .borrow_mut()
 309            .foreground_platform
 310            .on_event(Box::new(move |event| {
 311                callback(event, &mut *cx.borrow_mut())
 312            }));
 313        self
 314    }
 315
 316    pub fn on_open_files<F>(self, mut callback: F) -> Self
 317    where
 318        F: 'static + FnMut(Vec<PathBuf>, &mut MutableAppContext),
 319    {
 320        let cx = self.0.clone();
 321        self.0
 322            .borrow_mut()
 323            .foreground_platform
 324            .on_open_files(Box::new(move |paths| {
 325                callback(paths, &mut *cx.borrow_mut())
 326            }));
 327        self
 328    }
 329
 330    pub fn run<F>(self, on_finish_launching: F)
 331    where
 332        F: 'static + FnOnce(&mut MutableAppContext),
 333    {
 334        let platform = self.0.borrow().foreground_platform.clone();
 335        platform.run(Box::new(move || {
 336            let mut cx = self.0.borrow_mut();
 337            let cx = &mut *cx;
 338            crate::views::init(cx);
 339            on_finish_launching(cx);
 340        }))
 341    }
 342
 343    pub fn platform(&self) -> Arc<dyn Platform> {
 344        self.0.borrow().platform()
 345    }
 346
 347    pub fn font_cache(&self) -> Arc<FontCache> {
 348        self.0.borrow().cx.font_cache.clone()
 349    }
 350
 351    fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 352        let mut state = self.0.borrow_mut();
 353        let result = state.update(callback);
 354        state.pending_notifications.clear();
 355        result
 356    }
 357}
 358
 359impl TestAppContext {
 360    pub fn new(
 361        foreground_platform: Rc<platform::test::ForegroundPlatform>,
 362        platform: Arc<dyn Platform>,
 363        foreground: Rc<executor::Foreground>,
 364        background: Arc<executor::Background>,
 365        font_cache: Arc<FontCache>,
 366        first_entity_id: usize,
 367    ) -> Self {
 368        let mut cx = MutableAppContext::new(
 369            foreground.clone(),
 370            background,
 371            platform,
 372            foreground_platform.clone(),
 373            font_cache,
 374            (),
 375        );
 376        cx.next_entity_id = first_entity_id;
 377        let cx = TestAppContext {
 378            cx: Rc::new(RefCell::new(cx)),
 379            foreground_platform,
 380        };
 381        cx.cx.borrow_mut().weak_self = Some(Rc::downgrade(&cx.cx));
 382        cx
 383    }
 384
 385    pub fn dispatch_action<A: Action>(
 386        &self,
 387        window_id: usize,
 388        responder_chain: Vec<usize>,
 389        action: A,
 390    ) {
 391        self.cx
 392            .borrow_mut()
 393            .dispatch_action_any(window_id, &responder_chain, &action);
 394    }
 395
 396    pub fn dispatch_global_action<A: Action>(&self, action: A) {
 397        self.cx.borrow_mut().dispatch_global_action(action);
 398    }
 399
 400    pub fn dispatch_keystroke(
 401        &self,
 402        window_id: usize,
 403        responder_chain: Vec<usize>,
 404        keystroke: &Keystroke,
 405    ) -> Result<bool> {
 406        let mut state = self.cx.borrow_mut();
 407        state.dispatch_keystroke(window_id, responder_chain, keystroke)
 408    }
 409
 410    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
 411    where
 412        T: Entity,
 413        F: FnOnce(&mut ModelContext<T>) -> T,
 414    {
 415        self.cx.borrow_mut().add_model(build_model)
 416    }
 417
 418    pub fn add_window<T, F>(&mut self, build_root_view: F) -> (usize, ViewHandle<T>)
 419    where
 420        T: View,
 421        F: FnOnce(&mut ViewContext<T>) -> T,
 422    {
 423        self.cx
 424            .borrow_mut()
 425            .add_window(Default::default(), build_root_view)
 426    }
 427
 428    pub fn window_ids(&self) -> Vec<usize> {
 429        self.cx.borrow().window_ids().collect()
 430    }
 431
 432    pub fn root_view<T: View>(&self, window_id: usize) -> Option<ViewHandle<T>> {
 433        self.cx.borrow().root_view(window_id)
 434    }
 435
 436    pub fn add_view<T, F>(&mut self, window_id: usize, build_view: F) -> ViewHandle<T>
 437    where
 438        T: View,
 439        F: FnOnce(&mut ViewContext<T>) -> T,
 440    {
 441        self.cx.borrow_mut().add_view(window_id, build_view)
 442    }
 443
 444    pub fn add_option_view<T, F>(
 445        &mut self,
 446        window_id: usize,
 447        build_view: F,
 448    ) -> Option<ViewHandle<T>>
 449    where
 450        T: View,
 451        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
 452    {
 453        self.cx.borrow_mut().add_option_view(window_id, build_view)
 454    }
 455
 456    pub fn read<T, F: FnOnce(&AppContext) -> T>(&self, callback: F) -> T {
 457        callback(self.cx.borrow().as_ref())
 458    }
 459
 460    pub fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 461        let mut state = self.cx.borrow_mut();
 462        // Don't increment pending flushes in order to effects to be flushed before the callback
 463        // completes, which is helpful in tests.
 464        let result = callback(&mut *state);
 465        // Flush effects after the callback just in case there are any. This can happen in edge
 466        // cases such as the closure dropping handles.
 467        state.flush_effects();
 468        result
 469    }
 470
 471    pub fn to_async(&self) -> AsyncAppContext {
 472        AsyncAppContext(self.cx.clone())
 473    }
 474
 475    pub fn font_cache(&self) -> Arc<FontCache> {
 476        self.cx.borrow().cx.font_cache.clone()
 477    }
 478
 479    pub fn foreground_platform(&self) -> Rc<platform::test::ForegroundPlatform> {
 480        self.foreground_platform.clone()
 481    }
 482
 483    pub fn platform(&self) -> Arc<dyn platform::Platform> {
 484        self.cx.borrow().cx.platform.clone()
 485    }
 486
 487    pub fn foreground(&self) -> Rc<executor::Foreground> {
 488        self.cx.borrow().foreground().clone()
 489    }
 490
 491    pub fn background(&self) -> Arc<executor::Background> {
 492        self.cx.borrow().background().clone()
 493    }
 494
 495    pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
 496    where
 497        F: FnOnce(AsyncAppContext) -> Fut,
 498        Fut: 'static + Future<Output = T>,
 499        T: 'static,
 500    {
 501        self.cx.borrow_mut().spawn(f)
 502    }
 503
 504    pub fn simulate_new_path_selection(&self, result: impl FnOnce(PathBuf) -> Option<PathBuf>) {
 505        self.foreground_platform.simulate_new_path_selection(result);
 506    }
 507
 508    pub fn did_prompt_for_new_path(&self) -> bool {
 509        self.foreground_platform.as_ref().did_prompt_for_new_path()
 510    }
 511
 512    pub fn simulate_prompt_answer(&self, window_id: usize, answer: usize) {
 513        let mut state = self.cx.borrow_mut();
 514        let (_, window) = state
 515            .presenters_and_platform_windows
 516            .get_mut(&window_id)
 517            .unwrap();
 518        let test_window = window
 519            .as_any_mut()
 520            .downcast_mut::<platform::test::Window>()
 521            .unwrap();
 522        let mut done_tx = test_window
 523            .last_prompt
 524            .take()
 525            .expect("prompt was not called");
 526        let _ = done_tx.try_send(answer);
 527    }
 528}
 529
 530impl AsyncAppContext {
 531    pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
 532    where
 533        F: FnOnce(AsyncAppContext) -> Fut,
 534        Fut: 'static + Future<Output = T>,
 535        T: 'static,
 536    {
 537        self.0.borrow().foreground.spawn(f(self.clone()))
 538    }
 539
 540    pub fn read<T, F: FnOnce(&AppContext) -> T>(&mut self, callback: F) -> T {
 541        callback(self.0.borrow().as_ref())
 542    }
 543
 544    pub fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 545        self.0.borrow_mut().update(callback)
 546    }
 547
 548    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
 549    where
 550        T: Entity,
 551        F: FnOnce(&mut ModelContext<T>) -> T,
 552    {
 553        self.update(|cx| cx.add_model(build_model))
 554    }
 555
 556    pub fn platform(&self) -> Arc<dyn Platform> {
 557        self.0.borrow().platform()
 558    }
 559
 560    pub fn foreground(&self) -> Rc<executor::Foreground> {
 561        self.0.borrow().foreground.clone()
 562    }
 563
 564    pub fn background(&self) -> Arc<executor::Background> {
 565        self.0.borrow().cx.background.clone()
 566    }
 567}
 568
 569impl UpdateModel for AsyncAppContext {
 570    fn update_model<E: Entity, O>(
 571        &mut self,
 572        handle: &ModelHandle<E>,
 573        update: &mut dyn FnMut(&mut E, &mut ModelContext<E>) -> O,
 574    ) -> O {
 575        self.0.borrow_mut().update_model(handle, update)
 576    }
 577}
 578
 579impl UpgradeModelHandle for AsyncAppContext {
 580    fn upgrade_model_handle<T: Entity>(
 581        &self,
 582        handle: &WeakModelHandle<T>,
 583    ) -> Option<ModelHandle<T>> {
 584        self.0.borrow().upgrade_model_handle(handle)
 585    }
 586
 587    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
 588        self.0.borrow().upgrade_any_model_handle(handle)
 589    }
 590}
 591
 592impl UpgradeViewHandle for AsyncAppContext {
 593    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
 594        self.0.borrow_mut().upgrade_view_handle(handle)
 595    }
 596}
 597
 598impl ReadModelWith for AsyncAppContext {
 599    fn read_model_with<E: Entity, T>(
 600        &self,
 601        handle: &ModelHandle<E>,
 602        read: &mut dyn FnMut(&E, &AppContext) -> T,
 603    ) -> T {
 604        let cx = self.0.borrow();
 605        let cx = cx.as_ref();
 606        read(handle.read(cx), cx)
 607    }
 608}
 609
 610impl UpdateView for AsyncAppContext {
 611    fn update_view<T, S>(
 612        &mut self,
 613        handle: &ViewHandle<T>,
 614        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
 615    ) -> S
 616    where
 617        T: View,
 618    {
 619        self.0.borrow_mut().update_view(handle, update)
 620    }
 621}
 622
 623impl ReadViewWith for AsyncAppContext {
 624    fn read_view_with<V, T>(
 625        &self,
 626        handle: &ViewHandle<V>,
 627        read: &mut dyn FnMut(&V, &AppContext) -> T,
 628    ) -> T
 629    where
 630        V: View,
 631    {
 632        let cx = self.0.borrow();
 633        let cx = cx.as_ref();
 634        read(handle.read(cx), cx)
 635    }
 636}
 637
 638impl UpdateModel for TestAppContext {
 639    fn update_model<T: Entity, O>(
 640        &mut self,
 641        handle: &ModelHandle<T>,
 642        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
 643    ) -> O {
 644        self.cx.borrow_mut().update_model(handle, update)
 645    }
 646}
 647
 648impl ReadModelWith for TestAppContext {
 649    fn read_model_with<E: Entity, T>(
 650        &self,
 651        handle: &ModelHandle<E>,
 652        read: &mut dyn FnMut(&E, &AppContext) -> T,
 653    ) -> T {
 654        let cx = self.cx.borrow();
 655        let cx = cx.as_ref();
 656        read(handle.read(cx), cx)
 657    }
 658}
 659
 660impl UpdateView for TestAppContext {
 661    fn update_view<T, S>(
 662        &mut self,
 663        handle: &ViewHandle<T>,
 664        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
 665    ) -> S
 666    where
 667        T: View,
 668    {
 669        self.cx.borrow_mut().update_view(handle, update)
 670    }
 671}
 672
 673impl ReadViewWith for TestAppContext {
 674    fn read_view_with<V, T>(
 675        &self,
 676        handle: &ViewHandle<V>,
 677        read: &mut dyn FnMut(&V, &AppContext) -> T,
 678    ) -> T
 679    where
 680        V: View,
 681    {
 682        let cx = self.cx.borrow();
 683        let cx = cx.as_ref();
 684        read(handle.read(cx), cx)
 685    }
 686}
 687
 688type ActionCallback =
 689    dyn FnMut(&mut dyn AnyView, &dyn AnyAction, &mut MutableAppContext, usize, usize) -> bool;
 690type GlobalActionCallback = dyn FnMut(&dyn AnyAction, &mut MutableAppContext);
 691
 692type SubscriptionCallback = Box<dyn FnMut(&dyn Any, &mut MutableAppContext) -> bool>;
 693type ObservationCallback = Box<dyn FnMut(&mut MutableAppContext) -> bool>;
 694type ReleaseObservationCallback = Box<dyn FnMut(&mut MutableAppContext)>;
 695
 696pub struct MutableAppContext {
 697    weak_self: Option<rc::Weak<RefCell<Self>>>,
 698    foreground_platform: Rc<dyn platform::ForegroundPlatform>,
 699    assets: Arc<AssetCache>,
 700    cx: AppContext,
 701    actions: HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>>,
 702    global_actions: HashMap<TypeId, Box<GlobalActionCallback>>,
 703    keystroke_matcher: keymap::Matcher,
 704    next_entity_id: usize,
 705    next_window_id: usize,
 706    next_subscription_id: usize,
 707    frame_count: usize,
 708    subscriptions: Arc<Mutex<HashMap<usize, BTreeMap<usize, SubscriptionCallback>>>>,
 709    observations: Arc<Mutex<HashMap<usize, BTreeMap<usize, ObservationCallback>>>>,
 710    release_observations: Arc<Mutex<HashMap<usize, BTreeMap<usize, ReleaseObservationCallback>>>>,
 711    presenters_and_platform_windows:
 712        HashMap<usize, (Rc<RefCell<Presenter>>, Box<dyn platform::Window>)>,
 713    debug_elements_callbacks: HashMap<usize, Box<dyn Fn(&AppContext) -> crate::json::Value>>,
 714    foreground: Rc<executor::Foreground>,
 715    pending_effects: VecDeque<Effect>,
 716    pending_notifications: HashSet<usize>,
 717    pending_flushes: usize,
 718    flushing_effects: bool,
 719    next_cursor_style_handle_id: Arc<AtomicUsize>,
 720}
 721
 722impl MutableAppContext {
 723    fn new(
 724        foreground: Rc<executor::Foreground>,
 725        background: Arc<executor::Background>,
 726        platform: Arc<dyn platform::Platform>,
 727        foreground_platform: Rc<dyn platform::ForegroundPlatform>,
 728        font_cache: Arc<FontCache>,
 729        asset_source: impl AssetSource,
 730        // entity_drop_tx:
 731    ) -> Self {
 732        Self {
 733            weak_self: None,
 734            foreground_platform,
 735            assets: Arc::new(AssetCache::new(asset_source)),
 736            cx: AppContext {
 737                models: Default::default(),
 738                views: Default::default(),
 739                windows: Default::default(),
 740                element_states: Default::default(),
 741                ref_counts: Arc::new(Mutex::new(RefCounts::default())),
 742                background,
 743                font_cache,
 744                platform,
 745            },
 746            actions: HashMap::new(),
 747            global_actions: HashMap::new(),
 748            keystroke_matcher: keymap::Matcher::default(),
 749            next_entity_id: 0,
 750            next_window_id: 0,
 751            next_subscription_id: 0,
 752            frame_count: 0,
 753            subscriptions: Default::default(),
 754            observations: Default::default(),
 755            release_observations: Default::default(),
 756            presenters_and_platform_windows: HashMap::new(),
 757            debug_elements_callbacks: HashMap::new(),
 758            foreground,
 759            pending_effects: VecDeque::new(),
 760            pending_notifications: HashSet::new(),
 761            pending_flushes: 0,
 762            flushing_effects: false,
 763            next_cursor_style_handle_id: Default::default(),
 764        }
 765    }
 766
 767    pub fn upgrade(&self) -> App {
 768        App(self.weak_self.as_ref().unwrap().upgrade().unwrap())
 769    }
 770
 771    pub fn quit(&mut self) {
 772        let mut futures = Vec::new();
 773        for model_id in self.cx.models.keys().copied().collect::<Vec<_>>() {
 774            let mut model = self.cx.models.remove(&model_id).unwrap();
 775            futures.extend(model.app_will_quit(self));
 776            self.cx.models.insert(model_id, model);
 777        }
 778
 779        for view_id in self.cx.views.keys().copied().collect::<Vec<_>>() {
 780            let mut view = self.cx.views.remove(&view_id).unwrap();
 781            futures.extend(view.app_will_quit(self));
 782            self.cx.views.insert(view_id, view);
 783        }
 784
 785        self.remove_all_windows();
 786
 787        let futures = futures::future::join_all(futures);
 788        if self
 789            .background
 790            .block_with_timeout(Duration::from_millis(100), futures)
 791            .is_err()
 792        {
 793            log::error!("timed out waiting on app_will_quit");
 794        }
 795    }
 796
 797    fn remove_all_windows(&mut self) {
 798        for (window_id, _) in self.cx.windows.drain() {
 799            self.presenters_and_platform_windows.remove(&window_id);
 800        }
 801        self.remove_dropped_entities();
 802    }
 803
 804    pub fn platform(&self) -> Arc<dyn platform::Platform> {
 805        self.cx.platform.clone()
 806    }
 807
 808    pub fn font_cache(&self) -> &Arc<FontCache> {
 809        &self.cx.font_cache
 810    }
 811
 812    pub fn foreground(&self) -> &Rc<executor::Foreground> {
 813        &self.foreground
 814    }
 815
 816    pub fn background(&self) -> &Arc<executor::Background> {
 817        &self.cx.background
 818    }
 819
 820    pub fn on_debug_elements<F>(&mut self, window_id: usize, callback: F)
 821    where
 822        F: 'static + Fn(&AppContext) -> crate::json::Value,
 823    {
 824        self.debug_elements_callbacks
 825            .insert(window_id, Box::new(callback));
 826    }
 827
 828    pub fn debug_elements(&self, window_id: usize) -> Option<crate::json::Value> {
 829        self.debug_elements_callbacks
 830            .get(&window_id)
 831            .map(|debug_elements| debug_elements(&self.cx))
 832    }
 833
 834    pub fn add_action<A, V, F>(&mut self, mut handler: F)
 835    where
 836        A: Action,
 837        V: View,
 838        F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>),
 839    {
 840        let handler = Box::new(
 841            move |view: &mut dyn AnyView,
 842                  action: &dyn AnyAction,
 843                  cx: &mut MutableAppContext,
 844                  window_id: usize,
 845                  view_id: usize| {
 846                let action = action.as_any().downcast_ref().unwrap();
 847                let mut cx = ViewContext::new(cx, window_id, view_id);
 848                handler(
 849                    view.as_any_mut()
 850                        .downcast_mut()
 851                        .expect("downcast is type safe"),
 852                    action,
 853                    &mut cx,
 854                );
 855                cx.halt_action_dispatch
 856            },
 857        );
 858
 859        self.actions
 860            .entry(TypeId::of::<V>())
 861            .or_default()
 862            .entry(TypeId::of::<A>())
 863            .or_default()
 864            .push(handler);
 865    }
 866
 867    pub fn add_async_action<A, V, F>(&mut self, mut handler: F)
 868    where
 869        A: Action,
 870        V: View,
 871        F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>) -> Option<Task<Result<()>>>,
 872    {
 873        self.add_action(move |view, action, cx| {
 874            handler(view, action, cx).map(|task| task.detach_and_log_err(cx));
 875        })
 876    }
 877
 878    pub fn add_global_action<A, F>(&mut self, mut handler: F)
 879    where
 880        A: Action,
 881        F: 'static + FnMut(&A, &mut MutableAppContext),
 882    {
 883        let handler = Box::new(move |action: &dyn AnyAction, cx: &mut MutableAppContext| {
 884            let action = action.as_any().downcast_ref().unwrap();
 885            handler(action, cx);
 886        });
 887
 888        if self
 889            .global_actions
 890            .insert(TypeId::of::<A>(), handler)
 891            .is_some()
 892        {
 893            panic!("registered multiple global handlers for the same action type");
 894        }
 895    }
 896
 897    pub fn window_ids(&self) -> impl Iterator<Item = usize> + '_ {
 898        self.cx.windows.keys().cloned()
 899    }
 900
 901    pub fn activate_window(&self, window_id: usize) {
 902        if let Some((_, window)) = self.presenters_and_platform_windows.get(&window_id) {
 903            window.activate()
 904        }
 905    }
 906
 907    pub fn root_view<T: View>(&self, window_id: usize) -> Option<ViewHandle<T>> {
 908        self.cx
 909            .windows
 910            .get(&window_id)
 911            .and_then(|window| window.root_view.clone().downcast::<T>())
 912    }
 913
 914    pub fn root_view_id(&self, window_id: usize) -> Option<usize> {
 915        self.cx.root_view_id(window_id)
 916    }
 917
 918    pub fn focused_view_id(&self, window_id: usize) -> Option<usize> {
 919        self.cx.focused_view_id(window_id)
 920    }
 921
 922    pub fn render_view(
 923        &mut self,
 924        window_id: usize,
 925        view_id: usize,
 926        titlebar_height: f32,
 927        refreshing: bool,
 928    ) -> Result<ElementBox> {
 929        let mut view = self
 930            .cx
 931            .views
 932            .remove(&(window_id, view_id))
 933            .ok_or(anyhow!("view not found"))?;
 934        let element = view.render(window_id, view_id, titlebar_height, refreshing, self);
 935        self.cx.views.insert((window_id, view_id), view);
 936        Ok(element)
 937    }
 938
 939    pub fn render_views(
 940        &mut self,
 941        window_id: usize,
 942        titlebar_height: f32,
 943    ) -> HashMap<usize, ElementBox> {
 944        self.start_frame();
 945        let view_ids = self
 946            .views
 947            .keys()
 948            .filter_map(|(win_id, view_id)| {
 949                if *win_id == window_id {
 950                    Some(*view_id)
 951                } else {
 952                    None
 953                }
 954            })
 955            .collect::<Vec<_>>();
 956        view_ids
 957            .into_iter()
 958            .map(|view_id| {
 959                (
 960                    view_id,
 961                    self.render_view(window_id, view_id, titlebar_height, false)
 962                        .unwrap(),
 963                )
 964            })
 965            .collect()
 966    }
 967
 968    pub(crate) fn start_frame(&mut self) {
 969        self.frame_count += 1;
 970    }
 971
 972    pub fn update<T, F: FnOnce(&mut Self) -> T>(&mut self, callback: F) -> T {
 973        self.pending_flushes += 1;
 974        let result = callback(self);
 975        self.flush_effects();
 976        result
 977    }
 978
 979    pub fn set_menus(&mut self, menus: Vec<Menu>) {
 980        self.foreground_platform.set_menus(menus);
 981    }
 982
 983    fn prompt(
 984        &self,
 985        window_id: usize,
 986        level: PromptLevel,
 987        msg: &str,
 988        answers: &[&str],
 989    ) -> oneshot::Receiver<usize> {
 990        let (_, window) = &self.presenters_and_platform_windows[&window_id];
 991        window.prompt(level, msg, answers)
 992    }
 993
 994    pub fn prompt_for_paths(
 995        &self,
 996        options: PathPromptOptions,
 997    ) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
 998        self.foreground_platform.prompt_for_paths(options)
 999    }
1000
1001    pub fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
1002        self.foreground_platform.prompt_for_new_path(directory)
1003    }
1004
1005    pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
1006    where
1007        E: Entity,
1008        E::Event: 'static,
1009        H: Handle<E>,
1010        F: 'static + FnMut(H, &E::Event, &mut Self),
1011    {
1012        self.subscribe_internal(handle, move |handle, event, cx| {
1013            callback(handle, event, cx);
1014            true
1015        })
1016    }
1017
1018    pub fn observe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
1019    where
1020        E: Entity,
1021        E::Event: 'static,
1022        H: Handle<E>,
1023        F: 'static + FnMut(H, &mut Self),
1024    {
1025        self.observe_internal(handle, move |handle, cx| {
1026            callback(handle, cx);
1027            true
1028        })
1029    }
1030
1031    pub fn subscribe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
1032    where
1033        E: Entity,
1034        E::Event: 'static,
1035        H: Handle<E>,
1036        F: 'static + FnMut(H, &E::Event, &mut Self) -> bool,
1037    {
1038        let id = post_inc(&mut self.next_subscription_id);
1039        let emitter = handle.downgrade();
1040        self.subscriptions
1041            .lock()
1042            .entry(handle.id())
1043            .or_default()
1044            .insert(
1045                id,
1046                Box::new(move |payload, cx| {
1047                    if let Some(emitter) = H::upgrade_from(&emitter, cx.as_ref()) {
1048                        let payload = payload.downcast_ref().expect("downcast is type safe");
1049                        callback(emitter, payload, cx)
1050                    } else {
1051                        false
1052                    }
1053                }),
1054            );
1055        Subscription::Subscription {
1056            id,
1057            entity_id: handle.id(),
1058            subscriptions: Some(Arc::downgrade(&self.subscriptions)),
1059        }
1060    }
1061
1062    fn observe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
1063    where
1064        E: Entity,
1065        E::Event: 'static,
1066        H: Handle<E>,
1067        F: 'static + FnMut(H, &mut Self) -> bool,
1068    {
1069        let id = post_inc(&mut self.next_subscription_id);
1070        let observed = handle.downgrade();
1071        self.observations
1072            .lock()
1073            .entry(handle.id())
1074            .or_default()
1075            .insert(
1076                id,
1077                Box::new(move |cx| {
1078                    if let Some(observed) = H::upgrade_from(&observed, cx) {
1079                        callback(observed, cx)
1080                    } else {
1081                        false
1082                    }
1083                }),
1084            );
1085        Subscription::Observation {
1086            id,
1087            entity_id: handle.id(),
1088            observations: Some(Arc::downgrade(&self.observations)),
1089        }
1090    }
1091
1092    pub fn observe_release<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
1093    where
1094        E: Entity,
1095        E::Event: 'static,
1096        H: Handle<E>,
1097        F: 'static + FnMut(&mut Self),
1098    {
1099        let id = post_inc(&mut self.next_subscription_id);
1100        self.release_observations
1101            .lock()
1102            .entry(handle.id())
1103            .or_default()
1104            .insert(id, Box::new(move |cx| callback(cx)));
1105        Subscription::ReleaseObservation {
1106            id,
1107            entity_id: handle.id(),
1108            observations: Some(Arc::downgrade(&self.release_observations)),
1109        }
1110    }
1111
1112    fn defer(&mut self, callback: Box<dyn FnOnce(&mut MutableAppContext)>) {
1113        self.pending_effects.push_back(Effect::Deferred(callback))
1114    }
1115
1116    pub(crate) fn notify_model(&mut self, model_id: usize) {
1117        if self.pending_notifications.insert(model_id) {
1118            self.pending_effects
1119                .push_back(Effect::ModelNotification { model_id });
1120        }
1121    }
1122
1123    pub(crate) fn notify_view(&mut self, window_id: usize, view_id: usize) {
1124        if self.pending_notifications.insert(view_id) {
1125            self.pending_effects
1126                .push_back(Effect::ViewNotification { window_id, view_id });
1127        }
1128    }
1129
1130    pub fn dispatch_action<A: Action>(
1131        &mut self,
1132        window_id: usize,
1133        responder_chain: Vec<usize>,
1134        action: &A,
1135    ) {
1136        self.dispatch_action_any(window_id, &responder_chain, action);
1137    }
1138
1139    pub(crate) fn dispatch_action_any(
1140        &mut self,
1141        window_id: usize,
1142        path: &[usize],
1143        action: &dyn AnyAction,
1144    ) -> bool {
1145        self.update(|this| {
1146            let mut halted_dispatch = false;
1147            for view_id in path.iter().rev() {
1148                if let Some(mut view) = this.cx.views.remove(&(window_id, *view_id)) {
1149                    let type_id = view.as_any().type_id();
1150
1151                    if let Some((name, mut handlers)) = this
1152                        .actions
1153                        .get_mut(&type_id)
1154                        .and_then(|h| h.remove_entry(&action.id()))
1155                    {
1156                        for handler in handlers.iter_mut().rev() {
1157                            let halt_dispatch =
1158                                handler(view.as_mut(), action, this, window_id, *view_id);
1159                            if halt_dispatch {
1160                                halted_dispatch = true;
1161                                break;
1162                            }
1163                        }
1164                        this.actions
1165                            .get_mut(&type_id)
1166                            .unwrap()
1167                            .insert(name, handlers);
1168                    }
1169
1170                    this.cx.views.insert((window_id, *view_id), view);
1171
1172                    if halted_dispatch {
1173                        break;
1174                    }
1175                }
1176            }
1177
1178            if !halted_dispatch {
1179                halted_dispatch = this.dispatch_global_action_any(action);
1180            }
1181            halted_dispatch
1182        })
1183    }
1184
1185    pub fn dispatch_global_action<A: Action>(&mut self, action: A) {
1186        self.dispatch_global_action_any(&action);
1187    }
1188
1189    fn dispatch_global_action_any(&mut self, action: &dyn AnyAction) -> bool {
1190        self.update(|this| {
1191            if let Some((name, mut handler)) = this.global_actions.remove_entry(&action.id()) {
1192                handler(action, this);
1193                this.global_actions.insert(name, handler);
1194                true
1195            } else {
1196                false
1197            }
1198        })
1199    }
1200
1201    pub fn add_bindings<T: IntoIterator<Item = keymap::Binding>>(&mut self, bindings: T) {
1202        self.keystroke_matcher.add_bindings(bindings);
1203    }
1204
1205    pub fn dispatch_keystroke(
1206        &mut self,
1207        window_id: usize,
1208        responder_chain: Vec<usize>,
1209        keystroke: &Keystroke,
1210    ) -> Result<bool> {
1211        let mut context_chain = Vec::new();
1212        for view_id in &responder_chain {
1213            if let Some(view) = self.cx.views.get(&(window_id, *view_id)) {
1214                context_chain.push(view.keymap_context(self.as_ref()));
1215            } else {
1216                return Err(anyhow!(
1217                    "View {} in responder chain does not exist",
1218                    view_id
1219                ));
1220            }
1221        }
1222
1223        let mut pending = false;
1224        for (i, cx) in context_chain.iter().enumerate().rev() {
1225            match self
1226                .keystroke_matcher
1227                .push_keystroke(keystroke.clone(), responder_chain[i], cx)
1228            {
1229                MatchResult::None => {}
1230                MatchResult::Pending => pending = true,
1231                MatchResult::Action(action) => {
1232                    if self.dispatch_action_any(window_id, &responder_chain[0..=i], action.as_ref())
1233                    {
1234                        self.keystroke_matcher.clear_pending();
1235                        return Ok(true);
1236                    }
1237                }
1238            }
1239        }
1240
1241        Ok(pending)
1242    }
1243
1244    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
1245    where
1246        T: Entity,
1247        F: FnOnce(&mut ModelContext<T>) -> T,
1248    {
1249        self.update(|this| {
1250            let model_id = post_inc(&mut this.next_entity_id);
1251            let handle = ModelHandle::new(model_id, &this.cx.ref_counts);
1252            let mut cx = ModelContext::new(this, model_id);
1253            let model = build_model(&mut cx);
1254            this.cx.models.insert(model_id, Box::new(model));
1255            handle
1256        })
1257    }
1258
1259    pub fn add_window<T, F>(
1260        &mut self,
1261        window_options: WindowOptions,
1262        build_root_view: F,
1263    ) -> (usize, ViewHandle<T>)
1264    where
1265        T: View,
1266        F: FnOnce(&mut ViewContext<T>) -> T,
1267    {
1268        self.update(|this| {
1269            let window_id = post_inc(&mut this.next_window_id);
1270            let root_view = this.add_view(window_id, build_root_view);
1271
1272            this.cx.windows.insert(
1273                window_id,
1274                Window {
1275                    root_view: root_view.clone().into(),
1276                    focused_view_id: root_view.id(),
1277                    invalidation: None,
1278                },
1279            );
1280            this.open_platform_window(window_id, window_options);
1281            root_view.update(this, |view, cx| {
1282                view.on_focus(cx);
1283                cx.notify();
1284            });
1285
1286            (window_id, root_view)
1287        })
1288    }
1289
1290    pub fn remove_window(&mut self, window_id: usize) {
1291        self.cx.windows.remove(&window_id);
1292        self.presenters_and_platform_windows.remove(&window_id);
1293        self.remove_dropped_entities();
1294        self.flush_effects();
1295    }
1296
1297    fn open_platform_window(&mut self, window_id: usize, window_options: WindowOptions) {
1298        let mut window =
1299            self.cx
1300                .platform
1301                .open_window(window_id, window_options, self.foreground.clone());
1302        let presenter = Rc::new(RefCell::new(
1303            self.build_presenter(window_id, window.titlebar_height()),
1304        ));
1305
1306        {
1307            let mut app = self.upgrade();
1308            let presenter = presenter.clone();
1309            window.on_event(Box::new(move |event| {
1310                app.update(|cx| {
1311                    if let Event::KeyDown { keystroke, .. } = &event {
1312                        if cx
1313                            .dispatch_keystroke(
1314                                window_id,
1315                                presenter.borrow().dispatch_path(cx.as_ref()),
1316                                keystroke,
1317                            )
1318                            .unwrap()
1319                        {
1320                            return;
1321                        }
1322                    }
1323
1324                    presenter.borrow_mut().dispatch_event(event, cx);
1325                })
1326            }));
1327        }
1328
1329        {
1330            let mut app = self.upgrade();
1331            window.on_resize(Box::new(move || {
1332                app.update(|cx| cx.resize_window(window_id))
1333            }));
1334        }
1335
1336        {
1337            let mut app = self.upgrade();
1338            window.on_close(Box::new(move || {
1339                app.update(|cx| cx.remove_window(window_id));
1340            }));
1341        }
1342
1343        self.presenters_and_platform_windows
1344            .insert(window_id, (presenter.clone(), window));
1345
1346        self.on_debug_elements(window_id, move |cx| {
1347            presenter.borrow().debug_elements(cx).unwrap()
1348        });
1349    }
1350
1351    pub fn build_presenter(&mut self, window_id: usize, titlebar_height: f32) -> Presenter {
1352        Presenter::new(
1353            window_id,
1354            titlebar_height,
1355            self.cx.font_cache.clone(),
1356            TextLayoutCache::new(self.cx.platform.fonts()),
1357            self.assets.clone(),
1358            self,
1359        )
1360    }
1361
1362    pub fn build_render_context<V: View>(
1363        &mut self,
1364        window_id: usize,
1365        view_id: usize,
1366        titlebar_height: f32,
1367        refreshing: bool,
1368    ) -> RenderContext<V> {
1369        RenderContext {
1370            app: self,
1371            titlebar_height,
1372            refreshing,
1373            window_id,
1374            view_id,
1375            view_type: PhantomData,
1376        }
1377    }
1378
1379    pub fn add_view<T, F>(&mut self, window_id: usize, build_view: F) -> ViewHandle<T>
1380    where
1381        T: View,
1382        F: FnOnce(&mut ViewContext<T>) -> T,
1383    {
1384        self.add_option_view(window_id, |cx| Some(build_view(cx)))
1385            .unwrap()
1386    }
1387
1388    pub fn add_option_view<T, F>(
1389        &mut self,
1390        window_id: usize,
1391        build_view: F,
1392    ) -> Option<ViewHandle<T>>
1393    where
1394        T: View,
1395        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
1396    {
1397        self.update(|this| {
1398            let view_id = post_inc(&mut this.next_entity_id);
1399            let mut cx = ViewContext::new(this, window_id, view_id);
1400            let handle = if let Some(view) = build_view(&mut cx) {
1401                this.cx.views.insert((window_id, view_id), Box::new(view));
1402                if let Some(window) = this.cx.windows.get_mut(&window_id) {
1403                    window
1404                        .invalidation
1405                        .get_or_insert_with(Default::default)
1406                        .updated
1407                        .insert(view_id);
1408                }
1409                Some(ViewHandle::new(window_id, view_id, &this.cx.ref_counts))
1410            } else {
1411                None
1412            };
1413            handle
1414        })
1415    }
1416
1417    pub fn element_state<Tag: 'static, T: 'static + Default>(
1418        &mut self,
1419        id: ElementStateId,
1420    ) -> ElementStateHandle<T> {
1421        let key = (TypeId::of::<Tag>(), id);
1422        self.cx
1423            .element_states
1424            .entry(key)
1425            .or_insert_with(|| Box::new(T::default()));
1426        ElementStateHandle::new(
1427            TypeId::of::<Tag>(),
1428            id,
1429            self.frame_count,
1430            &self.cx.ref_counts,
1431        )
1432    }
1433
1434    fn remove_dropped_entities(&mut self) {
1435        loop {
1436            let (dropped_models, dropped_views, dropped_element_states) =
1437                self.cx.ref_counts.lock().take_dropped();
1438            if dropped_models.is_empty()
1439                && dropped_views.is_empty()
1440                && dropped_element_states.is_empty()
1441            {
1442                break;
1443            }
1444
1445            for model_id in dropped_models {
1446                self.subscriptions.lock().remove(&model_id);
1447                self.observations.lock().remove(&model_id);
1448                let mut model = self.cx.models.remove(&model_id).unwrap();
1449                model.release(self);
1450                self.pending_effects.push_back(Effect::Release {
1451                    entity_id: model_id,
1452                });
1453            }
1454
1455            for (window_id, view_id) in dropped_views {
1456                self.subscriptions.lock().remove(&view_id);
1457                self.observations.lock().remove(&view_id);
1458                let mut view = self.cx.views.remove(&(window_id, view_id)).unwrap();
1459                view.release(self);
1460                let change_focus_to = self.cx.windows.get_mut(&window_id).and_then(|window| {
1461                    window
1462                        .invalidation
1463                        .get_or_insert_with(Default::default)
1464                        .removed
1465                        .push(view_id);
1466                    if window.focused_view_id == view_id {
1467                        Some(window.root_view.id())
1468                    } else {
1469                        None
1470                    }
1471                });
1472
1473                if let Some(view_id) = change_focus_to {
1474                    self.focus(window_id, view_id);
1475                }
1476
1477                self.pending_effects
1478                    .push_back(Effect::Release { entity_id: view_id });
1479            }
1480
1481            for key in dropped_element_states {
1482                self.cx.element_states.remove(&key);
1483            }
1484        }
1485    }
1486
1487    fn flush_effects(&mut self) {
1488        self.pending_flushes = self.pending_flushes.saturating_sub(1);
1489
1490        if !self.flushing_effects && self.pending_flushes == 0 {
1491            self.flushing_effects = true;
1492
1493            let mut refreshing = false;
1494            loop {
1495                if let Some(effect) = self.pending_effects.pop_front() {
1496                    match effect {
1497                        Effect::Event { entity_id, payload } => self.emit_event(entity_id, payload),
1498                        Effect::ModelNotification { model_id } => {
1499                            self.notify_model_observers(model_id)
1500                        }
1501                        Effect::ViewNotification { window_id, view_id } => {
1502                            self.notify_view_observers(window_id, view_id)
1503                        }
1504                        Effect::Deferred(callback) => callback(self),
1505                        Effect::Release { entity_id } => self.notify_release_observers(entity_id),
1506                        Effect::Focus { window_id, view_id } => {
1507                            self.focus(window_id, view_id);
1508                        }
1509                        Effect::ResizeWindow { window_id } => {
1510                            if let Some(window) = self.cx.windows.get_mut(&window_id) {
1511                                window
1512                                    .invalidation
1513                                    .get_or_insert(WindowInvalidation::default());
1514                            }
1515                        }
1516                        Effect::RefreshWindows => {
1517                            refreshing = true;
1518                        }
1519                    }
1520                    self.pending_notifications.clear();
1521                    self.remove_dropped_entities();
1522                } else {
1523                    self.remove_dropped_entities();
1524                    if refreshing {
1525                        self.perform_window_refresh();
1526                    } else {
1527                        self.update_windows();
1528                    }
1529
1530                    if self.pending_effects.is_empty() {
1531                        self.flushing_effects = false;
1532                        self.pending_notifications.clear();
1533                        break;
1534                    } else {
1535                        refreshing = false;
1536                    }
1537                }
1538            }
1539        }
1540    }
1541
1542    fn update_windows(&mut self) {
1543        let mut invalidations = HashMap::new();
1544        for (window_id, window) in &mut self.cx.windows {
1545            if let Some(invalidation) = window.invalidation.take() {
1546                invalidations.insert(*window_id, invalidation);
1547            }
1548        }
1549
1550        for (window_id, invalidation) in invalidations {
1551            if let Some((presenter, mut window)) =
1552                self.presenters_and_platform_windows.remove(&window_id)
1553            {
1554                {
1555                    let mut presenter = presenter.borrow_mut();
1556                    presenter.invalidate(invalidation, self);
1557                    let scene =
1558                        presenter.build_scene(window.size(), window.scale_factor(), false, self);
1559                    window.present_scene(scene);
1560                }
1561                self.presenters_and_platform_windows
1562                    .insert(window_id, (presenter, window));
1563            }
1564        }
1565    }
1566
1567    fn resize_window(&mut self, window_id: usize) {
1568        self.pending_effects
1569            .push_back(Effect::ResizeWindow { window_id });
1570    }
1571
1572    pub fn refresh_windows(&mut self) {
1573        self.pending_effects.push_back(Effect::RefreshWindows);
1574    }
1575
1576    fn perform_window_refresh(&mut self) {
1577        let mut presenters = mem::take(&mut self.presenters_and_platform_windows);
1578        for (window_id, (presenter, window)) in &mut presenters {
1579            let invalidation = self
1580                .cx
1581                .windows
1582                .get_mut(&window_id)
1583                .unwrap()
1584                .invalidation
1585                .take();
1586            let mut presenter = presenter.borrow_mut();
1587            presenter.refresh(invalidation, self);
1588            let scene = presenter.build_scene(window.size(), window.scale_factor(), true, self);
1589            window.present_scene(scene);
1590        }
1591        self.presenters_and_platform_windows = presenters;
1592    }
1593
1594    pub fn set_cursor_style(&mut self, style: CursorStyle) -> CursorStyleHandle {
1595        self.platform.set_cursor_style(style);
1596        let id = self.next_cursor_style_handle_id.fetch_add(1, SeqCst);
1597        CursorStyleHandle {
1598            id,
1599            next_cursor_style_handle_id: self.next_cursor_style_handle_id.clone(),
1600            platform: self.platform(),
1601        }
1602    }
1603
1604    fn emit_event(&mut self, entity_id: usize, payload: Box<dyn Any>) {
1605        let callbacks = self.subscriptions.lock().remove(&entity_id);
1606        if let Some(callbacks) = callbacks {
1607            for (id, mut callback) in callbacks {
1608                let alive = callback(payload.as_ref(), self);
1609                if alive {
1610                    self.subscriptions
1611                        .lock()
1612                        .entry(entity_id)
1613                        .or_default()
1614                        .insert(id, callback);
1615                }
1616            }
1617        }
1618    }
1619
1620    fn notify_model_observers(&mut self, observed_id: usize) {
1621        let callbacks = self.observations.lock().remove(&observed_id);
1622        if let Some(callbacks) = callbacks {
1623            if self.cx.models.contains_key(&observed_id) {
1624                for (id, mut callback) in callbacks {
1625                    let alive = callback(self);
1626                    if alive {
1627                        self.observations
1628                            .lock()
1629                            .entry(observed_id)
1630                            .or_default()
1631                            .insert(id, callback);
1632                    }
1633                }
1634            }
1635        }
1636    }
1637
1638    fn notify_view_observers(&mut self, observed_window_id: usize, observed_view_id: usize) {
1639        if let Some(window) = self.cx.windows.get_mut(&observed_window_id) {
1640            window
1641                .invalidation
1642                .get_or_insert_with(Default::default)
1643                .updated
1644                .insert(observed_view_id);
1645        }
1646
1647        let callbacks = self.observations.lock().remove(&observed_view_id);
1648        if let Some(callbacks) = callbacks {
1649            if self
1650                .cx
1651                .views
1652                .contains_key(&(observed_window_id, observed_view_id))
1653            {
1654                for (id, mut callback) in callbacks {
1655                    let alive = callback(self);
1656                    if alive {
1657                        self.observations
1658                            .lock()
1659                            .entry(observed_view_id)
1660                            .or_default()
1661                            .insert(id, callback);
1662                    }
1663                }
1664            }
1665        }
1666    }
1667
1668    fn notify_release_observers(&mut self, entity_id: usize) {
1669        let callbacks = self.release_observations.lock().remove(&entity_id);
1670        if let Some(callbacks) = callbacks {
1671            for (_, mut callback) in callbacks {
1672                callback(self);
1673            }
1674        }
1675    }
1676
1677    fn focus(&mut self, window_id: usize, focused_id: usize) {
1678        if self
1679            .cx
1680            .windows
1681            .get(&window_id)
1682            .map(|w| w.focused_view_id)
1683            .map_or(false, |cur_focused| cur_focused == focused_id)
1684        {
1685            return;
1686        }
1687
1688        self.update(|this| {
1689            let blurred_id = this.cx.windows.get_mut(&window_id).map(|window| {
1690                let blurred_id = window.focused_view_id;
1691                window.focused_view_id = focused_id;
1692                blurred_id
1693            });
1694
1695            if let Some(blurred_id) = blurred_id {
1696                if let Some(mut blurred_view) = this.cx.views.remove(&(window_id, blurred_id)) {
1697                    blurred_view.on_blur(this, window_id, blurred_id);
1698                    this.cx.views.insert((window_id, blurred_id), blurred_view);
1699                }
1700            }
1701
1702            if let Some(mut focused_view) = this.cx.views.remove(&(window_id, focused_id)) {
1703                focused_view.on_focus(this, window_id, focused_id);
1704                this.cx.views.insert((window_id, focused_id), focused_view);
1705            }
1706        })
1707    }
1708
1709    pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
1710    where
1711        F: FnOnce(AsyncAppContext) -> Fut,
1712        Fut: 'static + Future<Output = T>,
1713        T: 'static,
1714    {
1715        let future = f(self.to_async());
1716        let cx = self.to_async();
1717        self.foreground.spawn(async move {
1718            let result = future.await;
1719            cx.0.borrow_mut().flush_effects();
1720            result
1721        })
1722    }
1723
1724    pub fn to_async(&self) -> AsyncAppContext {
1725        AsyncAppContext(self.weak_self.as_ref().unwrap().upgrade().unwrap())
1726    }
1727
1728    pub fn write_to_clipboard(&self, item: ClipboardItem) {
1729        self.cx.platform.write_to_clipboard(item);
1730    }
1731
1732    pub fn read_from_clipboard(&self) -> Option<ClipboardItem> {
1733        self.cx.platform.read_from_clipboard()
1734    }
1735}
1736
1737impl ReadModel for MutableAppContext {
1738    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1739        if let Some(model) = self.cx.models.get(&handle.model_id) {
1740            model
1741                .as_any()
1742                .downcast_ref()
1743                .expect("downcast is type safe")
1744        } else {
1745            panic!("circular model reference");
1746        }
1747    }
1748}
1749
1750impl UpdateModel for MutableAppContext {
1751    fn update_model<T: Entity, V>(
1752        &mut self,
1753        handle: &ModelHandle<T>,
1754        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
1755    ) -> V {
1756        if let Some(mut model) = self.cx.models.remove(&handle.model_id) {
1757            self.update(|this| {
1758                let mut cx = ModelContext::new(this, handle.model_id);
1759                let result = update(
1760                    model
1761                        .as_any_mut()
1762                        .downcast_mut()
1763                        .expect("downcast is type safe"),
1764                    &mut cx,
1765                );
1766                this.cx.models.insert(handle.model_id, model);
1767                result
1768            })
1769        } else {
1770            panic!("circular model update");
1771        }
1772    }
1773}
1774
1775impl UpgradeModelHandle for MutableAppContext {
1776    fn upgrade_model_handle<T: Entity>(
1777        &self,
1778        handle: &WeakModelHandle<T>,
1779    ) -> Option<ModelHandle<T>> {
1780        self.cx.upgrade_model_handle(handle)
1781    }
1782
1783    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
1784        self.cx.upgrade_any_model_handle(handle)
1785    }
1786}
1787
1788impl UpgradeViewHandle for MutableAppContext {
1789    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
1790        self.cx.upgrade_view_handle(handle)
1791    }
1792}
1793
1794impl ReadView for MutableAppContext {
1795    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
1796        if let Some(view) = self.cx.views.get(&(handle.window_id, handle.view_id)) {
1797            view.as_any().downcast_ref().expect("downcast is type safe")
1798        } else {
1799            panic!("circular view reference");
1800        }
1801    }
1802}
1803
1804impl UpdateView for MutableAppContext {
1805    fn update_view<T, S>(
1806        &mut self,
1807        handle: &ViewHandle<T>,
1808        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
1809    ) -> S
1810    where
1811        T: View,
1812    {
1813        self.update(|this| {
1814            let mut view = this
1815                .cx
1816                .views
1817                .remove(&(handle.window_id, handle.view_id))
1818                .expect("circular view update");
1819
1820            let mut cx = ViewContext::new(this, handle.window_id, handle.view_id);
1821            let result = update(
1822                view.as_any_mut()
1823                    .downcast_mut()
1824                    .expect("downcast is type safe"),
1825                &mut cx,
1826            );
1827            this.cx
1828                .views
1829                .insert((handle.window_id, handle.view_id), view);
1830            result
1831        })
1832    }
1833}
1834
1835impl AsRef<AppContext> for MutableAppContext {
1836    fn as_ref(&self) -> &AppContext {
1837        &self.cx
1838    }
1839}
1840
1841impl Deref for MutableAppContext {
1842    type Target = AppContext;
1843
1844    fn deref(&self) -> &Self::Target {
1845        &self.cx
1846    }
1847}
1848
1849pub struct AppContext {
1850    models: HashMap<usize, Box<dyn AnyModel>>,
1851    views: HashMap<(usize, usize), Box<dyn AnyView>>,
1852    windows: HashMap<usize, Window>,
1853    element_states: HashMap<(TypeId, ElementStateId), Box<dyn Any>>,
1854    background: Arc<executor::Background>,
1855    ref_counts: Arc<Mutex<RefCounts>>,
1856    font_cache: Arc<FontCache>,
1857    platform: Arc<dyn Platform>,
1858}
1859
1860impl AppContext {
1861    pub fn root_view_id(&self, window_id: usize) -> Option<usize> {
1862        self.windows
1863            .get(&window_id)
1864            .map(|window| window.root_view.id())
1865    }
1866
1867    pub fn focused_view_id(&self, window_id: usize) -> Option<usize> {
1868        self.windows
1869            .get(&window_id)
1870            .map(|window| window.focused_view_id)
1871    }
1872
1873    pub fn background(&self) -> &Arc<executor::Background> {
1874        &self.background
1875    }
1876
1877    pub fn font_cache(&self) -> &Arc<FontCache> {
1878        &self.font_cache
1879    }
1880
1881    pub fn platform(&self) -> &Arc<dyn Platform> {
1882        &self.platform
1883    }
1884}
1885
1886impl ReadModel for AppContext {
1887    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1888        if let Some(model) = self.models.get(&handle.model_id) {
1889            model
1890                .as_any()
1891                .downcast_ref()
1892                .expect("downcast should be type safe")
1893        } else {
1894            panic!("circular model reference");
1895        }
1896    }
1897}
1898
1899impl UpgradeModelHandle for AppContext {
1900    fn upgrade_model_handle<T: Entity>(
1901        &self,
1902        handle: &WeakModelHandle<T>,
1903    ) -> Option<ModelHandle<T>> {
1904        if self.models.contains_key(&handle.model_id) {
1905            Some(ModelHandle::new(handle.model_id, &self.ref_counts))
1906        } else {
1907            None
1908        }
1909    }
1910
1911    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
1912        if self.models.contains_key(&handle.model_id) {
1913            self.ref_counts.lock().inc_model(handle.model_id);
1914            Some(AnyModelHandle {
1915                model_id: handle.model_id,
1916                model_type: handle.model_type,
1917                ref_counts: self.ref_counts.clone(),
1918            })
1919        } else {
1920            None
1921        }
1922    }
1923}
1924
1925impl UpgradeViewHandle for AppContext {
1926    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
1927        if self.ref_counts.lock().is_entity_alive(handle.view_id) {
1928            Some(ViewHandle::new(
1929                handle.window_id,
1930                handle.view_id,
1931                &self.ref_counts,
1932            ))
1933        } else {
1934            None
1935        }
1936    }
1937}
1938
1939impl ReadView for AppContext {
1940    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
1941        if let Some(view) = self.views.get(&(handle.window_id, handle.view_id)) {
1942            view.as_any()
1943                .downcast_ref()
1944                .expect("downcast should be type safe")
1945        } else {
1946            panic!("circular view reference");
1947        }
1948    }
1949}
1950
1951struct Window {
1952    root_view: AnyViewHandle,
1953    focused_view_id: usize,
1954    invalidation: Option<WindowInvalidation>,
1955}
1956
1957#[derive(Default, Clone)]
1958pub struct WindowInvalidation {
1959    pub updated: HashSet<usize>,
1960    pub removed: Vec<usize>,
1961}
1962
1963pub enum Effect {
1964    Event {
1965        entity_id: usize,
1966        payload: Box<dyn Any>,
1967    },
1968    ModelNotification {
1969        model_id: usize,
1970    },
1971    ViewNotification {
1972        window_id: usize,
1973        view_id: usize,
1974    },
1975    Deferred(Box<dyn FnOnce(&mut MutableAppContext)>),
1976    Release {
1977        entity_id: usize,
1978    },
1979    Focus {
1980        window_id: usize,
1981        view_id: usize,
1982    },
1983    ResizeWindow {
1984        window_id: usize,
1985    },
1986    RefreshWindows,
1987}
1988
1989impl Debug for Effect {
1990    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1991        match self {
1992            Effect::Event { entity_id, .. } => f
1993                .debug_struct("Effect::Event")
1994                .field("entity_id", entity_id)
1995                .finish(),
1996            Effect::ModelNotification { model_id } => f
1997                .debug_struct("Effect::ModelNotification")
1998                .field("model_id", model_id)
1999                .finish(),
2000            Effect::ViewNotification { window_id, view_id } => f
2001                .debug_struct("Effect::ViewNotification")
2002                .field("window_id", window_id)
2003                .field("view_id", view_id)
2004                .finish(),
2005            Effect::Deferred(_) => f.debug_struct("Effect::Deferred").finish(),
2006            Effect::Release { entity_id } => f
2007                .debug_struct("Effect::Release")
2008                .field("entity_id", entity_id)
2009                .finish(),
2010            Effect::Focus { window_id, view_id } => f
2011                .debug_struct("Effect::Focus")
2012                .field("window_id", window_id)
2013                .field("view_id", view_id)
2014                .finish(),
2015            Effect::ResizeWindow { window_id } => f
2016                .debug_struct("Effect::RefreshWindow")
2017                .field("window_id", window_id)
2018                .finish(),
2019            Effect::RefreshWindows => f.debug_struct("Effect::FullViewRefresh").finish(),
2020        }
2021    }
2022}
2023
2024pub trait AnyModel {
2025    fn as_any(&self) -> &dyn Any;
2026    fn as_any_mut(&mut self) -> &mut dyn Any;
2027    fn release(&mut self, cx: &mut MutableAppContext);
2028    fn app_will_quit(
2029        &mut self,
2030        cx: &mut MutableAppContext,
2031    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
2032}
2033
2034impl<T> AnyModel for T
2035where
2036    T: Entity,
2037{
2038    fn as_any(&self) -> &dyn Any {
2039        self
2040    }
2041
2042    fn as_any_mut(&mut self) -> &mut dyn Any {
2043        self
2044    }
2045
2046    fn release(&mut self, cx: &mut MutableAppContext) {
2047        self.release(cx);
2048    }
2049
2050    fn app_will_quit(
2051        &mut self,
2052        cx: &mut MutableAppContext,
2053    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
2054        self.app_will_quit(cx)
2055    }
2056}
2057
2058pub trait AnyView {
2059    fn as_any(&self) -> &dyn Any;
2060    fn as_any_mut(&mut self) -> &mut dyn Any;
2061    fn release(&mut self, cx: &mut MutableAppContext);
2062    fn app_will_quit(
2063        &mut self,
2064        cx: &mut MutableAppContext,
2065    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
2066    fn ui_name(&self) -> &'static str;
2067    fn render<'a>(
2068        &mut self,
2069        window_id: usize,
2070        view_id: usize,
2071        titlebar_height: f32,
2072        refreshing: bool,
2073        cx: &mut MutableAppContext,
2074    ) -> ElementBox;
2075    fn on_focus(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize);
2076    fn on_blur(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize);
2077    fn keymap_context(&self, cx: &AppContext) -> keymap::Context;
2078}
2079
2080impl<T> AnyView for T
2081where
2082    T: View,
2083{
2084    fn as_any(&self) -> &dyn Any {
2085        self
2086    }
2087
2088    fn as_any_mut(&mut self) -> &mut dyn Any {
2089        self
2090    }
2091
2092    fn release(&mut self, cx: &mut MutableAppContext) {
2093        self.release(cx);
2094    }
2095
2096    fn app_will_quit(
2097        &mut self,
2098        cx: &mut MutableAppContext,
2099    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
2100        self.app_will_quit(cx)
2101    }
2102
2103    fn ui_name(&self) -> &'static str {
2104        T::ui_name()
2105    }
2106
2107    fn render<'a>(
2108        &mut self,
2109        window_id: usize,
2110        view_id: usize,
2111        titlebar_height: f32,
2112        refreshing: bool,
2113        cx: &mut MutableAppContext,
2114    ) -> ElementBox {
2115        View::render(
2116            self,
2117            &mut RenderContext {
2118                window_id,
2119                view_id,
2120                app: cx,
2121                view_type: PhantomData::<T>,
2122                titlebar_height,
2123                refreshing,
2124            },
2125        )
2126    }
2127
2128    fn on_focus(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize) {
2129        let mut cx = ViewContext::new(cx, window_id, view_id);
2130        View::on_focus(self, &mut cx);
2131    }
2132
2133    fn on_blur(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize) {
2134        let mut cx = ViewContext::new(cx, window_id, view_id);
2135        View::on_blur(self, &mut cx);
2136    }
2137
2138    fn keymap_context(&self, cx: &AppContext) -> keymap::Context {
2139        View::keymap_context(self, cx)
2140    }
2141}
2142
2143pub struct ModelContext<'a, T: ?Sized> {
2144    app: &'a mut MutableAppContext,
2145    model_id: usize,
2146    model_type: PhantomData<T>,
2147    halt_stream: bool,
2148}
2149
2150impl<'a, T: Entity> ModelContext<'a, T> {
2151    fn new(app: &'a mut MutableAppContext, model_id: usize) -> Self {
2152        Self {
2153            app,
2154            model_id,
2155            model_type: PhantomData,
2156            halt_stream: false,
2157        }
2158    }
2159
2160    pub fn background(&self) -> &Arc<executor::Background> {
2161        &self.app.cx.background
2162    }
2163
2164    pub fn halt_stream(&mut self) {
2165        self.halt_stream = true;
2166    }
2167
2168    pub fn model_id(&self) -> usize {
2169        self.model_id
2170    }
2171
2172    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
2173    where
2174        S: Entity,
2175        F: FnOnce(&mut ModelContext<S>) -> S,
2176    {
2177        self.app.add_model(build_model)
2178    }
2179
2180    pub fn emit(&mut self, payload: T::Event) {
2181        self.app.pending_effects.push_back(Effect::Event {
2182            entity_id: self.model_id,
2183            payload: Box::new(payload),
2184        });
2185    }
2186
2187    pub fn notify(&mut self) {
2188        self.app.notify_model(self.model_id);
2189    }
2190
2191    pub fn subscribe<S: Entity, F>(
2192        &mut self,
2193        handle: &ModelHandle<S>,
2194        mut callback: F,
2195    ) -> Subscription
2196    where
2197        S::Event: 'static,
2198        F: 'static + FnMut(&mut T, ModelHandle<S>, &S::Event, &mut ModelContext<T>),
2199    {
2200        let subscriber = self.weak_handle();
2201        self.app
2202            .subscribe_internal(handle, move |emitter, event, cx| {
2203                if let Some(subscriber) = subscriber.upgrade(cx) {
2204                    subscriber.update(cx, |subscriber, cx| {
2205                        callback(subscriber, emitter, event, cx);
2206                    });
2207                    true
2208                } else {
2209                    false
2210                }
2211            })
2212    }
2213
2214    pub fn observe<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F) -> Subscription
2215    where
2216        S: Entity,
2217        F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ModelContext<T>),
2218    {
2219        let observer = self.weak_handle();
2220        self.app.observe_internal(handle, move |observed, cx| {
2221            if let Some(observer) = observer.upgrade(cx) {
2222                observer.update(cx, |observer, cx| {
2223                    callback(observer, observed, cx);
2224                });
2225                true
2226            } else {
2227                false
2228            }
2229        })
2230    }
2231
2232    pub fn observe_release<S, F>(
2233        &mut self,
2234        handle: &ModelHandle<S>,
2235        mut callback: F,
2236    ) -> Subscription
2237    where
2238        S: Entity,
2239        F: 'static + FnMut(&mut T, &mut ModelContext<T>),
2240    {
2241        let observer = self.weak_handle();
2242        self.app.observe_release(handle, move |cx| {
2243            if let Some(observer) = observer.upgrade(cx) {
2244                observer.update(cx, |observer, cx| {
2245                    callback(observer, cx);
2246                });
2247            }
2248        })
2249    }
2250
2251    pub fn handle(&self) -> ModelHandle<T> {
2252        ModelHandle::new(self.model_id, &self.app.cx.ref_counts)
2253    }
2254
2255    pub fn weak_handle(&self) -> WeakModelHandle<T> {
2256        WeakModelHandle::new(self.model_id)
2257    }
2258
2259    pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
2260    where
2261        F: FnOnce(ModelHandle<T>, AsyncAppContext) -> Fut,
2262        Fut: 'static + Future<Output = S>,
2263        S: 'static,
2264    {
2265        let handle = self.handle();
2266        self.app.spawn(|cx| f(handle, cx))
2267    }
2268
2269    pub fn spawn_weak<F, Fut, S>(&self, f: F) -> Task<S>
2270    where
2271        F: FnOnce(WeakModelHandle<T>, AsyncAppContext) -> Fut,
2272        Fut: 'static + Future<Output = S>,
2273        S: 'static,
2274    {
2275        let handle = self.weak_handle();
2276        self.app.spawn(|cx| f(handle, cx))
2277    }
2278}
2279
2280impl<M> AsRef<AppContext> for ModelContext<'_, M> {
2281    fn as_ref(&self) -> &AppContext {
2282        &self.app.cx
2283    }
2284}
2285
2286impl<M> AsMut<MutableAppContext> for ModelContext<'_, M> {
2287    fn as_mut(&mut self) -> &mut MutableAppContext {
2288        self.app
2289    }
2290}
2291
2292impl<M> ReadModel for ModelContext<'_, M> {
2293    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2294        self.app.read_model(handle)
2295    }
2296}
2297
2298impl<M> UpdateModel for ModelContext<'_, M> {
2299    fn update_model<T: Entity, V>(
2300        &mut self,
2301        handle: &ModelHandle<T>,
2302        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
2303    ) -> V {
2304        self.app.update_model(handle, update)
2305    }
2306}
2307
2308impl<M> UpgradeModelHandle for ModelContext<'_, M> {
2309    fn upgrade_model_handle<T: Entity>(
2310        &self,
2311        handle: &WeakModelHandle<T>,
2312    ) -> Option<ModelHandle<T>> {
2313        self.cx.upgrade_model_handle(handle)
2314    }
2315
2316    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
2317        self.cx.upgrade_any_model_handle(handle)
2318    }
2319}
2320
2321impl<M> Deref for ModelContext<'_, M> {
2322    type Target = MutableAppContext;
2323
2324    fn deref(&self) -> &Self::Target {
2325        &self.app
2326    }
2327}
2328
2329impl<M> DerefMut for ModelContext<'_, M> {
2330    fn deref_mut(&mut self) -> &mut Self::Target {
2331        &mut self.app
2332    }
2333}
2334
2335pub struct ViewContext<'a, T: ?Sized> {
2336    app: &'a mut MutableAppContext,
2337    window_id: usize,
2338    view_id: usize,
2339    view_type: PhantomData<T>,
2340    halt_action_dispatch: bool,
2341}
2342
2343impl<'a, T: View> ViewContext<'a, T> {
2344    fn new(app: &'a mut MutableAppContext, window_id: usize, view_id: usize) -> Self {
2345        Self {
2346            app,
2347            window_id,
2348            view_id,
2349            view_type: PhantomData,
2350            halt_action_dispatch: true,
2351        }
2352    }
2353
2354    pub fn handle(&self) -> ViewHandle<T> {
2355        ViewHandle::new(self.window_id, self.view_id, &self.app.cx.ref_counts)
2356    }
2357
2358    pub fn weak_handle(&self) -> WeakViewHandle<T> {
2359        WeakViewHandle::new(self.window_id, self.view_id)
2360    }
2361
2362    pub fn window_id(&self) -> usize {
2363        self.window_id
2364    }
2365
2366    pub fn view_id(&self) -> usize {
2367        self.view_id
2368    }
2369
2370    pub fn foreground(&self) -> &Rc<executor::Foreground> {
2371        self.app.foreground()
2372    }
2373
2374    pub fn background_executor(&self) -> &Arc<executor::Background> {
2375        &self.app.cx.background
2376    }
2377
2378    pub fn platform(&self) -> Arc<dyn Platform> {
2379        self.app.platform()
2380    }
2381
2382    pub fn prompt(
2383        &self,
2384        level: PromptLevel,
2385        msg: &str,
2386        answers: &[&str],
2387    ) -> oneshot::Receiver<usize> {
2388        self.app.prompt(self.window_id, level, msg, answers)
2389    }
2390
2391    pub fn prompt_for_paths(
2392        &self,
2393        options: PathPromptOptions,
2394    ) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
2395        self.app.prompt_for_paths(options)
2396    }
2397
2398    pub fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
2399        self.app.prompt_for_new_path(directory)
2400    }
2401
2402    pub fn debug_elements(&self) -> crate::json::Value {
2403        self.app.debug_elements(self.window_id).unwrap()
2404    }
2405
2406    pub fn focus<S>(&mut self, handle: S)
2407    where
2408        S: Into<AnyViewHandle>,
2409    {
2410        let handle = handle.into();
2411        self.app.pending_effects.push_back(Effect::Focus {
2412            window_id: handle.window_id,
2413            view_id: handle.view_id,
2414        });
2415    }
2416
2417    pub fn focus_self(&mut self) {
2418        self.app.pending_effects.push_back(Effect::Focus {
2419            window_id: self.window_id,
2420            view_id: self.view_id,
2421        });
2422    }
2423
2424    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
2425    where
2426        S: Entity,
2427        F: FnOnce(&mut ModelContext<S>) -> S,
2428    {
2429        self.app.add_model(build_model)
2430    }
2431
2432    pub fn add_view<S, F>(&mut self, build_view: F) -> ViewHandle<S>
2433    where
2434        S: View,
2435        F: FnOnce(&mut ViewContext<S>) -> S,
2436    {
2437        self.app.add_view(self.window_id, build_view)
2438    }
2439
2440    pub fn add_option_view<S, F>(&mut self, build_view: F) -> Option<ViewHandle<S>>
2441    where
2442        S: View,
2443        F: FnOnce(&mut ViewContext<S>) -> Option<S>,
2444    {
2445        self.app.add_option_view(self.window_id, build_view)
2446    }
2447
2448    pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
2449    where
2450        E: Entity,
2451        E::Event: 'static,
2452        H: Handle<E>,
2453        F: 'static + FnMut(&mut T, H, &E::Event, &mut ViewContext<T>),
2454    {
2455        let subscriber = self.weak_handle();
2456        self.app
2457            .subscribe_internal(handle, move |emitter, event, cx| {
2458                if let Some(subscriber) = subscriber.upgrade(cx) {
2459                    subscriber.update(cx, |subscriber, cx| {
2460                        callback(subscriber, emitter, event, cx);
2461                    });
2462                    true
2463                } else {
2464                    false
2465                }
2466            })
2467    }
2468
2469    pub fn observe<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
2470    where
2471        E: Entity,
2472        H: Handle<E>,
2473        F: 'static + FnMut(&mut T, H, &mut ViewContext<T>),
2474    {
2475        let observer = self.weak_handle();
2476        self.app.observe_internal(handle, move |observed, cx| {
2477            if let Some(observer) = observer.upgrade(cx) {
2478                observer.update(cx, |observer, cx| {
2479                    callback(observer, observed, cx);
2480                });
2481                true
2482            } else {
2483                false
2484            }
2485        })
2486    }
2487
2488    pub fn observe_release<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
2489    where
2490        E: Entity,
2491        H: Handle<E>,
2492        F: 'static + FnMut(&mut T, &mut ViewContext<T>),
2493    {
2494        let observer = self.weak_handle();
2495        self.app.observe_release(handle, move |cx| {
2496            if let Some(observer) = observer.upgrade(cx) {
2497                observer.update(cx, |observer, cx| {
2498                    callback(observer, cx);
2499                });
2500            }
2501        })
2502    }
2503
2504    pub fn emit(&mut self, payload: T::Event) {
2505        self.app.pending_effects.push_back(Effect::Event {
2506            entity_id: self.view_id,
2507            payload: Box::new(payload),
2508        });
2509    }
2510
2511    pub fn notify(&mut self) {
2512        self.app.notify_view(self.window_id, self.view_id);
2513    }
2514
2515    pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut T, &mut ViewContext<T>)) {
2516        let handle = self.handle();
2517        self.app.defer(Box::new(move |cx| {
2518            handle.update(cx, |view, cx| {
2519                callback(view, cx);
2520            })
2521        }))
2522    }
2523
2524    pub fn propagate_action(&mut self) {
2525        self.halt_action_dispatch = false;
2526    }
2527
2528    pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
2529    where
2530        F: FnOnce(ViewHandle<T>, AsyncAppContext) -> Fut,
2531        Fut: 'static + Future<Output = S>,
2532        S: 'static,
2533    {
2534        let handle = self.handle();
2535        self.app.spawn(|cx| f(handle, cx))
2536    }
2537
2538    pub fn spawn_weak<F, Fut, S>(&self, f: F) -> Task<S>
2539    where
2540        F: FnOnce(WeakViewHandle<T>, AsyncAppContext) -> Fut,
2541        Fut: 'static + Future<Output = S>,
2542        S: 'static,
2543    {
2544        let handle = self.weak_handle();
2545        self.app.spawn(|cx| f(handle, cx))
2546    }
2547}
2548
2549pub struct RenderContext<'a, T: View> {
2550    pub app: &'a mut MutableAppContext,
2551    pub titlebar_height: f32,
2552    pub refreshing: bool,
2553    window_id: usize,
2554    view_id: usize,
2555    view_type: PhantomData<T>,
2556}
2557
2558impl<'a, T: View> RenderContext<'a, T> {
2559    pub fn handle(&self) -> WeakViewHandle<T> {
2560        WeakViewHandle::new(self.window_id, self.view_id)
2561    }
2562
2563    pub fn view_id(&self) -> usize {
2564        self.view_id
2565    }
2566}
2567
2568impl AsRef<AppContext> for &AppContext {
2569    fn as_ref(&self) -> &AppContext {
2570        self
2571    }
2572}
2573
2574impl<V: View> Deref for RenderContext<'_, V> {
2575    type Target = MutableAppContext;
2576
2577    fn deref(&self) -> &Self::Target {
2578        self.app
2579    }
2580}
2581
2582impl<V: View> DerefMut for RenderContext<'_, V> {
2583    fn deref_mut(&mut self) -> &mut Self::Target {
2584        self.app
2585    }
2586}
2587
2588impl<V: View> ReadModel for RenderContext<'_, V> {
2589    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2590        self.app.read_model(handle)
2591    }
2592}
2593
2594impl<V: View> UpdateModel for RenderContext<'_, V> {
2595    fn update_model<T: Entity, O>(
2596        &mut self,
2597        handle: &ModelHandle<T>,
2598        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
2599    ) -> O {
2600        self.app.update_model(handle, update)
2601    }
2602}
2603
2604impl<V: View> ReadView for RenderContext<'_, V> {
2605    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
2606        self.app.read_view(handle)
2607    }
2608}
2609
2610impl<M> AsRef<AppContext> for ViewContext<'_, M> {
2611    fn as_ref(&self) -> &AppContext {
2612        &self.app.cx
2613    }
2614}
2615
2616impl<M> Deref for ViewContext<'_, M> {
2617    type Target = MutableAppContext;
2618
2619    fn deref(&self) -> &Self::Target {
2620        &self.app
2621    }
2622}
2623
2624impl<M> DerefMut for ViewContext<'_, M> {
2625    fn deref_mut(&mut self) -> &mut Self::Target {
2626        &mut self.app
2627    }
2628}
2629
2630impl<M> AsMut<MutableAppContext> for ViewContext<'_, M> {
2631    fn as_mut(&mut self) -> &mut MutableAppContext {
2632        self.app
2633    }
2634}
2635
2636impl<V> ReadModel for ViewContext<'_, V> {
2637    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2638        self.app.read_model(handle)
2639    }
2640}
2641
2642impl<V> UpgradeModelHandle for ViewContext<'_, V> {
2643    fn upgrade_model_handle<T: Entity>(
2644        &self,
2645        handle: &WeakModelHandle<T>,
2646    ) -> Option<ModelHandle<T>> {
2647        self.cx.upgrade_model_handle(handle)
2648    }
2649
2650    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
2651        self.cx.upgrade_any_model_handle(handle)
2652    }
2653}
2654
2655impl<V> UpgradeViewHandle for ViewContext<'_, V> {
2656    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
2657        self.cx.upgrade_view_handle(handle)
2658    }
2659}
2660
2661impl<V: View> UpdateModel for ViewContext<'_, V> {
2662    fn update_model<T: Entity, O>(
2663        &mut self,
2664        handle: &ModelHandle<T>,
2665        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
2666    ) -> O {
2667        self.app.update_model(handle, update)
2668    }
2669}
2670
2671impl<V: View> ReadView for ViewContext<'_, V> {
2672    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
2673        self.app.read_view(handle)
2674    }
2675}
2676
2677impl<V: View> UpdateView for ViewContext<'_, V> {
2678    fn update_view<T, S>(
2679        &mut self,
2680        handle: &ViewHandle<T>,
2681        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
2682    ) -> S
2683    where
2684        T: View,
2685    {
2686        self.app.update_view(handle, update)
2687    }
2688}
2689
2690pub trait Handle<T> {
2691    type Weak: 'static;
2692    fn id(&self) -> usize;
2693    fn location(&self) -> EntityLocation;
2694    fn downgrade(&self) -> Self::Weak;
2695    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
2696    where
2697        Self: Sized;
2698}
2699
2700#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
2701pub enum EntityLocation {
2702    Model(usize),
2703    View(usize, usize),
2704}
2705
2706pub struct ModelHandle<T> {
2707    model_id: usize,
2708    model_type: PhantomData<T>,
2709    ref_counts: Arc<Mutex<RefCounts>>,
2710}
2711
2712impl<T: Entity> ModelHandle<T> {
2713    fn new(model_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
2714        ref_counts.lock().inc_model(model_id);
2715        Self {
2716            model_id,
2717            model_type: PhantomData,
2718            ref_counts: ref_counts.clone(),
2719        }
2720    }
2721
2722    pub fn downgrade(&self) -> WeakModelHandle<T> {
2723        WeakModelHandle::new(self.model_id)
2724    }
2725
2726    pub fn id(&self) -> usize {
2727        self.model_id
2728    }
2729
2730    pub fn read<'a, C: ReadModel>(&self, cx: &'a C) -> &'a T {
2731        cx.read_model(self)
2732    }
2733
2734    pub fn read_with<'a, C, F, S>(&self, cx: &C, read: F) -> S
2735    where
2736        C: ReadModelWith,
2737        F: FnOnce(&T, &AppContext) -> S,
2738    {
2739        let mut read = Some(read);
2740        cx.read_model_with(self, &mut |model, cx| {
2741            let read = read.take().unwrap();
2742            read(model, cx)
2743        })
2744    }
2745
2746    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
2747    where
2748        C: UpdateModel,
2749        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
2750    {
2751        let mut update = Some(update);
2752        cx.update_model(self, &mut |model, cx| {
2753            let update = update.take().unwrap();
2754            update(model, cx)
2755        })
2756    }
2757
2758    pub fn next_notification(&self, cx: &TestAppContext) -> impl Future<Output = ()> {
2759        let (mut tx, mut rx) = mpsc::channel(1);
2760        let mut cx = cx.cx.borrow_mut();
2761        let subscription = cx.observe(self, move |_, _| {
2762            tx.try_send(()).ok();
2763        });
2764
2765        let duration = if std::env::var("CI").is_ok() {
2766            Duration::from_secs(5)
2767        } else {
2768            Duration::from_secs(1)
2769        };
2770
2771        async move {
2772            let notification = timeout(duration, rx.recv())
2773                .await
2774                .expect("next notification timed out");
2775            drop(subscription);
2776            notification.expect("model dropped while test was waiting for its next notification")
2777        }
2778    }
2779
2780    pub fn next_event(&self, cx: &TestAppContext) -> impl Future<Output = T::Event>
2781    where
2782        T::Event: Clone,
2783    {
2784        let (mut tx, mut rx) = mpsc::channel(1);
2785        let mut cx = cx.cx.borrow_mut();
2786        let subscription = cx.subscribe(self, move |_, event, _| {
2787            tx.blocking_send(event.clone()).ok();
2788        });
2789
2790        let duration = if std::env::var("CI").is_ok() {
2791            Duration::from_secs(5)
2792        } else {
2793            Duration::from_secs(1)
2794        };
2795
2796        async move {
2797            let event = timeout(duration, rx.recv())
2798                .await
2799                .expect("next event timed out");
2800            drop(subscription);
2801            event.expect("model dropped while test was waiting for its next event")
2802        }
2803    }
2804
2805    pub fn condition(
2806        &self,
2807        cx: &TestAppContext,
2808        mut predicate: impl FnMut(&T, &AppContext) -> bool,
2809    ) -> impl Future<Output = ()> {
2810        let (tx, mut rx) = mpsc::channel(1024);
2811
2812        let mut cx = cx.cx.borrow_mut();
2813        let subscriptions = (
2814            cx.observe(self, {
2815                let mut tx = tx.clone();
2816                move |_, _| {
2817                    tx.blocking_send(()).ok();
2818                }
2819            }),
2820            cx.subscribe(self, {
2821                let mut tx = tx.clone();
2822                move |_, _, _| {
2823                    tx.blocking_send(()).ok();
2824                }
2825            }),
2826        );
2827
2828        let cx = cx.weak_self.as_ref().unwrap().upgrade().unwrap();
2829        let handle = self.downgrade();
2830        let duration = if std::env::var("CI").is_ok() {
2831            Duration::from_secs(5)
2832        } else {
2833            Duration::from_secs(1)
2834        };
2835
2836        async move {
2837            timeout(duration, async move {
2838                loop {
2839                    {
2840                        let cx = cx.borrow();
2841                        let cx = cx.as_ref();
2842                        if predicate(
2843                            handle
2844                                .upgrade(cx)
2845                                .expect("model dropped with pending condition")
2846                                .read(cx),
2847                            cx,
2848                        ) {
2849                            break;
2850                        }
2851                    }
2852
2853                    cx.borrow().foreground().start_waiting();
2854                    rx.recv()
2855                        .await
2856                        .expect("model dropped with pending condition");
2857                    cx.borrow().foreground().finish_waiting();
2858                }
2859            })
2860            .await
2861            .expect("condition timed out");
2862            drop(subscriptions);
2863        }
2864    }
2865}
2866
2867impl<T> Clone for ModelHandle<T> {
2868    fn clone(&self) -> Self {
2869        self.ref_counts.lock().inc_model(self.model_id);
2870        Self {
2871            model_id: self.model_id,
2872            model_type: PhantomData,
2873            ref_counts: self.ref_counts.clone(),
2874        }
2875    }
2876}
2877
2878impl<T> PartialEq for ModelHandle<T> {
2879    fn eq(&self, other: &Self) -> bool {
2880        self.model_id == other.model_id
2881    }
2882}
2883
2884impl<T> Eq for ModelHandle<T> {}
2885
2886impl<T> Hash for ModelHandle<T> {
2887    fn hash<H: Hasher>(&self, state: &mut H) {
2888        self.model_id.hash(state);
2889    }
2890}
2891
2892impl<T> std::borrow::Borrow<usize> for ModelHandle<T> {
2893    fn borrow(&self) -> &usize {
2894        &self.model_id
2895    }
2896}
2897
2898impl<T> Debug for ModelHandle<T> {
2899    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2900        f.debug_tuple(&format!("ModelHandle<{}>", type_name::<T>()))
2901            .field(&self.model_id)
2902            .finish()
2903    }
2904}
2905
2906unsafe impl<T> Send for ModelHandle<T> {}
2907unsafe impl<T> Sync for ModelHandle<T> {}
2908
2909impl<T> Drop for ModelHandle<T> {
2910    fn drop(&mut self) {
2911        self.ref_counts.lock().dec_model(self.model_id);
2912    }
2913}
2914
2915impl<T: Entity> Handle<T> for ModelHandle<T> {
2916    type Weak = WeakModelHandle<T>;
2917
2918    fn id(&self) -> usize {
2919        self.model_id
2920    }
2921
2922    fn location(&self) -> EntityLocation {
2923        EntityLocation::Model(self.model_id)
2924    }
2925
2926    fn downgrade(&self) -> Self::Weak {
2927        self.downgrade()
2928    }
2929
2930    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
2931    where
2932        Self: Sized,
2933    {
2934        weak.upgrade(cx)
2935    }
2936}
2937
2938pub struct WeakModelHandle<T> {
2939    model_id: usize,
2940    model_type: PhantomData<T>,
2941}
2942
2943unsafe impl<T> Send for WeakModelHandle<T> {}
2944unsafe impl<T> Sync for WeakModelHandle<T> {}
2945
2946impl<T: Entity> WeakModelHandle<T> {
2947    fn new(model_id: usize) -> Self {
2948        Self {
2949            model_id,
2950            model_type: PhantomData,
2951        }
2952    }
2953
2954    pub fn id(&self) -> usize {
2955        self.model_id
2956    }
2957
2958    pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<ModelHandle<T>> {
2959        cx.upgrade_model_handle(self)
2960    }
2961}
2962
2963impl<T> Hash for WeakModelHandle<T> {
2964    fn hash<H: Hasher>(&self, state: &mut H) {
2965        self.model_id.hash(state)
2966    }
2967}
2968
2969impl<T> PartialEq for WeakModelHandle<T> {
2970    fn eq(&self, other: &Self) -> bool {
2971        self.model_id == other.model_id
2972    }
2973}
2974
2975impl<T> Eq for WeakModelHandle<T> {}
2976
2977impl<T> Clone for WeakModelHandle<T> {
2978    fn clone(&self) -> Self {
2979        Self {
2980            model_id: self.model_id,
2981            model_type: PhantomData,
2982        }
2983    }
2984}
2985
2986impl<T> Copy for WeakModelHandle<T> {}
2987
2988pub struct ViewHandle<T> {
2989    window_id: usize,
2990    view_id: usize,
2991    view_type: PhantomData<T>,
2992    ref_counts: Arc<Mutex<RefCounts>>,
2993}
2994
2995impl<T: View> ViewHandle<T> {
2996    fn new(window_id: usize, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
2997        ref_counts.lock().inc_view(window_id, view_id);
2998        Self {
2999            window_id,
3000            view_id,
3001            view_type: PhantomData,
3002            ref_counts: ref_counts.clone(),
3003        }
3004    }
3005
3006    pub fn downgrade(&self) -> WeakViewHandle<T> {
3007        WeakViewHandle::new(self.window_id, self.view_id)
3008    }
3009
3010    pub fn window_id(&self) -> usize {
3011        self.window_id
3012    }
3013
3014    pub fn id(&self) -> usize {
3015        self.view_id
3016    }
3017
3018    pub fn read<'a, C: ReadView>(&self, cx: &'a C) -> &'a T {
3019        cx.read_view(self)
3020    }
3021
3022    pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> S
3023    where
3024        C: ReadViewWith,
3025        F: FnOnce(&T, &AppContext) -> S,
3026    {
3027        let mut read = Some(read);
3028        cx.read_view_with(self, &mut |view, cx| {
3029            let read = read.take().unwrap();
3030            read(view, cx)
3031        })
3032    }
3033
3034    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
3035    where
3036        C: UpdateView,
3037        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
3038    {
3039        let mut update = Some(update);
3040        cx.update_view(self, &mut |view, cx| {
3041            let update = update.take().unwrap();
3042            update(view, cx)
3043        })
3044    }
3045
3046    pub fn defer<C, F>(&self, cx: &mut C, update: F)
3047    where
3048        C: AsMut<MutableAppContext>,
3049        F: 'static + FnOnce(&mut T, &mut ViewContext<T>),
3050    {
3051        let this = self.clone();
3052        cx.as_mut().defer(Box::new(move |cx| {
3053            this.update(cx, |view, cx| update(view, cx));
3054        }));
3055    }
3056
3057    pub fn is_focused(&self, cx: &AppContext) -> bool {
3058        cx.focused_view_id(self.window_id)
3059            .map_or(false, |focused_id| focused_id == self.view_id)
3060    }
3061
3062    pub fn next_notification(&self, cx: &TestAppContext) -> impl Future<Output = ()> {
3063        let (mut tx, mut rx) = mpsc::channel(1);
3064        let mut cx = cx.cx.borrow_mut();
3065        let subscription = cx.observe(self, move |_, _| {
3066            tx.try_send(()).ok();
3067        });
3068
3069        let duration = if std::env::var("CI").is_ok() {
3070            Duration::from_secs(5)
3071        } else {
3072            Duration::from_secs(1)
3073        };
3074
3075        async move {
3076            let notification = timeout(duration, rx.recv())
3077                .await
3078                .expect("next notification timed out");
3079            drop(subscription);
3080            notification.expect("model dropped while test was waiting for its next notification")
3081        }
3082    }
3083
3084    pub fn condition(
3085        &self,
3086        cx: &TestAppContext,
3087        mut predicate: impl FnMut(&T, &AppContext) -> bool,
3088    ) -> impl Future<Output = ()> {
3089        let (tx, mut rx) = mpsc::channel(1024);
3090
3091        let mut cx = cx.cx.borrow_mut();
3092        let subscriptions = self.update(&mut *cx, |_, cx| {
3093            (
3094                cx.observe(self, {
3095                    let mut tx = tx.clone();
3096                    move |_, _, _| {
3097                        tx.blocking_send(()).ok();
3098                    }
3099                }),
3100                cx.subscribe(self, {
3101                    let mut tx = tx.clone();
3102                    move |_, _, _, _| {
3103                        tx.blocking_send(()).ok();
3104                    }
3105                }),
3106            )
3107        });
3108
3109        let cx = cx.weak_self.as_ref().unwrap().upgrade().unwrap();
3110        let handle = self.downgrade();
3111        let duration = if std::env::var("CI").is_ok() {
3112            Duration::from_secs(2)
3113        } else {
3114            Duration::from_millis(500)
3115        };
3116
3117        async move {
3118            timeout(duration, async move {
3119                loop {
3120                    {
3121                        let cx = cx.borrow();
3122                        let cx = cx.as_ref();
3123                        if predicate(
3124                            handle
3125                                .upgrade(cx)
3126                                .expect("view dropped with pending condition")
3127                                .read(cx),
3128                            cx,
3129                        ) {
3130                            break;
3131                        }
3132                    }
3133
3134                    cx.borrow().foreground().start_waiting();
3135                    rx.recv()
3136                        .await
3137                        .expect("view dropped with pending condition");
3138                    cx.borrow().foreground().finish_waiting();
3139                }
3140            })
3141            .await
3142            .expect("condition timed out");
3143            drop(subscriptions);
3144        }
3145    }
3146}
3147
3148impl<T> Clone for ViewHandle<T> {
3149    fn clone(&self) -> Self {
3150        self.ref_counts
3151            .lock()
3152            .inc_view(self.window_id, self.view_id);
3153        Self {
3154            window_id: self.window_id,
3155            view_id: self.view_id,
3156            view_type: PhantomData,
3157            ref_counts: self.ref_counts.clone(),
3158        }
3159    }
3160}
3161
3162impl<T> PartialEq for ViewHandle<T> {
3163    fn eq(&self, other: &Self) -> bool {
3164        self.window_id == other.window_id && self.view_id == other.view_id
3165    }
3166}
3167
3168impl<T> Eq for ViewHandle<T> {}
3169
3170impl<T> Debug for ViewHandle<T> {
3171    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3172        f.debug_struct(&format!("ViewHandle<{}>", type_name::<T>()))
3173            .field("window_id", &self.window_id)
3174            .field("view_id", &self.view_id)
3175            .finish()
3176    }
3177}
3178
3179impl<T> Drop for ViewHandle<T> {
3180    fn drop(&mut self) {
3181        self.ref_counts
3182            .lock()
3183            .dec_view(self.window_id, self.view_id);
3184    }
3185}
3186
3187impl<T: View> Handle<T> for ViewHandle<T> {
3188    type Weak = WeakViewHandle<T>;
3189
3190    fn id(&self) -> usize {
3191        self.view_id
3192    }
3193
3194    fn location(&self) -> EntityLocation {
3195        EntityLocation::View(self.window_id, self.view_id)
3196    }
3197
3198    fn downgrade(&self) -> Self::Weak {
3199        self.downgrade()
3200    }
3201
3202    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
3203    where
3204        Self: Sized,
3205    {
3206        weak.upgrade(cx)
3207    }
3208}
3209
3210pub struct AnyViewHandle {
3211    window_id: usize,
3212    view_id: usize,
3213    view_type: TypeId,
3214    ref_counts: Arc<Mutex<RefCounts>>,
3215}
3216
3217impl AnyViewHandle {
3218    pub fn id(&self) -> usize {
3219        self.view_id
3220    }
3221
3222    pub fn is<T: 'static>(&self) -> bool {
3223        TypeId::of::<T>() == self.view_type
3224    }
3225
3226    pub fn is_focused(&self, cx: &AppContext) -> bool {
3227        cx.focused_view_id(self.window_id)
3228            .map_or(false, |focused_id| focused_id == self.view_id)
3229    }
3230
3231    pub fn downcast<T: View>(self) -> Option<ViewHandle<T>> {
3232        if self.is::<T>() {
3233            let result = Some(ViewHandle {
3234                window_id: self.window_id,
3235                view_id: self.view_id,
3236                ref_counts: self.ref_counts.clone(),
3237                view_type: PhantomData,
3238            });
3239            unsafe {
3240                Arc::decrement_strong_count(&self.ref_counts);
3241            }
3242            std::mem::forget(self);
3243            result
3244        } else {
3245            None
3246        }
3247    }
3248}
3249
3250impl Clone for AnyViewHandle {
3251    fn clone(&self) -> Self {
3252        self.ref_counts
3253            .lock()
3254            .inc_view(self.window_id, self.view_id);
3255        Self {
3256            window_id: self.window_id,
3257            view_id: self.view_id,
3258            view_type: self.view_type,
3259            ref_counts: self.ref_counts.clone(),
3260        }
3261    }
3262}
3263
3264impl From<&AnyViewHandle> for AnyViewHandle {
3265    fn from(handle: &AnyViewHandle) -> Self {
3266        handle.clone()
3267    }
3268}
3269
3270impl<T: View> From<&ViewHandle<T>> for AnyViewHandle {
3271    fn from(handle: &ViewHandle<T>) -> Self {
3272        handle
3273            .ref_counts
3274            .lock()
3275            .inc_view(handle.window_id, handle.view_id);
3276        AnyViewHandle {
3277            window_id: handle.window_id,
3278            view_id: handle.view_id,
3279            view_type: TypeId::of::<T>(),
3280            ref_counts: handle.ref_counts.clone(),
3281        }
3282    }
3283}
3284
3285impl<T: View> From<ViewHandle<T>> for AnyViewHandle {
3286    fn from(handle: ViewHandle<T>) -> Self {
3287        let any_handle = AnyViewHandle {
3288            window_id: handle.window_id,
3289            view_id: handle.view_id,
3290            view_type: TypeId::of::<T>(),
3291            ref_counts: handle.ref_counts.clone(),
3292        };
3293        unsafe {
3294            Arc::decrement_strong_count(&handle.ref_counts);
3295        }
3296        std::mem::forget(handle);
3297        any_handle
3298    }
3299}
3300
3301impl Drop for AnyViewHandle {
3302    fn drop(&mut self) {
3303        self.ref_counts
3304            .lock()
3305            .dec_view(self.window_id, self.view_id);
3306    }
3307}
3308
3309pub struct AnyModelHandle {
3310    model_id: usize,
3311    model_type: TypeId,
3312    ref_counts: Arc<Mutex<RefCounts>>,
3313}
3314
3315impl AnyModelHandle {
3316    pub fn downcast<T: Entity>(self) -> Option<ModelHandle<T>> {
3317        if self.is::<T>() {
3318            let result = Some(ModelHandle {
3319                model_id: self.model_id,
3320                model_type: PhantomData,
3321                ref_counts: self.ref_counts.clone(),
3322            });
3323            unsafe {
3324                Arc::decrement_strong_count(&self.ref_counts);
3325            }
3326            std::mem::forget(self);
3327            result
3328        } else {
3329            None
3330        }
3331    }
3332
3333    pub fn downgrade(&self) -> AnyWeakModelHandle {
3334        AnyWeakModelHandle {
3335            model_id: self.model_id,
3336            model_type: self.model_type,
3337        }
3338    }
3339
3340    pub fn is<T: Entity>(&self) -> bool {
3341        self.model_type == TypeId::of::<T>()
3342    }
3343}
3344
3345impl<T: Entity> From<ModelHandle<T>> for AnyModelHandle {
3346    fn from(handle: ModelHandle<T>) -> Self {
3347        handle.ref_counts.lock().inc_model(handle.model_id);
3348        Self {
3349            model_id: handle.model_id,
3350            model_type: TypeId::of::<T>(),
3351            ref_counts: handle.ref_counts.clone(),
3352        }
3353    }
3354}
3355
3356impl Clone for AnyModelHandle {
3357    fn clone(&self) -> Self {
3358        self.ref_counts.lock().inc_model(self.model_id);
3359        Self {
3360            model_id: self.model_id,
3361            model_type: self.model_type,
3362            ref_counts: self.ref_counts.clone(),
3363        }
3364    }
3365}
3366
3367impl Drop for AnyModelHandle {
3368    fn drop(&mut self) {
3369        self.ref_counts.lock().dec_model(self.model_id);
3370    }
3371}
3372
3373pub struct AnyWeakModelHandle {
3374    model_id: usize,
3375    model_type: TypeId,
3376}
3377
3378impl AnyWeakModelHandle {
3379    pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<AnyModelHandle> {
3380        cx.upgrade_any_model_handle(self)
3381    }
3382}
3383
3384pub struct WeakViewHandle<T> {
3385    window_id: usize,
3386    view_id: usize,
3387    view_type: PhantomData<T>,
3388}
3389
3390impl<T: View> WeakViewHandle<T> {
3391    fn new(window_id: usize, view_id: usize) -> Self {
3392        Self {
3393            window_id,
3394            view_id,
3395            view_type: PhantomData,
3396        }
3397    }
3398
3399    pub fn id(&self) -> usize {
3400        self.view_id
3401    }
3402
3403    pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<ViewHandle<T>> {
3404        cx.upgrade_view_handle(self)
3405    }
3406}
3407
3408impl<T> Clone for WeakViewHandle<T> {
3409    fn clone(&self) -> Self {
3410        Self {
3411            window_id: self.window_id,
3412            view_id: self.view_id,
3413            view_type: PhantomData,
3414        }
3415    }
3416}
3417
3418impl<T> PartialEq for WeakViewHandle<T> {
3419    fn eq(&self, other: &Self) -> bool {
3420        self.window_id == other.window_id && self.view_id == other.view_id
3421    }
3422}
3423
3424impl<T> Eq for WeakViewHandle<T> {}
3425
3426impl<T> Hash for WeakViewHandle<T> {
3427    fn hash<H: Hasher>(&self, state: &mut H) {
3428        self.window_id.hash(state);
3429        self.view_id.hash(state);
3430    }
3431}
3432
3433#[derive(Clone, Copy, PartialEq, Eq, Hash)]
3434pub struct ElementStateId(usize, usize);
3435
3436impl From<usize> for ElementStateId {
3437    fn from(id: usize) -> Self {
3438        Self(id, 0)
3439    }
3440}
3441
3442impl From<(usize, usize)> for ElementStateId {
3443    fn from(id: (usize, usize)) -> Self {
3444        Self(id.0, id.1)
3445    }
3446}
3447
3448pub struct ElementStateHandle<T> {
3449    value_type: PhantomData<T>,
3450    tag_type_id: TypeId,
3451    id: ElementStateId,
3452    ref_counts: Weak<Mutex<RefCounts>>,
3453}
3454
3455impl<T: 'static> ElementStateHandle<T> {
3456    fn new(
3457        tag_type_id: TypeId,
3458        id: ElementStateId,
3459        frame_id: usize,
3460        ref_counts: &Arc<Mutex<RefCounts>>,
3461    ) -> Self {
3462        ref_counts
3463            .lock()
3464            .inc_element_state(tag_type_id, id, frame_id);
3465        Self {
3466            value_type: PhantomData,
3467            tag_type_id,
3468            id,
3469            ref_counts: Arc::downgrade(ref_counts),
3470        }
3471    }
3472
3473    pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
3474        cx.element_states
3475            .get(&(self.tag_type_id, self.id))
3476            .unwrap()
3477            .downcast_ref()
3478            .unwrap()
3479    }
3480
3481    pub fn update<C, R>(&self, cx: &mut C, f: impl FnOnce(&mut T, &mut C) -> R) -> R
3482    where
3483        C: DerefMut<Target = MutableAppContext>,
3484    {
3485        let mut element_state = cx
3486            .deref_mut()
3487            .cx
3488            .element_states
3489            .remove(&(self.tag_type_id, self.id))
3490            .unwrap();
3491        let result = f(element_state.downcast_mut().unwrap(), cx);
3492        cx.deref_mut()
3493            .cx
3494            .element_states
3495            .insert((self.tag_type_id, self.id), element_state);
3496        result
3497    }
3498}
3499
3500impl<T> Drop for ElementStateHandle<T> {
3501    fn drop(&mut self) {
3502        if let Some(ref_counts) = self.ref_counts.upgrade() {
3503            ref_counts
3504                .lock()
3505                .dec_element_state(self.tag_type_id, self.id);
3506        }
3507    }
3508}
3509
3510pub struct CursorStyleHandle {
3511    id: usize,
3512    next_cursor_style_handle_id: Arc<AtomicUsize>,
3513    platform: Arc<dyn Platform>,
3514}
3515
3516impl Drop for CursorStyleHandle {
3517    fn drop(&mut self) {
3518        if self.id + 1 == self.next_cursor_style_handle_id.load(SeqCst) {
3519            self.platform.set_cursor_style(CursorStyle::Arrow);
3520        }
3521    }
3522}
3523
3524#[must_use]
3525pub enum Subscription {
3526    Subscription {
3527        id: usize,
3528        entity_id: usize,
3529        subscriptions: Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, SubscriptionCallback>>>>>,
3530    },
3531    Observation {
3532        id: usize,
3533        entity_id: usize,
3534        observations: Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, ObservationCallback>>>>>,
3535    },
3536    ReleaseObservation {
3537        id: usize,
3538        entity_id: usize,
3539        observations:
3540            Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, ReleaseObservationCallback>>>>>,
3541    },
3542}
3543
3544impl Subscription {
3545    pub fn detach(&mut self) {
3546        match self {
3547            Subscription::Subscription { subscriptions, .. } => {
3548                subscriptions.take();
3549            }
3550            Subscription::Observation { observations, .. } => {
3551                observations.take();
3552            }
3553            Subscription::ReleaseObservation { observations, .. } => {
3554                observations.take();
3555            }
3556        }
3557    }
3558}
3559
3560impl Drop for Subscription {
3561    fn drop(&mut self) {
3562        match self {
3563            Subscription::Observation {
3564                id,
3565                entity_id,
3566                observations,
3567            } => {
3568                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
3569                    if let Some(observations) = observations.lock().get_mut(entity_id) {
3570                        observations.remove(id);
3571                    }
3572                }
3573            }
3574            Subscription::ReleaseObservation {
3575                id,
3576                entity_id,
3577                observations,
3578            } => {
3579                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
3580                    if let Some(observations) = observations.lock().get_mut(entity_id) {
3581                        observations.remove(id);
3582                    }
3583                }
3584            }
3585            Subscription::Subscription {
3586                id,
3587                entity_id,
3588                subscriptions,
3589            } => {
3590                if let Some(subscriptions) = subscriptions.as_ref().and_then(Weak::upgrade) {
3591                    if let Some(subscriptions) = subscriptions.lock().get_mut(entity_id) {
3592                        subscriptions.remove(id);
3593                    }
3594                }
3595            }
3596        }
3597    }
3598}
3599
3600#[derive(Default)]
3601struct RefCounts {
3602    entity_counts: HashMap<usize, usize>,
3603    element_state_counts: HashMap<(TypeId, ElementStateId), ElementStateRefCount>,
3604    dropped_models: HashSet<usize>,
3605    dropped_views: HashSet<(usize, usize)>,
3606    dropped_element_states: HashSet<(TypeId, ElementStateId)>,
3607}
3608
3609struct ElementStateRefCount {
3610    ref_count: usize,
3611    frame_id: usize,
3612}
3613
3614impl RefCounts {
3615    fn inc_model(&mut self, model_id: usize) {
3616        match self.entity_counts.entry(model_id) {
3617            Entry::Occupied(mut entry) => {
3618                *entry.get_mut() += 1;
3619            }
3620            Entry::Vacant(entry) => {
3621                entry.insert(1);
3622                self.dropped_models.remove(&model_id);
3623            }
3624        }
3625    }
3626
3627    fn inc_view(&mut self, window_id: usize, view_id: usize) {
3628        match self.entity_counts.entry(view_id) {
3629            Entry::Occupied(mut entry) => *entry.get_mut() += 1,
3630            Entry::Vacant(entry) => {
3631                entry.insert(1);
3632                self.dropped_views.remove(&(window_id, view_id));
3633            }
3634        }
3635    }
3636
3637    fn inc_element_state(&mut self, tag_type_id: TypeId, id: ElementStateId, frame_id: usize) {
3638        match self.element_state_counts.entry((tag_type_id, id)) {
3639            Entry::Occupied(mut entry) => {
3640                let entry = entry.get_mut();
3641                if entry.frame_id == frame_id || entry.ref_count >= 2 {
3642                    panic!("used the same element state more than once in the same frame");
3643                }
3644                entry.ref_count += 1;
3645                entry.frame_id = frame_id;
3646            }
3647            Entry::Vacant(entry) => {
3648                entry.insert(ElementStateRefCount {
3649                    ref_count: 1,
3650                    frame_id,
3651                });
3652                self.dropped_element_states.remove(&(tag_type_id, id));
3653            }
3654        }
3655    }
3656
3657    fn dec_model(&mut self, model_id: usize) {
3658        let count = self.entity_counts.get_mut(&model_id).unwrap();
3659        *count -= 1;
3660        if *count == 0 {
3661            self.entity_counts.remove(&model_id);
3662            self.dropped_models.insert(model_id);
3663        }
3664    }
3665
3666    fn dec_view(&mut self, window_id: usize, view_id: usize) {
3667        let count = self.entity_counts.get_mut(&view_id).unwrap();
3668        *count -= 1;
3669        if *count == 0 {
3670            self.entity_counts.remove(&view_id);
3671            self.dropped_views.insert((window_id, view_id));
3672        }
3673    }
3674
3675    fn dec_element_state(&mut self, tag_type_id: TypeId, id: ElementStateId) {
3676        let key = (tag_type_id, id);
3677        let entry = self.element_state_counts.get_mut(&key).unwrap();
3678        entry.ref_count -= 1;
3679        if entry.ref_count == 0 {
3680            self.element_state_counts.remove(&key);
3681            self.dropped_element_states.insert(key);
3682        }
3683    }
3684
3685    fn is_entity_alive(&self, entity_id: usize) -> bool {
3686        self.entity_counts.contains_key(&entity_id)
3687    }
3688
3689    fn take_dropped(
3690        &mut self,
3691    ) -> (
3692        HashSet<usize>,
3693        HashSet<(usize, usize)>,
3694        HashSet<(TypeId, ElementStateId)>,
3695    ) {
3696        (
3697            std::mem::take(&mut self.dropped_models),
3698            std::mem::take(&mut self.dropped_views),
3699            std::mem::take(&mut self.dropped_element_states),
3700        )
3701    }
3702}
3703
3704#[cfg(test)]
3705mod tests {
3706    use super::*;
3707    use crate::elements::*;
3708    use smol::future::poll_once;
3709    use std::{
3710        cell::Cell,
3711        sync::atomic::{AtomicUsize, Ordering::SeqCst},
3712    };
3713
3714    #[crate::test(self)]
3715    fn test_model_handles(cx: &mut MutableAppContext) {
3716        struct Model {
3717            other: Option<ModelHandle<Model>>,
3718            events: Vec<String>,
3719        }
3720
3721        impl Entity for Model {
3722            type Event = usize;
3723        }
3724
3725        impl Model {
3726            fn new(other: Option<ModelHandle<Self>>, cx: &mut ModelContext<Self>) -> Self {
3727                if let Some(other) = other.as_ref() {
3728                    cx.observe(other, |me, _, _| {
3729                        me.events.push("notified".into());
3730                    })
3731                    .detach();
3732                    cx.subscribe(other, |me, _, event, _| {
3733                        me.events.push(format!("observed event {}", event));
3734                    })
3735                    .detach();
3736                }
3737
3738                Self {
3739                    other,
3740                    events: Vec::new(),
3741                }
3742            }
3743        }
3744
3745        let handle_1 = cx.add_model(|cx| Model::new(None, cx));
3746        let handle_2 = cx.add_model(|cx| Model::new(Some(handle_1.clone()), cx));
3747        assert_eq!(cx.cx.models.len(), 2);
3748
3749        handle_1.update(cx, |model, cx| {
3750            model.events.push("updated".into());
3751            cx.emit(1);
3752            cx.notify();
3753            cx.emit(2);
3754        });
3755        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
3756        assert_eq!(
3757            handle_2.read(cx).events,
3758            vec![
3759                "observed event 1".to_string(),
3760                "notified".to_string(),
3761                "observed event 2".to_string(),
3762            ]
3763        );
3764
3765        handle_2.update(cx, |model, _| {
3766            drop(handle_1);
3767            model.other.take();
3768        });
3769
3770        assert_eq!(cx.cx.models.len(), 1);
3771        assert!(cx.subscriptions.lock().is_empty());
3772        assert!(cx.observations.lock().is_empty());
3773    }
3774
3775    #[crate::test(self)]
3776    fn test_subscribe_and_emit_from_model(cx: &mut MutableAppContext) {
3777        #[derive(Default)]
3778        struct Model {
3779            events: Vec<usize>,
3780        }
3781
3782        impl Entity for Model {
3783            type Event = usize;
3784        }
3785
3786        let handle_1 = cx.add_model(|_| Model::default());
3787        let handle_2 = cx.add_model(|_| Model::default());
3788        let handle_2b = handle_2.clone();
3789
3790        handle_1.update(cx, |_, c| {
3791            c.subscribe(&handle_2, move |model: &mut Model, _, event, c| {
3792                model.events.push(*event);
3793
3794                c.subscribe(&handle_2b, |model, _, event, _| {
3795                    model.events.push(*event * 2);
3796                })
3797                .detach();
3798            })
3799            .detach();
3800        });
3801
3802        handle_2.update(cx, |_, c| c.emit(7));
3803        assert_eq!(handle_1.read(cx).events, vec![7]);
3804
3805        handle_2.update(cx, |_, c| c.emit(5));
3806        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
3807    }
3808
3809    #[crate::test(self)]
3810    fn test_observe_and_notify_from_model(cx: &mut MutableAppContext) {
3811        #[derive(Default)]
3812        struct Model {
3813            count: usize,
3814            events: Vec<usize>,
3815        }
3816
3817        impl Entity for Model {
3818            type Event = ();
3819        }
3820
3821        let handle_1 = cx.add_model(|_| Model::default());
3822        let handle_2 = cx.add_model(|_| Model::default());
3823        let handle_2b = handle_2.clone();
3824
3825        handle_1.update(cx, |_, c| {
3826            c.observe(&handle_2, move |model, observed, c| {
3827                model.events.push(observed.read(c).count);
3828                c.observe(&handle_2b, |model, observed, c| {
3829                    model.events.push(observed.read(c).count * 2);
3830                })
3831                .detach();
3832            })
3833            .detach();
3834        });
3835
3836        handle_2.update(cx, |model, c| {
3837            model.count = 7;
3838            c.notify()
3839        });
3840        assert_eq!(handle_1.read(cx).events, vec![7]);
3841
3842        handle_2.update(cx, |model, c| {
3843            model.count = 5;
3844            c.notify()
3845        });
3846        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10])
3847    }
3848
3849    #[crate::test(self)]
3850    fn test_view_handles(cx: &mut MutableAppContext) {
3851        struct View {
3852            other: Option<ViewHandle<View>>,
3853            events: Vec<String>,
3854        }
3855
3856        impl Entity for View {
3857            type Event = usize;
3858        }
3859
3860        impl super::View for View {
3861            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
3862                Empty::new().boxed()
3863            }
3864
3865            fn ui_name() -> &'static str {
3866                "View"
3867            }
3868        }
3869
3870        impl View {
3871            fn new(other: Option<ViewHandle<View>>, cx: &mut ViewContext<Self>) -> Self {
3872                if let Some(other) = other.as_ref() {
3873                    cx.subscribe(other, |me, _, event, _| {
3874                        me.events.push(format!("observed event {}", event));
3875                    })
3876                    .detach();
3877                }
3878                Self {
3879                    other,
3880                    events: Vec::new(),
3881                }
3882            }
3883        }
3884
3885        let (window_id, _) = cx.add_window(Default::default(), |cx| View::new(None, cx));
3886        let handle_1 = cx.add_view(window_id, |cx| View::new(None, cx));
3887        let handle_2 = cx.add_view(window_id, |cx| View::new(Some(handle_1.clone()), cx));
3888        assert_eq!(cx.cx.views.len(), 3);
3889
3890        handle_1.update(cx, |view, cx| {
3891            view.events.push("updated".into());
3892            cx.emit(1);
3893            cx.emit(2);
3894        });
3895        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
3896        assert_eq!(
3897            handle_2.read(cx).events,
3898            vec![
3899                "observed event 1".to_string(),
3900                "observed event 2".to_string(),
3901            ]
3902        );
3903
3904        handle_2.update(cx, |view, _| {
3905            drop(handle_1);
3906            view.other.take();
3907        });
3908
3909        assert_eq!(cx.cx.views.len(), 2);
3910        assert!(cx.subscriptions.lock().is_empty());
3911        assert!(cx.observations.lock().is_empty());
3912    }
3913
3914    #[crate::test(self)]
3915    fn test_add_window(cx: &mut MutableAppContext) {
3916        struct View {
3917            mouse_down_count: Arc<AtomicUsize>,
3918        }
3919
3920        impl Entity for View {
3921            type Event = ();
3922        }
3923
3924        impl super::View for View {
3925            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
3926                let mouse_down_count = self.mouse_down_count.clone();
3927                EventHandler::new(Empty::new().boxed())
3928                    .on_mouse_down(move |_| {
3929                        mouse_down_count.fetch_add(1, SeqCst);
3930                        true
3931                    })
3932                    .boxed()
3933            }
3934
3935            fn ui_name() -> &'static str {
3936                "View"
3937            }
3938        }
3939
3940        let mouse_down_count = Arc::new(AtomicUsize::new(0));
3941        let (window_id, _) = cx.add_window(Default::default(), |_| View {
3942            mouse_down_count: mouse_down_count.clone(),
3943        });
3944        let presenter = cx.presenters_and_platform_windows[&window_id].0.clone();
3945        // Ensure window's root element is in a valid lifecycle state.
3946        presenter.borrow_mut().dispatch_event(
3947            Event::LeftMouseDown {
3948                position: Default::default(),
3949                ctrl: false,
3950                alt: false,
3951                shift: false,
3952                cmd: false,
3953                click_count: 1,
3954            },
3955            cx,
3956        );
3957        assert_eq!(mouse_down_count.load(SeqCst), 1);
3958    }
3959
3960    #[crate::test(self)]
3961    fn test_entity_release_hooks(cx: &mut MutableAppContext) {
3962        struct Model {
3963            released: Rc<Cell<bool>>,
3964        }
3965
3966        struct View {
3967            released: Rc<Cell<bool>>,
3968        }
3969
3970        impl Entity for Model {
3971            type Event = ();
3972
3973            fn release(&mut self, _: &mut MutableAppContext) {
3974                self.released.set(true);
3975            }
3976        }
3977
3978        impl Entity for View {
3979            type Event = ();
3980
3981            fn release(&mut self, _: &mut MutableAppContext) {
3982                self.released.set(true);
3983            }
3984        }
3985
3986        impl super::View for View {
3987            fn ui_name() -> &'static str {
3988                "View"
3989            }
3990
3991            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
3992                Empty::new().boxed()
3993            }
3994        }
3995
3996        let model_released = Rc::new(Cell::new(false));
3997        let model_release_observed = Rc::new(Cell::new(false));
3998        let view_released = Rc::new(Cell::new(false));
3999        let view_release_observed = Rc::new(Cell::new(false));
4000
4001        let model = cx.add_model(|_| Model {
4002            released: model_released.clone(),
4003        });
4004        let (window_id, view) = cx.add_window(Default::default(), |_| View {
4005            released: view_released.clone(),
4006        });
4007        assert!(!model_released.get());
4008        assert!(!view_released.get());
4009
4010        cx.observe_release(&model, {
4011            let model_release_observed = model_release_observed.clone();
4012            move |_| model_release_observed.set(true)
4013        })
4014        .detach();
4015        cx.observe_release(&view, {
4016            let view_release_observed = view_release_observed.clone();
4017            move |_| view_release_observed.set(true)
4018        })
4019        .detach();
4020
4021        cx.update(move |_| {
4022            drop(model);
4023        });
4024        assert!(model_released.get());
4025        assert!(model_release_observed.get());
4026
4027        drop(view);
4028        cx.remove_window(window_id);
4029        assert!(view_released.get());
4030        assert!(view_release_observed.get());
4031    }
4032
4033    #[crate::test(self)]
4034    fn test_subscribe_and_emit_from_view(cx: &mut MutableAppContext) {
4035        #[derive(Default)]
4036        struct View {
4037            events: Vec<usize>,
4038        }
4039
4040        impl Entity for View {
4041            type Event = usize;
4042        }
4043
4044        impl super::View for View {
4045            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4046                Empty::new().boxed()
4047            }
4048
4049            fn ui_name() -> &'static str {
4050                "View"
4051            }
4052        }
4053
4054        struct Model;
4055
4056        impl Entity for Model {
4057            type Event = usize;
4058        }
4059
4060        let (window_id, handle_1) = cx.add_window(Default::default(), |_| View::default());
4061        let handle_2 = cx.add_view(window_id, |_| View::default());
4062        let handle_2b = handle_2.clone();
4063        let handle_3 = cx.add_model(|_| Model);
4064
4065        handle_1.update(cx, |_, c| {
4066            c.subscribe(&handle_2, move |me, _, event, c| {
4067                me.events.push(*event);
4068
4069                c.subscribe(&handle_2b, |me, _, event, _| {
4070                    me.events.push(*event * 2);
4071                })
4072                .detach();
4073            })
4074            .detach();
4075
4076            c.subscribe(&handle_3, |me, _, event, _| {
4077                me.events.push(*event);
4078            })
4079            .detach();
4080        });
4081
4082        handle_2.update(cx, |_, c| c.emit(7));
4083        assert_eq!(handle_1.read(cx).events, vec![7]);
4084
4085        handle_2.update(cx, |_, c| c.emit(5));
4086        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
4087
4088        handle_3.update(cx, |_, c| c.emit(9));
4089        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10, 9]);
4090    }
4091
4092    #[crate::test(self)]
4093    fn test_dropping_subscribers(cx: &mut MutableAppContext) {
4094        struct View;
4095
4096        impl Entity for View {
4097            type Event = ();
4098        }
4099
4100        impl super::View for View {
4101            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4102                Empty::new().boxed()
4103            }
4104
4105            fn ui_name() -> &'static str {
4106                "View"
4107            }
4108        }
4109
4110        struct Model;
4111
4112        impl Entity for Model {
4113            type Event = ();
4114        }
4115
4116        let (window_id, _) = cx.add_window(Default::default(), |_| View);
4117        let observing_view = cx.add_view(window_id, |_| View);
4118        let emitting_view = cx.add_view(window_id, |_| View);
4119        let observing_model = cx.add_model(|_| Model);
4120        let observed_model = cx.add_model(|_| Model);
4121
4122        observing_view.update(cx, |_, cx| {
4123            cx.subscribe(&emitting_view, |_, _, _, _| {}).detach();
4124            cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
4125        });
4126        observing_model.update(cx, |_, cx| {
4127            cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
4128        });
4129
4130        cx.update(|_| {
4131            drop(observing_view);
4132            drop(observing_model);
4133        });
4134
4135        emitting_view.update(cx, |_, cx| cx.emit(()));
4136        observed_model.update(cx, |_, cx| cx.emit(()));
4137    }
4138
4139    #[crate::test(self)]
4140    fn test_observe_and_notify_from_view(cx: &mut MutableAppContext) {
4141        #[derive(Default)]
4142        struct View {
4143            events: Vec<usize>,
4144        }
4145
4146        impl Entity for View {
4147            type Event = usize;
4148        }
4149
4150        impl super::View for View {
4151            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4152                Empty::new().boxed()
4153            }
4154
4155            fn ui_name() -> &'static str {
4156                "View"
4157            }
4158        }
4159
4160        #[derive(Default)]
4161        struct Model {
4162            count: usize,
4163        }
4164
4165        impl Entity for Model {
4166            type Event = ();
4167        }
4168
4169        let (_, view) = cx.add_window(Default::default(), |_| View::default());
4170        let model = cx.add_model(|_| Model::default());
4171
4172        view.update(cx, |_, c| {
4173            c.observe(&model, |me, observed, c| {
4174                me.events.push(observed.read(c).count)
4175            })
4176            .detach();
4177        });
4178
4179        model.update(cx, |model, c| {
4180            model.count = 11;
4181            c.notify();
4182        });
4183        assert_eq!(view.read(cx).events, vec![11]);
4184    }
4185
4186    #[crate::test(self)]
4187    fn test_dropping_observers(cx: &mut MutableAppContext) {
4188        struct View;
4189
4190        impl Entity for View {
4191            type Event = ();
4192        }
4193
4194        impl super::View for View {
4195            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4196                Empty::new().boxed()
4197            }
4198
4199            fn ui_name() -> &'static str {
4200                "View"
4201            }
4202        }
4203
4204        struct Model;
4205
4206        impl Entity for Model {
4207            type Event = ();
4208        }
4209
4210        let (window_id, _) = cx.add_window(Default::default(), |_| View);
4211        let observing_view = cx.add_view(window_id, |_| View);
4212        let observing_model = cx.add_model(|_| Model);
4213        let observed_model = cx.add_model(|_| Model);
4214
4215        observing_view.update(cx, |_, cx| {
4216            cx.observe(&observed_model, |_, _, _| {}).detach();
4217        });
4218        observing_model.update(cx, |_, cx| {
4219            cx.observe(&observed_model, |_, _, _| {}).detach();
4220        });
4221
4222        cx.update(|_| {
4223            drop(observing_view);
4224            drop(observing_model);
4225        });
4226
4227        observed_model.update(cx, |_, cx| cx.notify());
4228    }
4229
4230    #[crate::test(self)]
4231    fn test_focus(cx: &mut MutableAppContext) {
4232        struct View {
4233            name: String,
4234            events: Arc<Mutex<Vec<String>>>,
4235        }
4236
4237        impl Entity for View {
4238            type Event = ();
4239        }
4240
4241        impl super::View for View {
4242            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4243                Empty::new().boxed()
4244            }
4245
4246            fn ui_name() -> &'static str {
4247                "View"
4248            }
4249
4250            fn on_focus(&mut self, _: &mut ViewContext<Self>) {
4251                self.events.lock().push(format!("{} focused", &self.name));
4252            }
4253
4254            fn on_blur(&mut self, _: &mut ViewContext<Self>) {
4255                self.events.lock().push(format!("{} blurred", &self.name));
4256            }
4257        }
4258
4259        let events: Arc<Mutex<Vec<String>>> = Default::default();
4260        let (window_id, view_1) = cx.add_window(Default::default(), |_| View {
4261            events: events.clone(),
4262            name: "view 1".to_string(),
4263        });
4264        let view_2 = cx.add_view(window_id, |_| View {
4265            events: events.clone(),
4266            name: "view 2".to_string(),
4267        });
4268
4269        view_1.update(cx, |_, cx| cx.focus(&view_2));
4270        view_1.update(cx, |_, cx| cx.focus(&view_1));
4271        view_1.update(cx, |_, cx| cx.focus(&view_2));
4272        view_1.update(cx, |_, _| drop(view_2));
4273
4274        assert_eq!(
4275            *events.lock(),
4276            [
4277                "view 1 focused".to_string(),
4278                "view 1 blurred".to_string(),
4279                "view 2 focused".to_string(),
4280                "view 2 blurred".to_string(),
4281                "view 1 focused".to_string(),
4282                "view 1 blurred".to_string(),
4283                "view 2 focused".to_string(),
4284                "view 1 focused".to_string(),
4285            ],
4286        );
4287    }
4288
4289    #[crate::test(self)]
4290    fn test_dispatch_action(cx: &mut MutableAppContext) {
4291        struct ViewA {
4292            id: usize,
4293        }
4294
4295        impl Entity for ViewA {
4296            type Event = ();
4297        }
4298
4299        impl View for ViewA {
4300            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4301                Empty::new().boxed()
4302            }
4303
4304            fn ui_name() -> &'static str {
4305                "View"
4306            }
4307        }
4308
4309        struct ViewB {
4310            id: usize,
4311        }
4312
4313        impl Entity for ViewB {
4314            type Event = ();
4315        }
4316
4317        impl View for ViewB {
4318            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4319                Empty::new().boxed()
4320            }
4321
4322            fn ui_name() -> &'static str {
4323                "View"
4324            }
4325        }
4326
4327        action!(Action, &'static str);
4328
4329        let actions = Rc::new(RefCell::new(Vec::new()));
4330
4331        let actions_clone = actions.clone();
4332        cx.add_global_action(move |_: &Action, _: &mut MutableAppContext| {
4333            actions_clone.borrow_mut().push("global".to_string());
4334        });
4335
4336        let actions_clone = actions.clone();
4337        cx.add_action(move |view: &mut ViewA, action: &Action, cx| {
4338            assert_eq!(action.0, "bar");
4339            cx.propagate_action();
4340            actions_clone.borrow_mut().push(format!("{} a", view.id));
4341        });
4342
4343        let actions_clone = actions.clone();
4344        cx.add_action(move |view: &mut ViewA, _: &Action, cx| {
4345            if view.id != 1 {
4346                cx.propagate_action();
4347            }
4348            actions_clone.borrow_mut().push(format!("{} b", view.id));
4349        });
4350
4351        let actions_clone = actions.clone();
4352        cx.add_action(move |view: &mut ViewB, _: &Action, cx| {
4353            cx.propagate_action();
4354            actions_clone.borrow_mut().push(format!("{} c", view.id));
4355        });
4356
4357        let actions_clone = actions.clone();
4358        cx.add_action(move |view: &mut ViewB, _: &Action, cx| {
4359            cx.propagate_action();
4360            actions_clone.borrow_mut().push(format!("{} d", view.id));
4361        });
4362
4363        let (window_id, view_1) = cx.add_window(Default::default(), |_| ViewA { id: 1 });
4364        let view_2 = cx.add_view(window_id, |_| ViewB { id: 2 });
4365        let view_3 = cx.add_view(window_id, |_| ViewA { id: 3 });
4366        let view_4 = cx.add_view(window_id, |_| ViewB { id: 4 });
4367
4368        cx.dispatch_action(
4369            window_id,
4370            vec![view_1.id(), view_2.id(), view_3.id(), view_4.id()],
4371            &Action("bar"),
4372        );
4373
4374        assert_eq!(
4375            *actions.borrow(),
4376            vec!["4 d", "4 c", "3 b", "3 a", "2 d", "2 c", "1 b"]
4377        );
4378
4379        // Remove view_1, which doesn't propagate the action
4380        actions.borrow_mut().clear();
4381        cx.dispatch_action(
4382            window_id,
4383            vec![view_2.id(), view_3.id(), view_4.id()],
4384            &Action("bar"),
4385        );
4386
4387        assert_eq!(
4388            *actions.borrow(),
4389            vec!["4 d", "4 c", "3 b", "3 a", "2 d", "2 c", "global"]
4390        );
4391    }
4392
4393    #[crate::test(self)]
4394    fn test_dispatch_keystroke(cx: &mut MutableAppContext) {
4395        use std::cell::Cell;
4396
4397        action!(Action, &'static str);
4398
4399        struct View {
4400            id: usize,
4401            keymap_context: keymap::Context,
4402        }
4403
4404        impl Entity for View {
4405            type Event = ();
4406        }
4407
4408        impl super::View for View {
4409            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4410                Empty::new().boxed()
4411            }
4412
4413            fn ui_name() -> &'static str {
4414                "View"
4415            }
4416
4417            fn keymap_context(&self, _: &AppContext) -> keymap::Context {
4418                self.keymap_context.clone()
4419            }
4420        }
4421
4422        impl View {
4423            fn new(id: usize) -> Self {
4424                View {
4425                    id,
4426                    keymap_context: keymap::Context::default(),
4427                }
4428            }
4429        }
4430
4431        let mut view_1 = View::new(1);
4432        let mut view_2 = View::new(2);
4433        let mut view_3 = View::new(3);
4434        view_1.keymap_context.set.insert("a".into());
4435        view_2.keymap_context.set.insert("a".into());
4436        view_2.keymap_context.set.insert("b".into());
4437        view_3.keymap_context.set.insert("a".into());
4438        view_3.keymap_context.set.insert("b".into());
4439        view_3.keymap_context.set.insert("c".into());
4440
4441        let (window_id, view_1) = cx.add_window(Default::default(), |_| view_1);
4442        let view_2 = cx.add_view(window_id, |_| view_2);
4443        let view_3 = cx.add_view(window_id, |_| view_3);
4444
4445        // This keymap's only binding dispatches an action on view 2 because that view will have
4446        // "a" and "b" in its context, but not "c".
4447        cx.add_bindings(vec![keymap::Binding::new(
4448            "a",
4449            Action("a"),
4450            Some("a && b && !c"),
4451        )]);
4452
4453        let handled_action = Rc::new(Cell::new(false));
4454        let handled_action_clone = handled_action.clone();
4455        cx.add_action(move |view: &mut View, action: &Action, _| {
4456            handled_action_clone.set(true);
4457            assert_eq!(view.id, 2);
4458            assert_eq!(action.0, "a");
4459        });
4460
4461        cx.dispatch_keystroke(
4462            window_id,
4463            vec![view_1.id(), view_2.id(), view_3.id()],
4464            &Keystroke::parse("a").unwrap(),
4465        )
4466        .unwrap();
4467
4468        assert!(handled_action.get());
4469    }
4470
4471    #[crate::test(self)]
4472    async fn test_model_condition(mut cx: TestAppContext) {
4473        struct Counter(usize);
4474
4475        impl super::Entity for Counter {
4476            type Event = ();
4477        }
4478
4479        impl Counter {
4480            fn inc(&mut self, cx: &mut ModelContext<Self>) {
4481                self.0 += 1;
4482                cx.notify();
4483            }
4484        }
4485
4486        let model = cx.add_model(|_| Counter(0));
4487
4488        let condition1 = model.condition(&cx, |model, _| model.0 == 2);
4489        let condition2 = model.condition(&cx, |model, _| model.0 == 3);
4490        smol::pin!(condition1, condition2);
4491
4492        model.update(&mut cx, |model, cx| model.inc(cx));
4493        assert_eq!(poll_once(&mut condition1).await, None);
4494        assert_eq!(poll_once(&mut condition2).await, None);
4495
4496        model.update(&mut cx, |model, cx| model.inc(cx));
4497        assert_eq!(poll_once(&mut condition1).await, Some(()));
4498        assert_eq!(poll_once(&mut condition2).await, None);
4499
4500        model.update(&mut cx, |model, cx| model.inc(cx));
4501        assert_eq!(poll_once(&mut condition2).await, Some(()));
4502
4503        model.update(&mut cx, |_, cx| cx.notify());
4504    }
4505
4506    #[crate::test(self)]
4507    #[should_panic]
4508    async fn test_model_condition_timeout(mut cx: TestAppContext) {
4509        struct Model;
4510
4511        impl super::Entity for Model {
4512            type Event = ();
4513        }
4514
4515        let model = cx.add_model(|_| Model);
4516        model.condition(&cx, |_, _| false).await;
4517    }
4518
4519    #[crate::test(self)]
4520    #[should_panic(expected = "model dropped with pending condition")]
4521    async fn test_model_condition_panic_on_drop(mut cx: TestAppContext) {
4522        struct Model;
4523
4524        impl super::Entity for Model {
4525            type Event = ();
4526        }
4527
4528        let model = cx.add_model(|_| Model);
4529        let condition = model.condition(&cx, |_, _| false);
4530        cx.update(|_| drop(model));
4531        condition.await;
4532    }
4533
4534    #[crate::test(self)]
4535    async fn test_view_condition(mut cx: TestAppContext) {
4536        struct Counter(usize);
4537
4538        impl super::Entity for Counter {
4539            type Event = ();
4540        }
4541
4542        impl super::View for Counter {
4543            fn ui_name() -> &'static str {
4544                "test view"
4545            }
4546
4547            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4548                Empty::new().boxed()
4549            }
4550        }
4551
4552        impl Counter {
4553            fn inc(&mut self, cx: &mut ViewContext<Self>) {
4554                self.0 += 1;
4555                cx.notify();
4556            }
4557        }
4558
4559        let (_, view) = cx.add_window(|_| Counter(0));
4560
4561        let condition1 = view.condition(&cx, |view, _| view.0 == 2);
4562        let condition2 = view.condition(&cx, |view, _| view.0 == 3);
4563        smol::pin!(condition1, condition2);
4564
4565        view.update(&mut cx, |view, cx| view.inc(cx));
4566        assert_eq!(poll_once(&mut condition1).await, None);
4567        assert_eq!(poll_once(&mut condition2).await, None);
4568
4569        view.update(&mut cx, |view, cx| view.inc(cx));
4570        assert_eq!(poll_once(&mut condition1).await, Some(()));
4571        assert_eq!(poll_once(&mut condition2).await, None);
4572
4573        view.update(&mut cx, |view, cx| view.inc(cx));
4574        assert_eq!(poll_once(&mut condition2).await, Some(()));
4575        view.update(&mut cx, |_, cx| cx.notify());
4576    }
4577
4578    #[crate::test(self)]
4579    #[should_panic]
4580    async fn test_view_condition_timeout(mut cx: TestAppContext) {
4581        struct View;
4582
4583        impl super::Entity for View {
4584            type Event = ();
4585        }
4586
4587        impl super::View for View {
4588            fn ui_name() -> &'static str {
4589                "test view"
4590            }
4591
4592            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4593                Empty::new().boxed()
4594            }
4595        }
4596
4597        let (_, view) = cx.add_window(|_| View);
4598        view.condition(&cx, |_, _| false).await;
4599    }
4600
4601    #[crate::test(self)]
4602    #[should_panic(expected = "view dropped with pending condition")]
4603    async fn test_view_condition_panic_on_drop(mut cx: TestAppContext) {
4604        struct View;
4605
4606        impl super::Entity for View {
4607            type Event = ();
4608        }
4609
4610        impl super::View for View {
4611            fn ui_name() -> &'static str {
4612                "test view"
4613            }
4614
4615            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4616                Empty::new().boxed()
4617            }
4618        }
4619
4620        let window_id = cx.add_window(|_| View).0;
4621        let view = cx.add_view(window_id, |_| View);
4622
4623        let condition = view.condition(&cx, |_, _| false);
4624        cx.update(|_| drop(view));
4625        condition.await;
4626    }
4627}