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:
Max Brunsfeld 2023-11-01 11:31:23 -07:00 committed by Nathan Sobo
parent ea7fdef417
commit 57ffa8201e
38 changed files with 506 additions and 932 deletions

View file

@ -68,24 +68,20 @@ use derive_more::{Deref, DerefMut};
use std::{
any::{Any, TypeId},
borrow::{Borrow, BorrowMut},
mem,
ops::{Deref, DerefMut},
sync::Arc,
};
use taffy::TaffyLayoutEngine;
type AnyBox = Box<dyn Any + Send>;
type AnyBox = Box<dyn Any>;
pub trait Context {
type ModelContext<'a, T>;
type Result<T>;
fn build_model<T>(
fn build_model<T: 'static>(
&mut self,
build_model: impl FnOnce(&mut Self::ModelContext<'_, T>) -> T,
) -> Self::Result<Model<T>>
where
T: 'static + Send;
) -> Self::Result<Model<T>>;
fn update_model<T: 'static, R>(
&mut self,
@ -102,7 +98,7 @@ pub trait VisualContext: Context {
build_view_state: impl FnOnce(&mut Self::ViewContext<'_, '_, V>) -> V,
) -> Self::Result<View<V>>
where
V: 'static + Send;
V: 'static;
fn update_view<V: 'static, R>(
&mut self,
@ -127,100 +123,6 @@ pub enum GlobalKey {
Type(TypeId),
}
#[repr(transparent)]
pub struct MainThread<T>(T);
impl<T> Deref for MainThread<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for MainThread<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<C: Context> Context for MainThread<C> {
type ModelContext<'a, T> = MainThread<C::ModelContext<'a, T>>;
type Result<T> = C::Result<T>;
fn build_model<T>(
&mut self,
build_model: impl FnOnce(&mut Self::ModelContext<'_, T>) -> T,
) -> Self::Result<Model<T>>
where
T: 'static + Send,
{
self.0.build_model(|cx| {
let cx = unsafe {
mem::transmute::<
&mut C::ModelContext<'_, T>,
&mut MainThread<C::ModelContext<'_, T>>,
>(cx)
};
build_model(cx)
})
}
fn update_model<T: 'static, R>(
&mut self,
handle: &Model<T>,
update: impl FnOnce(&mut T, &mut Self::ModelContext<'_, T>) -> R,
) -> Self::Result<R> {
self.0.update_model(handle, |entity, cx| {
let cx = unsafe {
mem::transmute::<
&mut C::ModelContext<'_, T>,
&mut MainThread<C::ModelContext<'_, T>>,
>(cx)
};
update(entity, cx)
})
}
}
impl<C: VisualContext> VisualContext for MainThread<C> {
type ViewContext<'a, 'w, V> = MainThread<C::ViewContext<'a, 'w, V>>;
fn build_view<V>(
&mut self,
build_view_state: impl FnOnce(&mut Self::ViewContext<'_, '_, V>) -> V,
) -> Self::Result<View<V>>
where
V: 'static + Send,
{
self.0.build_view(|cx| {
let cx = unsafe {
mem::transmute::<
&mut C::ViewContext<'_, '_, V>,
&mut MainThread<C::ViewContext<'_, '_, V>>,
>(cx)
};
build_view_state(cx)
})
}
fn update_view<V: 'static, R>(
&mut self,
view: &View<V>,
update: impl FnOnce(&mut V, &mut Self::ViewContext<'_, '_, V>) -> R,
) -> Self::Result<R> {
self.0.update_view(view, |view_state, cx| {
let cx = unsafe {
mem::transmute::<
&mut C::ViewContext<'_, '_, V>,
&mut MainThread<C::ViewContext<'_, '_, V>>,
>(cx)
};
update(view_state, cx)
})
}
}
pub trait BorrowAppContext {
fn with_text_style<F, R>(&mut self, style: TextStyleRefinement, f: F) -> R
where
@ -333,32 +235,3 @@ impl<'a, T> DerefMut for Reference<'a, T> {
}
}
}
pub(crate) struct MainThreadOnly<T: ?Sized> {
executor: Executor,
value: Arc<T>,
}
impl<T: ?Sized> Clone for MainThreadOnly<T> {
fn clone(&self) -> Self {
Self {
executor: self.executor.clone(),
value: self.value.clone(),
}
}
}
/// Allows a value to be accessed only on the main thread, allowing a non-`Send` type
/// to become `Send`.
impl<T: 'static + ?Sized> MainThreadOnly<T> {
pub(crate) fn new(value: Arc<T>, executor: Executor) -> Self {
Self { executor, value }
}
pub(crate) fn borrow_on_main_thread(&self) -> &T {
assert!(self.executor.is_main_thread());
&self.value
}
}
unsafe impl<T: ?Sized> Send for MainThreadOnly<T> {}