Start removing the Send impl for App
Co-authored-by: Antonio <antonio@zed.dev> Co-authored-by: Nathan <nathan@zed.dev>
This commit is contained in:
parent
ea7fdef417
commit
57ffa8201e
38 changed files with 506 additions and 932 deletions
|
@ -3,12 +3,11 @@ use crate::{
|
|||
Bounds, BoxShadow, Context, Corners, DevicePixels, DispatchContext, DisplayId, Edges, Effect,
|
||||
Entity, EntityId, EventEmitter, FileDropEvent, FocusEvent, FontId, GlobalElementId, GlyphId,
|
||||
Hsla, ImageData, InputEvent, IsZero, KeyListener, KeyMatch, KeyMatcher, Keystroke, LayoutId,
|
||||
MainThread, MainThreadOnly, Model, ModelContext, Modifiers, MonochromeSprite, MouseButton,
|
||||
MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformWindow,
|
||||
Point, PolychromeSprite, Quad, Reference, RenderGlyphParams, RenderImageParams,
|
||||
RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style, Subscription,
|
||||
TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, VisualContext, WeakModel, WeakView,
|
||||
WindowOptions, SUBPIXEL_VARIANTS,
|
||||
Model, ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseDownEvent, MouseMoveEvent,
|
||||
MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformWindow, Point, PolychromeSprite, Quad,
|
||||
Reference, RenderGlyphParams, RenderImageParams, RenderSvgParams, ScaledPixels, SceneBuilder,
|
||||
Shadow, SharedString, Size, Style, Subscription, TaffyLayoutEngine, Task, Underline,
|
||||
UnderlineStyle, View, VisualContext, WeakModel, WeakView, WindowOptions, SUBPIXEL_VARIANTS,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use collections::HashMap;
|
||||
|
@ -52,7 +51,7 @@ pub enum DispatchPhase {
|
|||
Capture,
|
||||
}
|
||||
|
||||
type AnyListener = Box<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext) + Send + 'static>;
|
||||
type AnyListener = Box<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext) + 'static>;
|
||||
type AnyKeyListener = Box<
|
||||
dyn Fn(
|
||||
&dyn Any,
|
||||
|
@ -60,10 +59,9 @@ type AnyKeyListener = Box<
|
|||
DispatchPhase,
|
||||
&mut WindowContext,
|
||||
) -> Option<Box<dyn Action>>
|
||||
+ Send
|
||||
+ 'static,
|
||||
>;
|
||||
type AnyFocusListener = Box<dyn Fn(&FocusEvent, &mut WindowContext) + Send + 'static>;
|
||||
type AnyFocusListener = Box<dyn Fn(&FocusEvent, &mut WindowContext) + 'static>;
|
||||
|
||||
slotmap::new_key_type! { pub struct FocusId; }
|
||||
|
||||
|
@ -159,7 +157,7 @@ impl Drop for FocusHandle {
|
|||
// Holds the state for a specific window.
|
||||
pub struct Window {
|
||||
handle: AnyWindowHandle,
|
||||
platform_window: MainThreadOnly<Box<dyn PlatformWindow>>,
|
||||
platform_window: Box<dyn PlatformWindow>,
|
||||
display_id: DisplayId,
|
||||
sprite_atlas: Arc<dyn PlatformAtlas>,
|
||||
rem_size: Pixels,
|
||||
|
@ -194,7 +192,7 @@ impl Window {
|
|||
pub(crate) fn new(
|
||||
handle: AnyWindowHandle,
|
||||
options: WindowOptions,
|
||||
cx: &mut MainThread<AppContext>,
|
||||
cx: &mut AppContext,
|
||||
) -> Self {
|
||||
let platform_window = cx.platform().open_window(handle, options);
|
||||
let display_id = platform_window.display().id();
|
||||
|
@ -209,12 +207,7 @@ impl Window {
|
|||
cx.window.scale_factor = scale_factor;
|
||||
cx.window.scene_builder = SceneBuilder::new();
|
||||
cx.window.content_size = content_size;
|
||||
cx.window.display_id = cx
|
||||
.window
|
||||
.platform_window
|
||||
.borrow_on_main_thread()
|
||||
.display()
|
||||
.id();
|
||||
cx.window.display_id = cx.window.platform_window.display().id();
|
||||
cx.window.dirty = true;
|
||||
})
|
||||
.log_err();
|
||||
|
@ -230,8 +223,6 @@ impl Window {
|
|||
})
|
||||
});
|
||||
|
||||
let platform_window = MainThreadOnly::new(Arc::new(platform_window), cx.executor.clone());
|
||||
|
||||
Window {
|
||||
handle,
|
||||
platform_window,
|
||||
|
@ -378,26 +369,6 @@ impl<'a, 'w> WindowContext<'a, 'w> {
|
|||
self.notify();
|
||||
}
|
||||
|
||||
/// Schedule the given closure to be run on the main thread. It will be invoked with
|
||||
/// a `MainThread<WindowContext>`, which provides access to platform-specific functionality
|
||||
/// of the window.
|
||||
pub fn run_on_main<R>(
|
||||
&mut self,
|
||||
f: impl FnOnce(&mut MainThread<WindowContext<'_, '_>>) -> R + Send + 'static,
|
||||
) -> Task<Result<R>>
|
||||
where
|
||||
R: Send + 'static,
|
||||
{
|
||||
if self.executor.is_main_thread() {
|
||||
Task::ready(Ok(f(unsafe {
|
||||
mem::transmute::<&mut Self, &mut MainThread<Self>>(self)
|
||||
})))
|
||||
} else {
|
||||
let id = self.window.handle.id;
|
||||
self.app.run_on_main(move |cx| cx.update_window(id, f))
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an `AsyncWindowContext`, which has a static lifetime and can be held across
|
||||
/// await points in async code.
|
||||
pub fn to_async(&self) -> AsyncWindowContext {
|
||||
|
@ -408,44 +379,39 @@ impl<'a, 'w> WindowContext<'a, 'w> {
|
|||
pub fn on_next_frame(&mut self, f: impl FnOnce(&mut WindowContext) + Send + 'static) {
|
||||
let f = Box::new(f);
|
||||
let display_id = self.window.display_id;
|
||||
self.run_on_main(move |cx| {
|
||||
if let Some(callbacks) = cx.next_frame_callbacks.get_mut(&display_id) {
|
||||
callbacks.push(f);
|
||||
// If there was already a callback, it means that we already scheduled a frame.
|
||||
if callbacks.len() > 1 {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
let async_cx = cx.to_async();
|
||||
cx.next_frame_callbacks.insert(display_id, vec![f]);
|
||||
cx.platform().set_display_link_output_callback(
|
||||
display_id,
|
||||
Box::new(move |_current_time, _output_time| {
|
||||
let _ = async_cx.update(|cx| {
|
||||
let callbacks = cx
|
||||
.next_frame_callbacks
|
||||
.get_mut(&display_id)
|
||||
.unwrap()
|
||||
.drain(..)
|
||||
.collect::<Vec<_>>();
|
||||
for callback in callbacks {
|
||||
callback(cx);
|
||||
}
|
||||
|
||||
cx.run_on_main(move |cx| {
|
||||
if cx.next_frame_callbacks.get(&display_id).unwrap().is_empty() {
|
||||
cx.platform().stop_display_link(display_id);
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
});
|
||||
}),
|
||||
);
|
||||
if let Some(callbacks) = self.next_frame_callbacks.get_mut(&display_id) {
|
||||
callbacks.push(f);
|
||||
// If there was already a callback, it means that we already scheduled a frame.
|
||||
if callbacks.len() > 1 {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
let async_cx = self.to_async();
|
||||
self.next_frame_callbacks.insert(display_id, vec![f]);
|
||||
self.platform().set_display_link_output_callback(
|
||||
display_id,
|
||||
Box::new(move |_current_time, _output_time| {
|
||||
let _ = async_cx.update(|cx| {
|
||||
let callbacks = cx
|
||||
.next_frame_callbacks
|
||||
.get_mut(&display_id)
|
||||
.unwrap()
|
||||
.drain(..)
|
||||
.collect::<Vec<_>>();
|
||||
for callback in callbacks {
|
||||
callback(cx);
|
||||
}
|
||||
|
||||
cx.platform().start_display_link(display_id);
|
||||
})
|
||||
.detach();
|
||||
if cx.next_frame_callbacks.get(&display_id).unwrap().is_empty() {
|
||||
cx.platform().stop_display_link(display_id);
|
||||
}
|
||||
});
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
self.platform().start_display_link(display_id);
|
||||
}
|
||||
|
||||
/// Spawn the future returned by the given closure on the application thread pool.
|
||||
|
@ -453,17 +419,16 @@ impl<'a, 'w> WindowContext<'a, 'w> {
|
|||
/// use within your future.
|
||||
pub fn spawn<Fut, R>(
|
||||
&mut self,
|
||||
f: impl FnOnce(AnyWindowHandle, AsyncWindowContext) -> Fut + Send + 'static,
|
||||
f: impl FnOnce(AnyWindowHandle, AsyncWindowContext) -> Fut,
|
||||
) -> Task<R>
|
||||
where
|
||||
R: Send + 'static,
|
||||
Fut: Future<Output = R> + Send + 'static,
|
||||
R: 'static,
|
||||
Fut: Future<Output = R> + 'static,
|
||||
{
|
||||
let window = self.window.handle;
|
||||
self.app.spawn(move |app| {
|
||||
let cx = AsyncWindowContext::new(app, window);
|
||||
let future = f(window, cx);
|
||||
async move { future.await }
|
||||
f(window, cx)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -569,7 +534,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
|
|||
/// a specific need to register a global listener.
|
||||
pub fn on_mouse_event<Event: 'static>(
|
||||
&mut self,
|
||||
handler: impl Fn(&Event, DispatchPhase, &mut WindowContext) + Send + 'static,
|
||||
handler: impl Fn(&Event, DispatchPhase, &mut WindowContext) + 'static,
|
||||
) {
|
||||
let order = self.window.z_index_stack.clone();
|
||||
self.window
|
||||
|
@ -906,14 +871,8 @@ impl<'a, 'w> WindowContext<'a, 'w> {
|
|||
self.window.root_view = Some(root_view);
|
||||
let scene = self.window.scene_builder.build();
|
||||
|
||||
self.run_on_main(|cx| {
|
||||
cx.window
|
||||
.platform_window
|
||||
.borrow_on_main_thread()
|
||||
.draw(scene);
|
||||
cx.window.dirty = false;
|
||||
})
|
||||
.detach();
|
||||
self.window.platform_window.draw(scene);
|
||||
self.window.dirty = false;
|
||||
}
|
||||
|
||||
fn start_frame(&mut self) {
|
||||
|
@ -1246,7 +1205,7 @@ impl Context for WindowContext<'_, '_> {
|
|||
build_model: impl FnOnce(&mut Self::ModelContext<'_, T>) -> T,
|
||||
) -> Model<T>
|
||||
where
|
||||
T: 'static + Send,
|
||||
T: 'static,
|
||||
{
|
||||
let slot = self.app.entities.reserve();
|
||||
let model = build_model(&mut ModelContext::mutable(&mut *self.app, slot.downgrade()));
|
||||
|
@ -1276,7 +1235,7 @@ impl VisualContext for WindowContext<'_, '_> {
|
|||
build_view_state: impl FnOnce(&mut Self::ViewContext<'_, '_, V>) -> V,
|
||||
) -> Self::Result<View<V>>
|
||||
where
|
||||
V: 'static + Send,
|
||||
V: 'static,
|
||||
{
|
||||
let slot = self.app.entities.reserve();
|
||||
let view = View {
|
||||
|
@ -1422,7 +1381,7 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
|
|||
f: impl FnOnce(Option<S>, &mut Self) -> (R, S),
|
||||
) -> R
|
||||
where
|
||||
S: 'static + Send,
|
||||
S: 'static,
|
||||
{
|
||||
self.with_element_id(id, |global_id, cx| {
|
||||
if let Some(any) = cx
|
||||
|
@ -1460,7 +1419,7 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
|
|||
f: impl FnOnce(Option<S>, &mut Self) -> (R, S),
|
||||
) -> R
|
||||
where
|
||||
S: 'static + Send,
|
||||
S: 'static,
|
||||
{
|
||||
if let Some(element_id) = element_id {
|
||||
self.with_element_state(element_id, f)
|
||||
|
@ -1772,30 +1731,13 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
|
|||
result
|
||||
}
|
||||
|
||||
pub fn run_on_main<R>(
|
||||
&mut self,
|
||||
view: &mut V,
|
||||
f: impl FnOnce(&mut V, &mut MainThread<ViewContext<'_, '_, V>>) -> R + Send + 'static,
|
||||
) -> Task<Result<R>>
|
||||
where
|
||||
R: Send + 'static,
|
||||
{
|
||||
if self.executor.is_main_thread() {
|
||||
let cx = unsafe { mem::transmute::<&mut Self, &mut MainThread<Self>>(self) };
|
||||
Task::ready(Ok(f(view, cx)))
|
||||
} else {
|
||||
let view = self.view().upgrade().unwrap();
|
||||
self.window_cx.run_on_main(move |cx| view.update(cx, f))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spawn<Fut, R>(
|
||||
&mut self,
|
||||
f: impl FnOnce(WeakView<V>, AsyncWindowContext) -> Fut + Send + 'static,
|
||||
f: impl FnOnce(WeakView<V>, AsyncWindowContext) -> Fut,
|
||||
) -> Task<R>
|
||||
where
|
||||
R: Send + 'static,
|
||||
Fut: Future<Output = R> + Send + 'static,
|
||||
R: 'static,
|
||||
Fut: Future<Output = R> + 'static,
|
||||
{
|
||||
let view = self.view();
|
||||
self.window_cx.spawn(move |_, cx| {
|
||||
|
@ -1833,7 +1775,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
|
|||
|
||||
pub fn on_mouse_event<Event: 'static>(
|
||||
&mut self,
|
||||
handler: impl Fn(&mut V, &Event, DispatchPhase, &mut ViewContext<V>) + Send + 'static,
|
||||
handler: impl Fn(&mut V, &Event, DispatchPhase, &mut ViewContext<V>) + 'static,
|
||||
) {
|
||||
let handle = self.view().upgrade().unwrap();
|
||||
self.window_cx.on_mouse_event(move |event, phase, cx| {
|
||||
|
@ -1862,13 +1804,10 @@ impl<'a, 'w, V> Context for ViewContext<'a, 'w, V> {
|
|||
type ModelContext<'b, U> = ModelContext<'b, U>;
|
||||
type Result<U> = U;
|
||||
|
||||
fn build_model<T>(
|
||||
fn build_model<T: 'static>(
|
||||
&mut self,
|
||||
build_model: impl FnOnce(&mut Self::ModelContext<'_, T>) -> T,
|
||||
) -> Model<T>
|
||||
where
|
||||
T: 'static + Send,
|
||||
{
|
||||
) -> Model<T> {
|
||||
self.window_cx.build_model(build_model)
|
||||
}
|
||||
|
||||
|
@ -1884,7 +1823,7 @@ impl<'a, 'w, V> Context for ViewContext<'a, 'w, V> {
|
|||
impl<V: 'static> VisualContext for ViewContext<'_, '_, V> {
|
||||
type ViewContext<'a, 'w, V2> = ViewContext<'a, 'w, V2>;
|
||||
|
||||
fn build_view<W: 'static + Send>(
|
||||
fn build_view<W: 'static>(
|
||||
&mut self,
|
||||
build_view: impl FnOnce(&mut Self::ViewContext<'_, '_, W>) -> W,
|
||||
) -> Self::Result<View<W>> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue