app.rs

   1pub mod action;
   2mod callback_collection;
   3#[cfg(any(test, feature = "test-support"))]
   4pub mod test_app_context;
   5
   6use std::{
   7    any::{type_name, Any, TypeId},
   8    cell::RefCell,
   9    fmt::{self, Debug},
  10    hash::{Hash, Hasher},
  11    marker::PhantomData,
  12    mem,
  13    ops::{Deref, DerefMut, Range},
  14    path::{Path, PathBuf},
  15    pin::Pin,
  16    rc::{self, Rc},
  17    sync::{Arc, Weak},
  18    time::Duration,
  19};
  20
  21use anyhow::{anyhow, Context, Result};
  22use lazy_static::lazy_static;
  23use parking_lot::Mutex;
  24use postage::oneshot;
  25use smallvec::SmallVec;
  26use smol::prelude::*;
  27
  28pub use action::*;
  29use callback_collection::{CallbackCollection, Mapping};
  30use collections::{btree_map, hash_map::Entry, BTreeMap, HashMap, HashSet, VecDeque};
  31use keymap::MatchResult;
  32use platform::Event;
  33#[cfg(any(test, feature = "test-support"))]
  34pub use test_app_context::{ContextHandle, TestAppContext};
  35
  36use crate::{
  37    elements::ElementBox,
  38    executor::{self, Task},
  39    geometry::rect::RectF,
  40    keymap::{self, Binding, Keystroke},
  41    platform::{self, KeyDownEvent, Platform, PromptLevel, WindowOptions},
  42    presenter::Presenter,
  43    util::post_inc,
  44    Appearance, AssetCache, AssetSource, ClipboardItem, FontCache, InputHandler, MouseButton,
  45    MouseRegionId, PathPromptOptions, TextLayoutCache,
  46};
  47
  48pub trait Entity: 'static {
  49    type Event;
  50
  51    fn release(&mut self, _: &mut MutableAppContext) {}
  52    fn app_will_quit(
  53        &mut self,
  54        _: &mut MutableAppContext,
  55    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
  56        None
  57    }
  58}
  59
  60pub trait View: Entity + Sized {
  61    fn ui_name() -> &'static str;
  62    fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox;
  63    fn on_focus_in(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {}
  64    fn on_focus_out(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {}
  65    fn keymap_context(&self, _: &AppContext) -> keymap::Context {
  66        Self::default_keymap_context()
  67    }
  68    fn default_keymap_context() -> keymap::Context {
  69        let mut cx = keymap::Context::default();
  70        cx.set.insert(Self::ui_name().into());
  71        cx
  72    }
  73    fn debug_json(&self, _: &AppContext) -> serde_json::Value {
  74        serde_json::Value::Null
  75    }
  76
  77    fn text_for_range(&self, _: Range<usize>, _: &AppContext) -> Option<String> {
  78        None
  79    }
  80    fn selected_text_range(&self, _: &AppContext) -> Option<Range<usize>> {
  81        None
  82    }
  83    fn marked_text_range(&self, _: &AppContext) -> Option<Range<usize>> {
  84        None
  85    }
  86    fn unmark_text(&mut self, _: &mut ViewContext<Self>) {}
  87    fn replace_text_in_range(
  88        &mut self,
  89        _: Option<Range<usize>>,
  90        _: &str,
  91        _: &mut ViewContext<Self>,
  92    ) {
  93    }
  94    fn replace_and_mark_text_in_range(
  95        &mut self,
  96        _: Option<Range<usize>>,
  97        _: &str,
  98        _: Option<Range<usize>>,
  99        _: &mut ViewContext<Self>,
 100    ) {
 101    }
 102}
 103
 104pub trait ReadModel {
 105    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T;
 106}
 107
 108pub trait ReadModelWith {
 109    fn read_model_with<E: Entity, T>(
 110        &self,
 111        handle: &ModelHandle<E>,
 112        read: &mut dyn FnMut(&E, &AppContext) -> T,
 113    ) -> T;
 114}
 115
 116pub trait UpdateModel {
 117    fn update_model<T: Entity, O>(
 118        &mut self,
 119        handle: &ModelHandle<T>,
 120        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
 121    ) -> O;
 122}
 123
 124pub trait UpgradeModelHandle {
 125    fn upgrade_model_handle<T: Entity>(
 126        &self,
 127        handle: &WeakModelHandle<T>,
 128    ) -> Option<ModelHandle<T>>;
 129
 130    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool;
 131
 132    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle>;
 133}
 134
 135pub trait UpgradeViewHandle {
 136    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>>;
 137
 138    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle>;
 139}
 140
 141pub trait ReadView {
 142    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T;
 143}
 144
 145pub trait ReadViewWith {
 146    fn read_view_with<V, T>(
 147        &self,
 148        handle: &ViewHandle<V>,
 149        read: &mut dyn FnMut(&V, &AppContext) -> T,
 150    ) -> T
 151    where
 152        V: View;
 153}
 154
 155pub trait UpdateView {
 156    fn update_view<T, S>(
 157        &mut self,
 158        handle: &ViewHandle<T>,
 159        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
 160    ) -> S
 161    where
 162        T: View;
 163}
 164
 165pub struct Menu<'a> {
 166    pub name: &'a str,
 167    pub items: Vec<MenuItem<'a>>,
 168}
 169
 170pub enum MenuItem<'a> {
 171    Separator,
 172    Submenu(Menu<'a>),
 173    Action {
 174        name: &'a str,
 175        action: Box<dyn Action>,
 176    },
 177}
 178
 179#[derive(Clone)]
 180pub struct App(Rc<RefCell<MutableAppContext>>);
 181
 182#[derive(Clone)]
 183pub struct AsyncAppContext(Rc<RefCell<MutableAppContext>>);
 184
 185pub struct WindowInputHandler {
 186    app: Rc<RefCell<MutableAppContext>>,
 187    window_id: usize,
 188}
 189
 190impl App {
 191    pub fn new(asset_source: impl AssetSource) -> Result<Self> {
 192        let platform = platform::current::platform();
 193        let foreground_platform = platform::current::foreground_platform();
 194        let foreground = Rc::new(executor::Foreground::platform(platform.dispatcher())?);
 195        let app = Self(Rc::new(RefCell::new(MutableAppContext::new(
 196            foreground,
 197            Arc::new(executor::Background::new()),
 198            platform.clone(),
 199            foreground_platform.clone(),
 200            Arc::new(FontCache::new(platform.fonts())),
 201            Default::default(),
 202            asset_source,
 203        ))));
 204
 205        foreground_platform.on_quit(Box::new({
 206            let cx = app.0.clone();
 207            move || {
 208                cx.borrow_mut().quit();
 209            }
 210        }));
 211        foreground_platform.on_will_open_menu(Box::new({
 212            let cx = app.0.clone();
 213            move || {
 214                let mut cx = cx.borrow_mut();
 215                cx.keystroke_matcher.clear_pending();
 216            }
 217        }));
 218        foreground_platform.on_validate_menu_command(Box::new({
 219            let cx = app.0.clone();
 220            move |action| {
 221                let cx = cx.borrow_mut();
 222                !cx.keystroke_matcher.has_pending_keystrokes() && cx.is_action_available(action)
 223            }
 224        }));
 225        foreground_platform.on_menu_command(Box::new({
 226            let cx = app.0.clone();
 227            move |action| {
 228                let mut cx = cx.borrow_mut();
 229                if let Some(key_window_id) = cx.cx.platform.key_window_id() {
 230                    if let Some(view_id) = cx.focused_view_id(key_window_id) {
 231                        cx.handle_dispatch_action_from_effect(key_window_id, Some(view_id), action);
 232                        return;
 233                    }
 234                }
 235                cx.dispatch_global_action_any(action);
 236            }
 237        }));
 238
 239        app.0.borrow_mut().weak_self = Some(Rc::downgrade(&app.0));
 240        Ok(app)
 241    }
 242
 243    pub fn background(&self) -> Arc<executor::Background> {
 244        self.0.borrow().background().clone()
 245    }
 246
 247    pub fn on_become_active<F>(self, mut callback: F) -> Self
 248    where
 249        F: 'static + FnMut(&mut MutableAppContext),
 250    {
 251        let cx = self.0.clone();
 252        self.0
 253            .borrow_mut()
 254            .foreground_platform
 255            .on_become_active(Box::new(move || callback(&mut *cx.borrow_mut())));
 256        self
 257    }
 258
 259    pub fn on_resign_active<F>(self, mut callback: F) -> Self
 260    where
 261        F: 'static + FnMut(&mut MutableAppContext),
 262    {
 263        let cx = self.0.clone();
 264        self.0
 265            .borrow_mut()
 266            .foreground_platform
 267            .on_resign_active(Box::new(move || callback(&mut *cx.borrow_mut())));
 268        self
 269    }
 270
 271    pub fn on_quit<F>(&mut self, mut callback: F) -> &mut Self
 272    where
 273        F: 'static + FnMut(&mut MutableAppContext),
 274    {
 275        let cx = self.0.clone();
 276        self.0
 277            .borrow_mut()
 278            .foreground_platform
 279            .on_quit(Box::new(move || callback(&mut *cx.borrow_mut())));
 280        self
 281    }
 282
 283    pub fn on_event<F>(&mut self, mut callback: F) -> &mut Self
 284    where
 285        F: 'static + FnMut(Event, &mut MutableAppContext) -> bool,
 286    {
 287        let cx = self.0.clone();
 288        self.0
 289            .borrow_mut()
 290            .foreground_platform
 291            .on_event(Box::new(move |event| {
 292                callback(event, &mut *cx.borrow_mut())
 293            }));
 294        self
 295    }
 296
 297    pub fn on_open_urls<F>(&mut self, mut callback: F) -> &mut Self
 298    where
 299        F: 'static + FnMut(Vec<String>, &mut MutableAppContext),
 300    {
 301        let cx = self.0.clone();
 302        self.0
 303            .borrow_mut()
 304            .foreground_platform
 305            .on_open_urls(Box::new(move |paths| {
 306                callback(paths, &mut *cx.borrow_mut())
 307            }));
 308        self
 309    }
 310
 311    pub fn run<F>(self, on_finish_launching: F)
 312    where
 313        F: 'static + FnOnce(&mut MutableAppContext),
 314    {
 315        let platform = self.0.borrow().foreground_platform.clone();
 316        platform.run(Box::new(move || {
 317            let mut cx = self.0.borrow_mut();
 318            let cx = &mut *cx;
 319            crate::views::init(cx);
 320            on_finish_launching(cx);
 321        }))
 322    }
 323
 324    pub fn platform(&self) -> Arc<dyn Platform> {
 325        self.0.borrow().platform()
 326    }
 327
 328    pub fn font_cache(&self) -> Arc<FontCache> {
 329        self.0.borrow().cx.font_cache.clone()
 330    }
 331
 332    fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 333        let mut state = self.0.borrow_mut();
 334        let result = state.update(callback);
 335        state.pending_notifications.clear();
 336        result
 337    }
 338}
 339
 340impl WindowInputHandler {
 341    fn read_focused_view<T, F>(&self, f: F) -> Option<T>
 342    where
 343        F: FnOnce(&dyn AnyView, &AppContext) -> T,
 344    {
 345        // Input-related application hooks are sometimes called by the OS during
 346        // a call to a window-manipulation API, like prompting the user for file
 347        // paths. In that case, the AppContext will already be borrowed, so any
 348        // InputHandler methods need to fail gracefully.
 349        //
 350        // See https://github.com/zed-industries/feedback/issues/444
 351        let app = self.app.try_borrow().ok()?;
 352
 353        let view_id = app.focused_view_id(self.window_id)?;
 354        let view = app.cx.views.get(&(self.window_id, view_id))?;
 355        let result = f(view.as_ref(), &app);
 356        Some(result)
 357    }
 358
 359    fn update_focused_view<T, F>(&mut self, f: F) -> Option<T>
 360    where
 361        F: FnOnce(usize, usize, &mut dyn AnyView, &mut MutableAppContext) -> T,
 362    {
 363        let mut app = self.app.try_borrow_mut().ok()?;
 364        app.update(|app| {
 365            let view_id = app.focused_view_id(self.window_id)?;
 366            let mut view = app.cx.views.remove(&(self.window_id, view_id))?;
 367            let result = f(self.window_id, view_id, view.as_mut(), &mut *app);
 368            app.cx.views.insert((self.window_id, view_id), view);
 369            Some(result)
 370        })
 371    }
 372}
 373
 374impl InputHandler for WindowInputHandler {
 375    fn text_for_range(&self, range: Range<usize>) -> Option<String> {
 376        self.read_focused_view(|view, cx| view.text_for_range(range.clone(), cx))
 377            .flatten()
 378    }
 379
 380    fn selected_text_range(&self) -> Option<Range<usize>> {
 381        self.read_focused_view(|view, cx| view.selected_text_range(cx))
 382            .flatten()
 383    }
 384
 385    fn replace_text_in_range(&mut self, range: Option<Range<usize>>, text: &str) {
 386        self.update_focused_view(|window_id, view_id, view, cx| {
 387            view.replace_text_in_range(range, text, cx, window_id, view_id);
 388        });
 389    }
 390
 391    fn marked_text_range(&self) -> Option<Range<usize>> {
 392        self.read_focused_view(|view, cx| view.marked_text_range(cx))
 393            .flatten()
 394    }
 395
 396    fn unmark_text(&mut self) {
 397        self.update_focused_view(|window_id, view_id, view, cx| {
 398            view.unmark_text(cx, window_id, view_id);
 399        });
 400    }
 401
 402    fn replace_and_mark_text_in_range(
 403        &mut self,
 404        range: Option<Range<usize>>,
 405        new_text: &str,
 406        new_selected_range: Option<Range<usize>>,
 407    ) {
 408        self.update_focused_view(|window_id, view_id, view, cx| {
 409            view.replace_and_mark_text_in_range(
 410                range,
 411                new_text,
 412                new_selected_range,
 413                cx,
 414                window_id,
 415                view_id,
 416            );
 417        });
 418    }
 419
 420    fn rect_for_range(&self, range_utf16: Range<usize>) -> Option<RectF> {
 421        let app = self.app.borrow();
 422        let (presenter, _) = app.presenters_and_platform_windows.get(&self.window_id)?;
 423        let presenter = presenter.borrow();
 424        presenter.rect_for_text_range(range_utf16, &app)
 425    }
 426}
 427
 428impl AsyncAppContext {
 429    pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
 430    where
 431        F: FnOnce(AsyncAppContext) -> Fut,
 432        Fut: 'static + Future<Output = T>,
 433        T: 'static,
 434    {
 435        self.0.borrow().foreground.spawn(f(self.clone()))
 436    }
 437
 438    pub fn read<T, F: FnOnce(&AppContext) -> T>(&self, callback: F) -> T {
 439        callback(self.0.borrow().as_ref())
 440    }
 441
 442    pub fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 443        self.0.borrow_mut().update(callback)
 444    }
 445
 446    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
 447    where
 448        T: Entity,
 449        F: FnOnce(&mut ModelContext<T>) -> T,
 450    {
 451        self.update(|cx| cx.add_model(build_model))
 452    }
 453
 454    pub fn add_window<T, F>(
 455        &mut self,
 456        window_options: WindowOptions,
 457        build_root_view: F,
 458    ) -> (usize, ViewHandle<T>)
 459    where
 460        T: View,
 461        F: FnOnce(&mut ViewContext<T>) -> T,
 462    {
 463        self.update(|cx| cx.add_window(window_options, build_root_view))
 464    }
 465
 466    pub fn platform(&self) -> Arc<dyn Platform> {
 467        self.0.borrow().platform()
 468    }
 469
 470    pub fn foreground(&self) -> Rc<executor::Foreground> {
 471        self.0.borrow().foreground.clone()
 472    }
 473
 474    pub fn background(&self) -> Arc<executor::Background> {
 475        self.0.borrow().cx.background.clone()
 476    }
 477}
 478
 479impl UpdateModel for AsyncAppContext {
 480    fn update_model<E: Entity, O>(
 481        &mut self,
 482        handle: &ModelHandle<E>,
 483        update: &mut dyn FnMut(&mut E, &mut ModelContext<E>) -> O,
 484    ) -> O {
 485        self.0.borrow_mut().update_model(handle, update)
 486    }
 487}
 488
 489impl UpgradeModelHandle for AsyncAppContext {
 490    fn upgrade_model_handle<T: Entity>(
 491        &self,
 492        handle: &WeakModelHandle<T>,
 493    ) -> Option<ModelHandle<T>> {
 494        self.0.borrow().upgrade_model_handle(handle)
 495    }
 496
 497    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
 498        self.0.borrow().model_handle_is_upgradable(handle)
 499    }
 500
 501    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
 502        self.0.borrow().upgrade_any_model_handle(handle)
 503    }
 504}
 505
 506impl UpgradeViewHandle for AsyncAppContext {
 507    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
 508        self.0.borrow_mut().upgrade_view_handle(handle)
 509    }
 510
 511    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
 512        self.0.borrow_mut().upgrade_any_view_handle(handle)
 513    }
 514}
 515
 516impl ReadModelWith for AsyncAppContext {
 517    fn read_model_with<E: Entity, T>(
 518        &self,
 519        handle: &ModelHandle<E>,
 520        read: &mut dyn FnMut(&E, &AppContext) -> T,
 521    ) -> T {
 522        let cx = self.0.borrow();
 523        let cx = cx.as_ref();
 524        read(handle.read(cx), cx)
 525    }
 526}
 527
 528impl UpdateView for AsyncAppContext {
 529    fn update_view<T, S>(
 530        &mut self,
 531        handle: &ViewHandle<T>,
 532        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
 533    ) -> S
 534    where
 535        T: View,
 536    {
 537        self.0.borrow_mut().update_view(handle, update)
 538    }
 539}
 540
 541impl ReadViewWith for AsyncAppContext {
 542    fn read_view_with<V, T>(
 543        &self,
 544        handle: &ViewHandle<V>,
 545        read: &mut dyn FnMut(&V, &AppContext) -> T,
 546    ) -> T
 547    where
 548        V: View,
 549    {
 550        let cx = self.0.borrow();
 551        let cx = cx.as_ref();
 552        read(handle.read(cx), cx)
 553    }
 554}
 555
 556type ActionCallback =
 557    dyn FnMut(&mut dyn AnyView, &dyn Action, &mut MutableAppContext, usize, usize);
 558type GlobalActionCallback = dyn FnMut(&dyn Action, &mut MutableAppContext);
 559
 560type SubscriptionCallback = Box<dyn FnMut(&dyn Any, &mut MutableAppContext) -> bool>;
 561type GlobalSubscriptionCallback = Box<dyn FnMut(&dyn Any, &mut MutableAppContext)>;
 562type ObservationCallback = Box<dyn FnMut(&mut MutableAppContext) -> bool>;
 563type FocusObservationCallback = Box<dyn FnMut(bool, &mut MutableAppContext) -> bool>;
 564type GlobalObservationCallback = Box<dyn FnMut(&mut MutableAppContext)>;
 565type ReleaseObservationCallback = Box<dyn FnOnce(&dyn Any, &mut MutableAppContext)>;
 566type ActionObservationCallback = Box<dyn FnMut(TypeId, &mut MutableAppContext)>;
 567type WindowActivationCallback = Box<dyn FnMut(bool, &mut MutableAppContext) -> bool>;
 568type WindowFullscreenCallback = Box<dyn FnMut(bool, &mut MutableAppContext) -> bool>;
 569type DeserializeActionCallback = fn(json: &str) -> anyhow::Result<Box<dyn Action>>;
 570type WindowShouldCloseSubscriptionCallback = Box<dyn FnMut(&mut MutableAppContext) -> bool>;
 571
 572pub struct MutableAppContext {
 573    weak_self: Option<rc::Weak<RefCell<Self>>>,
 574    foreground_platform: Rc<dyn platform::ForegroundPlatform>,
 575    assets: Arc<AssetCache>,
 576    cx: AppContext,
 577    action_deserializers: HashMap<&'static str, (TypeId, DeserializeActionCallback)>,
 578    capture_actions: HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>>,
 579    actions: HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>>,
 580    global_actions: HashMap<TypeId, Box<GlobalActionCallback>>,
 581    keystroke_matcher: keymap::Matcher,
 582    next_entity_id: usize,
 583    next_window_id: usize,
 584    next_subscription_id: usize,
 585    frame_count: usize,
 586
 587    focus_observations: CallbackCollection<usize, FocusObservationCallback>,
 588    global_subscriptions: CallbackCollection<TypeId, GlobalSubscriptionCallback>,
 589    global_observations: CallbackCollection<TypeId, GlobalObservationCallback>,
 590    subscriptions: CallbackCollection<usize, SubscriptionCallback>,
 591    observations: CallbackCollection<usize, ObservationCallback>,
 592    window_activation_observations: CallbackCollection<usize, WindowActivationCallback>,
 593    window_fullscreen_observations: CallbackCollection<usize, WindowFullscreenCallback>,
 594
 595    release_observations: Arc<Mutex<HashMap<usize, BTreeMap<usize, ReleaseObservationCallback>>>>,
 596    action_dispatch_observations: Arc<Mutex<BTreeMap<usize, ActionObservationCallback>>>,
 597
 598    #[allow(clippy::type_complexity)]
 599    presenters_and_platform_windows:
 600        HashMap<usize, (Rc<RefCell<Presenter>>, Box<dyn platform::Window>)>,
 601    foreground: Rc<executor::Foreground>,
 602    pending_effects: VecDeque<Effect>,
 603    pending_focus_index: Option<usize>,
 604    pending_notifications: HashSet<usize>,
 605    pending_global_notifications: HashSet<TypeId>,
 606    pending_flushes: usize,
 607    flushing_effects: bool,
 608    halt_action_dispatch: bool,
 609}
 610
 611impl MutableAppContext {
 612    fn new(
 613        foreground: Rc<executor::Foreground>,
 614        background: Arc<executor::Background>,
 615        platform: Arc<dyn platform::Platform>,
 616        foreground_platform: Rc<dyn platform::ForegroundPlatform>,
 617        font_cache: Arc<FontCache>,
 618        ref_counts: RefCounts,
 619        asset_source: impl AssetSource,
 620    ) -> Self {
 621        Self {
 622            weak_self: None,
 623            foreground_platform,
 624            assets: Arc::new(AssetCache::new(asset_source)),
 625            cx: AppContext {
 626                models: Default::default(),
 627                views: Default::default(),
 628                parents: Default::default(),
 629                windows: Default::default(),
 630                globals: Default::default(),
 631                element_states: Default::default(),
 632                ref_counts: Arc::new(Mutex::new(ref_counts)),
 633                background,
 634                font_cache,
 635                platform,
 636            },
 637            action_deserializers: Default::default(),
 638            capture_actions: Default::default(),
 639            actions: Default::default(),
 640            global_actions: Default::default(),
 641            keystroke_matcher: keymap::Matcher::default(),
 642            next_entity_id: 0,
 643            next_window_id: 0,
 644            next_subscription_id: 0,
 645            frame_count: 0,
 646            subscriptions: Default::default(),
 647            global_subscriptions: Default::default(),
 648            observations: Default::default(),
 649            focus_observations: Default::default(),
 650            release_observations: Default::default(),
 651            global_observations: Default::default(),
 652            window_activation_observations: Default::default(),
 653            window_fullscreen_observations: Default::default(),
 654            action_dispatch_observations: Default::default(),
 655            presenters_and_platform_windows: Default::default(),
 656            foreground,
 657            pending_effects: VecDeque::new(),
 658            pending_focus_index: None,
 659            pending_notifications: Default::default(),
 660            pending_global_notifications: Default::default(),
 661            pending_flushes: 0,
 662            flushing_effects: false,
 663            halt_action_dispatch: false,
 664        }
 665    }
 666
 667    pub fn upgrade(&self) -> App {
 668        App(self.weak_self.as_ref().unwrap().upgrade().unwrap())
 669    }
 670
 671    pub fn quit(&mut self) {
 672        let mut futures = Vec::new();
 673        for model_id in self.cx.models.keys().copied().collect::<Vec<_>>() {
 674            let mut model = self.cx.models.remove(&model_id).unwrap();
 675            futures.extend(model.app_will_quit(self));
 676            self.cx.models.insert(model_id, model);
 677        }
 678
 679        for view_id in self.cx.views.keys().copied().collect::<Vec<_>>() {
 680            let mut view = self.cx.views.remove(&view_id).unwrap();
 681            futures.extend(view.app_will_quit(self));
 682            self.cx.views.insert(view_id, view);
 683        }
 684
 685        self.remove_all_windows();
 686
 687        let futures = futures::future::join_all(futures);
 688        if self
 689            .background
 690            .block_with_timeout(Duration::from_millis(100), futures)
 691            .is_err()
 692        {
 693            log::error!("timed out waiting on app_will_quit");
 694        }
 695    }
 696
 697    pub fn remove_all_windows(&mut self) {
 698        for (window_id, _) in self.cx.windows.drain() {
 699            self.presenters_and_platform_windows.remove(&window_id);
 700        }
 701        self.flush_effects();
 702    }
 703
 704    pub fn platform(&self) -> Arc<dyn platform::Platform> {
 705        self.cx.platform.clone()
 706    }
 707
 708    pub fn font_cache(&self) -> &Arc<FontCache> {
 709        &self.cx.font_cache
 710    }
 711
 712    pub fn foreground(&self) -> &Rc<executor::Foreground> {
 713        &self.foreground
 714    }
 715
 716    pub fn background(&self) -> &Arc<executor::Background> {
 717        &self.cx.background
 718    }
 719
 720    pub fn debug_elements(&self, window_id: usize) -> Option<crate::json::Value> {
 721        self.presenters_and_platform_windows
 722            .get(&window_id)
 723            .and_then(|(presenter, _)| presenter.borrow().debug_elements(self))
 724    }
 725
 726    pub fn deserialize_action(
 727        &self,
 728        name: &str,
 729        argument: Option<&str>,
 730    ) -> Result<Box<dyn Action>> {
 731        let callback = self
 732            .action_deserializers
 733            .get(name)
 734            .ok_or_else(|| anyhow!("unknown action {}", name))?
 735            .1;
 736        callback(argument.unwrap_or("{}"))
 737            .with_context(|| format!("invalid data for action {}", name))
 738    }
 739
 740    pub fn add_action<A, V, F>(&mut self, handler: F)
 741    where
 742        A: Action,
 743        V: View,
 744        F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>),
 745    {
 746        self.add_action_internal(handler, false)
 747    }
 748
 749    pub fn capture_action<A, V, F>(&mut self, handler: F)
 750    where
 751        A: Action,
 752        V: View,
 753        F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>),
 754    {
 755        self.add_action_internal(handler, true)
 756    }
 757
 758    fn add_action_internal<A, V, F>(&mut self, mut handler: F, capture: bool)
 759    where
 760        A: Action,
 761        V: View,
 762        F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>),
 763    {
 764        let handler = Box::new(
 765            move |view: &mut dyn AnyView,
 766                  action: &dyn Action,
 767                  cx: &mut MutableAppContext,
 768                  window_id: usize,
 769                  view_id: usize| {
 770                let action = action.as_any().downcast_ref().unwrap();
 771                let mut cx = ViewContext::new(cx, window_id, view_id);
 772                handler(
 773                    view.as_any_mut()
 774                        .downcast_mut()
 775                        .expect("downcast is type safe"),
 776                    action,
 777                    &mut cx,
 778                );
 779            },
 780        );
 781
 782        self.action_deserializers
 783            .entry(A::qualified_name())
 784            .or_insert((TypeId::of::<A>(), A::from_json_str));
 785
 786        let actions = if capture {
 787            &mut self.capture_actions
 788        } else {
 789            &mut self.actions
 790        };
 791
 792        actions
 793            .entry(TypeId::of::<V>())
 794            .or_default()
 795            .entry(TypeId::of::<A>())
 796            .or_default()
 797            .push(handler);
 798    }
 799
 800    pub fn add_async_action<A, V, F>(&mut self, mut handler: F)
 801    where
 802        A: Action,
 803        V: View,
 804        F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>) -> Option<Task<Result<()>>>,
 805    {
 806        self.add_action(move |view, action, cx| {
 807            if let Some(task) = handler(view, action, cx) {
 808                task.detach_and_log_err(cx);
 809            }
 810        })
 811    }
 812
 813    pub fn add_global_action<A, F>(&mut self, mut handler: F)
 814    where
 815        A: Action,
 816        F: 'static + FnMut(&A, &mut MutableAppContext),
 817    {
 818        let handler = Box::new(move |action: &dyn Action, cx: &mut MutableAppContext| {
 819            let action = action.as_any().downcast_ref().unwrap();
 820            handler(action, cx);
 821        });
 822
 823        self.action_deserializers
 824            .entry(A::qualified_name())
 825            .or_insert((TypeId::of::<A>(), A::from_json_str));
 826
 827        if self
 828            .global_actions
 829            .insert(TypeId::of::<A>(), handler)
 830            .is_some()
 831        {
 832            panic!(
 833                "registered multiple global handlers for {}",
 834                type_name::<A>()
 835            );
 836        }
 837    }
 838
 839    pub fn window_ids(&self) -> impl Iterator<Item = usize> + '_ {
 840        self.cx.windows.keys().cloned()
 841    }
 842
 843    pub fn activate_window(&self, window_id: usize) {
 844        if let Some((_, window)) = self.presenters_and_platform_windows.get(&window_id) {
 845            window.activate()
 846        }
 847    }
 848
 849    pub fn root_view<T: View>(&self, window_id: usize) -> Option<ViewHandle<T>> {
 850        self.cx
 851            .windows
 852            .get(&window_id)
 853            .and_then(|window| window.root_view.clone().downcast::<T>())
 854    }
 855
 856    pub fn window_is_active(&self, window_id: usize) -> bool {
 857        self.cx
 858            .windows
 859            .get(&window_id)
 860            .map_or(false, |window| window.is_active)
 861    }
 862
 863    pub fn window_is_fullscreen(&self, window_id: usize) -> bool {
 864        self.cx
 865            .windows
 866            .get(&window_id)
 867            .map_or(false, |window| window.is_fullscreen)
 868    }
 869
 870    pub fn window_bounds(&self, window_id: usize) -> RectF {
 871        self.presenters_and_platform_windows[&window_id].1.bounds()
 872    }
 873
 874    pub fn render_view(&mut self, params: RenderParams) -> Result<ElementBox> {
 875        let window_id = params.window_id;
 876        let view_id = params.view_id;
 877        let mut view = self
 878            .cx
 879            .views
 880            .remove(&(window_id, view_id))
 881            .ok_or_else(|| anyhow!("view not found"))?;
 882        let element = view.render(params, self);
 883        self.cx.views.insert((window_id, view_id), view);
 884        Ok(element)
 885    }
 886
 887    pub fn render_views(
 888        &mut self,
 889        window_id: usize,
 890        titlebar_height: f32,
 891        appearance: Appearance,
 892    ) -> HashMap<usize, ElementBox> {
 893        self.start_frame();
 894        #[allow(clippy::needless_collect)]
 895        let view_ids = self
 896            .views
 897            .keys()
 898            .filter_map(|(win_id, view_id)| {
 899                if *win_id == window_id {
 900                    Some(*view_id)
 901                } else {
 902                    None
 903                }
 904            })
 905            .collect::<Vec<_>>();
 906
 907        view_ids
 908            .into_iter()
 909            .map(|view_id| {
 910                (
 911                    view_id,
 912                    self.render_view(RenderParams {
 913                        window_id,
 914                        view_id,
 915                        titlebar_height,
 916                        hovered_region_ids: Default::default(),
 917                        clicked_region_ids: None,
 918                        refreshing: false,
 919                        appearance,
 920                    })
 921                    .unwrap(),
 922                )
 923            })
 924            .collect()
 925    }
 926
 927    pub(crate) fn start_frame(&mut self) {
 928        self.frame_count += 1;
 929    }
 930
 931    pub fn update<T, F: FnOnce(&mut Self) -> T>(&mut self, callback: F) -> T {
 932        self.pending_flushes += 1;
 933        let result = callback(self);
 934        self.flush_effects();
 935        result
 936    }
 937
 938    pub fn set_menus(&mut self, menus: Vec<Menu>) {
 939        self.foreground_platform
 940            .set_menus(menus, &self.keystroke_matcher);
 941    }
 942
 943    fn show_character_palette(&self, window_id: usize) {
 944        let (_, window) = &self.presenters_and_platform_windows[&window_id];
 945        window.show_character_palette();
 946    }
 947
 948    pub fn minimize_window(&self, window_id: usize) {
 949        let (_, window) = &self.presenters_and_platform_windows[&window_id];
 950        window.minimize();
 951    }
 952
 953    pub fn zoom_window(&self, window_id: usize) {
 954        let (_, window) = &self.presenters_and_platform_windows[&window_id];
 955        window.zoom();
 956    }
 957
 958    pub fn toggle_window_full_screen(&self, window_id: usize) {
 959        let (_, window) = &self.presenters_and_platform_windows[&window_id];
 960        window.toggle_full_screen();
 961    }
 962
 963    fn prompt(
 964        &self,
 965        window_id: usize,
 966        level: PromptLevel,
 967        msg: &str,
 968        answers: &[&str],
 969    ) -> oneshot::Receiver<usize> {
 970        let (_, window) = &self.presenters_and_platform_windows[&window_id];
 971        window.prompt(level, msg, answers)
 972    }
 973
 974    pub fn prompt_for_paths(
 975        &self,
 976        options: PathPromptOptions,
 977    ) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
 978        self.foreground_platform.prompt_for_paths(options)
 979    }
 980
 981    pub fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
 982        self.foreground_platform.prompt_for_new_path(directory)
 983    }
 984
 985    pub fn emit_global<E: Any>(&mut self, payload: E) {
 986        self.pending_effects.push_back(Effect::GlobalEvent {
 987            payload: Box::new(payload),
 988        });
 989    }
 990
 991    pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
 992    where
 993        E: Entity,
 994        E::Event: 'static,
 995        H: Handle<E>,
 996        F: 'static + FnMut(H, &E::Event, &mut Self),
 997    {
 998        self.subscribe_internal(handle, move |handle, event, cx| {
 999            callback(handle, event, cx);
1000            true
1001        })
1002    }
1003
1004    pub fn subscribe_global<E, F>(&mut self, mut callback: F) -> Subscription
1005    where
1006        E: Any,
1007        F: 'static + FnMut(&E, &mut Self),
1008    {
1009        let subscription_id = post_inc(&mut self.next_subscription_id);
1010        let type_id = TypeId::of::<E>();
1011        self.pending_effects.push_back(Effect::GlobalSubscription {
1012            type_id,
1013            subscription_id,
1014            callback: Box::new(move |payload, cx| {
1015                let payload = payload.downcast_ref().expect("downcast is type safe");
1016                callback(payload, cx)
1017            }),
1018        });
1019
1020        Subscription::GlobalSubscription {
1021            id: subscription_id,
1022            type_id,
1023            subscriptions: Some(self.global_subscriptions.downgrade()),
1024        }
1025    }
1026
1027    pub fn observe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
1028    where
1029        E: Entity,
1030        E::Event: 'static,
1031        H: Handle<E>,
1032        F: 'static + FnMut(H, &mut Self),
1033    {
1034        self.observe_internal(handle, move |handle, cx| {
1035            callback(handle, cx);
1036            true
1037        })
1038    }
1039
1040    pub fn subscribe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
1041    where
1042        E: Entity,
1043        E::Event: 'static,
1044        H: Handle<E>,
1045        F: 'static + FnMut(H, &E::Event, &mut Self) -> bool,
1046    {
1047        let subscription_id = post_inc(&mut self.next_subscription_id);
1048        let emitter = handle.downgrade();
1049        self.pending_effects.push_back(Effect::Subscription {
1050            entity_id: handle.id(),
1051            subscription_id,
1052            callback: Box::new(move |payload, cx| {
1053                if let Some(emitter) = H::upgrade_from(&emitter, cx.as_ref()) {
1054                    let payload = payload.downcast_ref().expect("downcast is type safe");
1055                    callback(emitter, payload, cx)
1056                } else {
1057                    false
1058                }
1059            }),
1060        });
1061        Subscription::Subscription {
1062            id: subscription_id,
1063            entity_id: handle.id(),
1064            subscriptions: Some(self.subscriptions.downgrade()),
1065        }
1066    }
1067
1068    fn observe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
1069    where
1070        E: Entity,
1071        E::Event: 'static,
1072        H: Handle<E>,
1073        F: 'static + FnMut(H, &mut Self) -> bool,
1074    {
1075        let subscription_id = post_inc(&mut self.next_subscription_id);
1076        let observed = handle.downgrade();
1077        let entity_id = handle.id();
1078        self.pending_effects.push_back(Effect::Observation {
1079            entity_id,
1080            subscription_id,
1081            callback: Box::new(move |cx| {
1082                if let Some(observed) = H::upgrade_from(&observed, cx) {
1083                    callback(observed, cx)
1084                } else {
1085                    false
1086                }
1087            }),
1088        });
1089        Subscription::Observation {
1090            id: subscription_id,
1091            entity_id,
1092            observations: Some(self.observations.downgrade()),
1093        }
1094    }
1095
1096    fn observe_focus<F, V>(&mut self, handle: &ViewHandle<V>, mut callback: F) -> Subscription
1097    where
1098        F: 'static + FnMut(ViewHandle<V>, bool, &mut MutableAppContext) -> bool,
1099        V: View,
1100    {
1101        let subscription_id = post_inc(&mut self.next_subscription_id);
1102        let observed = handle.downgrade();
1103        let view_id = handle.id();
1104
1105        self.pending_effects.push_back(Effect::FocusObservation {
1106            view_id,
1107            subscription_id,
1108            callback: Box::new(move |focused, cx| {
1109                if let Some(observed) = observed.upgrade(cx) {
1110                    callback(observed, focused, cx)
1111                } else {
1112                    false
1113                }
1114            }),
1115        });
1116
1117        Subscription::FocusObservation {
1118            id: subscription_id,
1119            view_id,
1120            observations: Some(self.focus_observations.downgrade()),
1121        }
1122    }
1123
1124    pub fn observe_global<G, F>(&mut self, mut observe: F) -> Subscription
1125    where
1126        G: Any,
1127        F: 'static + FnMut(&mut MutableAppContext),
1128    {
1129        let type_id = TypeId::of::<G>();
1130        let id = post_inc(&mut self.next_subscription_id);
1131
1132        self.global_observations.add_callback(
1133            type_id,
1134            id,
1135            Box::new(move |cx: &mut MutableAppContext| observe(cx)),
1136        );
1137
1138        Subscription::GlobalObservation {
1139            id,
1140            type_id,
1141            observations: Some(self.global_observations.downgrade()),
1142        }
1143    }
1144
1145    pub fn observe_release<E, H, F>(&mut self, handle: &H, callback: F) -> Subscription
1146    where
1147        E: Entity,
1148        E::Event: 'static,
1149        H: Handle<E>,
1150        F: 'static + FnOnce(&E, &mut Self),
1151    {
1152        let id = post_inc(&mut self.next_subscription_id);
1153        self.release_observations
1154            .lock()
1155            .entry(handle.id())
1156            .or_default()
1157            .insert(
1158                id,
1159                Box::new(move |released, cx| {
1160                    let released = released.downcast_ref().unwrap();
1161                    callback(released, cx)
1162                }),
1163            );
1164        Subscription::ReleaseObservation {
1165            id,
1166            entity_id: handle.id(),
1167            observations: Some(Arc::downgrade(&self.release_observations)),
1168        }
1169    }
1170
1171    pub fn observe_actions<F>(&mut self, callback: F) -> Subscription
1172    where
1173        F: 'static + FnMut(TypeId, &mut MutableAppContext),
1174    {
1175        let id = post_inc(&mut self.next_subscription_id);
1176        self.action_dispatch_observations
1177            .lock()
1178            .insert(id, Box::new(callback));
1179        Subscription::ActionObservation {
1180            id,
1181            observations: Some(Arc::downgrade(&self.action_dispatch_observations)),
1182        }
1183    }
1184
1185    fn observe_window_activation<F>(&mut self, window_id: usize, callback: F) -> Subscription
1186    where
1187        F: 'static + FnMut(bool, &mut MutableAppContext) -> bool,
1188    {
1189        let subscription_id = post_inc(&mut self.next_subscription_id);
1190        self.pending_effects
1191            .push_back(Effect::WindowActivationObservation {
1192                window_id,
1193                subscription_id,
1194                callback: Box::new(callback),
1195            });
1196        Subscription::WindowActivationObservation {
1197            id: subscription_id,
1198            window_id,
1199            observations: Some(self.window_activation_observations.downgrade()),
1200        }
1201    }
1202
1203    fn observe_fullscreen<F>(&mut self, window_id: usize, callback: F) -> Subscription
1204    where
1205        F: 'static + FnMut(bool, &mut MutableAppContext) -> bool,
1206    {
1207        let subscription_id = post_inc(&mut self.next_subscription_id);
1208        self.pending_effects
1209            .push_back(Effect::WindowFullscreenObservation {
1210                window_id,
1211                subscription_id,
1212                callback: Box::new(callback),
1213            });
1214        Subscription::WindowFullscreenObservation {
1215            id: subscription_id,
1216            window_id,
1217            observations: Some(self.window_activation_observations.downgrade()),
1218        }
1219    }
1220
1221    pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut MutableAppContext)) {
1222        self.pending_effects.push_back(Effect::Deferred {
1223            callback: Box::new(callback),
1224            after_window_update: false,
1225        })
1226    }
1227
1228    pub fn after_window_update(&mut self, callback: impl 'static + FnOnce(&mut MutableAppContext)) {
1229        self.pending_effects.push_back(Effect::Deferred {
1230            callback: Box::new(callback),
1231            after_window_update: true,
1232        })
1233    }
1234
1235    pub(crate) fn notify_model(&mut self, model_id: usize) {
1236        if self.pending_notifications.insert(model_id) {
1237            self.pending_effects
1238                .push_back(Effect::ModelNotification { model_id });
1239        }
1240    }
1241
1242    pub(crate) fn notify_view(&mut self, window_id: usize, view_id: usize) {
1243        if self.pending_notifications.insert(view_id) {
1244            self.pending_effects
1245                .push_back(Effect::ViewNotification { window_id, view_id });
1246        }
1247    }
1248
1249    pub(crate) fn notify_global(&mut self, type_id: TypeId) {
1250        if self.pending_global_notifications.insert(type_id) {
1251            self.pending_effects
1252                .push_back(Effect::GlobalNotification { type_id });
1253        }
1254    }
1255
1256    pub(crate) fn name_for_view(&self, window_id: usize, view_id: usize) -> Option<&str> {
1257        self.views
1258            .get(&(window_id, view_id))
1259            .map(|view| view.ui_name())
1260    }
1261
1262    pub fn all_action_names<'a>(&'a self) -> impl Iterator<Item = &'static str> + 'a {
1263        self.action_deserializers.keys().copied()
1264    }
1265
1266    pub fn available_actions(
1267        &self,
1268        window_id: usize,
1269        view_id: usize,
1270    ) -> impl Iterator<Item = (&'static str, Box<dyn Action>, SmallVec<[&Binding; 1]>)> {
1271        let mut action_types: HashSet<_> = self.global_actions.keys().copied().collect();
1272
1273        for view_id in self.parents(window_id, view_id) {
1274            if let Some(view) = self.views.get(&(window_id, view_id)) {
1275                let view_type = view.as_any().type_id();
1276                if let Some(actions) = self.actions.get(&view_type) {
1277                    action_types.extend(actions.keys().copied());
1278                }
1279            }
1280        }
1281
1282        self.action_deserializers
1283            .iter()
1284            .filter_map(move |(name, (type_id, deserialize))| {
1285                if action_types.contains(type_id) {
1286                    Some((
1287                        *name,
1288                        deserialize("{}").ok()?,
1289                        self.keystroke_matcher
1290                            .bindings_for_action_type(*type_id)
1291                            .collect(),
1292                    ))
1293                } else {
1294                    None
1295                }
1296            })
1297    }
1298
1299    pub fn is_action_available(&self, action: &dyn Action) -> bool {
1300        let action_type = action.as_any().type_id();
1301        if let Some(window_id) = self.cx.platform.key_window_id() {
1302            if let Some(focused_view_id) = self.focused_view_id(window_id) {
1303                for view_id in self.parents(window_id, focused_view_id) {
1304                    if let Some(view) = self.views.get(&(window_id, view_id)) {
1305                        let view_type = view.as_any().type_id();
1306                        if let Some(actions) = self.actions.get(&view_type) {
1307                            if actions.contains_key(&action_type) {
1308                                return true;
1309                            }
1310                        }
1311                    }
1312                }
1313            }
1314        }
1315        self.global_actions.contains_key(&action_type)
1316    }
1317
1318    /// Return keystrokes that would dispatch the given action closest to the focused view, if there are any.
1319    pub(crate) fn keystrokes_for_action(
1320        &self,
1321        window_id: usize,
1322        dispatch_path: &[usize],
1323        action: &dyn Action,
1324    ) -> Option<SmallVec<[Keystroke; 2]>> {
1325        for view_id in dispatch_path.iter().rev() {
1326            let view = self
1327                .cx
1328                .views
1329                .get(&(window_id, *view_id))
1330                .expect("view in responder chain does not exist");
1331            let cx = view.keymap_context(self.as_ref());
1332            let keystrokes = self.keystroke_matcher.keystrokes_for_action(action, &cx);
1333            if keystrokes.is_some() {
1334                return keystrokes;
1335            }
1336        }
1337
1338        None
1339    }
1340
1341    // Traverses the parent tree. Walks down the tree toward the passed
1342    // view calling visit with true. Then walks back up the tree calling visit with false.
1343    // If `visit` returns false this function will immediately return.
1344    // Returns a bool indicating if the traversal was completed early.
1345    fn visit_dispatch_path(
1346        &mut self,
1347        window_id: usize,
1348        view_id: usize,
1349        mut visit: impl FnMut(usize, bool, &mut MutableAppContext) -> bool,
1350    ) -> bool {
1351        // List of view ids from the leaf to the root of the window
1352        let path = self.parents(window_id, view_id).collect::<Vec<_>>();
1353
1354        // Walk down from the root to the leaf calling visit with capture_phase = true
1355        for view_id in path.iter().rev() {
1356            if !visit(*view_id, true, self) {
1357                return false;
1358            }
1359        }
1360
1361        // Walk up from the leaf to the root calling visit with capture_phase = false
1362        for view_id in path.iter() {
1363            if !visit(*view_id, false, self) {
1364                return false;
1365            }
1366        }
1367
1368        true
1369    }
1370
1371    // Returns an iterator over all of the view ids from the passed view up to the root of the window
1372    // Includes the passed view itself
1373    fn parents(&self, window_id: usize, mut view_id: usize) -> impl Iterator<Item = usize> + '_ {
1374        std::iter::once(view_id)
1375            .into_iter()
1376            .chain(std::iter::from_fn(move || {
1377                if let Some(ParentId::View(parent_id)) = self.parents.get(&(window_id, view_id)) {
1378                    view_id = *parent_id;
1379                    Some(view_id)
1380                } else {
1381                    None
1382                }
1383            }))
1384    }
1385
1386    fn actions_mut(
1387        &mut self,
1388        capture_phase: bool,
1389    ) -> &mut HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>> {
1390        if capture_phase {
1391            &mut self.capture_actions
1392        } else {
1393            &mut self.actions
1394        }
1395    }
1396
1397    pub fn dispatch_global_action<A: Action>(&mut self, action: A) {
1398        self.dispatch_global_action_any(&action);
1399    }
1400
1401    fn dispatch_global_action_any(&mut self, action: &dyn Action) -> bool {
1402        self.update(|this| {
1403            if let Some((name, mut handler)) = this.global_actions.remove_entry(&action.id()) {
1404                handler(action, this);
1405                this.global_actions.insert(name, handler);
1406                true
1407            } else {
1408                false
1409            }
1410        })
1411    }
1412
1413    pub fn add_bindings<T: IntoIterator<Item = keymap::Binding>>(&mut self, bindings: T) {
1414        self.keystroke_matcher.add_bindings(bindings);
1415    }
1416
1417    pub fn clear_bindings(&mut self) {
1418        self.keystroke_matcher.clear_bindings();
1419    }
1420
1421    pub fn dispatch_keystroke(&mut self, window_id: usize, keystroke: &Keystroke) -> bool {
1422        let mut pending = false;
1423
1424        if let Some(focused_view_id) = self.focused_view_id(window_id) {
1425            for view_id in self.parents(window_id, focused_view_id).collect::<Vec<_>>() {
1426                let keymap_context = self
1427                    .cx
1428                    .views
1429                    .get(&(window_id, view_id))
1430                    .unwrap()
1431                    .keymap_context(self.as_ref());
1432
1433                match self.keystroke_matcher.push_keystroke(
1434                    keystroke.clone(),
1435                    view_id,
1436                    &keymap_context,
1437                ) {
1438                    MatchResult::None => {}
1439                    MatchResult::Pending => pending = true,
1440                    MatchResult::Action(action) => {
1441                        if self.handle_dispatch_action_from_effect(
1442                            window_id,
1443                            Some(view_id),
1444                            action.as_ref(),
1445                        ) {
1446                            self.keystroke_matcher.clear_pending();
1447                            return true;
1448                        }
1449                    }
1450                }
1451            }
1452        }
1453
1454        pending
1455    }
1456
1457    pub fn default_global<T: 'static + Default>(&mut self) -> &T {
1458        let type_id = TypeId::of::<T>();
1459        self.update(|this| {
1460            if let Entry::Vacant(entry) = this.cx.globals.entry(type_id) {
1461                entry.insert(Box::new(T::default()));
1462                this.notify_global(type_id);
1463            }
1464        });
1465        self.globals.get(&type_id).unwrap().downcast_ref().unwrap()
1466    }
1467
1468    pub fn set_global<T: 'static>(&mut self, state: T) {
1469        self.update(|this| {
1470            let type_id = TypeId::of::<T>();
1471            this.cx.globals.insert(type_id, Box::new(state));
1472            this.notify_global(type_id);
1473        });
1474    }
1475
1476    pub fn update_default_global<T, F, U>(&mut self, update: F) -> U
1477    where
1478        T: 'static + Default,
1479        F: FnOnce(&mut T, &mut MutableAppContext) -> U,
1480    {
1481        self.update(|this| {
1482            let type_id = TypeId::of::<T>();
1483            let mut state = this
1484                .cx
1485                .globals
1486                .remove(&type_id)
1487                .unwrap_or_else(|| Box::new(T::default()));
1488            let result = update(state.downcast_mut().unwrap(), this);
1489            this.cx.globals.insert(type_id, state);
1490            this.notify_global(type_id);
1491            result
1492        })
1493    }
1494
1495    pub fn update_global<T, F, U>(&mut self, update: F) -> U
1496    where
1497        T: 'static,
1498        F: FnOnce(&mut T, &mut MutableAppContext) -> U,
1499    {
1500        self.update(|this| {
1501            let type_id = TypeId::of::<T>();
1502            if let Some(mut state) = this.cx.globals.remove(&type_id) {
1503                let result = update(state.downcast_mut().unwrap(), this);
1504                this.cx.globals.insert(type_id, state);
1505                this.notify_global(type_id);
1506                result
1507            } else {
1508                panic!("No global added for {}", std::any::type_name::<T>());
1509            }
1510        })
1511    }
1512
1513    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
1514    where
1515        T: Entity,
1516        F: FnOnce(&mut ModelContext<T>) -> T,
1517    {
1518        self.update(|this| {
1519            let model_id = post_inc(&mut this.next_entity_id);
1520            let handle = ModelHandle::new(model_id, &this.cx.ref_counts);
1521            let mut cx = ModelContext::new(this, model_id);
1522            let model = build_model(&mut cx);
1523            this.cx.models.insert(model_id, Box::new(model));
1524            handle
1525        })
1526    }
1527
1528    pub fn add_window<T, F>(
1529        &mut self,
1530        window_options: WindowOptions,
1531        build_root_view: F,
1532    ) -> (usize, ViewHandle<T>)
1533    where
1534        T: View,
1535        F: FnOnce(&mut ViewContext<T>) -> T,
1536    {
1537        self.update(|this| {
1538            let window_id = post_inc(&mut this.next_window_id);
1539            let root_view = this
1540                .build_and_insert_view(window_id, ParentId::Root, |cx| Some(build_root_view(cx)))
1541                .unwrap();
1542            this.cx.windows.insert(
1543                window_id,
1544                Window {
1545                    root_view: root_view.clone().into(),
1546                    focused_view_id: Some(root_view.id()),
1547                    is_active: false,
1548                    invalidation: None,
1549                    is_fullscreen: false,
1550                },
1551            );
1552            root_view.update(this, |view, cx| view.on_focus_in(cx.handle().into(), cx));
1553
1554            let window =
1555                this.cx
1556                    .platform
1557                    .open_window(window_id, window_options, this.foreground.clone());
1558            this.register_platform_window(window_id, window);
1559
1560            (window_id, root_view)
1561        })
1562    }
1563
1564    pub fn add_status_bar_item<T, F>(&mut self, build_root_view: F) -> (usize, ViewHandle<T>)
1565    where
1566        T: View,
1567        F: FnOnce(&mut ViewContext<T>) -> T,
1568    {
1569        self.update(|this| {
1570            let window_id = post_inc(&mut this.next_window_id);
1571            let root_view = this
1572                .build_and_insert_view(window_id, ParentId::Root, |cx| Some(build_root_view(cx)))
1573                .unwrap();
1574            this.cx.windows.insert(
1575                window_id,
1576                Window {
1577                    root_view: root_view.clone().into(),
1578                    focused_view_id: Some(root_view.id()),
1579                    is_active: false,
1580                    invalidation: None,
1581                    is_fullscreen: false,
1582                },
1583            );
1584            root_view.update(this, |view, cx| view.on_focus_in(cx.handle().into(), cx));
1585
1586            let status_item = this.cx.platform.add_status_item();
1587            this.register_platform_window(window_id, status_item);
1588
1589            (window_id, root_view)
1590        })
1591    }
1592
1593    fn register_platform_window(
1594        &mut self,
1595        window_id: usize,
1596        mut window: Box<dyn platform::Window>,
1597    ) {
1598        let presenter = Rc::new(RefCell::new(self.build_presenter(
1599            window_id,
1600            window.titlebar_height(),
1601            window.appearance(),
1602        )));
1603
1604        {
1605            let mut app = self.upgrade();
1606            let presenter = Rc::downgrade(&presenter);
1607
1608            window.on_event(Box::new(move |event| {
1609                app.update(|cx| {
1610                    if let Some(presenter) = presenter.upgrade() {
1611                        if let Event::KeyDown(KeyDownEvent { keystroke, .. }) = &event {
1612                            if cx.dispatch_keystroke(window_id, keystroke) {
1613                                return true;
1614                            }
1615                        }
1616
1617                        presenter.borrow_mut().dispatch_event(event, false, cx)
1618                    } else {
1619                        false
1620                    }
1621                })
1622            }));
1623        }
1624
1625        {
1626            let mut app = self.upgrade();
1627            window.on_active_status_change(Box::new(move |is_active| {
1628                app.update(|cx| cx.window_changed_active_status(window_id, is_active))
1629            }));
1630        }
1631
1632        {
1633            let mut app = self.upgrade();
1634            window.on_resize(Box::new(move || {
1635                app.update(|cx| cx.window_was_resized(window_id))
1636            }));
1637        }
1638
1639        {
1640            let mut app = self.upgrade();
1641            window.on_fullscreen(Box::new(move |is_fullscreen| {
1642                app.update(|cx| cx.window_was_fullscreen_changed(window_id, is_fullscreen))
1643            }));
1644        }
1645
1646        {
1647            let mut app = self.upgrade();
1648            window.on_close(Box::new(move || {
1649                app.update(|cx| cx.remove_window(window_id));
1650            }));
1651        }
1652
1653        {
1654            let mut app = self.upgrade();
1655            window.on_appearance_changed(Box::new(move || app.update(|cx| cx.refresh_windows())));
1656        }
1657
1658        window.set_input_handler(Box::new(WindowInputHandler {
1659            app: self.upgrade().0,
1660            window_id,
1661        }));
1662
1663        let scene = presenter.borrow_mut().build_scene(
1664            window.content_size(),
1665            window.scale_factor(),
1666            false,
1667            self,
1668        );
1669        window.present_scene(scene);
1670        self.presenters_and_platform_windows
1671            .insert(window_id, (presenter.clone(), window));
1672    }
1673
1674    pub fn replace_root_view<T, F>(&mut self, window_id: usize, build_root_view: F) -> ViewHandle<T>
1675    where
1676        T: View,
1677        F: FnOnce(&mut ViewContext<T>) -> T,
1678    {
1679        self.update(|this| {
1680            let root_view = this
1681                .build_and_insert_view(window_id, ParentId::Root, |cx| Some(build_root_view(cx)))
1682                .unwrap();
1683            let window = this.cx.windows.get_mut(&window_id).unwrap();
1684            window.root_view = root_view.clone().into();
1685            window.focused_view_id = Some(root_view.id());
1686            root_view
1687        })
1688    }
1689
1690    pub fn remove_window(&mut self, window_id: usize) {
1691        self.cx.windows.remove(&window_id);
1692        self.presenters_and_platform_windows.remove(&window_id);
1693        self.flush_effects();
1694    }
1695
1696    pub fn build_presenter(
1697        &mut self,
1698        window_id: usize,
1699        titlebar_height: f32,
1700        appearance: Appearance,
1701    ) -> Presenter {
1702        Presenter::new(
1703            window_id,
1704            titlebar_height,
1705            appearance,
1706            self.cx.font_cache.clone(),
1707            TextLayoutCache::new(self.cx.platform.fonts()),
1708            self.assets.clone(),
1709            self,
1710        )
1711    }
1712
1713    pub fn add_view<T, F>(
1714        &mut self,
1715        parent_handle: impl Into<AnyViewHandle>,
1716        build_view: F,
1717    ) -> ViewHandle<T>
1718    where
1719        T: View,
1720        F: FnOnce(&mut ViewContext<T>) -> T,
1721    {
1722        let parent_handle = parent_handle.into();
1723        self.build_and_insert_view(
1724            parent_handle.window_id,
1725            ParentId::View(parent_handle.view_id),
1726            |cx| Some(build_view(cx)),
1727        )
1728        .unwrap()
1729    }
1730
1731    pub fn add_option_view<T, F>(
1732        &mut self,
1733        parent_handle: impl Into<AnyViewHandle>,
1734        build_view: F,
1735    ) -> Option<ViewHandle<T>>
1736    where
1737        T: View,
1738        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
1739    {
1740        let parent_handle = parent_handle.into();
1741        self.build_and_insert_view(
1742            parent_handle.window_id,
1743            ParentId::View(parent_handle.view_id),
1744            build_view,
1745        )
1746    }
1747
1748    pub(crate) fn build_and_insert_view<T, F>(
1749        &mut self,
1750        window_id: usize,
1751        parent_id: ParentId,
1752        build_view: F,
1753    ) -> Option<ViewHandle<T>>
1754    where
1755        T: View,
1756        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
1757    {
1758        self.update(|this| {
1759            let view_id = post_inc(&mut this.next_entity_id);
1760            let mut cx = ViewContext::new(this, window_id, view_id);
1761            let handle = if let Some(view) = build_view(&mut cx) {
1762                this.cx.views.insert((window_id, view_id), Box::new(view));
1763                this.cx.parents.insert((window_id, view_id), parent_id);
1764                if let Some(window) = this.cx.windows.get_mut(&window_id) {
1765                    window
1766                        .invalidation
1767                        .get_or_insert_with(Default::default)
1768                        .updated
1769                        .insert(view_id);
1770                }
1771                Some(ViewHandle::new(window_id, view_id, &this.cx.ref_counts))
1772            } else {
1773                None
1774            };
1775            handle
1776        })
1777    }
1778
1779    fn remove_dropped_entities(&mut self) {
1780        loop {
1781            let (dropped_models, dropped_views, dropped_element_states) =
1782                self.cx.ref_counts.lock().take_dropped();
1783            if dropped_models.is_empty()
1784                && dropped_views.is_empty()
1785                && dropped_element_states.is_empty()
1786            {
1787                break;
1788            }
1789
1790            for model_id in dropped_models {
1791                self.subscriptions.remove(model_id);
1792                self.observations.remove(model_id);
1793                let mut model = self.cx.models.remove(&model_id).unwrap();
1794                model.release(self);
1795                self.pending_effects
1796                    .push_back(Effect::ModelRelease { model_id, model });
1797            }
1798
1799            for (window_id, view_id) in dropped_views {
1800                self.subscriptions.remove(view_id);
1801                self.observations.remove(view_id);
1802                let mut view = self.cx.views.remove(&(window_id, view_id)).unwrap();
1803                view.release(self);
1804                let change_focus_to = self.cx.windows.get_mut(&window_id).and_then(|window| {
1805                    window
1806                        .invalidation
1807                        .get_or_insert_with(Default::default)
1808                        .removed
1809                        .push(view_id);
1810                    if window.focused_view_id == Some(view_id) {
1811                        Some(window.root_view.id())
1812                    } else {
1813                        None
1814                    }
1815                });
1816                self.cx.parents.remove(&(window_id, view_id));
1817
1818                if let Some(view_id) = change_focus_to {
1819                    self.handle_focus_effect(window_id, Some(view_id));
1820                }
1821
1822                self.pending_effects
1823                    .push_back(Effect::ViewRelease { view_id, view });
1824            }
1825
1826            for key in dropped_element_states {
1827                self.cx.element_states.remove(&key);
1828            }
1829        }
1830    }
1831
1832    fn flush_effects(&mut self) {
1833        self.pending_flushes = self.pending_flushes.saturating_sub(1);
1834        let mut after_window_update_callbacks = Vec::new();
1835
1836        if !self.flushing_effects && self.pending_flushes == 0 {
1837            self.flushing_effects = true;
1838
1839            let mut refreshing = false;
1840            loop {
1841                if let Some(effect) = self.pending_effects.pop_front() {
1842                    if let Some(pending_focus_index) = self.pending_focus_index.as_mut() {
1843                        *pending_focus_index = pending_focus_index.saturating_sub(1);
1844                    }
1845                    match effect {
1846                        Effect::Subscription {
1847                            entity_id,
1848                            subscription_id,
1849                            callback,
1850                        } => self.subscriptions.add_or_remove_callback(
1851                            entity_id,
1852                            subscription_id,
1853                            callback,
1854                        ),
1855
1856                        Effect::Event { entity_id, payload } => {
1857                            let mut subscriptions = self.subscriptions.clone();
1858                            subscriptions.emit_and_cleanup(entity_id, self, |callback, this| {
1859                                callback(payload.as_ref(), this)
1860                            })
1861                        }
1862
1863                        Effect::GlobalSubscription {
1864                            type_id,
1865                            subscription_id,
1866                            callback,
1867                        } => self.global_subscriptions.add_or_remove_callback(
1868                            type_id,
1869                            subscription_id,
1870                            callback,
1871                        ),
1872
1873                        Effect::GlobalEvent { payload } => self.emit_global_event(payload),
1874
1875                        Effect::Observation {
1876                            entity_id,
1877                            subscription_id,
1878                            callback,
1879                        } => self.observations.add_or_remove_callback(
1880                            entity_id,
1881                            subscription_id,
1882                            callback,
1883                        ),
1884
1885                        Effect::ModelNotification { model_id } => {
1886                            let mut observations = self.observations.clone();
1887                            observations
1888                                .emit_and_cleanup(model_id, self, |callback, this| callback(this));
1889                        }
1890
1891                        Effect::ViewNotification { window_id, view_id } => {
1892                            self.handle_view_notification_effect(window_id, view_id)
1893                        }
1894
1895                        Effect::GlobalNotification { type_id } => {
1896                            let mut subscriptions = self.global_observations.clone();
1897                            subscriptions.emit_and_cleanup(type_id, self, |callback, this| {
1898                                callback(this);
1899                                true
1900                            });
1901                        }
1902
1903                        Effect::Deferred {
1904                            callback,
1905                            after_window_update,
1906                        } => {
1907                            if after_window_update {
1908                                after_window_update_callbacks.push(callback);
1909                            } else {
1910                                callback(self)
1911                            }
1912                        }
1913
1914                        Effect::ModelRelease { model_id, model } => {
1915                            self.handle_entity_release_effect(model_id, model.as_any())
1916                        }
1917
1918                        Effect::ViewRelease { view_id, view } => {
1919                            self.handle_entity_release_effect(view_id, view.as_any())
1920                        }
1921
1922                        Effect::Focus { window_id, view_id } => {
1923                            self.handle_focus_effect(window_id, view_id);
1924                        }
1925
1926                        Effect::FocusObservation {
1927                            view_id,
1928                            subscription_id,
1929                            callback,
1930                        } => {
1931                            self.focus_observations.add_or_remove_callback(
1932                                view_id,
1933                                subscription_id,
1934                                callback,
1935                            );
1936                        }
1937
1938                        Effect::ResizeWindow { window_id } => {
1939                            if let Some(window) = self.cx.windows.get_mut(&window_id) {
1940                                window
1941                                    .invalidation
1942                                    .get_or_insert(WindowInvalidation::default());
1943                            }
1944                        }
1945
1946                        Effect::WindowActivationObservation {
1947                            window_id,
1948                            subscription_id,
1949                            callback,
1950                        } => self.window_activation_observations.add_or_remove_callback(
1951                            window_id,
1952                            subscription_id,
1953                            callback,
1954                        ),
1955
1956                        Effect::ActivateWindow {
1957                            window_id,
1958                            is_active,
1959                        } => self.handle_window_activation_effect(window_id, is_active),
1960
1961                        Effect::WindowFullscreenObservation {
1962                            window_id,
1963                            subscription_id,
1964                            callback,
1965                        } => self.window_fullscreen_observations.add_or_remove_callback(
1966                            window_id,
1967                            subscription_id,
1968                            callback,
1969                        ),
1970
1971                        Effect::FullscreenWindow {
1972                            window_id,
1973                            is_fullscreen,
1974                        } => self.handle_fullscreen_effect(window_id, is_fullscreen),
1975
1976                        Effect::RefreshWindows => {
1977                            refreshing = true;
1978                        }
1979                        Effect::DispatchActionFrom {
1980                            window_id,
1981                            view_id,
1982                            action,
1983                        } => {
1984                            self.handle_dispatch_action_from_effect(
1985                                window_id,
1986                                Some(view_id),
1987                                action.as_ref(),
1988                            );
1989                        }
1990                        Effect::ActionDispatchNotification { action_id } => {
1991                            self.handle_action_dispatch_notification_effect(action_id)
1992                        }
1993                        Effect::WindowShouldCloseSubscription {
1994                            window_id,
1995                            callback,
1996                        } => {
1997                            self.handle_window_should_close_subscription_effect(window_id, callback)
1998                        }
1999                    }
2000                    self.pending_notifications.clear();
2001                    self.remove_dropped_entities();
2002                } else {
2003                    self.remove_dropped_entities();
2004                    if refreshing {
2005                        self.perform_window_refresh();
2006                    } else {
2007                        self.update_windows();
2008                    }
2009
2010                    if self.pending_effects.is_empty() {
2011                        for callback in after_window_update_callbacks.drain(..) {
2012                            callback(self);
2013                        }
2014
2015                        if self.pending_effects.is_empty() {
2016                            self.flushing_effects = false;
2017                            self.pending_notifications.clear();
2018                            self.pending_global_notifications.clear();
2019                            break;
2020                        }
2021                    }
2022
2023                    refreshing = false;
2024                }
2025            }
2026        }
2027    }
2028
2029    fn update_windows(&mut self) {
2030        let mut invalidations: HashMap<_, _> = Default::default();
2031        for (window_id, window) in &mut self.cx.windows {
2032            if let Some(invalidation) = window.invalidation.take() {
2033                invalidations.insert(*window_id, invalidation);
2034            }
2035        }
2036
2037        for (window_id, mut invalidation) in invalidations {
2038            if let Some((presenter, mut window)) =
2039                self.presenters_and_platform_windows.remove(&window_id)
2040            {
2041                {
2042                    let mut presenter = presenter.borrow_mut();
2043                    presenter.invalidate(&mut invalidation, window.appearance(), self);
2044                    let scene = presenter.build_scene(
2045                        window.content_size(),
2046                        window.scale_factor(),
2047                        false,
2048                        self,
2049                    );
2050                    window.present_scene(scene);
2051                }
2052                self.presenters_and_platform_windows
2053                    .insert(window_id, (presenter, window));
2054            }
2055        }
2056    }
2057
2058    fn window_was_resized(&mut self, window_id: usize) {
2059        self.pending_effects
2060            .push_back(Effect::ResizeWindow { window_id });
2061    }
2062
2063    fn window_was_fullscreen_changed(&mut self, window_id: usize, is_fullscreen: bool) {
2064        self.pending_effects.push_back(Effect::FullscreenWindow {
2065            window_id,
2066            is_fullscreen,
2067        });
2068    }
2069
2070    fn window_changed_active_status(&mut self, window_id: usize, is_active: bool) {
2071        self.pending_effects.push_back(Effect::ActivateWindow {
2072            window_id,
2073            is_active,
2074        });
2075    }
2076
2077    pub fn refresh_windows(&mut self) {
2078        self.pending_effects.push_back(Effect::RefreshWindows);
2079    }
2080
2081    pub fn dispatch_action_at(&mut self, window_id: usize, view_id: usize, action: impl Action) {
2082        self.dispatch_any_action_at(window_id, view_id, Box::new(action));
2083    }
2084
2085    pub fn dispatch_any_action_at(
2086        &mut self,
2087        window_id: usize,
2088        view_id: usize,
2089        action: Box<dyn Action>,
2090    ) {
2091        self.pending_effects.push_back(Effect::DispatchActionFrom {
2092            window_id,
2093            view_id,
2094            action,
2095        });
2096    }
2097
2098    fn perform_window_refresh(&mut self) {
2099        let mut presenters = mem::take(&mut self.presenters_and_platform_windows);
2100        for (window_id, (presenter, window)) in &mut presenters {
2101            let mut invalidation = self
2102                .cx
2103                .windows
2104                .get_mut(window_id)
2105                .unwrap()
2106                .invalidation
2107                .take();
2108            let mut presenter = presenter.borrow_mut();
2109            presenter.refresh(
2110                invalidation.as_mut().unwrap_or(&mut Default::default()),
2111                window.appearance(),
2112                self,
2113            );
2114            let scene =
2115                presenter.build_scene(window.content_size(), window.scale_factor(), true, self);
2116            window.present_scene(scene);
2117        }
2118        self.presenters_and_platform_windows = presenters;
2119    }
2120
2121    fn emit_global_event(&mut self, payload: Box<dyn Any>) {
2122        let type_id = (&*payload).type_id();
2123
2124        let mut subscriptions = self.global_subscriptions.clone();
2125        subscriptions.emit_and_cleanup(type_id, self, |callback, this| {
2126            callback(payload.as_ref(), this);
2127            true //Always alive
2128        });
2129    }
2130
2131    fn handle_view_notification_effect(
2132        &mut self,
2133        observed_window_id: usize,
2134        observed_view_id: usize,
2135    ) {
2136        if self
2137            .cx
2138            .views
2139            .contains_key(&(observed_window_id, observed_view_id))
2140        {
2141            if let Some(window) = self.cx.windows.get_mut(&observed_window_id) {
2142                window
2143                    .invalidation
2144                    .get_or_insert_with(Default::default)
2145                    .updated
2146                    .insert(observed_view_id);
2147            }
2148
2149            let mut observations = self.observations.clone();
2150            observations.emit_and_cleanup(observed_view_id, self, |callback, this| callback(this));
2151        }
2152    }
2153
2154    fn handle_entity_release_effect(&mut self, entity_id: usize, entity: &dyn Any) {
2155        let callbacks = self.release_observations.lock().remove(&entity_id);
2156        if let Some(callbacks) = callbacks {
2157            for (_, callback) in callbacks {
2158                callback(entity, self);
2159            }
2160        }
2161    }
2162
2163    fn handle_fullscreen_effect(&mut self, window_id: usize, is_fullscreen: bool) {
2164        //Short circuit evaluation if we're already g2g
2165        if self
2166            .cx
2167            .windows
2168            .get(&window_id)
2169            .map(|w| w.is_fullscreen == is_fullscreen)
2170            .unwrap_or(false)
2171        {
2172            return;
2173        }
2174
2175        self.update(|this| {
2176            let window = this.cx.windows.get_mut(&window_id)?;
2177            window.is_fullscreen = is_fullscreen;
2178
2179            let mut observations = this.window_fullscreen_observations.clone();
2180            observations.emit_and_cleanup(window_id, this, |callback, this| {
2181                callback(is_fullscreen, this)
2182            });
2183
2184            Some(())
2185        });
2186    }
2187
2188    fn handle_window_activation_effect(&mut self, window_id: usize, active: bool) {
2189        //Short circuit evaluation if we're already g2g
2190        if self
2191            .cx
2192            .windows
2193            .get(&window_id)
2194            .map(|w| w.is_active == active)
2195            .unwrap_or(false)
2196        {
2197            return;
2198        }
2199
2200        self.update(|this| {
2201            let window = this.cx.windows.get_mut(&window_id)?;
2202            window.is_active = active;
2203
2204            //Handle focus
2205            let focused_id = window.focused_view_id?;
2206            for view_id in this.parents(window_id, focused_id).collect::<Vec<_>>() {
2207                if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) {
2208                    if active {
2209                        view.on_focus_in(this, window_id, view_id, focused_id);
2210                    } else {
2211                        view.on_focus_out(this, window_id, view_id, focused_id);
2212                    }
2213                    this.cx.views.insert((window_id, view_id), view);
2214                }
2215            }
2216
2217            let mut observations = this.window_activation_observations.clone();
2218            observations.emit_and_cleanup(window_id, this, |callback, this| callback(active, this));
2219
2220            Some(())
2221        });
2222    }
2223
2224    fn handle_focus_effect(&mut self, window_id: usize, focused_id: Option<usize>) {
2225        self.pending_focus_index.take();
2226
2227        if self
2228            .cx
2229            .windows
2230            .get(&window_id)
2231            .map(|w| w.focused_view_id)
2232            .map_or(false, |cur_focused| cur_focused == focused_id)
2233        {
2234            return;
2235        }
2236
2237        self.update(|this| {
2238            let blurred_id = this.cx.windows.get_mut(&window_id).and_then(|window| {
2239                let blurred_id = window.focused_view_id;
2240                window.focused_view_id = focused_id;
2241                blurred_id
2242            });
2243
2244            let blurred_parents = blurred_id
2245                .map(|blurred_id| this.parents(window_id, blurred_id).collect::<Vec<_>>())
2246                .unwrap_or_default();
2247            let focused_parents = focused_id
2248                .map(|focused_id| this.parents(window_id, focused_id).collect::<Vec<_>>())
2249                .unwrap_or_default();
2250
2251            if let Some(blurred_id) = blurred_id {
2252                for view_id in blurred_parents.iter().copied() {
2253                    if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) {
2254                        view.on_focus_out(this, window_id, view_id, blurred_id);
2255                        this.cx.views.insert((window_id, view_id), view);
2256                    }
2257                }
2258
2259                let mut subscriptions = this.focus_observations.clone();
2260                subscriptions
2261                    .emit_and_cleanup(blurred_id, this, |callback, this| callback(false, this));
2262            }
2263
2264            if let Some(focused_id) = focused_id {
2265                for view_id in focused_parents {
2266                    if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) {
2267                        view.on_focus_in(this, window_id, view_id, focused_id);
2268                        this.cx.views.insert((window_id, view_id), view);
2269                    }
2270                }
2271
2272                let mut subscriptions = this.focus_observations.clone();
2273                subscriptions
2274                    .emit_and_cleanup(focused_id, this, |callback, this| callback(true, this));
2275            }
2276        })
2277    }
2278
2279    fn handle_dispatch_action_from_effect(
2280        &mut self,
2281        window_id: usize,
2282        view_id: Option<usize>,
2283        action: &dyn Action,
2284    ) -> bool {
2285        self.update(|this| {
2286            if let Some(view_id) = view_id {
2287                this.halt_action_dispatch = false;
2288                this.visit_dispatch_path(window_id, view_id, |view_id, capture_phase, this| {
2289                    if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) {
2290                        let type_id = view.as_any().type_id();
2291
2292                        if let Some((name, mut handlers)) = this
2293                            .actions_mut(capture_phase)
2294                            .get_mut(&type_id)
2295                            .and_then(|h| h.remove_entry(&action.id()))
2296                        {
2297                            for handler in handlers.iter_mut().rev() {
2298                                this.halt_action_dispatch = true;
2299                                handler(view.as_mut(), action, this, window_id, view_id);
2300                                if this.halt_action_dispatch {
2301                                    break;
2302                                }
2303                            }
2304                            this.actions_mut(capture_phase)
2305                                .get_mut(&type_id)
2306                                .unwrap()
2307                                .insert(name, handlers);
2308                        }
2309
2310                        this.cx.views.insert((window_id, view_id), view);
2311                    }
2312
2313                    !this.halt_action_dispatch
2314                });
2315            }
2316
2317            if !this.halt_action_dispatch {
2318                this.halt_action_dispatch = this.dispatch_global_action_any(action);
2319            }
2320
2321            this.pending_effects
2322                .push_back(Effect::ActionDispatchNotification {
2323                    action_id: action.id(),
2324                });
2325            this.halt_action_dispatch
2326        })
2327    }
2328
2329    fn handle_action_dispatch_notification_effect(&mut self, action_id: TypeId) {
2330        let mut callbacks = mem::take(&mut *self.action_dispatch_observations.lock());
2331        for callback in callbacks.values_mut() {
2332            callback(action_id, self);
2333        }
2334        self.action_dispatch_observations.lock().extend(callbacks);
2335    }
2336
2337    fn handle_window_should_close_subscription_effect(
2338        &mut self,
2339        window_id: usize,
2340        mut callback: WindowShouldCloseSubscriptionCallback,
2341    ) {
2342        let mut app = self.upgrade();
2343        if let Some((_, window)) = self.presenters_and_platform_windows.get_mut(&window_id) {
2344            window.on_should_close(Box::new(move || app.update(|cx| callback(cx))))
2345        }
2346    }
2347
2348    pub fn focus(&mut self, window_id: usize, view_id: Option<usize>) {
2349        if let Some(pending_focus_index) = self.pending_focus_index {
2350            self.pending_effects.remove(pending_focus_index);
2351        }
2352        self.pending_focus_index = Some(self.pending_effects.len());
2353        self.pending_effects
2354            .push_back(Effect::Focus { window_id, view_id });
2355    }
2356
2357    pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
2358    where
2359        F: FnOnce(AsyncAppContext) -> Fut,
2360        Fut: 'static + Future<Output = T>,
2361        T: 'static,
2362    {
2363        let future = f(self.to_async());
2364        let cx = self.to_async();
2365        self.foreground.spawn(async move {
2366            let result = future.await;
2367            cx.0.borrow_mut().flush_effects();
2368            result
2369        })
2370    }
2371
2372    pub fn to_async(&self) -> AsyncAppContext {
2373        AsyncAppContext(self.weak_self.as_ref().unwrap().upgrade().unwrap())
2374    }
2375
2376    pub fn write_to_clipboard(&self, item: ClipboardItem) {
2377        self.cx.platform.write_to_clipboard(item);
2378    }
2379
2380    pub fn read_from_clipboard(&self) -> Option<ClipboardItem> {
2381        self.cx.platform.read_from_clipboard()
2382    }
2383
2384    #[cfg(any(test, feature = "test-support"))]
2385    pub fn leak_detector(&self) -> Arc<Mutex<LeakDetector>> {
2386        self.cx.ref_counts.lock().leak_detector.clone()
2387    }
2388}
2389
2390impl ReadModel for MutableAppContext {
2391    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2392        if let Some(model) = self.cx.models.get(&handle.model_id) {
2393            model
2394                .as_any()
2395                .downcast_ref()
2396                .expect("downcast is type safe")
2397        } else {
2398            panic!("circular model reference");
2399        }
2400    }
2401}
2402
2403impl UpdateModel for MutableAppContext {
2404    fn update_model<T: Entity, V>(
2405        &mut self,
2406        handle: &ModelHandle<T>,
2407        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
2408    ) -> V {
2409        if let Some(mut model) = self.cx.models.remove(&handle.model_id) {
2410            self.update(|this| {
2411                let mut cx = ModelContext::new(this, handle.model_id);
2412                let result = update(
2413                    model
2414                        .as_any_mut()
2415                        .downcast_mut()
2416                        .expect("downcast is type safe"),
2417                    &mut cx,
2418                );
2419                this.cx.models.insert(handle.model_id, model);
2420                result
2421            })
2422        } else {
2423            panic!("circular model update");
2424        }
2425    }
2426}
2427
2428impl UpgradeModelHandle for MutableAppContext {
2429    fn upgrade_model_handle<T: Entity>(
2430        &self,
2431        handle: &WeakModelHandle<T>,
2432    ) -> Option<ModelHandle<T>> {
2433        self.cx.upgrade_model_handle(handle)
2434    }
2435
2436    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
2437        self.cx.model_handle_is_upgradable(handle)
2438    }
2439
2440    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
2441        self.cx.upgrade_any_model_handle(handle)
2442    }
2443}
2444
2445impl UpgradeViewHandle for MutableAppContext {
2446    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
2447        self.cx.upgrade_view_handle(handle)
2448    }
2449
2450    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
2451        self.cx.upgrade_any_view_handle(handle)
2452    }
2453}
2454
2455impl ReadView for MutableAppContext {
2456    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
2457        if let Some(view) = self.cx.views.get(&(handle.window_id, handle.view_id)) {
2458            view.as_any().downcast_ref().expect("downcast is type safe")
2459        } else {
2460            panic!("circular view reference for type {}", type_name::<T>());
2461        }
2462    }
2463}
2464
2465impl UpdateView for MutableAppContext {
2466    fn update_view<T, S>(
2467        &mut self,
2468        handle: &ViewHandle<T>,
2469        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
2470    ) -> S
2471    where
2472        T: View,
2473    {
2474        self.update(|this| {
2475            let mut view = this
2476                .cx
2477                .views
2478                .remove(&(handle.window_id, handle.view_id))
2479                .expect("circular view update");
2480
2481            let mut cx = ViewContext::new(this, handle.window_id, handle.view_id);
2482            let result = update(
2483                view.as_any_mut()
2484                    .downcast_mut()
2485                    .expect("downcast is type safe"),
2486                &mut cx,
2487            );
2488            this.cx
2489                .views
2490                .insert((handle.window_id, handle.view_id), view);
2491            result
2492        })
2493    }
2494}
2495
2496impl AsRef<AppContext> for MutableAppContext {
2497    fn as_ref(&self) -> &AppContext {
2498        &self.cx
2499    }
2500}
2501
2502impl Deref for MutableAppContext {
2503    type Target = AppContext;
2504
2505    fn deref(&self) -> &Self::Target {
2506        &self.cx
2507    }
2508}
2509
2510#[derive(Debug)]
2511pub enum ParentId {
2512    View(usize),
2513    Root,
2514}
2515
2516pub struct AppContext {
2517    models: HashMap<usize, Box<dyn AnyModel>>,
2518    views: HashMap<(usize, usize), Box<dyn AnyView>>,
2519    pub(crate) parents: HashMap<(usize, usize), ParentId>,
2520    windows: HashMap<usize, Window>,
2521    globals: HashMap<TypeId, Box<dyn Any>>,
2522    element_states: HashMap<ElementStateId, Box<dyn Any>>,
2523    background: Arc<executor::Background>,
2524    ref_counts: Arc<Mutex<RefCounts>>,
2525    font_cache: Arc<FontCache>,
2526    platform: Arc<dyn Platform>,
2527}
2528
2529impl AppContext {
2530    pub(crate) fn root_view(&self, window_id: usize) -> Option<AnyViewHandle> {
2531        self.windows
2532            .get(&window_id)
2533            .map(|window| window.root_view.clone())
2534    }
2535
2536    pub fn root_view_id(&self, window_id: usize) -> Option<usize> {
2537        self.windows
2538            .get(&window_id)
2539            .map(|window| window.root_view.id())
2540    }
2541
2542    pub fn focused_view_id(&self, window_id: usize) -> Option<usize> {
2543        self.windows
2544            .get(&window_id)
2545            .and_then(|window| window.focused_view_id)
2546    }
2547
2548    pub fn background(&self) -> &Arc<executor::Background> {
2549        &self.background
2550    }
2551
2552    pub fn font_cache(&self) -> &Arc<FontCache> {
2553        &self.font_cache
2554    }
2555
2556    pub fn platform(&self) -> &Arc<dyn Platform> {
2557        &self.platform
2558    }
2559
2560    pub fn has_global<T: 'static>(&self) -> bool {
2561        self.globals.contains_key(&TypeId::of::<T>())
2562    }
2563
2564    pub fn global<T: 'static>(&self) -> &T {
2565        if let Some(global) = self.globals.get(&TypeId::of::<T>()) {
2566            global.downcast_ref().unwrap()
2567        } else {
2568            panic!("no global has been added for {}", type_name::<T>());
2569        }
2570    }
2571}
2572
2573impl ReadModel for AppContext {
2574    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2575        if let Some(model) = self.models.get(&handle.model_id) {
2576            model
2577                .as_any()
2578                .downcast_ref()
2579                .expect("downcast should be type safe")
2580        } else {
2581            panic!("circular model reference");
2582        }
2583    }
2584}
2585
2586impl UpgradeModelHandle for AppContext {
2587    fn upgrade_model_handle<T: Entity>(
2588        &self,
2589        handle: &WeakModelHandle<T>,
2590    ) -> Option<ModelHandle<T>> {
2591        if self.models.contains_key(&handle.model_id) {
2592            Some(ModelHandle::new(handle.model_id, &self.ref_counts))
2593        } else {
2594            None
2595        }
2596    }
2597
2598    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
2599        self.models.contains_key(&handle.model_id)
2600    }
2601
2602    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
2603        if self.models.contains_key(&handle.model_id) {
2604            Some(AnyModelHandle::new(
2605                handle.model_id,
2606                handle.model_type,
2607                self.ref_counts.clone(),
2608            ))
2609        } else {
2610            None
2611        }
2612    }
2613}
2614
2615impl UpgradeViewHandle for AppContext {
2616    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
2617        if self.ref_counts.lock().is_entity_alive(handle.view_id) {
2618            Some(ViewHandle::new(
2619                handle.window_id,
2620                handle.view_id,
2621                &self.ref_counts,
2622            ))
2623        } else {
2624            None
2625        }
2626    }
2627
2628    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
2629        if self.ref_counts.lock().is_entity_alive(handle.view_id) {
2630            Some(AnyViewHandle::new(
2631                handle.window_id,
2632                handle.view_id,
2633                handle.view_type,
2634                self.ref_counts.clone(),
2635            ))
2636        } else {
2637            None
2638        }
2639    }
2640}
2641
2642impl ReadView for AppContext {
2643    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
2644        if let Some(view) = self.views.get(&(handle.window_id, handle.view_id)) {
2645            view.as_any()
2646                .downcast_ref()
2647                .expect("downcast should be type safe")
2648        } else {
2649            panic!("circular view reference");
2650        }
2651    }
2652}
2653
2654struct Window {
2655    root_view: AnyViewHandle,
2656    focused_view_id: Option<usize>,
2657    is_active: bool,
2658    is_fullscreen: bool,
2659    invalidation: Option<WindowInvalidation>,
2660}
2661
2662#[derive(Default, Clone)]
2663pub struct WindowInvalidation {
2664    pub updated: HashSet<usize>,
2665    pub removed: Vec<usize>,
2666}
2667
2668pub enum Effect {
2669    Subscription {
2670        entity_id: usize,
2671        subscription_id: usize,
2672        callback: SubscriptionCallback,
2673    },
2674    Event {
2675        entity_id: usize,
2676        payload: Box<dyn Any>,
2677    },
2678    GlobalSubscription {
2679        type_id: TypeId,
2680        subscription_id: usize,
2681        callback: GlobalSubscriptionCallback,
2682    },
2683    GlobalEvent {
2684        payload: Box<dyn Any>,
2685    },
2686    Observation {
2687        entity_id: usize,
2688        subscription_id: usize,
2689        callback: ObservationCallback,
2690    },
2691    ModelNotification {
2692        model_id: usize,
2693    },
2694    ViewNotification {
2695        window_id: usize,
2696        view_id: usize,
2697    },
2698    Deferred {
2699        callback: Box<dyn FnOnce(&mut MutableAppContext)>,
2700        after_window_update: bool,
2701    },
2702    GlobalNotification {
2703        type_id: TypeId,
2704    },
2705    ModelRelease {
2706        model_id: usize,
2707        model: Box<dyn AnyModel>,
2708    },
2709    ViewRelease {
2710        view_id: usize,
2711        view: Box<dyn AnyView>,
2712    },
2713    Focus {
2714        window_id: usize,
2715        view_id: Option<usize>,
2716    },
2717    FocusObservation {
2718        view_id: usize,
2719        subscription_id: usize,
2720        callback: FocusObservationCallback,
2721    },
2722    ResizeWindow {
2723        window_id: usize,
2724    },
2725    FullscreenWindow {
2726        window_id: usize,
2727        is_fullscreen: bool,
2728    },
2729    ActivateWindow {
2730        window_id: usize,
2731        is_active: bool,
2732    },
2733    WindowActivationObservation {
2734        window_id: usize,
2735        subscription_id: usize,
2736        callback: WindowActivationCallback,
2737    },
2738    WindowFullscreenObservation {
2739        window_id: usize,
2740        subscription_id: usize,
2741        callback: WindowFullscreenCallback,
2742    },
2743    RefreshWindows,
2744    DispatchActionFrom {
2745        window_id: usize,
2746        view_id: usize,
2747        action: Box<dyn Action>,
2748    },
2749    ActionDispatchNotification {
2750        action_id: TypeId,
2751    },
2752    WindowShouldCloseSubscription {
2753        window_id: usize,
2754        callback: WindowShouldCloseSubscriptionCallback,
2755    },
2756}
2757
2758impl Debug for Effect {
2759    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2760        match self {
2761            Effect::Subscription {
2762                entity_id,
2763                subscription_id,
2764                ..
2765            } => f
2766                .debug_struct("Effect::Subscribe")
2767                .field("entity_id", entity_id)
2768                .field("subscription_id", subscription_id)
2769                .finish(),
2770            Effect::Event { entity_id, .. } => f
2771                .debug_struct("Effect::Event")
2772                .field("entity_id", entity_id)
2773                .finish(),
2774            Effect::GlobalSubscription {
2775                type_id,
2776                subscription_id,
2777                ..
2778            } => f
2779                .debug_struct("Effect::Subscribe")
2780                .field("type_id", type_id)
2781                .field("subscription_id", subscription_id)
2782                .finish(),
2783            Effect::GlobalEvent { payload, .. } => f
2784                .debug_struct("Effect::GlobalEvent")
2785                .field("type_id", &(&*payload).type_id())
2786                .finish(),
2787            Effect::Observation {
2788                entity_id,
2789                subscription_id,
2790                ..
2791            } => f
2792                .debug_struct("Effect::Observation")
2793                .field("entity_id", entity_id)
2794                .field("subscription_id", subscription_id)
2795                .finish(),
2796            Effect::ModelNotification { model_id } => f
2797                .debug_struct("Effect::ModelNotification")
2798                .field("model_id", model_id)
2799                .finish(),
2800            Effect::ViewNotification { window_id, view_id } => f
2801                .debug_struct("Effect::ViewNotification")
2802                .field("window_id", window_id)
2803                .field("view_id", view_id)
2804                .finish(),
2805            Effect::GlobalNotification { type_id } => f
2806                .debug_struct("Effect::GlobalNotification")
2807                .field("type_id", type_id)
2808                .finish(),
2809            Effect::Deferred { .. } => f.debug_struct("Effect::Deferred").finish(),
2810            Effect::ModelRelease { model_id, .. } => f
2811                .debug_struct("Effect::ModelRelease")
2812                .field("model_id", model_id)
2813                .finish(),
2814            Effect::ViewRelease { view_id, .. } => f
2815                .debug_struct("Effect::ViewRelease")
2816                .field("view_id", view_id)
2817                .finish(),
2818            Effect::Focus { window_id, view_id } => f
2819                .debug_struct("Effect::Focus")
2820                .field("window_id", window_id)
2821                .field("view_id", view_id)
2822                .finish(),
2823            Effect::FocusObservation {
2824                view_id,
2825                subscription_id,
2826                ..
2827            } => f
2828                .debug_struct("Effect::FocusObservation")
2829                .field("view_id", view_id)
2830                .field("subscription_id", subscription_id)
2831                .finish(),
2832            Effect::DispatchActionFrom {
2833                window_id, view_id, ..
2834            } => f
2835                .debug_struct("Effect::DispatchActionFrom")
2836                .field("window_id", window_id)
2837                .field("view_id", view_id)
2838                .finish(),
2839            Effect::ActionDispatchNotification { action_id, .. } => f
2840                .debug_struct("Effect::ActionDispatchNotification")
2841                .field("action_id", action_id)
2842                .finish(),
2843            Effect::ResizeWindow { window_id } => f
2844                .debug_struct("Effect::RefreshWindow")
2845                .field("window_id", window_id)
2846                .finish(),
2847            Effect::WindowActivationObservation {
2848                window_id,
2849                subscription_id,
2850                ..
2851            } => f
2852                .debug_struct("Effect::WindowActivationObservation")
2853                .field("window_id", window_id)
2854                .field("subscription_id", subscription_id)
2855                .finish(),
2856            Effect::ActivateWindow {
2857                window_id,
2858                is_active,
2859            } => f
2860                .debug_struct("Effect::ActivateWindow")
2861                .field("window_id", window_id)
2862                .field("is_active", is_active)
2863                .finish(),
2864            Effect::FullscreenWindow {
2865                window_id,
2866                is_fullscreen,
2867            } => f
2868                .debug_struct("Effect::FullscreenWindow")
2869                .field("window_id", window_id)
2870                .field("is_fullscreen", is_fullscreen)
2871                .finish(),
2872            Effect::WindowFullscreenObservation {
2873                window_id,
2874                subscription_id,
2875                callback: _,
2876            } => f
2877                .debug_struct("Effect::WindowFullscreenObservation")
2878                .field("window_id", window_id)
2879                .field("subscription_id", subscription_id)
2880                .finish(),
2881            Effect::RefreshWindows => f.debug_struct("Effect::FullViewRefresh").finish(),
2882            Effect::WindowShouldCloseSubscription { window_id, .. } => f
2883                .debug_struct("Effect::WindowShouldCloseSubscription")
2884                .field("window_id", window_id)
2885                .finish(),
2886        }
2887    }
2888}
2889
2890pub trait AnyModel {
2891    fn as_any(&self) -> &dyn Any;
2892    fn as_any_mut(&mut self) -> &mut dyn Any;
2893    fn release(&mut self, cx: &mut MutableAppContext);
2894    fn app_will_quit(
2895        &mut self,
2896        cx: &mut MutableAppContext,
2897    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
2898}
2899
2900impl<T> AnyModel for T
2901where
2902    T: Entity,
2903{
2904    fn as_any(&self) -> &dyn Any {
2905        self
2906    }
2907
2908    fn as_any_mut(&mut self) -> &mut dyn Any {
2909        self
2910    }
2911
2912    fn release(&mut self, cx: &mut MutableAppContext) {
2913        self.release(cx);
2914    }
2915
2916    fn app_will_quit(
2917        &mut self,
2918        cx: &mut MutableAppContext,
2919    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
2920        self.app_will_quit(cx)
2921    }
2922}
2923
2924pub trait AnyView {
2925    fn as_any(&self) -> &dyn Any;
2926    fn as_any_mut(&mut self) -> &mut dyn Any;
2927    fn release(&mut self, cx: &mut MutableAppContext);
2928    fn app_will_quit(
2929        &mut self,
2930        cx: &mut MutableAppContext,
2931    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
2932    fn ui_name(&self) -> &'static str;
2933    fn render(&mut self, params: RenderParams, cx: &mut MutableAppContext) -> ElementBox;
2934    fn on_focus_in(
2935        &mut self,
2936        cx: &mut MutableAppContext,
2937        window_id: usize,
2938        view_id: usize,
2939        focused_id: usize,
2940    );
2941    fn on_focus_out(
2942        &mut self,
2943        cx: &mut MutableAppContext,
2944        window_id: usize,
2945        view_id: usize,
2946        focused_id: usize,
2947    );
2948    fn keymap_context(&self, cx: &AppContext) -> keymap::Context;
2949    fn debug_json(&self, cx: &AppContext) -> serde_json::Value;
2950
2951    fn text_for_range(&self, range: Range<usize>, cx: &AppContext) -> Option<String>;
2952    fn selected_text_range(&self, cx: &AppContext) -> Option<Range<usize>>;
2953    fn marked_text_range(&self, cx: &AppContext) -> Option<Range<usize>>;
2954    fn unmark_text(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize);
2955    fn replace_text_in_range(
2956        &mut self,
2957        range: Option<Range<usize>>,
2958        text: &str,
2959        cx: &mut MutableAppContext,
2960        window_id: usize,
2961        view_id: usize,
2962    );
2963    fn replace_and_mark_text_in_range(
2964        &mut self,
2965        range: Option<Range<usize>>,
2966        new_text: &str,
2967        new_selected_range: Option<Range<usize>>,
2968        cx: &mut MutableAppContext,
2969        window_id: usize,
2970        view_id: usize,
2971    );
2972    fn any_handle(&self, window_id: usize, view_id: usize, cx: &AppContext) -> AnyViewHandle {
2973        AnyViewHandle::new(
2974            window_id,
2975            view_id,
2976            self.as_any().type_id(),
2977            cx.ref_counts.clone(),
2978        )
2979    }
2980}
2981
2982impl<T> AnyView for T
2983where
2984    T: View,
2985{
2986    fn as_any(&self) -> &dyn Any {
2987        self
2988    }
2989
2990    fn as_any_mut(&mut self) -> &mut dyn Any {
2991        self
2992    }
2993
2994    fn release(&mut self, cx: &mut MutableAppContext) {
2995        self.release(cx);
2996    }
2997
2998    fn app_will_quit(
2999        &mut self,
3000        cx: &mut MutableAppContext,
3001    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
3002        self.app_will_quit(cx)
3003    }
3004
3005    fn ui_name(&self) -> &'static str {
3006        T::ui_name()
3007    }
3008
3009    fn render(&mut self, params: RenderParams, cx: &mut MutableAppContext) -> ElementBox {
3010        View::render(self, &mut RenderContext::new(params, cx))
3011    }
3012
3013    fn on_focus_in(
3014        &mut self,
3015        cx: &mut MutableAppContext,
3016        window_id: usize,
3017        view_id: usize,
3018        focused_id: usize,
3019    ) {
3020        let mut cx = ViewContext::new(cx, window_id, view_id);
3021        let focused_view_handle: AnyViewHandle = if view_id == focused_id {
3022            cx.handle().into()
3023        } else {
3024            let focused_type = cx
3025                .views
3026                .get(&(window_id, focused_id))
3027                .unwrap()
3028                .as_any()
3029                .type_id();
3030            AnyViewHandle::new(window_id, focused_id, focused_type, cx.ref_counts.clone())
3031        };
3032        View::on_focus_in(self, focused_view_handle, &mut cx);
3033    }
3034
3035    fn on_focus_out(
3036        &mut self,
3037        cx: &mut MutableAppContext,
3038        window_id: usize,
3039        view_id: usize,
3040        blurred_id: usize,
3041    ) {
3042        let mut cx = ViewContext::new(cx, window_id, view_id);
3043        let blurred_view_handle: AnyViewHandle = if view_id == blurred_id {
3044            cx.handle().into()
3045        } else {
3046            let blurred_type = cx
3047                .views
3048                .get(&(window_id, blurred_id))
3049                .unwrap()
3050                .as_any()
3051                .type_id();
3052            AnyViewHandle::new(window_id, blurred_id, blurred_type, cx.ref_counts.clone())
3053        };
3054        View::on_focus_out(self, blurred_view_handle, &mut cx);
3055    }
3056
3057    fn keymap_context(&self, cx: &AppContext) -> keymap::Context {
3058        View::keymap_context(self, cx)
3059    }
3060
3061    fn debug_json(&self, cx: &AppContext) -> serde_json::Value {
3062        View::debug_json(self, cx)
3063    }
3064
3065    fn text_for_range(&self, range: Range<usize>, cx: &AppContext) -> Option<String> {
3066        View::text_for_range(self, range, cx)
3067    }
3068
3069    fn selected_text_range(&self, cx: &AppContext) -> Option<Range<usize>> {
3070        View::selected_text_range(self, cx)
3071    }
3072
3073    fn marked_text_range(&self, cx: &AppContext) -> Option<Range<usize>> {
3074        View::marked_text_range(self, cx)
3075    }
3076
3077    fn unmark_text(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize) {
3078        let mut cx = ViewContext::new(cx, window_id, view_id);
3079        View::unmark_text(self, &mut cx)
3080    }
3081
3082    fn replace_text_in_range(
3083        &mut self,
3084        range: Option<Range<usize>>,
3085        text: &str,
3086        cx: &mut MutableAppContext,
3087        window_id: usize,
3088        view_id: usize,
3089    ) {
3090        let mut cx = ViewContext::new(cx, window_id, view_id);
3091        View::replace_text_in_range(self, range, text, &mut cx)
3092    }
3093
3094    fn replace_and_mark_text_in_range(
3095        &mut self,
3096        range: Option<Range<usize>>,
3097        new_text: &str,
3098        new_selected_range: Option<Range<usize>>,
3099        cx: &mut MutableAppContext,
3100        window_id: usize,
3101        view_id: usize,
3102    ) {
3103        let mut cx = ViewContext::new(cx, window_id, view_id);
3104        View::replace_and_mark_text_in_range(self, range, new_text, new_selected_range, &mut cx)
3105    }
3106}
3107
3108pub struct ModelContext<'a, T: ?Sized> {
3109    app: &'a mut MutableAppContext,
3110    model_id: usize,
3111    model_type: PhantomData<T>,
3112    halt_stream: bool,
3113}
3114
3115impl<'a, T: Entity> ModelContext<'a, T> {
3116    fn new(app: &'a mut MutableAppContext, model_id: usize) -> Self {
3117        Self {
3118            app,
3119            model_id,
3120            model_type: PhantomData,
3121            halt_stream: false,
3122        }
3123    }
3124
3125    pub fn background(&self) -> &Arc<executor::Background> {
3126        &self.app.cx.background
3127    }
3128
3129    pub fn halt_stream(&mut self) {
3130        self.halt_stream = true;
3131    }
3132
3133    pub fn model_id(&self) -> usize {
3134        self.model_id
3135    }
3136
3137    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
3138    where
3139        S: Entity,
3140        F: FnOnce(&mut ModelContext<S>) -> S,
3141    {
3142        self.app.add_model(build_model)
3143    }
3144
3145    pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut T, &mut ModelContext<T>)) {
3146        let handle = self.handle();
3147        self.app.defer(move |cx| {
3148            handle.update(cx, |model, cx| {
3149                callback(model, cx);
3150            })
3151        })
3152    }
3153
3154    pub fn emit(&mut self, payload: T::Event) {
3155        self.app.pending_effects.push_back(Effect::Event {
3156            entity_id: self.model_id,
3157            payload: Box::new(payload),
3158        });
3159    }
3160
3161    pub fn notify(&mut self) {
3162        self.app.notify_model(self.model_id);
3163    }
3164
3165    pub fn subscribe<S: Entity, F>(
3166        &mut self,
3167        handle: &ModelHandle<S>,
3168        mut callback: F,
3169    ) -> Subscription
3170    where
3171        S::Event: 'static,
3172        F: 'static + FnMut(&mut T, ModelHandle<S>, &S::Event, &mut ModelContext<T>),
3173    {
3174        let subscriber = self.weak_handle();
3175        self.app
3176            .subscribe_internal(handle, move |emitter, event, cx| {
3177                if let Some(subscriber) = subscriber.upgrade(cx) {
3178                    subscriber.update(cx, |subscriber, cx| {
3179                        callback(subscriber, emitter, event, cx);
3180                    });
3181                    true
3182                } else {
3183                    false
3184                }
3185            })
3186    }
3187
3188    pub fn observe<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F) -> Subscription
3189    where
3190        S: Entity,
3191        F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ModelContext<T>),
3192    {
3193        let observer = self.weak_handle();
3194        self.app.observe_internal(handle, move |observed, cx| {
3195            if let Some(observer) = observer.upgrade(cx) {
3196                observer.update(cx, |observer, cx| {
3197                    callback(observer, observed, cx);
3198                });
3199                true
3200            } else {
3201                false
3202            }
3203        })
3204    }
3205
3206    pub fn observe_global<G, F>(&mut self, mut callback: F) -> Subscription
3207    where
3208        G: Any,
3209        F: 'static + FnMut(&mut T, &mut ModelContext<T>),
3210    {
3211        let observer = self.weak_handle();
3212        self.app.observe_global::<G, _>(move |cx| {
3213            if let Some(observer) = observer.upgrade(cx) {
3214                observer.update(cx, |observer, cx| callback(observer, cx));
3215            }
3216        })
3217    }
3218
3219    pub fn observe_release<S, F>(
3220        &mut self,
3221        handle: &ModelHandle<S>,
3222        mut callback: F,
3223    ) -> Subscription
3224    where
3225        S: Entity,
3226        F: 'static + FnMut(&mut T, &S, &mut ModelContext<T>),
3227    {
3228        let observer = self.weak_handle();
3229        self.app.observe_release(handle, move |released, cx| {
3230            if let Some(observer) = observer.upgrade(cx) {
3231                observer.update(cx, |observer, cx| {
3232                    callback(observer, released, cx);
3233                });
3234            }
3235        })
3236    }
3237
3238    pub fn handle(&self) -> ModelHandle<T> {
3239        ModelHandle::new(self.model_id, &self.app.cx.ref_counts)
3240    }
3241
3242    pub fn weak_handle(&self) -> WeakModelHandle<T> {
3243        WeakModelHandle::new(self.model_id)
3244    }
3245
3246    pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
3247    where
3248        F: FnOnce(ModelHandle<T>, AsyncAppContext) -> Fut,
3249        Fut: 'static + Future<Output = S>,
3250        S: 'static,
3251    {
3252        let handle = self.handle();
3253        self.app.spawn(|cx| f(handle, cx))
3254    }
3255
3256    pub fn spawn_weak<F, Fut, S>(&self, f: F) -> Task<S>
3257    where
3258        F: FnOnce(WeakModelHandle<T>, AsyncAppContext) -> Fut,
3259        Fut: 'static + Future<Output = S>,
3260        S: 'static,
3261    {
3262        let handle = self.weak_handle();
3263        self.app.spawn(|cx| f(handle, cx))
3264    }
3265}
3266
3267impl<M> AsRef<AppContext> for ModelContext<'_, M> {
3268    fn as_ref(&self) -> &AppContext {
3269        &self.app.cx
3270    }
3271}
3272
3273impl<M> AsMut<MutableAppContext> for ModelContext<'_, M> {
3274    fn as_mut(&mut self) -> &mut MutableAppContext {
3275        self.app
3276    }
3277}
3278
3279impl<M> ReadModel for ModelContext<'_, M> {
3280    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
3281        self.app.read_model(handle)
3282    }
3283}
3284
3285impl<M> UpdateModel for ModelContext<'_, M> {
3286    fn update_model<T: Entity, V>(
3287        &mut self,
3288        handle: &ModelHandle<T>,
3289        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
3290    ) -> V {
3291        self.app.update_model(handle, update)
3292    }
3293}
3294
3295impl<M> UpgradeModelHandle for ModelContext<'_, M> {
3296    fn upgrade_model_handle<T: Entity>(
3297        &self,
3298        handle: &WeakModelHandle<T>,
3299    ) -> Option<ModelHandle<T>> {
3300        self.cx.upgrade_model_handle(handle)
3301    }
3302
3303    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
3304        self.cx.model_handle_is_upgradable(handle)
3305    }
3306
3307    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
3308        self.cx.upgrade_any_model_handle(handle)
3309    }
3310}
3311
3312impl<M> Deref for ModelContext<'_, M> {
3313    type Target = MutableAppContext;
3314
3315    fn deref(&self) -> &Self::Target {
3316        self.app
3317    }
3318}
3319
3320impl<M> DerefMut for ModelContext<'_, M> {
3321    fn deref_mut(&mut self) -> &mut Self::Target {
3322        &mut self.app
3323    }
3324}
3325
3326pub struct ViewContext<'a, T: ?Sized> {
3327    app: &'a mut MutableAppContext,
3328    window_id: usize,
3329    view_id: usize,
3330    view_type: PhantomData<T>,
3331}
3332
3333impl<'a, T: View> ViewContext<'a, T> {
3334    fn new(app: &'a mut MutableAppContext, window_id: usize, view_id: usize) -> Self {
3335        Self {
3336            app,
3337            window_id,
3338            view_id,
3339            view_type: PhantomData,
3340        }
3341    }
3342
3343    pub fn handle(&self) -> ViewHandle<T> {
3344        ViewHandle::new(self.window_id, self.view_id, &self.app.cx.ref_counts)
3345    }
3346
3347    pub fn weak_handle(&self) -> WeakViewHandle<T> {
3348        WeakViewHandle::new(self.window_id, self.view_id)
3349    }
3350
3351    pub fn window_id(&self) -> usize {
3352        self.window_id
3353    }
3354
3355    pub fn view_id(&self) -> usize {
3356        self.view_id
3357    }
3358
3359    pub fn foreground(&self) -> &Rc<executor::Foreground> {
3360        self.app.foreground()
3361    }
3362
3363    pub fn background_executor(&self) -> &Arc<executor::Background> {
3364        &self.app.cx.background
3365    }
3366
3367    pub fn platform(&self) -> Arc<dyn Platform> {
3368        self.app.platform()
3369    }
3370
3371    pub fn show_character_palette(&self) {
3372        self.app.show_character_palette(self.window_id);
3373    }
3374
3375    pub fn minimize_window(&self) {
3376        self.app.minimize_window(self.window_id)
3377    }
3378
3379    pub fn zoom_window(&self) {
3380        self.app.zoom_window(self.window_id)
3381    }
3382
3383    pub fn toggle_full_screen(&self) {
3384        self.app.toggle_window_full_screen(self.window_id)
3385    }
3386
3387    pub fn window_bounds(&self) -> RectF {
3388        self.app.window_bounds(self.window_id)
3389    }
3390
3391    pub fn prompt(
3392        &self,
3393        level: PromptLevel,
3394        msg: &str,
3395        answers: &[&str],
3396    ) -> oneshot::Receiver<usize> {
3397        self.app.prompt(self.window_id, level, msg, answers)
3398    }
3399
3400    pub fn prompt_for_paths(
3401        &self,
3402        options: PathPromptOptions,
3403    ) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
3404        self.app.prompt_for_paths(options)
3405    }
3406
3407    pub fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
3408        self.app.prompt_for_new_path(directory)
3409    }
3410
3411    pub fn debug_elements(&self) -> crate::json::Value {
3412        self.app.debug_elements(self.window_id).unwrap()
3413    }
3414
3415    pub fn focus<S>(&mut self, handle: S)
3416    where
3417        S: Into<AnyViewHandle>,
3418    {
3419        let handle = handle.into();
3420        self.app.focus(handle.window_id, Some(handle.view_id));
3421    }
3422
3423    pub fn focus_self(&mut self) {
3424        self.app.focus(self.window_id, Some(self.view_id));
3425    }
3426
3427    pub fn is_self_focused(&self) -> bool {
3428        self.app.focused_view_id(self.window_id) == Some(self.view_id)
3429    }
3430
3431    pub fn blur(&mut self) {
3432        self.app.focus(self.window_id, None);
3433    }
3434
3435    pub fn set_window_title(&mut self, title: &str) {
3436        let window_id = self.window_id();
3437        if let Some((_, window)) = self.presenters_and_platform_windows.get_mut(&window_id) {
3438            window.set_title(title);
3439        }
3440    }
3441
3442    pub fn set_window_edited(&mut self, edited: bool) {
3443        let window_id = self.window_id();
3444        if let Some((_, window)) = self.presenters_and_platform_windows.get_mut(&window_id) {
3445            window.set_edited(edited);
3446        }
3447    }
3448
3449    pub fn on_window_should_close<F>(&mut self, mut callback: F)
3450    where
3451        F: 'static + FnMut(&mut T, &mut ViewContext<T>) -> bool,
3452    {
3453        let window_id = self.window_id();
3454        let view = self.weak_handle();
3455        self.pending_effects
3456            .push_back(Effect::WindowShouldCloseSubscription {
3457                window_id,
3458                callback: Box::new(move |cx| {
3459                    if let Some(view) = view.upgrade(cx) {
3460                        view.update(cx, |view, cx| callback(view, cx))
3461                    } else {
3462                        true
3463                    }
3464                }),
3465            });
3466    }
3467
3468    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
3469    where
3470        S: Entity,
3471        F: FnOnce(&mut ModelContext<S>) -> S,
3472    {
3473        self.app.add_model(build_model)
3474    }
3475
3476    pub fn add_view<S, F>(&mut self, build_view: F) -> ViewHandle<S>
3477    where
3478        S: View,
3479        F: FnOnce(&mut ViewContext<S>) -> S,
3480    {
3481        self.app
3482            .build_and_insert_view(self.window_id, ParentId::View(self.view_id), |cx| {
3483                Some(build_view(cx))
3484            })
3485            .unwrap()
3486    }
3487
3488    pub fn add_option_view<S, F>(&mut self, build_view: F) -> Option<ViewHandle<S>>
3489    where
3490        S: View,
3491        F: FnOnce(&mut ViewContext<S>) -> Option<S>,
3492    {
3493        self.app
3494            .build_and_insert_view(self.window_id, ParentId::View(self.view_id), build_view)
3495    }
3496
3497    pub fn reparent(&mut self, view_handle: impl Into<AnyViewHandle>) {
3498        let view_handle = view_handle.into();
3499        if self.window_id != view_handle.window_id {
3500            panic!("Can't reparent view to a view from a different window");
3501        }
3502        self.cx
3503            .parents
3504            .remove(&(view_handle.window_id, view_handle.view_id));
3505        let new_parent_id = self.view_id;
3506        self.cx.parents.insert(
3507            (view_handle.window_id, view_handle.view_id),
3508            ParentId::View(new_parent_id),
3509        );
3510    }
3511
3512    pub fn replace_root_view<V, F>(&mut self, build_root_view: F) -> ViewHandle<V>
3513    where
3514        V: View,
3515        F: FnOnce(&mut ViewContext<V>) -> V,
3516    {
3517        let window_id = self.window_id;
3518        self.update(|this| {
3519            let root_view = this
3520                .build_and_insert_view(window_id, ParentId::Root, |cx| Some(build_root_view(cx)))
3521                .unwrap();
3522            let window = this.cx.windows.get_mut(&window_id).unwrap();
3523            window.root_view = root_view.clone().into();
3524            window.focused_view_id = Some(root_view.id());
3525            root_view
3526        })
3527    }
3528
3529    pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
3530    where
3531        E: Entity,
3532        E::Event: 'static,
3533        H: Handle<E>,
3534        F: 'static + FnMut(&mut T, H, &E::Event, &mut ViewContext<T>),
3535    {
3536        let subscriber = self.weak_handle();
3537        self.app
3538            .subscribe_internal(handle, move |emitter, event, cx| {
3539                if let Some(subscriber) = subscriber.upgrade(cx) {
3540                    subscriber.update(cx, |subscriber, cx| {
3541                        callback(subscriber, emitter, event, cx);
3542                    });
3543                    true
3544                } else {
3545                    false
3546                }
3547            })
3548    }
3549
3550    pub fn observe<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
3551    where
3552        E: Entity,
3553        H: Handle<E>,
3554        F: 'static + FnMut(&mut T, H, &mut ViewContext<T>),
3555    {
3556        let observer = self.weak_handle();
3557        self.app.observe_internal(handle, move |observed, cx| {
3558            if let Some(observer) = observer.upgrade(cx) {
3559                observer.update(cx, |observer, cx| {
3560                    callback(observer, observed, cx);
3561                });
3562                true
3563            } else {
3564                false
3565            }
3566        })
3567    }
3568
3569    pub fn observe_focus<F, V>(&mut self, handle: &ViewHandle<V>, mut callback: F) -> Subscription
3570    where
3571        F: 'static + FnMut(&mut T, ViewHandle<V>, bool, &mut ViewContext<T>),
3572        V: View,
3573    {
3574        let observer = self.weak_handle();
3575        self.app
3576            .observe_focus(handle, move |observed, focused, cx| {
3577                if let Some(observer) = observer.upgrade(cx) {
3578                    observer.update(cx, |observer, cx| {
3579                        callback(observer, observed, focused, cx);
3580                    });
3581                    true
3582                } else {
3583                    false
3584                }
3585            })
3586    }
3587
3588    pub fn observe_release<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
3589    where
3590        E: Entity,
3591        H: Handle<E>,
3592        F: 'static + FnMut(&mut T, &E, &mut ViewContext<T>),
3593    {
3594        let observer = self.weak_handle();
3595        self.app.observe_release(handle, move |released, cx| {
3596            if let Some(observer) = observer.upgrade(cx) {
3597                observer.update(cx, |observer, cx| {
3598                    callback(observer, released, cx);
3599                });
3600            }
3601        })
3602    }
3603
3604    pub fn observe_actions<F>(&mut self, mut callback: F) -> Subscription
3605    where
3606        F: 'static + FnMut(&mut T, TypeId, &mut ViewContext<T>),
3607    {
3608        let observer = self.weak_handle();
3609        self.app.observe_actions(move |action_id, cx| {
3610            if let Some(observer) = observer.upgrade(cx) {
3611                observer.update(cx, |observer, cx| {
3612                    callback(observer, action_id, cx);
3613                });
3614            }
3615        })
3616    }
3617
3618    pub fn observe_window_activation<F>(&mut self, mut callback: F) -> Subscription
3619    where
3620        F: 'static + FnMut(&mut T, bool, &mut ViewContext<T>),
3621    {
3622        let observer = self.weak_handle();
3623        self.app
3624            .observe_window_activation(self.window_id(), move |active, cx| {
3625                if let Some(observer) = observer.upgrade(cx) {
3626                    observer.update(cx, |observer, cx| {
3627                        callback(observer, active, cx);
3628                    });
3629                    true
3630                } else {
3631                    false
3632                }
3633            })
3634    }
3635
3636    pub fn observe_fullscreen<F>(&mut self, mut callback: F) -> Subscription
3637    where
3638        F: 'static + FnMut(&mut T, bool, &mut ViewContext<T>),
3639    {
3640        let observer = self.weak_handle();
3641        self.app
3642            .observe_fullscreen(self.window_id(), move |active, cx| {
3643                if let Some(observer) = observer.upgrade(cx) {
3644                    observer.update(cx, |observer, cx| {
3645                        callback(observer, active, cx);
3646                    });
3647                    true
3648                } else {
3649                    false
3650                }
3651            })
3652    }
3653
3654    pub fn emit(&mut self, payload: T::Event) {
3655        self.app.pending_effects.push_back(Effect::Event {
3656            entity_id: self.view_id,
3657            payload: Box::new(payload),
3658        });
3659    }
3660
3661    pub fn notify(&mut self) {
3662        self.app.notify_view(self.window_id, self.view_id);
3663    }
3664
3665    pub fn dispatch_any_action(&mut self, action: Box<dyn Action>) {
3666        self.app
3667            .dispatch_any_action_at(self.window_id, self.view_id, action)
3668    }
3669
3670    pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut T, &mut ViewContext<T>)) {
3671        let handle = self.handle();
3672        self.app.defer(move |cx| {
3673            handle.update(cx, |view, cx| {
3674                callback(view, cx);
3675            })
3676        })
3677    }
3678
3679    pub fn after_window_update(
3680        &mut self,
3681        callback: impl 'static + FnOnce(&mut T, &mut ViewContext<T>),
3682    ) {
3683        let handle = self.handle();
3684        self.app.after_window_update(move |cx| {
3685            handle.update(cx, |view, cx| {
3686                callback(view, cx);
3687            })
3688        })
3689    }
3690
3691    pub fn propagate_action(&mut self) {
3692        self.app.halt_action_dispatch = false;
3693    }
3694
3695    pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
3696    where
3697        F: FnOnce(ViewHandle<T>, AsyncAppContext) -> Fut,
3698        Fut: 'static + Future<Output = S>,
3699        S: 'static,
3700    {
3701        let handle = self.handle();
3702        self.app.spawn(|cx| f(handle, cx))
3703    }
3704
3705    pub fn spawn_weak<F, Fut, S>(&self, f: F) -> Task<S>
3706    where
3707        F: FnOnce(WeakViewHandle<T>, AsyncAppContext) -> Fut,
3708        Fut: 'static + Future<Output = S>,
3709        S: 'static,
3710    {
3711        let handle = self.weak_handle();
3712        self.app.spawn(|cx| f(handle, cx))
3713    }
3714}
3715
3716pub struct RenderParams {
3717    pub window_id: usize,
3718    pub view_id: usize,
3719    pub titlebar_height: f32,
3720    pub hovered_region_ids: HashSet<MouseRegionId>,
3721    pub clicked_region_ids: Option<(HashSet<MouseRegionId>, MouseButton)>,
3722    pub refreshing: bool,
3723    pub appearance: Appearance,
3724}
3725
3726pub struct RenderContext<'a, T: View> {
3727    pub(crate) window_id: usize,
3728    pub(crate) view_id: usize,
3729    pub(crate) view_type: PhantomData<T>,
3730    pub(crate) hovered_region_ids: HashSet<MouseRegionId>,
3731    pub(crate) clicked_region_ids: Option<(HashSet<MouseRegionId>, MouseButton)>,
3732    pub app: &'a mut MutableAppContext,
3733    pub titlebar_height: f32,
3734    pub appearance: Appearance,
3735    pub refreshing: bool,
3736}
3737
3738#[derive(Clone, Copy, Default)]
3739pub struct MouseState {
3740    pub hovered: bool,
3741    pub clicked: Option<MouseButton>,
3742}
3743
3744impl<'a, V: View> RenderContext<'a, V> {
3745    fn new(params: RenderParams, app: &'a mut MutableAppContext) -> Self {
3746        Self {
3747            app,
3748            window_id: params.window_id,
3749            view_id: params.view_id,
3750            view_type: PhantomData,
3751            titlebar_height: params.titlebar_height,
3752            hovered_region_ids: params.hovered_region_ids.clone(),
3753            clicked_region_ids: params.clicked_region_ids.clone(),
3754            refreshing: params.refreshing,
3755            appearance: params.appearance,
3756        }
3757    }
3758
3759    pub fn handle(&self) -> WeakViewHandle<V> {
3760        WeakViewHandle::new(self.window_id, self.view_id)
3761    }
3762
3763    pub fn window_id(&self) -> usize {
3764        self.window_id
3765    }
3766
3767    pub fn view_id(&self) -> usize {
3768        self.view_id
3769    }
3770
3771    pub fn mouse_state<Tag: 'static>(&self, region_id: usize) -> MouseState {
3772        let region_id = MouseRegionId::new::<Tag>(self.view_id, region_id);
3773        MouseState {
3774            hovered: self.hovered_region_ids.contains(&region_id),
3775            clicked: self.clicked_region_ids.as_ref().and_then(|(ids, button)| {
3776                if ids.contains(&region_id) {
3777                    Some(*button)
3778                } else {
3779                    None
3780                }
3781            }),
3782        }
3783    }
3784
3785    pub fn element_state<Tag: 'static, T: 'static>(
3786        &mut self,
3787        element_id: usize,
3788        initial: T,
3789    ) -> ElementStateHandle<T> {
3790        let id = ElementStateId {
3791            view_id: self.view_id(),
3792            element_id,
3793            tag: TypeId::of::<Tag>(),
3794        };
3795        self.cx
3796            .element_states
3797            .entry(id)
3798            .or_insert_with(|| Box::new(initial));
3799        ElementStateHandle::new(id, self.frame_count, &self.cx.ref_counts)
3800    }
3801
3802    pub fn default_element_state<Tag: 'static, T: 'static + Default>(
3803        &mut self,
3804        element_id: usize,
3805    ) -> ElementStateHandle<T> {
3806        self.element_state::<Tag, T>(element_id, T::default())
3807    }
3808}
3809
3810impl AsRef<AppContext> for &AppContext {
3811    fn as_ref(&self) -> &AppContext {
3812        self
3813    }
3814}
3815
3816impl<V: View> Deref for RenderContext<'_, V> {
3817    type Target = MutableAppContext;
3818
3819    fn deref(&self) -> &Self::Target {
3820        self.app
3821    }
3822}
3823
3824impl<V: View> DerefMut for RenderContext<'_, V> {
3825    fn deref_mut(&mut self) -> &mut Self::Target {
3826        self.app
3827    }
3828}
3829
3830impl<V: View> ReadModel for RenderContext<'_, V> {
3831    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
3832        self.app.read_model(handle)
3833    }
3834}
3835
3836impl<V: View> UpdateModel for RenderContext<'_, V> {
3837    fn update_model<T: Entity, O>(
3838        &mut self,
3839        handle: &ModelHandle<T>,
3840        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
3841    ) -> O {
3842        self.app.update_model(handle, update)
3843    }
3844}
3845
3846impl<V: View> ReadView for RenderContext<'_, V> {
3847    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
3848        self.app.read_view(handle)
3849    }
3850}
3851
3852impl<M> AsRef<AppContext> for ViewContext<'_, M> {
3853    fn as_ref(&self) -> &AppContext {
3854        &self.app.cx
3855    }
3856}
3857
3858impl<M> Deref for ViewContext<'_, M> {
3859    type Target = MutableAppContext;
3860
3861    fn deref(&self) -> &Self::Target {
3862        self.app
3863    }
3864}
3865
3866impl<M> DerefMut for ViewContext<'_, M> {
3867    fn deref_mut(&mut self) -> &mut Self::Target {
3868        &mut self.app
3869    }
3870}
3871
3872impl<M> AsMut<MutableAppContext> for ViewContext<'_, M> {
3873    fn as_mut(&mut self) -> &mut MutableAppContext {
3874        self.app
3875    }
3876}
3877
3878impl<V> ReadModel for ViewContext<'_, V> {
3879    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
3880        self.app.read_model(handle)
3881    }
3882}
3883
3884impl<V> UpgradeModelHandle for ViewContext<'_, V> {
3885    fn upgrade_model_handle<T: Entity>(
3886        &self,
3887        handle: &WeakModelHandle<T>,
3888    ) -> Option<ModelHandle<T>> {
3889        self.cx.upgrade_model_handle(handle)
3890    }
3891
3892    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
3893        self.cx.model_handle_is_upgradable(handle)
3894    }
3895
3896    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
3897        self.cx.upgrade_any_model_handle(handle)
3898    }
3899}
3900
3901impl<V> UpgradeViewHandle for ViewContext<'_, V> {
3902    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
3903        self.cx.upgrade_view_handle(handle)
3904    }
3905
3906    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
3907        self.cx.upgrade_any_view_handle(handle)
3908    }
3909}
3910
3911impl<V: View> UpgradeViewHandle for RenderContext<'_, V> {
3912    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
3913        self.cx.upgrade_view_handle(handle)
3914    }
3915
3916    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
3917        self.cx.upgrade_any_view_handle(handle)
3918    }
3919}
3920
3921impl<V: View> UpdateModel for ViewContext<'_, V> {
3922    fn update_model<T: Entity, O>(
3923        &mut self,
3924        handle: &ModelHandle<T>,
3925        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
3926    ) -> O {
3927        self.app.update_model(handle, update)
3928    }
3929}
3930
3931impl<V: View> ReadView for ViewContext<'_, V> {
3932    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
3933        self.app.read_view(handle)
3934    }
3935}
3936
3937impl<V: View> UpdateView for ViewContext<'_, V> {
3938    fn update_view<T, S>(
3939        &mut self,
3940        handle: &ViewHandle<T>,
3941        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
3942    ) -> S
3943    where
3944        T: View,
3945    {
3946        self.app.update_view(handle, update)
3947    }
3948}
3949
3950pub trait Handle<T> {
3951    type Weak: 'static;
3952    fn id(&self) -> usize;
3953    fn location(&self) -> EntityLocation;
3954    fn downgrade(&self) -> Self::Weak;
3955    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
3956    where
3957        Self: Sized;
3958}
3959
3960pub trait WeakHandle {
3961    fn id(&self) -> usize;
3962}
3963
3964#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
3965pub enum EntityLocation {
3966    Model(usize),
3967    View(usize, usize),
3968}
3969
3970pub struct ModelHandle<T: Entity> {
3971    model_id: usize,
3972    model_type: PhantomData<T>,
3973    ref_counts: Arc<Mutex<RefCounts>>,
3974
3975    #[cfg(any(test, feature = "test-support"))]
3976    handle_id: usize,
3977}
3978
3979impl<T: Entity> ModelHandle<T> {
3980    fn new(model_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
3981        ref_counts.lock().inc_model(model_id);
3982
3983        #[cfg(any(test, feature = "test-support"))]
3984        let handle_id = ref_counts
3985            .lock()
3986            .leak_detector
3987            .lock()
3988            .handle_created(Some(type_name::<T>()), model_id);
3989
3990        Self {
3991            model_id,
3992            model_type: PhantomData,
3993            ref_counts: ref_counts.clone(),
3994
3995            #[cfg(any(test, feature = "test-support"))]
3996            handle_id,
3997        }
3998    }
3999
4000    pub fn downgrade(&self) -> WeakModelHandle<T> {
4001        WeakModelHandle::new(self.model_id)
4002    }
4003
4004    pub fn id(&self) -> usize {
4005        self.model_id
4006    }
4007
4008    pub fn read<'a, C: ReadModel>(&self, cx: &'a C) -> &'a T {
4009        cx.read_model(self)
4010    }
4011
4012    pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> S
4013    where
4014        C: ReadModelWith,
4015        F: FnOnce(&T, &AppContext) -> S,
4016    {
4017        let mut read = Some(read);
4018        cx.read_model_with(self, &mut |model, cx| {
4019            let read = read.take().unwrap();
4020            read(model, cx)
4021        })
4022    }
4023
4024    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
4025    where
4026        C: UpdateModel,
4027        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
4028    {
4029        let mut update = Some(update);
4030        cx.update_model(self, &mut |model, cx| {
4031            let update = update.take().unwrap();
4032            update(model, cx)
4033        })
4034    }
4035}
4036
4037impl<T: Entity> Clone for ModelHandle<T> {
4038    fn clone(&self) -> Self {
4039        Self::new(self.model_id, &self.ref_counts)
4040    }
4041}
4042
4043impl<T: Entity> PartialEq for ModelHandle<T> {
4044    fn eq(&self, other: &Self) -> bool {
4045        self.model_id == other.model_id
4046    }
4047}
4048
4049impl<T: Entity> Eq for ModelHandle<T> {}
4050
4051impl<T: Entity> PartialEq<WeakModelHandle<T>> for ModelHandle<T> {
4052    fn eq(&self, other: &WeakModelHandle<T>) -> bool {
4053        self.model_id == other.model_id
4054    }
4055}
4056
4057impl<T: Entity> Hash for ModelHandle<T> {
4058    fn hash<H: Hasher>(&self, state: &mut H) {
4059        self.model_id.hash(state);
4060    }
4061}
4062
4063impl<T: Entity> std::borrow::Borrow<usize> for ModelHandle<T> {
4064    fn borrow(&self) -> &usize {
4065        &self.model_id
4066    }
4067}
4068
4069impl<T: Entity> Debug for ModelHandle<T> {
4070    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4071        f.debug_tuple(&format!("ModelHandle<{}>", type_name::<T>()))
4072            .field(&self.model_id)
4073            .finish()
4074    }
4075}
4076
4077unsafe impl<T: Entity> Send for ModelHandle<T> {}
4078unsafe impl<T: Entity> Sync for ModelHandle<T> {}
4079
4080impl<T: Entity> Drop for ModelHandle<T> {
4081    fn drop(&mut self) {
4082        let mut ref_counts = self.ref_counts.lock();
4083        ref_counts.dec_model(self.model_id);
4084
4085        #[cfg(any(test, feature = "test-support"))]
4086        ref_counts
4087            .leak_detector
4088            .lock()
4089            .handle_dropped(self.model_id, self.handle_id);
4090    }
4091}
4092
4093impl<T: Entity> Handle<T> for ModelHandle<T> {
4094    type Weak = WeakModelHandle<T>;
4095
4096    fn id(&self) -> usize {
4097        self.model_id
4098    }
4099
4100    fn location(&self) -> EntityLocation {
4101        EntityLocation::Model(self.model_id)
4102    }
4103
4104    fn downgrade(&self) -> Self::Weak {
4105        self.downgrade()
4106    }
4107
4108    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
4109    where
4110        Self: Sized,
4111    {
4112        weak.upgrade(cx)
4113    }
4114}
4115
4116pub struct WeakModelHandle<T> {
4117    model_id: usize,
4118    model_type: PhantomData<T>,
4119}
4120
4121impl<T> WeakHandle for WeakModelHandle<T> {
4122    fn id(&self) -> usize {
4123        self.model_id
4124    }
4125}
4126
4127unsafe impl<T> Send for WeakModelHandle<T> {}
4128unsafe impl<T> Sync for WeakModelHandle<T> {}
4129
4130impl<T: Entity> WeakModelHandle<T> {
4131    fn new(model_id: usize) -> Self {
4132        Self {
4133            model_id,
4134            model_type: PhantomData,
4135        }
4136    }
4137
4138    pub fn id(&self) -> usize {
4139        self.model_id
4140    }
4141
4142    pub fn is_upgradable(&self, cx: &impl UpgradeModelHandle) -> bool {
4143        cx.model_handle_is_upgradable(self)
4144    }
4145
4146    pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<ModelHandle<T>> {
4147        cx.upgrade_model_handle(self)
4148    }
4149}
4150
4151impl<T> Hash for WeakModelHandle<T> {
4152    fn hash<H: Hasher>(&self, state: &mut H) {
4153        self.model_id.hash(state)
4154    }
4155}
4156
4157impl<T> PartialEq for WeakModelHandle<T> {
4158    fn eq(&self, other: &Self) -> bool {
4159        self.model_id == other.model_id
4160    }
4161}
4162
4163impl<T> Eq for WeakModelHandle<T> {}
4164
4165impl<T> Clone for WeakModelHandle<T> {
4166    fn clone(&self) -> Self {
4167        Self {
4168            model_id: self.model_id,
4169            model_type: PhantomData,
4170        }
4171    }
4172}
4173
4174impl<T> Copy for WeakModelHandle<T> {}
4175
4176pub struct ViewHandle<T> {
4177    window_id: usize,
4178    view_id: usize,
4179    view_type: PhantomData<T>,
4180    ref_counts: Arc<Mutex<RefCounts>>,
4181    #[cfg(any(test, feature = "test-support"))]
4182    handle_id: usize,
4183}
4184
4185impl<T: View> ViewHandle<T> {
4186    fn new(window_id: usize, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
4187        ref_counts.lock().inc_view(window_id, view_id);
4188        #[cfg(any(test, feature = "test-support"))]
4189        let handle_id = ref_counts
4190            .lock()
4191            .leak_detector
4192            .lock()
4193            .handle_created(Some(type_name::<T>()), view_id);
4194
4195        Self {
4196            window_id,
4197            view_id,
4198            view_type: PhantomData,
4199            ref_counts: ref_counts.clone(),
4200
4201            #[cfg(any(test, feature = "test-support"))]
4202            handle_id,
4203        }
4204    }
4205
4206    pub fn downgrade(&self) -> WeakViewHandle<T> {
4207        WeakViewHandle::new(self.window_id, self.view_id)
4208    }
4209
4210    pub fn window_id(&self) -> usize {
4211        self.window_id
4212    }
4213
4214    pub fn id(&self) -> usize {
4215        self.view_id
4216    }
4217
4218    pub fn read<'a, C: ReadView>(&self, cx: &'a C) -> &'a T {
4219        cx.read_view(self)
4220    }
4221
4222    pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> S
4223    where
4224        C: ReadViewWith,
4225        F: FnOnce(&T, &AppContext) -> S,
4226    {
4227        let mut read = Some(read);
4228        cx.read_view_with(self, &mut |view, cx| {
4229            let read = read.take().unwrap();
4230            read(view, cx)
4231        })
4232    }
4233
4234    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
4235    where
4236        C: UpdateView,
4237        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
4238    {
4239        let mut update = Some(update);
4240        cx.update_view(self, &mut |view, cx| {
4241            let update = update.take().unwrap();
4242            update(view, cx)
4243        })
4244    }
4245
4246    pub fn defer<C, F>(&self, cx: &mut C, update: F)
4247    where
4248        C: AsMut<MutableAppContext>,
4249        F: 'static + FnOnce(&mut T, &mut ViewContext<T>),
4250    {
4251        let this = self.clone();
4252        cx.as_mut().defer(move |cx| {
4253            this.update(cx, |view, cx| update(view, cx));
4254        });
4255    }
4256
4257    pub fn is_focused(&self, cx: &AppContext) -> bool {
4258        cx.focused_view_id(self.window_id)
4259            .map_or(false, |focused_id| focused_id == self.view_id)
4260    }
4261}
4262
4263impl<T: View> Clone for ViewHandle<T> {
4264    fn clone(&self) -> Self {
4265        ViewHandle::new(self.window_id, self.view_id, &self.ref_counts)
4266    }
4267}
4268
4269impl<T> PartialEq for ViewHandle<T> {
4270    fn eq(&self, other: &Self) -> bool {
4271        self.window_id == other.window_id && self.view_id == other.view_id
4272    }
4273}
4274
4275impl<T> PartialEq<WeakViewHandle<T>> for ViewHandle<T> {
4276    fn eq(&self, other: &WeakViewHandle<T>) -> bool {
4277        self.window_id == other.window_id && self.view_id == other.view_id
4278    }
4279}
4280
4281impl<T> PartialEq<ViewHandle<T>> for WeakViewHandle<T> {
4282    fn eq(&self, other: &ViewHandle<T>) -> bool {
4283        self.window_id == other.window_id && self.view_id == other.view_id
4284    }
4285}
4286
4287impl<T> Eq for ViewHandle<T> {}
4288
4289impl<T> Hash for ViewHandle<T> {
4290    fn hash<H: Hasher>(&self, state: &mut H) {
4291        self.window_id.hash(state);
4292        self.view_id.hash(state);
4293    }
4294}
4295
4296impl<T> Debug for ViewHandle<T> {
4297    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4298        f.debug_struct(&format!("ViewHandle<{}>", type_name::<T>()))
4299            .field("window_id", &self.window_id)
4300            .field("view_id", &self.view_id)
4301            .finish()
4302    }
4303}
4304
4305impl<T> Drop for ViewHandle<T> {
4306    fn drop(&mut self) {
4307        self.ref_counts
4308            .lock()
4309            .dec_view(self.window_id, self.view_id);
4310        #[cfg(any(test, feature = "test-support"))]
4311        self.ref_counts
4312            .lock()
4313            .leak_detector
4314            .lock()
4315            .handle_dropped(self.view_id, self.handle_id);
4316    }
4317}
4318
4319impl<T: View> Handle<T> for ViewHandle<T> {
4320    type Weak = WeakViewHandle<T>;
4321
4322    fn id(&self) -> usize {
4323        self.view_id
4324    }
4325
4326    fn location(&self) -> EntityLocation {
4327        EntityLocation::View(self.window_id, self.view_id)
4328    }
4329
4330    fn downgrade(&self) -> Self::Weak {
4331        self.downgrade()
4332    }
4333
4334    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
4335    where
4336        Self: Sized,
4337    {
4338        weak.upgrade(cx)
4339    }
4340}
4341
4342pub struct AnyViewHandle {
4343    window_id: usize,
4344    view_id: usize,
4345    view_type: TypeId,
4346    ref_counts: Arc<Mutex<RefCounts>>,
4347
4348    #[cfg(any(test, feature = "test-support"))]
4349    handle_id: usize,
4350}
4351
4352impl AnyViewHandle {
4353    fn new(
4354        window_id: usize,
4355        view_id: usize,
4356        view_type: TypeId,
4357        ref_counts: Arc<Mutex<RefCounts>>,
4358    ) -> Self {
4359        ref_counts.lock().inc_view(window_id, view_id);
4360
4361        #[cfg(any(test, feature = "test-support"))]
4362        let handle_id = ref_counts
4363            .lock()
4364            .leak_detector
4365            .lock()
4366            .handle_created(None, view_id);
4367
4368        Self {
4369            window_id,
4370            view_id,
4371            view_type,
4372            ref_counts,
4373            #[cfg(any(test, feature = "test-support"))]
4374            handle_id,
4375        }
4376    }
4377
4378    pub fn id(&self) -> usize {
4379        self.view_id
4380    }
4381
4382    pub fn is<T: 'static>(&self) -> bool {
4383        TypeId::of::<T>() == self.view_type
4384    }
4385
4386    pub fn is_focused(&self, cx: &AppContext) -> bool {
4387        cx.focused_view_id(self.window_id)
4388            .map_or(false, |focused_id| focused_id == self.view_id)
4389    }
4390
4391    pub fn downcast<T: View>(self) -> Option<ViewHandle<T>> {
4392        if self.is::<T>() {
4393            let result = Some(ViewHandle {
4394                window_id: self.window_id,
4395                view_id: self.view_id,
4396                ref_counts: self.ref_counts.clone(),
4397                view_type: PhantomData,
4398                #[cfg(any(test, feature = "test-support"))]
4399                handle_id: self.handle_id,
4400            });
4401            unsafe {
4402                Arc::decrement_strong_count(Arc::as_ptr(&self.ref_counts));
4403            }
4404            std::mem::forget(self);
4405            result
4406        } else {
4407            None
4408        }
4409    }
4410
4411    pub fn downgrade(&self) -> AnyWeakViewHandle {
4412        AnyWeakViewHandle {
4413            window_id: self.window_id,
4414            view_id: self.view_id,
4415            view_type: self.view_type,
4416        }
4417    }
4418
4419    pub fn view_type(&self) -> TypeId {
4420        self.view_type
4421    }
4422
4423    pub fn debug_json(&self, cx: &AppContext) -> serde_json::Value {
4424        cx.views
4425            .get(&(self.window_id, self.view_id))
4426            .map_or_else(|| serde_json::Value::Null, |view| view.debug_json(cx))
4427    }
4428}
4429
4430impl Clone for AnyViewHandle {
4431    fn clone(&self) -> Self {
4432        Self::new(
4433            self.window_id,
4434            self.view_id,
4435            self.view_type,
4436            self.ref_counts.clone(),
4437        )
4438    }
4439}
4440
4441impl From<&AnyViewHandle> for AnyViewHandle {
4442    fn from(handle: &AnyViewHandle) -> Self {
4443        handle.clone()
4444    }
4445}
4446
4447impl<T: View> From<&ViewHandle<T>> for AnyViewHandle {
4448    fn from(handle: &ViewHandle<T>) -> Self {
4449        Self::new(
4450            handle.window_id,
4451            handle.view_id,
4452            TypeId::of::<T>(),
4453            handle.ref_counts.clone(),
4454        )
4455    }
4456}
4457
4458impl<T: View> From<ViewHandle<T>> for AnyViewHandle {
4459    fn from(handle: ViewHandle<T>) -> Self {
4460        let any_handle = AnyViewHandle {
4461            window_id: handle.window_id,
4462            view_id: handle.view_id,
4463            view_type: TypeId::of::<T>(),
4464            ref_counts: handle.ref_counts.clone(),
4465            #[cfg(any(test, feature = "test-support"))]
4466            handle_id: handle.handle_id,
4467        };
4468
4469        unsafe {
4470            Arc::decrement_strong_count(Arc::as_ptr(&handle.ref_counts));
4471        }
4472        std::mem::forget(handle);
4473        any_handle
4474    }
4475}
4476
4477impl Drop for AnyViewHandle {
4478    fn drop(&mut self) {
4479        self.ref_counts
4480            .lock()
4481            .dec_view(self.window_id, self.view_id);
4482        #[cfg(any(test, feature = "test-support"))]
4483        self.ref_counts
4484            .lock()
4485            .leak_detector
4486            .lock()
4487            .handle_dropped(self.view_id, self.handle_id);
4488    }
4489}
4490
4491pub struct AnyModelHandle {
4492    model_id: usize,
4493    model_type: TypeId,
4494    ref_counts: Arc<Mutex<RefCounts>>,
4495
4496    #[cfg(any(test, feature = "test-support"))]
4497    handle_id: usize,
4498}
4499
4500impl AnyModelHandle {
4501    fn new(model_id: usize, model_type: TypeId, ref_counts: Arc<Mutex<RefCounts>>) -> Self {
4502        ref_counts.lock().inc_model(model_id);
4503
4504        #[cfg(any(test, feature = "test-support"))]
4505        let handle_id = ref_counts
4506            .lock()
4507            .leak_detector
4508            .lock()
4509            .handle_created(None, model_id);
4510
4511        Self {
4512            model_id,
4513            model_type,
4514            ref_counts,
4515
4516            #[cfg(any(test, feature = "test-support"))]
4517            handle_id,
4518        }
4519    }
4520
4521    pub fn downcast<T: Entity>(self) -> Option<ModelHandle<T>> {
4522        if self.is::<T>() {
4523            let result = Some(ModelHandle {
4524                model_id: self.model_id,
4525                model_type: PhantomData,
4526                ref_counts: self.ref_counts.clone(),
4527
4528                #[cfg(any(test, feature = "test-support"))]
4529                handle_id: self.handle_id,
4530            });
4531            unsafe {
4532                Arc::decrement_strong_count(Arc::as_ptr(&self.ref_counts));
4533            }
4534            std::mem::forget(self);
4535            result
4536        } else {
4537            None
4538        }
4539    }
4540
4541    pub fn downgrade(&self) -> AnyWeakModelHandle {
4542        AnyWeakModelHandle {
4543            model_id: self.model_id,
4544            model_type: self.model_type,
4545        }
4546    }
4547
4548    pub fn is<T: Entity>(&self) -> bool {
4549        self.model_type == TypeId::of::<T>()
4550    }
4551
4552    pub fn model_type(&self) -> TypeId {
4553        self.model_type
4554    }
4555}
4556
4557impl<T: Entity> From<ModelHandle<T>> for AnyModelHandle {
4558    fn from(handle: ModelHandle<T>) -> Self {
4559        Self::new(
4560            handle.model_id,
4561            TypeId::of::<T>(),
4562            handle.ref_counts.clone(),
4563        )
4564    }
4565}
4566
4567impl Clone for AnyModelHandle {
4568    fn clone(&self) -> Self {
4569        Self::new(self.model_id, self.model_type, self.ref_counts.clone())
4570    }
4571}
4572
4573impl Drop for AnyModelHandle {
4574    fn drop(&mut self) {
4575        let mut ref_counts = self.ref_counts.lock();
4576        ref_counts.dec_model(self.model_id);
4577
4578        #[cfg(any(test, feature = "test-support"))]
4579        ref_counts
4580            .leak_detector
4581            .lock()
4582            .handle_dropped(self.model_id, self.handle_id);
4583    }
4584}
4585
4586#[derive(Hash, PartialEq, Eq, Debug)]
4587pub struct AnyWeakModelHandle {
4588    model_id: usize,
4589    model_type: TypeId,
4590}
4591
4592impl AnyWeakModelHandle {
4593    pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<AnyModelHandle> {
4594        cx.upgrade_any_model_handle(self)
4595    }
4596    pub fn model_type(&self) -> TypeId {
4597        self.model_type
4598    }
4599
4600    fn is<T: 'static>(&self) -> bool {
4601        TypeId::of::<T>() == self.model_type
4602    }
4603
4604    pub fn downcast<T: Entity>(&self) -> Option<WeakModelHandle<T>> {
4605        if self.is::<T>() {
4606            let result = Some(WeakModelHandle {
4607                model_id: self.model_id,
4608                model_type: PhantomData,
4609            });
4610
4611            result
4612        } else {
4613            None
4614        }
4615    }
4616}
4617
4618impl<T: Entity> From<WeakModelHandle<T>> for AnyWeakModelHandle {
4619    fn from(handle: WeakModelHandle<T>) -> Self {
4620        AnyWeakModelHandle {
4621            model_id: handle.model_id,
4622            model_type: TypeId::of::<T>(),
4623        }
4624    }
4625}
4626
4627#[derive(Debug)]
4628pub struct WeakViewHandle<T> {
4629    window_id: usize,
4630    view_id: usize,
4631    view_type: PhantomData<T>,
4632}
4633
4634impl<T> WeakHandle for WeakViewHandle<T> {
4635    fn id(&self) -> usize {
4636        self.view_id
4637    }
4638}
4639
4640impl<T: View> WeakViewHandle<T> {
4641    fn new(window_id: usize, view_id: usize) -> Self {
4642        Self {
4643            window_id,
4644            view_id,
4645            view_type: PhantomData,
4646        }
4647    }
4648
4649    pub fn id(&self) -> usize {
4650        self.view_id
4651    }
4652
4653    pub fn window_id(&self) -> usize {
4654        self.window_id
4655    }
4656
4657    pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<ViewHandle<T>> {
4658        cx.upgrade_view_handle(self)
4659    }
4660}
4661
4662impl<T> Clone for WeakViewHandle<T> {
4663    fn clone(&self) -> Self {
4664        Self {
4665            window_id: self.window_id,
4666            view_id: self.view_id,
4667            view_type: PhantomData,
4668        }
4669    }
4670}
4671
4672impl<T> PartialEq for WeakViewHandle<T> {
4673    fn eq(&self, other: &Self) -> bool {
4674        self.window_id == other.window_id && self.view_id == other.view_id
4675    }
4676}
4677
4678impl<T> Eq for WeakViewHandle<T> {}
4679
4680impl<T> Hash for WeakViewHandle<T> {
4681    fn hash<H: Hasher>(&self, state: &mut H) {
4682        self.window_id.hash(state);
4683        self.view_id.hash(state);
4684    }
4685}
4686
4687pub struct AnyWeakViewHandle {
4688    window_id: usize,
4689    view_id: usize,
4690    view_type: TypeId,
4691}
4692
4693impl AnyWeakViewHandle {
4694    pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<AnyViewHandle> {
4695        cx.upgrade_any_view_handle(self)
4696    }
4697}
4698
4699impl<T: View> From<WeakViewHandle<T>> for AnyWeakViewHandle {
4700    fn from(handle: WeakViewHandle<T>) -> Self {
4701        AnyWeakViewHandle {
4702            window_id: handle.window_id,
4703            view_id: handle.view_id,
4704            view_type: TypeId::of::<T>(),
4705        }
4706    }
4707}
4708
4709#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4710pub struct ElementStateId {
4711    view_id: usize,
4712    element_id: usize,
4713    tag: TypeId,
4714}
4715
4716pub struct ElementStateHandle<T> {
4717    value_type: PhantomData<T>,
4718    id: ElementStateId,
4719    ref_counts: Weak<Mutex<RefCounts>>,
4720}
4721
4722impl<T: 'static> ElementStateHandle<T> {
4723    fn new(id: ElementStateId, frame_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
4724        ref_counts.lock().inc_element_state(id, frame_id);
4725        Self {
4726            value_type: PhantomData,
4727            id,
4728            ref_counts: Arc::downgrade(ref_counts),
4729        }
4730    }
4731
4732    pub fn id(&self) -> ElementStateId {
4733        self.id
4734    }
4735
4736    pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
4737        cx.element_states
4738            .get(&self.id)
4739            .unwrap()
4740            .downcast_ref()
4741            .unwrap()
4742    }
4743
4744    pub fn update<C, R>(&self, cx: &mut C, f: impl FnOnce(&mut T, &mut C) -> R) -> R
4745    where
4746        C: DerefMut<Target = MutableAppContext>,
4747    {
4748        let mut element_state = cx.deref_mut().cx.element_states.remove(&self.id).unwrap();
4749        let result = f(element_state.downcast_mut().unwrap(), cx);
4750        cx.deref_mut()
4751            .cx
4752            .element_states
4753            .insert(self.id, element_state);
4754        result
4755    }
4756}
4757
4758impl<T> Drop for ElementStateHandle<T> {
4759    fn drop(&mut self) {
4760        if let Some(ref_counts) = self.ref_counts.upgrade() {
4761            ref_counts.lock().dec_element_state(self.id);
4762        }
4763    }
4764}
4765
4766#[must_use]
4767pub enum Subscription {
4768    Subscription {
4769        id: usize,
4770        entity_id: usize,
4771        subscriptions: Option<Weak<Mapping<usize, SubscriptionCallback>>>,
4772    },
4773    GlobalSubscription {
4774        id: usize,
4775        type_id: TypeId,
4776        subscriptions: Option<Weak<Mapping<TypeId, GlobalSubscriptionCallback>>>,
4777    },
4778    Observation {
4779        id: usize,
4780        entity_id: usize,
4781        observations: Option<Weak<Mapping<usize, ObservationCallback>>>,
4782    },
4783    GlobalObservation {
4784        id: usize,
4785        type_id: TypeId,
4786        observations: Option<Weak<Mapping<TypeId, GlobalObservationCallback>>>,
4787    },
4788    FocusObservation {
4789        id: usize,
4790        view_id: usize,
4791        observations: Option<Weak<Mapping<usize, FocusObservationCallback>>>,
4792    },
4793    WindowActivationObservation {
4794        id: usize,
4795        window_id: usize,
4796        observations: Option<Weak<Mapping<usize, WindowActivationCallback>>>,
4797    },
4798    WindowFullscreenObservation {
4799        id: usize,
4800        window_id: usize,
4801        observations: Option<Weak<Mapping<usize, WindowFullscreenCallback>>>,
4802    },
4803
4804    ReleaseObservation {
4805        id: usize,
4806        entity_id: usize,
4807        #[allow(clippy::type_complexity)]
4808        observations:
4809            Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, ReleaseObservationCallback>>>>>,
4810    },
4811    ActionObservation {
4812        id: usize,
4813        observations: Option<Weak<Mutex<BTreeMap<usize, ActionObservationCallback>>>>,
4814    },
4815}
4816
4817impl Subscription {
4818    pub fn detach(&mut self) {
4819        match self {
4820            Subscription::Subscription { subscriptions, .. } => {
4821                subscriptions.take();
4822            }
4823            Subscription::GlobalSubscription { subscriptions, .. } => {
4824                subscriptions.take();
4825            }
4826            Subscription::Observation { observations, .. } => {
4827                observations.take();
4828            }
4829            Subscription::GlobalObservation { observations, .. } => {
4830                observations.take();
4831            }
4832            Subscription::ReleaseObservation { observations, .. } => {
4833                observations.take();
4834            }
4835            Subscription::FocusObservation { observations, .. } => {
4836                observations.take();
4837            }
4838            Subscription::ActionObservation { observations, .. } => {
4839                observations.take();
4840            }
4841            Subscription::WindowActivationObservation { observations, .. } => {
4842                observations.take();
4843            }
4844            Subscription::WindowFullscreenObservation { observations, .. } => {
4845                observations.take();
4846            }
4847        }
4848    }
4849}
4850
4851impl Drop for Subscription {
4852    fn drop(&mut self) {
4853        match self {
4854            Subscription::Subscription {
4855                id,
4856                entity_id,
4857                subscriptions,
4858            } => {
4859                if let Some(subscriptions) = subscriptions.as_ref().and_then(Weak::upgrade) {
4860                    match subscriptions
4861                        .lock()
4862                        .entry(*entity_id)
4863                        .or_default()
4864                        .entry(*id)
4865                    {
4866                        btree_map::Entry::Vacant(entry) => {
4867                            entry.insert(None);
4868                        }
4869                        btree_map::Entry::Occupied(entry) => {
4870                            entry.remove();
4871                        }
4872                    }
4873                }
4874            }
4875            Subscription::GlobalSubscription {
4876                id,
4877                type_id,
4878                subscriptions,
4879            } => {
4880                if let Some(subscriptions) = subscriptions.as_ref().and_then(Weak::upgrade) {
4881                    match subscriptions.lock().entry(*type_id).or_default().entry(*id) {
4882                        btree_map::Entry::Vacant(entry) => {
4883                            entry.insert(None);
4884                        }
4885                        btree_map::Entry::Occupied(entry) => {
4886                            entry.remove();
4887                        }
4888                    }
4889                }
4890            }
4891            Subscription::Observation {
4892                id,
4893                entity_id,
4894                observations,
4895            } => {
4896                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4897                    match observations
4898                        .lock()
4899                        .entry(*entity_id)
4900                        .or_default()
4901                        .entry(*id)
4902                    {
4903                        btree_map::Entry::Vacant(entry) => {
4904                            entry.insert(None);
4905                        }
4906                        btree_map::Entry::Occupied(entry) => {
4907                            entry.remove();
4908                        }
4909                    }
4910                }
4911            }
4912            Subscription::GlobalObservation {
4913                id,
4914                type_id,
4915                observations,
4916            } => {
4917                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4918                    match observations.lock().entry(*type_id).or_default().entry(*id) {
4919                        collections::btree_map::Entry::Vacant(entry) => {
4920                            entry.insert(None);
4921                        }
4922                        collections::btree_map::Entry::Occupied(entry) => {
4923                            entry.remove();
4924                        }
4925                    }
4926                }
4927            }
4928            Subscription::ReleaseObservation {
4929                id,
4930                entity_id,
4931                observations,
4932            } => {
4933                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4934                    if let Some(observations) = observations.lock().get_mut(entity_id) {
4935                        observations.remove(id);
4936                    }
4937                }
4938            }
4939            Subscription::FocusObservation {
4940                id,
4941                view_id,
4942                observations,
4943            } => {
4944                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4945                    match observations.lock().entry(*view_id).or_default().entry(*id) {
4946                        btree_map::Entry::Vacant(entry) => {
4947                            entry.insert(None);
4948                        }
4949                        btree_map::Entry::Occupied(entry) => {
4950                            entry.remove();
4951                        }
4952                    }
4953                }
4954            }
4955            Subscription::ActionObservation { id, observations } => {
4956                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4957                    observations.lock().remove(id);
4958                }
4959            }
4960            Subscription::WindowActivationObservation {
4961                id,
4962                window_id,
4963                observations,
4964            } => {
4965                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4966                    match observations
4967                        .lock()
4968                        .entry(*window_id)
4969                        .or_default()
4970                        .entry(*id)
4971                    {
4972                        btree_map::Entry::Vacant(entry) => {
4973                            entry.insert(None);
4974                        }
4975                        btree_map::Entry::Occupied(entry) => {
4976                            entry.remove();
4977                        }
4978                    }
4979                }
4980            }
4981            Subscription::WindowFullscreenObservation {
4982                id,
4983                window_id,
4984                observations,
4985            } => {
4986                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4987                    match observations
4988                        .lock()
4989                        .entry(*window_id)
4990                        .or_default()
4991                        .entry(*id)
4992                    {
4993                        btree_map::Entry::Vacant(entry) => {
4994                            entry.insert(None);
4995                        }
4996                        btree_map::Entry::Occupied(entry) => {
4997                            entry.remove();
4998                        }
4999                    }
5000                }
5001            }
5002        }
5003    }
5004}
5005
5006lazy_static! {
5007    static ref LEAK_BACKTRACE: bool =
5008        std::env::var("LEAK_BACKTRACE").map_or(false, |b| !b.is_empty());
5009}
5010
5011#[cfg(any(test, feature = "test-support"))]
5012#[derive(Default)]
5013pub struct LeakDetector {
5014    next_handle_id: usize,
5015    #[allow(clippy::type_complexity)]
5016    handle_backtraces: HashMap<
5017        usize,
5018        (
5019            Option<&'static str>,
5020            HashMap<usize, Option<backtrace::Backtrace>>,
5021        ),
5022    >,
5023}
5024
5025#[cfg(any(test, feature = "test-support"))]
5026impl LeakDetector {
5027    fn handle_created(&mut self, type_name: Option<&'static str>, entity_id: usize) -> usize {
5028        let handle_id = post_inc(&mut self.next_handle_id);
5029        let entry = self.handle_backtraces.entry(entity_id).or_default();
5030        let backtrace = if *LEAK_BACKTRACE {
5031            Some(backtrace::Backtrace::new_unresolved())
5032        } else {
5033            None
5034        };
5035        if let Some(type_name) = type_name {
5036            entry.0.get_or_insert(type_name);
5037        }
5038        entry.1.insert(handle_id, backtrace);
5039        handle_id
5040    }
5041
5042    fn handle_dropped(&mut self, entity_id: usize, handle_id: usize) {
5043        if let Some((_, backtraces)) = self.handle_backtraces.get_mut(&entity_id) {
5044            assert!(backtraces.remove(&handle_id).is_some());
5045            if backtraces.is_empty() {
5046                self.handle_backtraces.remove(&entity_id);
5047            }
5048        }
5049    }
5050
5051    pub fn assert_dropped(&mut self, entity_id: usize) {
5052        if let Some((type_name, backtraces)) = self.handle_backtraces.get_mut(&entity_id) {
5053            for trace in backtraces.values_mut().flatten() {
5054                trace.resolve();
5055                eprintln!("{:?}", crate::util::CwdBacktrace(trace));
5056            }
5057
5058            let hint = if *LEAK_BACKTRACE {
5059                ""
5060            } else {
5061                " – set LEAK_BACKTRACE=1 for more information"
5062            };
5063
5064            panic!(
5065                "{} handles to {} {} still exist{}",
5066                backtraces.len(),
5067                type_name.unwrap_or("entity"),
5068                entity_id,
5069                hint
5070            );
5071        }
5072    }
5073
5074    pub fn detect(&mut self) {
5075        let mut found_leaks = false;
5076        for (id, (type_name, backtraces)) in self.handle_backtraces.iter_mut() {
5077            eprintln!(
5078                "leaked {} handles to {} {}",
5079                backtraces.len(),
5080                type_name.unwrap_or("entity"),
5081                id
5082            );
5083            for trace in backtraces.values_mut().flatten() {
5084                trace.resolve();
5085                eprintln!("{:?}", crate::util::CwdBacktrace(trace));
5086            }
5087            found_leaks = true;
5088        }
5089
5090        let hint = if *LEAK_BACKTRACE {
5091            ""
5092        } else {
5093            " – set LEAK_BACKTRACE=1 for more information"
5094        };
5095        assert!(!found_leaks, "detected leaked handles{}", hint);
5096    }
5097}
5098
5099#[derive(Default)]
5100struct RefCounts {
5101    entity_counts: HashMap<usize, usize>,
5102    element_state_counts: HashMap<ElementStateId, ElementStateRefCount>,
5103    dropped_models: HashSet<usize>,
5104    dropped_views: HashSet<(usize, usize)>,
5105    dropped_element_states: HashSet<ElementStateId>,
5106
5107    #[cfg(any(test, feature = "test-support"))]
5108    leak_detector: Arc<Mutex<LeakDetector>>,
5109}
5110
5111struct ElementStateRefCount {
5112    ref_count: usize,
5113    frame_id: usize,
5114}
5115
5116impl RefCounts {
5117    fn inc_model(&mut self, model_id: usize) {
5118        match self.entity_counts.entry(model_id) {
5119            Entry::Occupied(mut entry) => {
5120                *entry.get_mut() += 1;
5121            }
5122            Entry::Vacant(entry) => {
5123                entry.insert(1);
5124                self.dropped_models.remove(&model_id);
5125            }
5126        }
5127    }
5128
5129    fn inc_view(&mut self, window_id: usize, view_id: usize) {
5130        match self.entity_counts.entry(view_id) {
5131            Entry::Occupied(mut entry) => *entry.get_mut() += 1,
5132            Entry::Vacant(entry) => {
5133                entry.insert(1);
5134                self.dropped_views.remove(&(window_id, view_id));
5135            }
5136        }
5137    }
5138
5139    fn inc_element_state(&mut self, id: ElementStateId, frame_id: usize) {
5140        match self.element_state_counts.entry(id) {
5141            Entry::Occupied(mut entry) => {
5142                let entry = entry.get_mut();
5143                if entry.frame_id == frame_id || entry.ref_count >= 2 {
5144                    panic!("used the same element state more than once in the same frame");
5145                }
5146                entry.ref_count += 1;
5147                entry.frame_id = frame_id;
5148            }
5149            Entry::Vacant(entry) => {
5150                entry.insert(ElementStateRefCount {
5151                    ref_count: 1,
5152                    frame_id,
5153                });
5154                self.dropped_element_states.remove(&id);
5155            }
5156        }
5157    }
5158
5159    fn dec_model(&mut self, model_id: usize) {
5160        let count = self.entity_counts.get_mut(&model_id).unwrap();
5161        *count -= 1;
5162        if *count == 0 {
5163            self.entity_counts.remove(&model_id);
5164            self.dropped_models.insert(model_id);
5165        }
5166    }
5167
5168    fn dec_view(&mut self, window_id: usize, view_id: usize) {
5169        let count = self.entity_counts.get_mut(&view_id).unwrap();
5170        *count -= 1;
5171        if *count == 0 {
5172            self.entity_counts.remove(&view_id);
5173            self.dropped_views.insert((window_id, view_id));
5174        }
5175    }
5176
5177    fn dec_element_state(&mut self, id: ElementStateId) {
5178        let entry = self.element_state_counts.get_mut(&id).unwrap();
5179        entry.ref_count -= 1;
5180        if entry.ref_count == 0 {
5181            self.element_state_counts.remove(&id);
5182            self.dropped_element_states.insert(id);
5183        }
5184    }
5185
5186    fn is_entity_alive(&self, entity_id: usize) -> bool {
5187        self.entity_counts.contains_key(&entity_id)
5188    }
5189
5190    fn take_dropped(
5191        &mut self,
5192    ) -> (
5193        HashSet<usize>,
5194        HashSet<(usize, usize)>,
5195        HashSet<ElementStateId>,
5196    ) {
5197        (
5198            std::mem::take(&mut self.dropped_models),
5199            std::mem::take(&mut self.dropped_views),
5200            std::mem::take(&mut self.dropped_element_states),
5201        )
5202    }
5203}
5204
5205#[cfg(test)]
5206mod tests {
5207    use super::*;
5208    use crate::{actions, elements::*, impl_actions, MouseButton, MouseButtonEvent};
5209    use serde::Deserialize;
5210    use smol::future::poll_once;
5211    use std::{
5212        cell::Cell,
5213        sync::atomic::{AtomicBool, AtomicUsize, Ordering::SeqCst},
5214    };
5215
5216    #[crate::test(self)]
5217    fn test_model_handles(cx: &mut MutableAppContext) {
5218        struct Model {
5219            other: Option<ModelHandle<Model>>,
5220            events: Vec<String>,
5221        }
5222
5223        impl Entity for Model {
5224            type Event = usize;
5225        }
5226
5227        impl Model {
5228            fn new(other: Option<ModelHandle<Self>>, cx: &mut ModelContext<Self>) -> Self {
5229                if let Some(other) = other.as_ref() {
5230                    cx.observe(other, |me, _, _| {
5231                        me.events.push("notified".into());
5232                    })
5233                    .detach();
5234                    cx.subscribe(other, |me, _, event, _| {
5235                        me.events.push(format!("observed event {}", event));
5236                    })
5237                    .detach();
5238                }
5239
5240                Self {
5241                    other,
5242                    events: Vec::new(),
5243                }
5244            }
5245        }
5246
5247        let handle_1 = cx.add_model(|cx| Model::new(None, cx));
5248        let handle_2 = cx.add_model(|cx| Model::new(Some(handle_1.clone()), cx));
5249        assert_eq!(cx.cx.models.len(), 2);
5250
5251        handle_1.update(cx, |model, cx| {
5252            model.events.push("updated".into());
5253            cx.emit(1);
5254            cx.notify();
5255            cx.emit(2);
5256        });
5257        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
5258        assert_eq!(
5259            handle_2.read(cx).events,
5260            vec![
5261                "observed event 1".to_string(),
5262                "notified".to_string(),
5263                "observed event 2".to_string(),
5264            ]
5265        );
5266
5267        handle_2.update(cx, |model, _| {
5268            drop(handle_1);
5269            model.other.take();
5270        });
5271
5272        assert_eq!(cx.cx.models.len(), 1);
5273        assert!(cx.subscriptions.is_empty());
5274        assert!(cx.observations.is_empty());
5275    }
5276
5277    #[crate::test(self)]
5278    fn test_model_events(cx: &mut MutableAppContext) {
5279        #[derive(Default)]
5280        struct Model {
5281            events: Vec<usize>,
5282        }
5283
5284        impl Entity for Model {
5285            type Event = usize;
5286        }
5287
5288        let handle_1 = cx.add_model(|_| Model::default());
5289        let handle_2 = cx.add_model(|_| Model::default());
5290
5291        handle_1.update(cx, |_, cx| {
5292            cx.subscribe(&handle_2, move |model: &mut Model, emitter, event, cx| {
5293                model.events.push(*event);
5294
5295                cx.subscribe(&emitter, |model, _, event, _| {
5296                    model.events.push(*event * 2);
5297                })
5298                .detach();
5299            })
5300            .detach();
5301        });
5302
5303        handle_2.update(cx, |_, c| c.emit(7));
5304        assert_eq!(handle_1.read(cx).events, vec![7]);
5305
5306        handle_2.update(cx, |_, c| c.emit(5));
5307        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
5308    }
5309
5310    #[crate::test(self)]
5311    fn test_model_emit_before_subscribe_in_same_update_cycle(cx: &mut MutableAppContext) {
5312        #[derive(Default)]
5313        struct Model;
5314
5315        impl Entity for Model {
5316            type Event = ();
5317        }
5318
5319        let events = Rc::new(RefCell::new(Vec::new()));
5320        cx.add_model(|cx| {
5321            drop(cx.subscribe(&cx.handle(), {
5322                let events = events.clone();
5323                move |_, _, _, _| events.borrow_mut().push("dropped before flush")
5324            }));
5325            cx.subscribe(&cx.handle(), {
5326                let events = events.clone();
5327                move |_, _, _, _| events.borrow_mut().push("before emit")
5328            })
5329            .detach();
5330            cx.emit(());
5331            cx.subscribe(&cx.handle(), {
5332                let events = events.clone();
5333                move |_, _, _, _| events.borrow_mut().push("after emit")
5334            })
5335            .detach();
5336            Model
5337        });
5338        assert_eq!(*events.borrow(), ["before emit"]);
5339    }
5340
5341    #[crate::test(self)]
5342    fn test_observe_and_notify_from_model(cx: &mut MutableAppContext) {
5343        #[derive(Default)]
5344        struct Model {
5345            count: usize,
5346            events: Vec<usize>,
5347        }
5348
5349        impl Entity for Model {
5350            type Event = ();
5351        }
5352
5353        let handle_1 = cx.add_model(|_| Model::default());
5354        let handle_2 = cx.add_model(|_| Model::default());
5355
5356        handle_1.update(cx, |_, c| {
5357            c.observe(&handle_2, move |model, observed, c| {
5358                model.events.push(observed.read(c).count);
5359                c.observe(&observed, |model, observed, c| {
5360                    model.events.push(observed.read(c).count * 2);
5361                })
5362                .detach();
5363            })
5364            .detach();
5365        });
5366
5367        handle_2.update(cx, |model, c| {
5368            model.count = 7;
5369            c.notify()
5370        });
5371        assert_eq!(handle_1.read(cx).events, vec![7]);
5372
5373        handle_2.update(cx, |model, c| {
5374            model.count = 5;
5375            c.notify()
5376        });
5377        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10])
5378    }
5379
5380    #[crate::test(self)]
5381    fn test_model_notify_before_observe_in_same_update_cycle(cx: &mut MutableAppContext) {
5382        #[derive(Default)]
5383        struct Model;
5384
5385        impl Entity for Model {
5386            type Event = ();
5387        }
5388
5389        let events = Rc::new(RefCell::new(Vec::new()));
5390        cx.add_model(|cx| {
5391            drop(cx.observe(&cx.handle(), {
5392                let events = events.clone();
5393                move |_, _, _| events.borrow_mut().push("dropped before flush")
5394            }));
5395            cx.observe(&cx.handle(), {
5396                let events = events.clone();
5397                move |_, _, _| events.borrow_mut().push("before notify")
5398            })
5399            .detach();
5400            cx.notify();
5401            cx.observe(&cx.handle(), {
5402                let events = events.clone();
5403                move |_, _, _| events.borrow_mut().push("after notify")
5404            })
5405            .detach();
5406            Model
5407        });
5408        assert_eq!(*events.borrow(), ["before notify"]);
5409    }
5410
5411    #[crate::test(self)]
5412    fn test_defer_and_after_window_update(cx: &mut MutableAppContext) {
5413        struct View {
5414            render_count: usize,
5415        }
5416
5417        impl Entity for View {
5418            type Event = usize;
5419        }
5420
5421        impl super::View for View {
5422            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5423                post_inc(&mut self.render_count);
5424                Empty::new().boxed()
5425            }
5426
5427            fn ui_name() -> &'static str {
5428                "View"
5429            }
5430        }
5431
5432        let (_, view) = cx.add_window(Default::default(), |_| View { render_count: 0 });
5433        let called_defer = Rc::new(AtomicBool::new(false));
5434        let called_after_window_update = Rc::new(AtomicBool::new(false));
5435
5436        view.update(cx, |this, cx| {
5437            assert_eq!(this.render_count, 1);
5438            cx.defer({
5439                let called_defer = called_defer.clone();
5440                move |this, _| {
5441                    assert_eq!(this.render_count, 1);
5442                    called_defer.store(true, SeqCst);
5443                }
5444            });
5445            cx.after_window_update({
5446                let called_after_window_update = called_after_window_update.clone();
5447                move |this, cx| {
5448                    assert_eq!(this.render_count, 2);
5449                    called_after_window_update.store(true, SeqCst);
5450                    cx.notify();
5451                }
5452            });
5453            assert!(!called_defer.load(SeqCst));
5454            assert!(!called_after_window_update.load(SeqCst));
5455            cx.notify();
5456        });
5457
5458        assert!(called_defer.load(SeqCst));
5459        assert!(called_after_window_update.load(SeqCst));
5460        assert_eq!(view.read(cx).render_count, 3);
5461    }
5462
5463    #[crate::test(self)]
5464    fn test_view_handles(cx: &mut MutableAppContext) {
5465        struct View {
5466            other: Option<ViewHandle<View>>,
5467            events: Vec<String>,
5468        }
5469
5470        impl Entity for View {
5471            type Event = usize;
5472        }
5473
5474        impl super::View for View {
5475            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5476                Empty::new().boxed()
5477            }
5478
5479            fn ui_name() -> &'static str {
5480                "View"
5481            }
5482        }
5483
5484        impl View {
5485            fn new(other: Option<ViewHandle<View>>, cx: &mut ViewContext<Self>) -> Self {
5486                if let Some(other) = other.as_ref() {
5487                    cx.subscribe(other, |me, _, event, _| {
5488                        me.events.push(format!("observed event {}", event));
5489                    })
5490                    .detach();
5491                }
5492                Self {
5493                    other,
5494                    events: Vec::new(),
5495                }
5496            }
5497        }
5498
5499        let (_, root_view) = cx.add_window(Default::default(), |cx| View::new(None, cx));
5500        let handle_1 = cx.add_view(&root_view, |cx| View::new(None, cx));
5501        let handle_2 = cx.add_view(&root_view, |cx| View::new(Some(handle_1.clone()), cx));
5502        assert_eq!(cx.cx.views.len(), 3);
5503
5504        handle_1.update(cx, |view, cx| {
5505            view.events.push("updated".into());
5506            cx.emit(1);
5507            cx.emit(2);
5508        });
5509        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
5510        assert_eq!(
5511            handle_2.read(cx).events,
5512            vec![
5513                "observed event 1".to_string(),
5514                "observed event 2".to_string(),
5515            ]
5516        );
5517
5518        handle_2.update(cx, |view, _| {
5519            drop(handle_1);
5520            view.other.take();
5521        });
5522
5523        assert_eq!(cx.cx.views.len(), 2);
5524        assert!(cx.subscriptions.is_empty());
5525        assert!(cx.observations.is_empty());
5526    }
5527
5528    #[crate::test(self)]
5529    fn test_add_window(cx: &mut MutableAppContext) {
5530        struct View {
5531            mouse_down_count: Arc<AtomicUsize>,
5532        }
5533
5534        impl Entity for View {
5535            type Event = ();
5536        }
5537
5538        impl super::View for View {
5539            fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
5540                enum Handler {}
5541                let mouse_down_count = self.mouse_down_count.clone();
5542                MouseEventHandler::<Handler>::new(0, cx, |_, _| Empty::new().boxed())
5543                    .on_down(MouseButton::Left, move |_, _| {
5544                        mouse_down_count.fetch_add(1, SeqCst);
5545                    })
5546                    .boxed()
5547            }
5548
5549            fn ui_name() -> &'static str {
5550                "View"
5551            }
5552        }
5553
5554        let mouse_down_count = Arc::new(AtomicUsize::new(0));
5555        let (window_id, _) = cx.add_window(Default::default(), |_| View {
5556            mouse_down_count: mouse_down_count.clone(),
5557        });
5558        let presenter = cx.presenters_and_platform_windows[&window_id].0.clone();
5559        // Ensure window's root element is in a valid lifecycle state.
5560        presenter.borrow_mut().dispatch_event(
5561            Event::MouseDown(MouseButtonEvent {
5562                position: Default::default(),
5563                button: MouseButton::Left,
5564                ctrl: false,
5565                alt: false,
5566                shift: false,
5567                cmd: false,
5568                click_count: 1,
5569            }),
5570            false,
5571            cx,
5572        );
5573        assert_eq!(mouse_down_count.load(SeqCst), 1);
5574    }
5575
5576    #[crate::test(self)]
5577    fn test_entity_release_hooks(cx: &mut MutableAppContext) {
5578        struct Model {
5579            released: Rc<Cell<bool>>,
5580        }
5581
5582        struct View {
5583            released: Rc<Cell<bool>>,
5584        }
5585
5586        impl Entity for Model {
5587            type Event = ();
5588
5589            fn release(&mut self, _: &mut MutableAppContext) {
5590                self.released.set(true);
5591            }
5592        }
5593
5594        impl Entity for View {
5595            type Event = ();
5596
5597            fn release(&mut self, _: &mut MutableAppContext) {
5598                self.released.set(true);
5599            }
5600        }
5601
5602        impl super::View for View {
5603            fn ui_name() -> &'static str {
5604                "View"
5605            }
5606
5607            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5608                Empty::new().boxed()
5609            }
5610        }
5611
5612        let model_released = Rc::new(Cell::new(false));
5613        let model_release_observed = Rc::new(Cell::new(false));
5614        let view_released = Rc::new(Cell::new(false));
5615        let view_release_observed = Rc::new(Cell::new(false));
5616
5617        let model = cx.add_model(|_| Model {
5618            released: model_released.clone(),
5619        });
5620        let (window_id, view) = cx.add_window(Default::default(), |_| View {
5621            released: view_released.clone(),
5622        });
5623        assert!(!model_released.get());
5624        assert!(!view_released.get());
5625
5626        cx.observe_release(&model, {
5627            let model_release_observed = model_release_observed.clone();
5628            move |_, _| model_release_observed.set(true)
5629        })
5630        .detach();
5631        cx.observe_release(&view, {
5632            let view_release_observed = view_release_observed.clone();
5633            move |_, _| view_release_observed.set(true)
5634        })
5635        .detach();
5636
5637        cx.update(move |_| {
5638            drop(model);
5639        });
5640        assert!(model_released.get());
5641        assert!(model_release_observed.get());
5642
5643        drop(view);
5644        cx.remove_window(window_id);
5645        assert!(view_released.get());
5646        assert!(view_release_observed.get());
5647    }
5648
5649    #[crate::test(self)]
5650    fn test_view_events(cx: &mut MutableAppContext) {
5651        #[derive(Default)]
5652        struct View {
5653            events: Vec<usize>,
5654        }
5655
5656        impl Entity for View {
5657            type Event = usize;
5658        }
5659
5660        impl super::View for View {
5661            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5662                Empty::new().boxed()
5663            }
5664
5665            fn ui_name() -> &'static str {
5666                "View"
5667            }
5668        }
5669
5670        struct Model;
5671
5672        impl Entity for Model {
5673            type Event = usize;
5674        }
5675
5676        let (_, handle_1) = cx.add_window(Default::default(), |_| View::default());
5677        let handle_2 = cx.add_view(&handle_1, |_| View::default());
5678        let handle_3 = cx.add_model(|_| Model);
5679
5680        handle_1.update(cx, |_, cx| {
5681            cx.subscribe(&handle_2, move |me, emitter, event, cx| {
5682                me.events.push(*event);
5683
5684                cx.subscribe(&emitter, |me, _, event, _| {
5685                    me.events.push(*event * 2);
5686                })
5687                .detach();
5688            })
5689            .detach();
5690
5691            cx.subscribe(&handle_3, |me, _, event, _| {
5692                me.events.push(*event);
5693            })
5694            .detach();
5695        });
5696
5697        handle_2.update(cx, |_, c| c.emit(7));
5698        assert_eq!(handle_1.read(cx).events, vec![7]);
5699
5700        handle_2.update(cx, |_, c| c.emit(5));
5701        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
5702
5703        handle_3.update(cx, |_, c| c.emit(9));
5704        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10, 9]);
5705    }
5706
5707    #[crate::test(self)]
5708    fn test_global_events(cx: &mut MutableAppContext) {
5709        #[derive(Clone, Debug, Eq, PartialEq)]
5710        struct GlobalEvent(u64);
5711
5712        let events = Rc::new(RefCell::new(Vec::new()));
5713        let first_subscription;
5714        let second_subscription;
5715
5716        {
5717            let events = events.clone();
5718            first_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
5719                events.borrow_mut().push(("First", e.clone()));
5720            });
5721        }
5722
5723        {
5724            let events = events.clone();
5725            second_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
5726                events.borrow_mut().push(("Second", e.clone()));
5727            });
5728        }
5729
5730        cx.update(|cx| {
5731            cx.emit_global(GlobalEvent(1));
5732            cx.emit_global(GlobalEvent(2));
5733        });
5734
5735        drop(first_subscription);
5736
5737        cx.update(|cx| {
5738            cx.emit_global(GlobalEvent(3));
5739        });
5740
5741        drop(second_subscription);
5742
5743        cx.update(|cx| {
5744            cx.emit_global(GlobalEvent(4));
5745        });
5746
5747        assert_eq!(
5748            &*events.borrow(),
5749            &[
5750                ("First", GlobalEvent(1)),
5751                ("Second", GlobalEvent(1)),
5752                ("First", GlobalEvent(2)),
5753                ("Second", GlobalEvent(2)),
5754                ("Second", GlobalEvent(3)),
5755            ]
5756        );
5757    }
5758
5759    #[crate::test(self)]
5760    fn test_global_events_emitted_before_subscription_in_same_update_cycle(
5761        cx: &mut MutableAppContext,
5762    ) {
5763        let events = Rc::new(RefCell::new(Vec::new()));
5764        cx.update(|cx| {
5765            {
5766                let events = events.clone();
5767                drop(cx.subscribe_global(move |_: &(), _| {
5768                    events.borrow_mut().push("dropped before emit");
5769                }));
5770            }
5771
5772            {
5773                let events = events.clone();
5774                cx.subscribe_global(move |_: &(), _| {
5775                    events.borrow_mut().push("before emit");
5776                })
5777                .detach();
5778            }
5779
5780            cx.emit_global(());
5781
5782            {
5783                let events = events.clone();
5784                cx.subscribe_global(move |_: &(), _| {
5785                    events.borrow_mut().push("after emit");
5786                })
5787                .detach();
5788            }
5789        });
5790
5791        assert_eq!(*events.borrow(), ["before emit"]);
5792    }
5793
5794    #[crate::test(self)]
5795    fn test_global_nested_events(cx: &mut MutableAppContext) {
5796        #[derive(Clone, Debug, Eq, PartialEq)]
5797        struct GlobalEvent(u64);
5798
5799        let events = Rc::new(RefCell::new(Vec::new()));
5800
5801        {
5802            let events = events.clone();
5803            cx.subscribe_global(move |e: &GlobalEvent, cx| {
5804                events.borrow_mut().push(("Outer", e.clone()));
5805
5806                if e.0 == 1 {
5807                    let events = events.clone();
5808                    cx.subscribe_global(move |e: &GlobalEvent, _| {
5809                        events.borrow_mut().push(("Inner", e.clone()));
5810                    })
5811                    .detach();
5812                }
5813            })
5814            .detach();
5815        }
5816
5817        cx.update(|cx| {
5818            cx.emit_global(GlobalEvent(1));
5819            cx.emit_global(GlobalEvent(2));
5820            cx.emit_global(GlobalEvent(3));
5821        });
5822        cx.update(|cx| {
5823            cx.emit_global(GlobalEvent(4));
5824        });
5825
5826        assert_eq!(
5827            &*events.borrow(),
5828            &[
5829                ("Outer", GlobalEvent(1)),
5830                ("Outer", GlobalEvent(2)),
5831                ("Outer", GlobalEvent(3)),
5832                ("Outer", GlobalEvent(4)),
5833                ("Inner", GlobalEvent(4)),
5834            ]
5835        );
5836    }
5837
5838    #[crate::test(self)]
5839    fn test_global(cx: &mut MutableAppContext) {
5840        type Global = usize;
5841
5842        let observation_count = Rc::new(RefCell::new(0));
5843        let subscription = cx.observe_global::<Global, _>({
5844            let observation_count = observation_count.clone();
5845            move |_| {
5846                *observation_count.borrow_mut() += 1;
5847            }
5848        });
5849
5850        assert!(!cx.has_global::<Global>());
5851        assert_eq!(cx.default_global::<Global>(), &0);
5852        assert_eq!(*observation_count.borrow(), 1);
5853        assert!(cx.has_global::<Global>());
5854        assert_eq!(
5855            cx.update_global::<Global, _, _>(|global, _| {
5856                *global = 1;
5857                "Update Result"
5858            }),
5859            "Update Result"
5860        );
5861        assert_eq!(*observation_count.borrow(), 2);
5862        assert_eq!(cx.global::<Global>(), &1);
5863
5864        drop(subscription);
5865        cx.update_global::<Global, _, _>(|global, _| {
5866            *global = 2;
5867        });
5868        assert_eq!(*observation_count.borrow(), 2);
5869
5870        type OtherGlobal = f32;
5871
5872        let observation_count = Rc::new(RefCell::new(0));
5873        cx.observe_global::<OtherGlobal, _>({
5874            let observation_count = observation_count.clone();
5875            move |_| {
5876                *observation_count.borrow_mut() += 1;
5877            }
5878        })
5879        .detach();
5880
5881        assert_eq!(
5882            cx.update_default_global::<OtherGlobal, _, _>(|global, _| {
5883                assert_eq!(global, &0.0);
5884                *global = 2.0;
5885                "Default update result"
5886            }),
5887            "Default update result"
5888        );
5889        assert_eq!(cx.global::<OtherGlobal>(), &2.0);
5890        assert_eq!(*observation_count.borrow(), 1);
5891    }
5892
5893    #[crate::test(self)]
5894    fn test_dropping_subscribers(cx: &mut MutableAppContext) {
5895        struct View;
5896
5897        impl Entity for View {
5898            type Event = ();
5899        }
5900
5901        impl super::View for View {
5902            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5903                Empty::new().boxed()
5904            }
5905
5906            fn ui_name() -> &'static str {
5907                "View"
5908            }
5909        }
5910
5911        struct Model;
5912
5913        impl Entity for Model {
5914            type Event = ();
5915        }
5916
5917        let (_, root_view) = cx.add_window(Default::default(), |_| View);
5918        let observing_view = cx.add_view(&root_view, |_| View);
5919        let emitting_view = cx.add_view(&root_view, |_| View);
5920        let observing_model = cx.add_model(|_| Model);
5921        let observed_model = cx.add_model(|_| Model);
5922
5923        observing_view.update(cx, |_, cx| {
5924            cx.subscribe(&emitting_view, |_, _, _, _| {}).detach();
5925            cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
5926        });
5927        observing_model.update(cx, |_, cx| {
5928            cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
5929        });
5930
5931        cx.update(|_| {
5932            drop(observing_view);
5933            drop(observing_model);
5934        });
5935
5936        emitting_view.update(cx, |_, cx| cx.emit(()));
5937        observed_model.update(cx, |_, cx| cx.emit(()));
5938    }
5939
5940    #[crate::test(self)]
5941    fn test_view_emit_before_subscribe_in_same_update_cycle(cx: &mut MutableAppContext) {
5942        #[derive(Default)]
5943        struct TestView;
5944
5945        impl Entity for TestView {
5946            type Event = ();
5947        }
5948
5949        impl View for TestView {
5950            fn ui_name() -> &'static str {
5951                "TestView"
5952            }
5953
5954            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5955                Empty::new().boxed()
5956            }
5957        }
5958
5959        let events = Rc::new(RefCell::new(Vec::new()));
5960        cx.add_window(Default::default(), |cx| {
5961            drop(cx.subscribe(&cx.handle(), {
5962                let events = events.clone();
5963                move |_, _, _, _| events.borrow_mut().push("dropped before flush")
5964            }));
5965            cx.subscribe(&cx.handle(), {
5966                let events = events.clone();
5967                move |_, _, _, _| events.borrow_mut().push("before emit")
5968            })
5969            .detach();
5970            cx.emit(());
5971            cx.subscribe(&cx.handle(), {
5972                let events = events.clone();
5973                move |_, _, _, _| events.borrow_mut().push("after emit")
5974            })
5975            .detach();
5976            TestView
5977        });
5978        assert_eq!(*events.borrow(), ["before emit"]);
5979    }
5980
5981    #[crate::test(self)]
5982    fn test_observe_and_notify_from_view(cx: &mut MutableAppContext) {
5983        #[derive(Default)]
5984        struct View {
5985            events: Vec<usize>,
5986        }
5987
5988        impl Entity for View {
5989            type Event = usize;
5990        }
5991
5992        impl super::View for View {
5993            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5994                Empty::new().boxed()
5995            }
5996
5997            fn ui_name() -> &'static str {
5998                "View"
5999            }
6000        }
6001
6002        #[derive(Default)]
6003        struct Model {
6004            count: usize,
6005        }
6006
6007        impl Entity for Model {
6008            type Event = ();
6009        }
6010
6011        let (_, view) = cx.add_window(Default::default(), |_| View::default());
6012        let model = cx.add_model(|_| Model::default());
6013
6014        view.update(cx, |_, c| {
6015            c.observe(&model, |me, observed, c| {
6016                me.events.push(observed.read(c).count)
6017            })
6018            .detach();
6019        });
6020
6021        model.update(cx, |model, c| {
6022            model.count = 11;
6023            c.notify();
6024        });
6025        assert_eq!(view.read(cx).events, vec![11]);
6026    }
6027
6028    #[crate::test(self)]
6029    fn test_view_notify_before_observe_in_same_update_cycle(cx: &mut MutableAppContext) {
6030        #[derive(Default)]
6031        struct TestView;
6032
6033        impl Entity for TestView {
6034            type Event = ();
6035        }
6036
6037        impl View for TestView {
6038            fn ui_name() -> &'static str {
6039                "TestView"
6040            }
6041
6042            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6043                Empty::new().boxed()
6044            }
6045        }
6046
6047        let events = Rc::new(RefCell::new(Vec::new()));
6048        cx.add_window(Default::default(), |cx| {
6049            drop(cx.observe(&cx.handle(), {
6050                let events = events.clone();
6051                move |_, _, _| events.borrow_mut().push("dropped before flush")
6052            }));
6053            cx.observe(&cx.handle(), {
6054                let events = events.clone();
6055                move |_, _, _| events.borrow_mut().push("before notify")
6056            })
6057            .detach();
6058            cx.notify();
6059            cx.observe(&cx.handle(), {
6060                let events = events.clone();
6061                move |_, _, _| events.borrow_mut().push("after notify")
6062            })
6063            .detach();
6064            TestView
6065        });
6066        assert_eq!(*events.borrow(), ["before notify"]);
6067    }
6068
6069    #[crate::test(self)]
6070    fn test_dropping_observers(cx: &mut MutableAppContext) {
6071        struct View;
6072
6073        impl Entity for View {
6074            type Event = ();
6075        }
6076
6077        impl super::View for View {
6078            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6079                Empty::new().boxed()
6080            }
6081
6082            fn ui_name() -> &'static str {
6083                "View"
6084            }
6085        }
6086
6087        struct Model;
6088
6089        impl Entity for Model {
6090            type Event = ();
6091        }
6092
6093        let (_, root_view) = cx.add_window(Default::default(), |_| View);
6094        let observing_view = cx.add_view(root_view, |_| View);
6095        let observing_model = cx.add_model(|_| Model);
6096        let observed_model = cx.add_model(|_| Model);
6097
6098        observing_view.update(cx, |_, cx| {
6099            cx.observe(&observed_model, |_, _, _| {}).detach();
6100        });
6101        observing_model.update(cx, |_, cx| {
6102            cx.observe(&observed_model, |_, _, _| {}).detach();
6103        });
6104
6105        cx.update(|_| {
6106            drop(observing_view);
6107            drop(observing_model);
6108        });
6109
6110        observed_model.update(cx, |_, cx| cx.notify());
6111    }
6112
6113    #[crate::test(self)]
6114    fn test_dropping_subscriptions_during_callback(cx: &mut MutableAppContext) {
6115        struct Model;
6116
6117        impl Entity for Model {
6118            type Event = u64;
6119        }
6120
6121        // Events
6122        let observing_model = cx.add_model(|_| Model);
6123        let observed_model = cx.add_model(|_| Model);
6124
6125        let events = Rc::new(RefCell::new(Vec::new()));
6126
6127        observing_model.update(cx, |_, cx| {
6128            let events = events.clone();
6129            let subscription = Rc::new(RefCell::new(None));
6130            *subscription.borrow_mut() = Some(cx.subscribe(&observed_model, {
6131                let subscription = subscription.clone();
6132                move |_, _, e, _| {
6133                    subscription.borrow_mut().take();
6134                    events.borrow_mut().push(*e);
6135                }
6136            }));
6137        });
6138
6139        observed_model.update(cx, |_, cx| {
6140            cx.emit(1);
6141            cx.emit(2);
6142        });
6143
6144        assert_eq!(*events.borrow(), [1]);
6145
6146        // Global Events
6147        #[derive(Clone, Debug, Eq, PartialEq)]
6148        struct GlobalEvent(u64);
6149
6150        let events = Rc::new(RefCell::new(Vec::new()));
6151
6152        {
6153            let events = events.clone();
6154            let subscription = Rc::new(RefCell::new(None));
6155            *subscription.borrow_mut() = Some(cx.subscribe_global({
6156                let subscription = subscription.clone();
6157                move |e: &GlobalEvent, _| {
6158                    subscription.borrow_mut().take();
6159                    events.borrow_mut().push(e.clone());
6160                }
6161            }));
6162        }
6163
6164        cx.update(|cx| {
6165            cx.emit_global(GlobalEvent(1));
6166            cx.emit_global(GlobalEvent(2));
6167        });
6168
6169        assert_eq!(*events.borrow(), [GlobalEvent(1)]);
6170
6171        // Model Observation
6172        let observing_model = cx.add_model(|_| Model);
6173        let observed_model = cx.add_model(|_| Model);
6174
6175        let observation_count = Rc::new(RefCell::new(0));
6176
6177        observing_model.update(cx, |_, cx| {
6178            let observation_count = observation_count.clone();
6179            let subscription = Rc::new(RefCell::new(None));
6180            *subscription.borrow_mut() = Some(cx.observe(&observed_model, {
6181                let subscription = subscription.clone();
6182                move |_, _, _| {
6183                    subscription.borrow_mut().take();
6184                    *observation_count.borrow_mut() += 1;
6185                }
6186            }));
6187        });
6188
6189        observed_model.update(cx, |_, cx| {
6190            cx.notify();
6191        });
6192
6193        observed_model.update(cx, |_, cx| {
6194            cx.notify();
6195        });
6196
6197        assert_eq!(*observation_count.borrow(), 1);
6198
6199        // View Observation
6200        struct View;
6201
6202        impl Entity for View {
6203            type Event = ();
6204        }
6205
6206        impl super::View for View {
6207            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6208                Empty::new().boxed()
6209            }
6210
6211            fn ui_name() -> &'static str {
6212                "View"
6213            }
6214        }
6215
6216        let (_, root_view) = cx.add_window(Default::default(), |_| View);
6217        let observing_view = cx.add_view(&root_view, |_| View);
6218        let observed_view = cx.add_view(&root_view, |_| View);
6219
6220        let observation_count = Rc::new(RefCell::new(0));
6221        observing_view.update(cx, |_, cx| {
6222            let observation_count = observation_count.clone();
6223            let subscription = Rc::new(RefCell::new(None));
6224            *subscription.borrow_mut() = Some(cx.observe(&observed_view, {
6225                let subscription = subscription.clone();
6226                move |_, _, _| {
6227                    subscription.borrow_mut().take();
6228                    *observation_count.borrow_mut() += 1;
6229                }
6230            }));
6231        });
6232
6233        observed_view.update(cx, |_, cx| {
6234            cx.notify();
6235        });
6236
6237        observed_view.update(cx, |_, cx| {
6238            cx.notify();
6239        });
6240
6241        assert_eq!(*observation_count.borrow(), 1);
6242
6243        // Global Observation
6244        let observation_count = Rc::new(RefCell::new(0));
6245        let subscription = Rc::new(RefCell::new(None));
6246        *subscription.borrow_mut() = Some(cx.observe_global::<(), _>({
6247            let observation_count = observation_count.clone();
6248            let subscription = subscription.clone();
6249            move |_| {
6250                subscription.borrow_mut().take();
6251                *observation_count.borrow_mut() += 1;
6252            }
6253        }));
6254
6255        cx.default_global::<()>();
6256        cx.set_global(());
6257        assert_eq!(*observation_count.borrow(), 1);
6258    }
6259
6260    #[crate::test(self)]
6261    fn test_focus(cx: &mut MutableAppContext) {
6262        struct View {
6263            name: String,
6264            events: Arc<Mutex<Vec<String>>>,
6265        }
6266
6267        impl Entity for View {
6268            type Event = ();
6269        }
6270
6271        impl super::View for View {
6272            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6273                Empty::new().boxed()
6274            }
6275
6276            fn ui_name() -> &'static str {
6277                "View"
6278            }
6279
6280            fn on_focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext<Self>) {
6281                if cx.handle().id() == focused.id() {
6282                    self.events.lock().push(format!("{} focused", &self.name));
6283                }
6284            }
6285
6286            fn on_focus_out(&mut self, blurred: AnyViewHandle, cx: &mut ViewContext<Self>) {
6287                if cx.handle().id() == blurred.id() {
6288                    self.events.lock().push(format!("{} blurred", &self.name));
6289                }
6290            }
6291        }
6292
6293        let view_events: Arc<Mutex<Vec<String>>> = Default::default();
6294        let (_, view_1) = cx.add_window(Default::default(), |_| View {
6295            events: view_events.clone(),
6296            name: "view 1".to_string(),
6297        });
6298        let view_2 = cx.add_view(&view_1, |_| View {
6299            events: view_events.clone(),
6300            name: "view 2".to_string(),
6301        });
6302
6303        let observed_events: Arc<Mutex<Vec<String>>> = Default::default();
6304        view_1.update(cx, |_, cx| {
6305            cx.observe_focus(&view_2, {
6306                let observed_events = observed_events.clone();
6307                move |this, view, focused, cx| {
6308                    let label = if focused { "focus" } else { "blur" };
6309                    observed_events.lock().push(format!(
6310                        "{} observed {}'s {}",
6311                        this.name,
6312                        view.read(cx).name,
6313                        label
6314                    ))
6315                }
6316            })
6317            .detach();
6318        });
6319        view_2.update(cx, |_, cx| {
6320            cx.observe_focus(&view_1, {
6321                let observed_events = observed_events.clone();
6322                move |this, view, focused, cx| {
6323                    let label = if focused { "focus" } else { "blur" };
6324                    observed_events.lock().push(format!(
6325                        "{} observed {}'s {}",
6326                        this.name,
6327                        view.read(cx).name,
6328                        label
6329                    ))
6330                }
6331            })
6332            .detach();
6333        });
6334        assert_eq!(mem::take(&mut *view_events.lock()), ["view 1 focused"]);
6335        assert_eq!(mem::take(&mut *observed_events.lock()), Vec::<&str>::new());
6336
6337        view_1.update(cx, |_, cx| {
6338            // Ensure only the latest focus is honored.
6339            cx.focus(&view_2);
6340            cx.focus(&view_1);
6341            cx.focus(&view_2);
6342        });
6343        assert_eq!(
6344            mem::take(&mut *view_events.lock()),
6345            ["view 1 blurred", "view 2 focused"],
6346        );
6347        assert_eq!(
6348            mem::take(&mut *observed_events.lock()),
6349            [
6350                "view 2 observed view 1's blur",
6351                "view 1 observed view 2's focus"
6352            ]
6353        );
6354
6355        view_1.update(cx, |_, cx| cx.focus(&view_1));
6356        assert_eq!(
6357            mem::take(&mut *view_events.lock()),
6358            ["view 2 blurred", "view 1 focused"],
6359        );
6360        assert_eq!(
6361            mem::take(&mut *observed_events.lock()),
6362            [
6363                "view 1 observed view 2's blur",
6364                "view 2 observed view 1's focus"
6365            ]
6366        );
6367
6368        view_1.update(cx, |_, cx| cx.focus(&view_2));
6369        assert_eq!(
6370            mem::take(&mut *view_events.lock()),
6371            ["view 1 blurred", "view 2 focused"],
6372        );
6373        assert_eq!(
6374            mem::take(&mut *observed_events.lock()),
6375            [
6376                "view 2 observed view 1's blur",
6377                "view 1 observed view 2's focus"
6378            ]
6379        );
6380
6381        view_1.update(cx, |_, _| drop(view_2));
6382        assert_eq!(mem::take(&mut *view_events.lock()), ["view 1 focused"]);
6383        assert_eq!(mem::take(&mut *observed_events.lock()), Vec::<&str>::new());
6384    }
6385
6386    #[crate::test(self)]
6387    fn test_deserialize_actions(cx: &mut MutableAppContext) {
6388        #[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
6389        pub struct ComplexAction {
6390            arg: String,
6391            count: usize,
6392        }
6393
6394        actions!(test::something, [SimpleAction]);
6395        impl_actions!(test::something, [ComplexAction]);
6396
6397        cx.add_global_action(move |_: &SimpleAction, _: &mut MutableAppContext| {});
6398        cx.add_global_action(move |_: &ComplexAction, _: &mut MutableAppContext| {});
6399
6400        let action1 = cx
6401            .deserialize_action(
6402                "test::something::ComplexAction",
6403                Some(r#"{"arg": "a", "count": 5}"#),
6404            )
6405            .unwrap();
6406        let action2 = cx
6407            .deserialize_action("test::something::SimpleAction", None)
6408            .unwrap();
6409        assert_eq!(
6410            action1.as_any().downcast_ref::<ComplexAction>().unwrap(),
6411            &ComplexAction {
6412                arg: "a".to_string(),
6413                count: 5,
6414            }
6415        );
6416        assert_eq!(
6417            action2.as_any().downcast_ref::<SimpleAction>().unwrap(),
6418            &SimpleAction
6419        );
6420    }
6421
6422    #[crate::test(self)]
6423    fn test_dispatch_action(cx: &mut MutableAppContext) {
6424        struct ViewA {
6425            id: usize,
6426        }
6427
6428        impl Entity for ViewA {
6429            type Event = ();
6430        }
6431
6432        impl View for ViewA {
6433            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6434                Empty::new().boxed()
6435            }
6436
6437            fn ui_name() -> &'static str {
6438                "View"
6439            }
6440        }
6441
6442        struct ViewB {
6443            id: usize,
6444        }
6445
6446        impl Entity for ViewB {
6447            type Event = ();
6448        }
6449
6450        impl View for ViewB {
6451            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6452                Empty::new().boxed()
6453            }
6454
6455            fn ui_name() -> &'static str {
6456                "View"
6457            }
6458        }
6459
6460        #[derive(Clone, Default, Deserialize, PartialEq)]
6461        pub struct Action(pub String);
6462
6463        impl_actions!(test, [Action]);
6464
6465        let actions = Rc::new(RefCell::new(Vec::new()));
6466
6467        cx.add_global_action({
6468            let actions = actions.clone();
6469            move |_: &Action, _: &mut MutableAppContext| {
6470                actions.borrow_mut().push("global".to_string());
6471            }
6472        });
6473
6474        cx.add_action({
6475            let actions = actions.clone();
6476            move |view: &mut ViewA, action: &Action, cx| {
6477                assert_eq!(action.0, "bar");
6478                cx.propagate_action();
6479                actions.borrow_mut().push(format!("{} a", view.id));
6480            }
6481        });
6482
6483        cx.add_action({
6484            let actions = actions.clone();
6485            move |view: &mut ViewA, _: &Action, cx| {
6486                if view.id != 1 {
6487                    cx.add_view(|cx| {
6488                        cx.propagate_action(); // Still works on a nested ViewContext
6489                        ViewB { id: 5 }
6490                    });
6491                }
6492                actions.borrow_mut().push(format!("{} b", view.id));
6493            }
6494        });
6495
6496        cx.add_action({
6497            let actions = actions.clone();
6498            move |view: &mut ViewB, _: &Action, cx| {
6499                cx.propagate_action();
6500                actions.borrow_mut().push(format!("{} c", view.id));
6501            }
6502        });
6503
6504        cx.add_action({
6505            let actions = actions.clone();
6506            move |view: &mut ViewB, _: &Action, cx| {
6507                cx.propagate_action();
6508                actions.borrow_mut().push(format!("{} d", view.id));
6509            }
6510        });
6511
6512        cx.capture_action({
6513            let actions = actions.clone();
6514            move |view: &mut ViewA, _: &Action, cx| {
6515                cx.propagate_action();
6516                actions.borrow_mut().push(format!("{} capture", view.id));
6517            }
6518        });
6519
6520        let observed_actions = Rc::new(RefCell::new(Vec::new()));
6521        cx.observe_actions({
6522            let observed_actions = observed_actions.clone();
6523            move |action_id, _| observed_actions.borrow_mut().push(action_id)
6524        })
6525        .detach();
6526
6527        let (window_id, view_1) = cx.add_window(Default::default(), |_| ViewA { id: 1 });
6528        let view_2 = cx.add_view(&view_1, |_| ViewB { id: 2 });
6529        let view_3 = cx.add_view(&view_2, |_| ViewA { id: 3 });
6530        let view_4 = cx.add_view(&view_3, |_| ViewB { id: 4 });
6531
6532        cx.handle_dispatch_action_from_effect(
6533            window_id,
6534            Some(view_4.id()),
6535            &Action("bar".to_string()),
6536        );
6537
6538        assert_eq!(
6539            *actions.borrow(),
6540            vec![
6541                "1 capture",
6542                "3 capture",
6543                "4 d",
6544                "4 c",
6545                "3 b",
6546                "3 a",
6547                "2 d",
6548                "2 c",
6549                "1 b"
6550            ]
6551        );
6552        assert_eq!(*observed_actions.borrow(), [Action::default().id()]);
6553
6554        // Remove view_1, which doesn't propagate the action
6555
6556        let (window_id, view_2) = cx.add_window(Default::default(), |_| ViewB { id: 2 });
6557        let view_3 = cx.add_view(&view_2, |_| ViewA { id: 3 });
6558        let view_4 = cx.add_view(&view_3, |_| ViewB { id: 4 });
6559
6560        actions.borrow_mut().clear();
6561        cx.handle_dispatch_action_from_effect(
6562            window_id,
6563            Some(view_4.id()),
6564            &Action("bar".to_string()),
6565        );
6566
6567        assert_eq!(
6568            *actions.borrow(),
6569            vec![
6570                "3 capture",
6571                "4 d",
6572                "4 c",
6573                "3 b",
6574                "3 a",
6575                "2 d",
6576                "2 c",
6577                "global"
6578            ]
6579        );
6580        assert_eq!(
6581            *observed_actions.borrow(),
6582            [Action::default().id(), Action::default().id()]
6583        );
6584    }
6585
6586    #[crate::test(self)]
6587    fn test_dispatch_keystroke(cx: &mut MutableAppContext) {
6588        #[derive(Clone, Deserialize, PartialEq)]
6589        pub struct Action(String);
6590
6591        impl_actions!(test, [Action]);
6592
6593        struct View {
6594            id: usize,
6595            keymap_context: keymap::Context,
6596        }
6597
6598        impl Entity for View {
6599            type Event = ();
6600        }
6601
6602        impl super::View for View {
6603            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6604                Empty::new().boxed()
6605            }
6606
6607            fn ui_name() -> &'static str {
6608                "View"
6609            }
6610
6611            fn keymap_context(&self, _: &AppContext) -> keymap::Context {
6612                self.keymap_context.clone()
6613            }
6614        }
6615
6616        impl View {
6617            fn new(id: usize) -> Self {
6618                View {
6619                    id,
6620                    keymap_context: keymap::Context::default(),
6621                }
6622            }
6623        }
6624
6625        let mut view_1 = View::new(1);
6626        let mut view_2 = View::new(2);
6627        let mut view_3 = View::new(3);
6628        view_1.keymap_context.set.insert("a".into());
6629        view_2.keymap_context.set.insert("a".into());
6630        view_2.keymap_context.set.insert("b".into());
6631        view_3.keymap_context.set.insert("a".into());
6632        view_3.keymap_context.set.insert("b".into());
6633        view_3.keymap_context.set.insert("c".into());
6634
6635        let (window_id, view_1) = cx.add_window(Default::default(), |_| view_1);
6636        let view_2 = cx.add_view(&view_1, |_| view_2);
6637        let _view_3 = cx.add_view(&view_2, |cx| {
6638            cx.focus_self();
6639            view_3
6640        });
6641
6642        // This keymap's only binding dispatches an action on view 2 because that view will have
6643        // "a" and "b" in its context, but not "c".
6644        cx.add_bindings(vec![keymap::Binding::new(
6645            "a",
6646            Action("a".to_string()),
6647            Some("a && b && !c"),
6648        )]);
6649
6650        cx.add_bindings(vec![keymap::Binding::new(
6651            "b",
6652            Action("b".to_string()),
6653            None,
6654        )]);
6655
6656        let actions = Rc::new(RefCell::new(Vec::new()));
6657        cx.add_action({
6658            let actions = actions.clone();
6659            move |view: &mut View, action: &Action, cx| {
6660                if action.0 == "a" {
6661                    actions.borrow_mut().push(format!("{} a", view.id));
6662                } else {
6663                    actions
6664                        .borrow_mut()
6665                        .push(format!("{} {}", view.id, action.0));
6666                    cx.propagate_action();
6667                }
6668            }
6669        });
6670
6671        cx.add_global_action({
6672            let actions = actions.clone();
6673            move |action: &Action, _| {
6674                actions.borrow_mut().push(format!("global {}", action.0));
6675            }
6676        });
6677
6678        cx.dispatch_keystroke(window_id, &Keystroke::parse("a").unwrap());
6679
6680        assert_eq!(&*actions.borrow(), &["2 a"]);
6681
6682        actions.borrow_mut().clear();
6683
6684        cx.dispatch_keystroke(window_id, &Keystroke::parse("b").unwrap());
6685
6686        assert_eq!(&*actions.borrow(), &["3 b", "2 b", "1 b", "global b"]);
6687    }
6688
6689    #[crate::test(self)]
6690    async fn test_model_condition(cx: &mut TestAppContext) {
6691        struct Counter(usize);
6692
6693        impl super::Entity for Counter {
6694            type Event = ();
6695        }
6696
6697        impl Counter {
6698            fn inc(&mut self, cx: &mut ModelContext<Self>) {
6699                self.0 += 1;
6700                cx.notify();
6701            }
6702        }
6703
6704        let model = cx.add_model(|_| Counter(0));
6705
6706        let condition1 = model.condition(cx, |model, _| model.0 == 2);
6707        let condition2 = model.condition(cx, |model, _| model.0 == 3);
6708        smol::pin!(condition1, condition2);
6709
6710        model.update(cx, |model, cx| model.inc(cx));
6711        assert_eq!(poll_once(&mut condition1).await, None);
6712        assert_eq!(poll_once(&mut condition2).await, None);
6713
6714        model.update(cx, |model, cx| model.inc(cx));
6715        assert_eq!(poll_once(&mut condition1).await, Some(()));
6716        assert_eq!(poll_once(&mut condition2).await, None);
6717
6718        model.update(cx, |model, cx| model.inc(cx));
6719        assert_eq!(poll_once(&mut condition2).await, Some(()));
6720
6721        model.update(cx, |_, cx| cx.notify());
6722    }
6723
6724    #[crate::test(self)]
6725    #[should_panic]
6726    async fn test_model_condition_timeout(cx: &mut TestAppContext) {
6727        struct Model;
6728
6729        impl super::Entity for Model {
6730            type Event = ();
6731        }
6732
6733        let model = cx.add_model(|_| Model);
6734        model.condition(cx, |_, _| false).await;
6735    }
6736
6737    #[crate::test(self)]
6738    #[should_panic(expected = "model dropped with pending condition")]
6739    async fn test_model_condition_panic_on_drop(cx: &mut TestAppContext) {
6740        struct Model;
6741
6742        impl super::Entity for Model {
6743            type Event = ();
6744        }
6745
6746        let model = cx.add_model(|_| Model);
6747        let condition = model.condition(cx, |_, _| false);
6748        cx.update(|_| drop(model));
6749        condition.await;
6750    }
6751
6752    #[crate::test(self)]
6753    async fn test_view_condition(cx: &mut TestAppContext) {
6754        struct Counter(usize);
6755
6756        impl super::Entity for Counter {
6757            type Event = ();
6758        }
6759
6760        impl super::View for Counter {
6761            fn ui_name() -> &'static str {
6762                "test view"
6763            }
6764
6765            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6766                Empty::new().boxed()
6767            }
6768        }
6769
6770        impl Counter {
6771            fn inc(&mut self, cx: &mut ViewContext<Self>) {
6772                self.0 += 1;
6773                cx.notify();
6774            }
6775        }
6776
6777        let (_, view) = cx.add_window(|_| Counter(0));
6778
6779        let condition1 = view.condition(cx, |view, _| view.0 == 2);
6780        let condition2 = view.condition(cx, |view, _| view.0 == 3);
6781        smol::pin!(condition1, condition2);
6782
6783        view.update(cx, |view, cx| view.inc(cx));
6784        assert_eq!(poll_once(&mut condition1).await, None);
6785        assert_eq!(poll_once(&mut condition2).await, None);
6786
6787        view.update(cx, |view, cx| view.inc(cx));
6788        assert_eq!(poll_once(&mut condition1).await, Some(()));
6789        assert_eq!(poll_once(&mut condition2).await, None);
6790
6791        view.update(cx, |view, cx| view.inc(cx));
6792        assert_eq!(poll_once(&mut condition2).await, Some(()));
6793        view.update(cx, |_, cx| cx.notify());
6794    }
6795
6796    #[crate::test(self)]
6797    #[should_panic]
6798    async fn test_view_condition_timeout(cx: &mut TestAppContext) {
6799        struct View;
6800
6801        impl super::Entity for View {
6802            type Event = ();
6803        }
6804
6805        impl super::View for View {
6806            fn ui_name() -> &'static str {
6807                "test view"
6808            }
6809
6810            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6811                Empty::new().boxed()
6812            }
6813        }
6814
6815        let (_, view) = cx.add_window(|_| View);
6816        view.condition(cx, |_, _| false).await;
6817    }
6818
6819    #[crate::test(self)]
6820    #[should_panic(expected = "view dropped with pending condition")]
6821    async fn test_view_condition_panic_on_drop(cx: &mut TestAppContext) {
6822        struct View;
6823
6824        impl super::Entity for View {
6825            type Event = ();
6826        }
6827
6828        impl super::View for View {
6829            fn ui_name() -> &'static str {
6830                "test view"
6831            }
6832
6833            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6834                Empty::new().boxed()
6835            }
6836        }
6837
6838        let (_, root_view) = cx.add_window(|_| View);
6839        let view = cx.add_view(&root_view, |_| View);
6840
6841        let condition = view.condition(cx, |_, _| false);
6842        cx.update(|_| drop(view));
6843        condition.await;
6844    }
6845
6846    #[crate::test(self)]
6847    fn test_refresh_windows(cx: &mut MutableAppContext) {
6848        struct View(usize);
6849
6850        impl super::Entity for View {
6851            type Event = ();
6852        }
6853
6854        impl super::View for View {
6855            fn ui_name() -> &'static str {
6856                "test view"
6857            }
6858
6859            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6860                Empty::new().named(format!("render count: {}", post_inc(&mut self.0)))
6861            }
6862        }
6863
6864        let (window_id, root_view) = cx.add_window(Default::default(), |_| View(0));
6865        let presenter = cx.presenters_and_platform_windows[&window_id].0.clone();
6866
6867        assert_eq!(
6868            presenter.borrow().rendered_views[&root_view.id()].name(),
6869            Some("render count: 0")
6870        );
6871
6872        let view = cx.add_view(&root_view, |cx| {
6873            cx.refresh_windows();
6874            View(0)
6875        });
6876
6877        assert_eq!(
6878            presenter.borrow().rendered_views[&root_view.id()].name(),
6879            Some("render count: 1")
6880        );
6881        assert_eq!(
6882            presenter.borrow().rendered_views[&view.id()].name(),
6883            Some("render count: 0")
6884        );
6885
6886        cx.update(|cx| cx.refresh_windows());
6887        assert_eq!(
6888            presenter.borrow().rendered_views[&root_view.id()].name(),
6889            Some("render count: 2")
6890        );
6891        assert_eq!(
6892            presenter.borrow().rendered_views[&view.id()].name(),
6893            Some("render count: 1")
6894        );
6895
6896        cx.update(|cx| {
6897            cx.refresh_windows();
6898            drop(view);
6899        });
6900        assert_eq!(
6901            presenter.borrow().rendered_views[&root_view.id()].name(),
6902            Some("render count: 3")
6903        );
6904        assert_eq!(presenter.borrow().rendered_views.len(), 1);
6905    }
6906
6907    #[crate::test(self)]
6908    async fn test_window_activation(cx: &mut TestAppContext) {
6909        struct View(&'static str);
6910
6911        impl super::Entity for View {
6912            type Event = ();
6913        }
6914
6915        impl super::View for View {
6916            fn ui_name() -> &'static str {
6917                "test view"
6918            }
6919
6920            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6921                Empty::new().boxed()
6922            }
6923        }
6924
6925        let events = Rc::new(RefCell::new(Vec::new()));
6926        let (window_1, _) = cx.add_window(|cx: &mut ViewContext<View>| {
6927            cx.observe_window_activation({
6928                let events = events.clone();
6929                move |this, active, _| events.borrow_mut().push((this.0, active))
6930            })
6931            .detach();
6932            View("window 1")
6933        });
6934        assert_eq!(mem::take(&mut *events.borrow_mut()), [("window 1", true)]);
6935
6936        let (window_2, _) = cx.add_window(|cx: &mut ViewContext<View>| {
6937            cx.observe_window_activation({
6938                let events = events.clone();
6939                move |this, active, _| events.borrow_mut().push((this.0, active))
6940            })
6941            .detach();
6942            View("window 2")
6943        });
6944        assert_eq!(
6945            mem::take(&mut *events.borrow_mut()),
6946            [("window 1", false), ("window 2", true)]
6947        );
6948
6949        let (window_3, _) = cx.add_window(|cx: &mut ViewContext<View>| {
6950            cx.observe_window_activation({
6951                let events = events.clone();
6952                move |this, active, _| events.borrow_mut().push((this.0, active))
6953            })
6954            .detach();
6955            View("window 3")
6956        });
6957        assert_eq!(
6958            mem::take(&mut *events.borrow_mut()),
6959            [("window 2", false), ("window 3", true)]
6960        );
6961
6962        cx.simulate_window_activation(Some(window_2));
6963        assert_eq!(
6964            mem::take(&mut *events.borrow_mut()),
6965            [("window 3", false), ("window 2", true)]
6966        );
6967
6968        cx.simulate_window_activation(Some(window_1));
6969        assert_eq!(
6970            mem::take(&mut *events.borrow_mut()),
6971            [("window 2", false), ("window 1", true)]
6972        );
6973
6974        cx.simulate_window_activation(Some(window_3));
6975        assert_eq!(
6976            mem::take(&mut *events.borrow_mut()),
6977            [("window 1", false), ("window 3", true)]
6978        );
6979
6980        cx.simulate_window_activation(Some(window_3));
6981        assert_eq!(mem::take(&mut *events.borrow_mut()), []);
6982    }
6983}