app.rs

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