gpui: Use ArenaBox for Effect::Emit payload (#49467)

Release Notes:

- N/A *or* Added/Fixed/Improved ...
This commit is contained in:
Lukas Wirth authored and GitHub committed 2026-02-18 14:48:38 +01:00
1 parent a8321800da
commit 2bdcee65b4
2 files changed
+21 -13

No files matched your search

+16 -12
View File
@@ -37,14 +37,14 @@ pub use visual_test_context::*;
use crate::InspectorElementRegistry;
use crate::{
Action, ActionBuildError, ActionRegistry, Any, AnyView, AnyWindowHandle, AppContext, Arena,
Asset, AssetSource, BackgroundExecutor, Bounds, ClipboardItem, CursorStyle, DispatchPhase,
DisplayId, EventEmitter, FocusHandle, FocusMap, ForegroundExecutor, Global, KeyBinding,
KeyContext, Keymap, Keystroke, LayoutId, Menu, MenuItem, OwnedMenu, PathPromptOptions, Pixels,
Platform, PlatformDisplay, PlatformKeyboardLayout, PlatformKeyboardMapper, Point, Priority,
PromptBuilder, PromptButton, PromptHandle, PromptLevel, Render, RenderImage,
RenderablePromptHandle, Reservation, ScreenCaptureSource, SharedString, SubscriberSet,
Subscription, SvgRenderer, Task, TextRenderingMode, TextSystem, ThermalState, Window,
WindowAppearance, WindowHandle, WindowId, WindowInvalidator,
ArenaBox, Asset, AssetSource, BackgroundExecutor, Bounds, ClipboardItem, CursorStyle,
DispatchPhase, DisplayId, EventEmitter, FocusHandle, FocusMap, ForegroundExecutor, Global,
KeyBinding, KeyContext, Keymap, Keystroke, LayoutId, Menu, MenuItem, OwnedMenu,
PathPromptOptions, Pixels, Platform, PlatformDisplay, PlatformKeyboardLayout,
PlatformKeyboardMapper, Point, Priority, PromptBuilder, PromptButton, PromptHandle,
PromptLevel, Render, RenderImage, RenderablePromptHandle, Reservation, ScreenCaptureSource,
SharedString, SubscriberSet, Subscription, SvgRenderer, Task, TextRenderingMode, TextSystem,
ThermalState, Window, WindowAppearance, WindowHandle, WindowId, WindowInvalidator,
colors::{Colors, GlobalColors},
current_platform, hash, init_app_menus,
};
@@ -643,6 +643,8 @@ pub struct App {
/// Per-App element arena. This isolates element allocations between different
/// App instances (important for tests where multiple Apps run concurrently).
pub(crate) element_arena: RefCell<Arena>,
/// Per-App event arena.
pub(crate) event_arena: Arena,
}
impl App {
@@ -722,6 +724,7 @@ impl App {
#[cfg(any(test, feature = "test-support", debug_assertions))]
name: None,
element_arena: RefCell::new(Arena::new(1024 * 1024)),
event_arena: Arena::new(1024 * 1024),
}),
});
@@ -1340,7 +1343,7 @@ impl App {
emitter,
event_type,
event,
} => self.apply_emit_effect(emitter, event_type, event),
} => self.apply_emit_effect(emitter, event_type, &*event),
Effect::RefreshWindows => {
self.apply_refresh_effect();
@@ -1377,6 +1380,7 @@ impl App {
}
if self.pending_effects.is_empty() {
self.event_arena.clear();
break;
}
}
@@ -1434,12 +1438,12 @@ impl App {
.retain(&emitter, |handler| handler(self));
}
fn apply_emit_effect(&mut self, emitter: EntityId, event_type: TypeId, event: Box<dyn Any>) {
fn apply_emit_effect(&mut self, emitter: EntityId, event_type: TypeId, event: &dyn Any) {
self.event_listeners
.clone()
.retain(&emitter, |(stored_type, handler)| {
if *stored_type == event_type {
handler(event.as_ref(), self)
handler(event, self)
} else {
true
}
@@ -2407,7 +2411,7 @@ pub(crate) enum Effect {
Emit {
emitter: EntityId,
event_type: TypeId,
event: Box<dyn Any>,
event: ArenaBox<dyn Any>,
},
RefreshWindows,
NotifyGlobalObservers {
+5 -1
View File
@@ -752,10 +752,14 @@ impl<T> Context<'_, T> {
T: EventEmitter<Evt>,
Evt: 'static,
{
let event = self
.event_arena
.alloc(|| event)
.map(|it| it as &mut dyn Any);
self.app.pending_effects.push_back(Effect::Emit {
emitter: self.entity_state.entity_id,
event_type: TypeId::of::<Evt>(),
event: Box::new(event),
event,
});
}
}