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