Reduce the need for Send + Sync bounds on generics

This commit is contained in:
Nathan Sobo 2023-10-24 14:20:01 +02:00
parent 4d621f355d
commit 0910760b76
17 changed files with 405 additions and 362 deletions

View file

@ -19,7 +19,7 @@ pub trait Action: Any + Send + Sync {
impl<A> Action for A impl<A> Action for A
where where
A: for<'a> Deserialize<'a> + Any + PartialEq + Clone + Default + Send + Sync, A: for<'a> Deserialize<'a> + PartialEq + Any + Send + Sync + Clone + Default,
{ {
fn qualified_name() -> SharedString { fn qualified_name() -> SharedString {
type_name::<A>().into() type_name::<A>().into()

View file

@ -22,7 +22,9 @@ use parking_lot::{Mutex, RwLock};
use slotmap::SlotMap; use slotmap::SlotMap;
use std::{ use std::{
any::{type_name, Any, TypeId}, any::{type_name, Any, TypeId},
marker::PhantomData,
mem, mem,
ops::{Deref, DerefMut},
sync::{atomic::Ordering::SeqCst, Arc, Weak}, sync::{atomic::Ordering::SeqCst, Arc, Weak},
time::Duration, time::Duration,
}; };
@ -178,7 +180,7 @@ pub struct AppContext {
pub(crate) svg_renderer: SvgRenderer, pub(crate) svg_renderer: SvgRenderer,
pub(crate) image_cache: ImageCache, pub(crate) image_cache: ImageCache,
pub(crate) text_style_stack: Vec<TextStyleRefinement>, pub(crate) text_style_stack: Vec<TextStyleRefinement>,
pub(crate) globals_by_type: HashMap<TypeId, Box<dyn Any + Send + Sync>>, pub(crate) globals_by_type: HashMap<TypeId, AnyBox>,
pub(crate) unit_entity: Handle<()>, pub(crate) unit_entity: Handle<()>,
pub(crate) entities: EntityMap, pub(crate) entities: EntityMap,
pub(crate) windows: SlotMap<WindowId, Option<Window>>, pub(crate) windows: SlotMap<WindowId, Option<Window>>,
@ -545,19 +547,16 @@ impl AppContext {
.unwrap() .unwrap()
} }
pub fn set_global<T: Send + Sync + 'static>(&mut self, global: T) { pub fn set_global<G: Any + Send + Sync>(&mut self, global: G) {
let global_type = TypeId::of::<T>(); let global_type = TypeId::of::<G>();
self.push_effect(Effect::NotifyGlobalObservers { global_type }); self.push_effect(Effect::NotifyGlobalObservers { global_type });
self.globals_by_type.insert(global_type, Box::new(global)); self.globals_by_type.insert(global_type, Box::new(global));
} }
pub fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R pub fn update_global<G: 'static, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R {
where
G: 'static + Send + Sync,
{
let mut global = self.lease_global::<G>(); let mut global = self.lease_global::<G>();
let result = f(global.as_mut(), self); let result = f(&mut global, self);
self.restore_global(global); self.end_global_lease(global);
result result
} }
@ -574,19 +573,19 @@ impl AppContext {
) )
} }
pub(crate) fn lease_global<G: 'static + Send + Sync>(&mut self) -> Box<G> { pub(crate) fn lease_global<G: 'static>(&mut self) -> GlobalLease<G> {
self.globals_by_type GlobalLease::new(
.remove(&TypeId::of::<G>()) self.globals_by_type
.ok_or_else(|| anyhow!("no global registered of type {}", type_name::<G>())) .remove(&TypeId::of::<G>())
.unwrap() .ok_or_else(|| anyhow!("no global registered of type {}", type_name::<G>()))
.downcast() .unwrap(),
.unwrap() )
} }
pub(crate) fn restore_global<G: 'static + Send + Sync>(&mut self, global: Box<G>) { pub(crate) fn end_global_lease<G: 'static>(&mut self, lease: GlobalLease<G>) {
let global_type = TypeId::of::<G>(); let global_type = TypeId::of::<G>();
self.push_effect(Effect::NotifyGlobalObservers { global_type }); self.push_effect(Effect::NotifyGlobalObservers { global_type });
self.globals_by_type.insert(global_type, global); self.globals_by_type.insert(global_type, lease.global);
} }
pub(crate) fn push_text_style(&mut self, text_style: TextStyleRefinement) { pub(crate) fn push_text_style(&mut self, text_style: TextStyleRefinement) {
@ -639,21 +638,21 @@ impl AppContext {
} }
impl Context for AppContext { impl Context for AppContext {
type EntityContext<'a, 'w, T: Send + Sync + 'static> = ModelContext<'a, T>; type EntityContext<'a, 'w, T> = ModelContext<'a, T>;
type Result<T> = T; type Result<T> = T;
fn entity<T: Send + Sync + 'static>( fn entity<T: Any + Send + Sync>(
&mut self, &mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T, build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
) -> Handle<T> { ) -> Handle<T> {
self.update(|cx| { self.update(|cx| {
let slot = cx.entities.reserve(); let slot = cx.entities.reserve();
let entity = build_entity(&mut ModelContext::mutable(cx, slot.entity_id)); let entity = build_entity(&mut ModelContext::mutable(cx, slot.downgrade()));
cx.entities.insert(slot, entity) cx.entities.insert(slot, entity)
}) })
} }
fn update_entity<T: Send + Sync + 'static, R>( fn update_entity<T: 'static, R>(
&mut self, &mut self,
handle: &Handle<T>, handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R, update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
@ -662,7 +661,7 @@ impl Context for AppContext {
let mut entity = cx.entities.lease(handle); let mut entity = cx.entities.lease(handle);
let result = update( let result = update(
&mut entity, &mut entity,
&mut ModelContext::mutable(cx, handle.entity_id), &mut ModelContext::mutable(cx, handle.downgrade()),
); );
cx.entities.end_lease(entity); cx.entities.end_lease(entity);
result result
@ -723,11 +722,11 @@ impl MainThread<AppContext> {
self.platform().open_url(url); self.platform().open_url(url);
} }
pub fn open_window<S: 'static + Send + Sync>( pub fn open_window<V: 'static>(
&mut self, &mut self,
options: crate::WindowOptions, options: crate::WindowOptions,
build_root_view: impl FnOnce(&mut WindowContext) -> View<S> + Send + 'static, build_root_view: impl FnOnce(&mut WindowContext) -> View<V> + Send + 'static,
) -> WindowHandle<S> { ) -> WindowHandle<V> {
self.update(|cx| { self.update(|cx| {
let id = cx.windows.insert(None); let id = cx.windows.insert(None);
let handle = WindowHandle::new(id); let handle = WindowHandle::new(id);
@ -768,6 +767,34 @@ pub(crate) enum Effect {
}, },
} }
pub(crate) struct GlobalLease<G: 'static> {
global: AnyBox,
global_type: PhantomData<G>,
}
impl<G: 'static> GlobalLease<G> {
fn new(global: AnyBox) -> Self {
GlobalLease {
global,
global_type: PhantomData,
}
}
}
impl<G: 'static> Deref for GlobalLease<G> {
type Target = G;
fn deref(&self) -> &Self::Target {
self.global.downcast_ref().unwrap()
}
}
impl<G: 'static> DerefMut for GlobalLease<G> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.global.downcast_mut().unwrap()
}
}
pub(crate) struct AnyDrag { pub(crate) struct AnyDrag {
pub drag_handle_view: AnyView, pub drag_handle_view: AnyView,
pub cursor_offset: Point<Pixels>, pub cursor_offset: Point<Pixels>,

View file

@ -5,7 +5,7 @@ use crate::{
use anyhow::anyhow; use anyhow::anyhow;
use derive_more::{Deref, DerefMut}; use derive_more::{Deref, DerefMut};
use parking_lot::Mutex; use parking_lot::Mutex;
use std::{future::Future, sync::Weak}; use std::{any::Any, future::Future, sync::Weak};
#[derive(Clone)] #[derive(Clone)]
pub struct AsyncAppContext { pub struct AsyncAppContext {
@ -14,13 +14,16 @@ pub struct AsyncAppContext {
} }
impl Context for AsyncAppContext { impl Context for AsyncAppContext {
type EntityContext<'a, 'w, T: 'static + Send + Sync> = ModelContext<'a, T>; type EntityContext<'a, 'w, T> = ModelContext<'a, T>;
type Result<T> = Result<T>; type Result<T> = Result<T>;
fn entity<T: Send + Sync + 'static>( fn entity<T: 'static>(
&mut self, &mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T, build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
) -> Self::Result<Handle<T>> { ) -> Self::Result<Handle<T>>
where
T: Any + Send + Sync,
{
let app = self let app = self
.app .app
.upgrade() .upgrade()
@ -29,7 +32,7 @@ impl Context for AsyncAppContext {
Ok(lock.entity(build_entity)) Ok(lock.entity(build_entity))
} }
fn update_entity<T: Send + Sync + 'static, R>( fn update_entity<T: 'static, R>(
&mut self, &mut self,
handle: &Handle<T>, handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R, update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
@ -129,7 +132,7 @@ impl AsyncAppContext {
Ok(app_context.run_on_main(f)) Ok(app_context.run_on_main(f))
} }
pub fn has_global<G: 'static + Send + Sync>(&self) -> Result<bool> { pub fn has_global<G: 'static>(&self) -> Result<bool> {
let app = self let app = self
.app .app
.upgrade() .upgrade()
@ -138,10 +141,7 @@ impl AsyncAppContext {
Ok(lock.has_global::<G>()) Ok(lock.has_global::<G>())
} }
pub fn read_global<G: 'static + Send + Sync, R>( pub fn read_global<G: 'static, R>(&self, read: impl FnOnce(&G, &AppContext) -> R) -> Result<R> {
&self,
read: impl FnOnce(&G, &AppContext) -> R,
) -> Result<R> {
let app = self let app = self
.app .app
.upgrade() .upgrade()
@ -150,7 +150,7 @@ impl AsyncAppContext {
Ok(read(lock.global(), &lock)) Ok(read(lock.global(), &lock))
} }
pub fn try_read_global<G: 'static + Send + Sync, R>( pub fn try_read_global<G: 'static, R>(
&self, &self,
read: impl FnOnce(&G, &AppContext) -> R, read: impl FnOnce(&G, &AppContext) -> R,
) -> Option<R> { ) -> Option<R> {
@ -159,7 +159,7 @@ impl AsyncAppContext {
Some(read(lock.try_global()?, &lock)) Some(read(lock.try_global()?, &lock))
} }
pub fn update_global<G: 'static + Send + Sync, R>( pub fn update_global<G: 'static, R>(
&mut self, &mut self,
update: impl FnOnce(&mut G, &mut AppContext) -> R, update: impl FnOnce(&mut G, &mut AppContext) -> R,
) -> Result<R> { ) -> Result<R> {
@ -195,7 +195,7 @@ impl AsyncWindowContext {
.ok(); .ok();
} }
pub fn read_global<G: 'static + Send + Sync, R>( pub fn read_global<G: 'static, R>(
&self, &self,
read: impl FnOnce(&G, &WindowContext) -> R, read: impl FnOnce(&G, &WindowContext) -> R,
) -> Result<R> { ) -> Result<R> {
@ -203,28 +203,34 @@ impl AsyncWindowContext {
.read_window(self.window, |cx| read(cx.global(), cx)) .read_window(self.window, |cx| read(cx.global(), cx))
} }
pub fn update_global<G: 'static + Send + Sync, R>( pub fn update_global<G, R>(
&mut self, &mut self,
update: impl FnOnce(&mut G, &mut WindowContext) -> R, update: impl FnOnce(&mut G, &mut WindowContext) -> R,
) -> Result<R> { ) -> Result<R>
where
G: 'static,
{
self.app self.app
.update_window(self.window, |cx| cx.update_global(update)) .update_window(self.window, |cx| cx.update_global(update))
} }
} }
impl Context for AsyncWindowContext { impl Context for AsyncWindowContext {
type EntityContext<'a, 'w, T: 'static + Send + Sync> = ViewContext<'a, 'w, T>; type EntityContext<'a, 'w, T> = ViewContext<'a, 'w, T>;
type Result<T> = Result<T>; type Result<T> = Result<T>;
fn entity<R: Send + Sync + 'static>( fn entity<T>(
&mut self, &mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, R>) -> R, build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
) -> Result<Handle<R>> { ) -> Result<Handle<T>>
where
T: Any + Send + Sync,
{
self.app self.app
.update_window(self.window, |cx| cx.entity(build_entity)) .update_window(self.window, |cx| cx.entity(build_entity))
} }
fn update_entity<T: Send + Sync + 'static, R>( fn update_entity<T: 'static, R>(
&mut self, &mut self,
handle: &Handle<T>, handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R, update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
@ -233,3 +239,14 @@ impl Context for AsyncWindowContext {
.update_window(self.window, |cx| cx.update_entity(handle, update)) .update_window(self.window, |cx| cx.update_entity(handle, update))
} }
} }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_async_app_context_send_sync() {
fn assert_send_sync<T: Send + Sync>() {}
assert_send_sync::<AsyncAppContext>();
}
}

View file

@ -1,4 +1,4 @@
use crate::{AppContext, Context}; use crate::{AnyBox, AppContext, Context};
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use derive_more::{Deref, DerefMut}; use derive_more::{Deref, DerefMut};
use parking_lot::{RwLock, RwLockUpgradableReadGuard}; use parking_lot::{RwLock, RwLockUpgradableReadGuard};
@ -30,7 +30,7 @@ impl Display for EntityId {
} }
pub(crate) struct EntityMap { pub(crate) struct EntityMap {
entities: SecondaryMap<EntityId, Box<dyn Any + Send + Sync>>, entities: SecondaryMap<EntityId, AnyBox>,
ref_counts: Arc<RwLock<EntityRefCounts>>, ref_counts: Arc<RwLock<EntityRefCounts>>,
} }
@ -51,56 +51,46 @@ impl EntityMap {
} }
/// Reserve a slot for an entity, which you can subsequently use with `insert`. /// Reserve a slot for an entity, which you can subsequently use with `insert`.
pub fn reserve<T: 'static + Send + Sync>(&self) -> Slot<T> { pub fn reserve<T: 'static>(&self) -> Slot<T> {
let id = self.ref_counts.write().counts.insert(1.into()); let id = self.ref_counts.write().counts.insert(1.into());
Slot(Handle::new(id, Arc::downgrade(&self.ref_counts))) Slot(Handle::new(id, Arc::downgrade(&self.ref_counts)))
} }
/// Insert an entity into a slot obtained by calling `reserve`. /// Insert an entity into a slot obtained by calling `reserve`.
pub fn insert<T: 'static + Any + Send + Sync>( pub fn insert<T>(&mut self, slot: Slot<T>, entity: T) -> Handle<T>
&mut self, where
slot: Slot<T>, T: Any + Send + Sync,
entity: T, {
) -> Handle<T> {
let handle = slot.0; let handle = slot.0;
self.entities.insert(handle.entity_id, Box::new(entity)); self.entities.insert(handle.entity_id, Box::new(entity));
handle handle
} }
/// Move an entity to the stack. /// Move an entity to the stack.
pub fn lease<'a, T: 'static + Send + Sync>(&mut self, handle: &'a Handle<T>) -> Lease<'a, T> { pub fn lease<'a, T>(&mut self, handle: &'a Handle<T>) -> Lease<'a, T> {
let entity = Some( let entity = Some(
self.entities self.entities
.remove(handle.entity_id) .remove(handle.entity_id)
.expect("Circular entity lease. Is the entity already being updated?") .expect("Circular entity lease. Is the entity already being updated?"),
.downcast::<T>()
.unwrap(),
); );
Lease { handle, entity } Lease {
} handle,
entity,
/// Return an entity after moving it to the stack.
pub fn end_lease<T: 'static + Send + Sync>(&mut self, mut lease: Lease<T>) {
self.entities
.insert(lease.handle.entity_id, lease.entity.take().unwrap());
}
pub fn read<T: 'static + Send + Sync>(&self, handle: &Handle<T>) -> &T {
self.entities[handle.entity_id].downcast_ref().unwrap()
}
pub fn weak_handle<T: 'static + Send + Sync>(&self, id: EntityId) -> WeakHandle<T> {
WeakHandle {
any_handle: AnyWeakHandle {
entity_id: id,
entity_type: TypeId::of::<T>(),
entity_ref_counts: Arc::downgrade(&self.ref_counts),
},
entity_type: PhantomData, entity_type: PhantomData,
} }
} }
pub fn take_dropped(&mut self) -> Vec<(EntityId, Box<dyn Any + Send + Sync>)> { /// Return an entity after moving it to the stack.
pub fn end_lease<T>(&mut self, mut lease: Lease<T>) {
self.entities
.insert(lease.handle.entity_id, lease.entity.take().unwrap());
}
pub fn read<T>(&self, handle: &Handle<T>) -> &T {
(handle.downcast_entity)(&self.entities[handle.entity_id])
}
pub fn take_dropped(&mut self) -> Vec<(EntityId, AnyBox)> {
let dropped_entity_ids = mem::take(&mut self.ref_counts.write().dropped_entity_ids); let dropped_entity_ids = mem::take(&mut self.ref_counts.write().dropped_entity_ids);
dropped_entity_ids dropped_entity_ids
.into_iter() .into_iter()
@ -109,35 +99,27 @@ impl EntityMap {
} }
} }
pub struct Lease<'a, T: Send + Sync> { pub struct Lease<'a, T> {
entity: Option<Box<T>>, entity: Option<AnyBox>,
pub handle: &'a Handle<T>, pub handle: &'a Handle<T>,
entity_type: PhantomData<T>,
} }
impl<'a, T> core::ops::Deref for Lease<'a, T> impl<'a, T> core::ops::Deref for Lease<'a, T> {
where
T: Send + Sync,
{
type Target = T; type Target = T;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
self.entity.as_ref().unwrap() (self.handle.downcast_entity)(self.entity.as_ref().unwrap())
} }
} }
impl<'a, T> core::ops::DerefMut for Lease<'a, T> impl<'a, T> core::ops::DerefMut for Lease<'a, T> {
where
T: Send + Sync,
{
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
self.entity.as_mut().unwrap() (self.handle.downcast_entity_mut)(self.entity.as_mut().unwrap())
} }
} }
impl<'a, T> Drop for Lease<'a, T> impl<'a, T> Drop for Lease<'a, T> {
where
T: Send + Sync,
{
fn drop(&mut self) { fn drop(&mut self) {
if self.entity.is_some() { if self.entity.is_some() {
// We don't panic here, because other panics can cause us to drop the lease without ending it cleanly. // We don't panic here, because other panics can cause us to drop the lease without ending it cleanly.
@ -147,7 +129,7 @@ where
} }
#[derive(Deref, DerefMut)] #[derive(Deref, DerefMut)]
pub struct Slot<T: Send + Sync + 'static>(Handle<T>); pub struct Slot<T>(Handle<T>);
pub struct AnyHandle { pub struct AnyHandle {
pub(crate) entity_id: EntityId, pub(crate) entity_id: EntityId,
@ -176,14 +158,13 @@ impl AnyHandle {
} }
} }
pub fn downcast<T>(&self) -> Option<Handle<T>> pub fn downcast<T: 'static>(&self) -> Option<Handle<T>> {
where
T: 'static + Send + Sync,
{
if TypeId::of::<T>() == self.entity_type { if TypeId::of::<T>() == self.entity_type {
Some(Handle { Some(Handle {
any_handle: self.clone(), any_handle: self.clone(),
entity_type: PhantomData, entity_type: PhantomData,
downcast_entity: |any| any.downcast_ref().unwrap(),
downcast_entity_mut: |any| any.downcast_mut().unwrap(),
}) })
} else { } else {
None None
@ -231,10 +212,7 @@ impl Drop for AnyHandle {
} }
} }
impl<T> From<Handle<T>> for AnyHandle impl<T> From<Handle<T>> for AnyHandle {
where
T: 'static + Send + Sync,
{
fn from(handle: Handle<T>) -> Self { fn from(handle: Handle<T>) -> Self {
handle.any_handle handle.any_handle
} }
@ -255,18 +233,28 @@ impl PartialEq for AnyHandle {
impl Eq for AnyHandle {} impl Eq for AnyHandle {}
#[derive(Deref, DerefMut)] #[derive(Deref, DerefMut)]
pub struct Handle<T: Send + Sync> { pub struct Handle<T> {
#[deref] #[deref]
#[deref_mut] #[deref_mut]
any_handle: AnyHandle, any_handle: AnyHandle,
entity_type: PhantomData<T>, entity_type: PhantomData<T>,
downcast_entity: fn(&dyn Any) -> &T,
downcast_entity_mut: fn(&mut dyn Any) -> &mut T,
} }
impl<T: 'static + Send + Sync> Handle<T> { unsafe impl<T> Send for Handle<T> {}
fn new(id: EntityId, entity_map: Weak<RwLock<EntityRefCounts>>) -> Self { unsafe impl<T> Sync for Handle<T> {}
impl<T: 'static> Handle<T> {
fn new(id: EntityId, entity_map: Weak<RwLock<EntityRefCounts>>) -> Self
where
T: 'static,
{
Self { Self {
any_handle: AnyHandle::new(id, TypeId::of::<T>(), entity_map), any_handle: AnyHandle::new(id, TypeId::of::<T>(), entity_map),
entity_type: PhantomData, entity_type: PhantomData,
downcast_entity: |any| any.downcast_ref().unwrap(),
downcast_entity_mut: |any| any.downcast_mut().unwrap(),
} }
} }
@ -274,6 +262,8 @@ impl<T: 'static + Send + Sync> Handle<T> {
WeakHandle { WeakHandle {
any_handle: self.any_handle.downgrade(), any_handle: self.any_handle.downgrade(),
entity_type: self.entity_type, entity_type: self.entity_type,
downcast_entity: self.downcast_entity,
downcast_entity_mut: self.downcast_entity_mut,
} }
} }
@ -286,25 +276,30 @@ impl<T: 'static + Send + Sync> Handle<T> {
/// The update function receives a context appropriate for its environment. /// The update function receives a context appropriate for its environment.
/// When updating in an `AppContext`, it receives a `ModelContext`. /// When updating in an `AppContext`, it receives a `ModelContext`.
/// When updating an a `WindowContext`, it receives a `ViewContext`. /// When updating an a `WindowContext`, it receives a `ViewContext`.
pub fn update<C: Context, R>( pub fn update<C, R>(
&self, &self,
cx: &mut C, cx: &mut C,
update: impl FnOnce(&mut T, &mut C::EntityContext<'_, '_, T>) -> R, update: impl FnOnce(&mut T, &mut C::EntityContext<'_, '_, T>) -> R,
) -> C::Result<R> { ) -> C::Result<R>
where
C: Context,
{
cx.update_entity(self, update) cx.update_entity(self, update)
} }
} }
impl<T: Send + Sync> Clone for Handle<T> { impl<T> Clone for Handle<T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
any_handle: self.any_handle.clone(), any_handle: self.any_handle.clone(),
entity_type: self.entity_type, entity_type: self.entity_type,
downcast_entity: self.downcast_entity,
downcast_entity_mut: self.downcast_entity_mut,
} }
} }
} }
impl<T: 'static + Send + Sync> std::fmt::Debug for Handle<T> { impl<T> std::fmt::Debug for Handle<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!( write!(
f, f,
@ -315,19 +310,19 @@ impl<T: 'static + Send + Sync> std::fmt::Debug for Handle<T> {
} }
} }
impl<T: Send + Sync + 'static> Hash for Handle<T> { impl<T> Hash for Handle<T> {
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
self.any_handle.hash(state); self.any_handle.hash(state);
} }
} }
impl<T: Send + Sync + 'static> PartialEq for Handle<T> { impl<T> PartialEq for Handle<T> {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.any_handle == other.any_handle self.any_handle == other.any_handle
} }
} }
impl<T: Send + Sync + 'static> Eq for Handle<T> {} impl<T> Eq for Handle<T> {}
#[derive(Clone)] #[derive(Clone)]
pub struct AnyWeakHandle { pub struct AnyWeakHandle {
@ -365,10 +360,7 @@ impl AnyWeakHandle {
} }
} }
impl<T> From<WeakHandle<T>> for AnyWeakHandle impl<T> From<WeakHandle<T>> for AnyWeakHandle {
where
T: 'static + Send + Sync,
{
fn from(handle: WeakHandle<T>) -> Self { fn from(handle: WeakHandle<T>) -> Self {
handle.any_handle handle.any_handle
} }
@ -394,22 +386,31 @@ pub struct WeakHandle<T> {
#[deref_mut] #[deref_mut]
any_handle: AnyWeakHandle, any_handle: AnyWeakHandle,
entity_type: PhantomData<T>, entity_type: PhantomData<T>,
downcast_entity: fn(&dyn Any) -> &T,
pub(crate) downcast_entity_mut: fn(&mut dyn Any) -> &mut T,
} }
impl<T: 'static + Send + Sync> Clone for WeakHandle<T> { unsafe impl<T> Send for WeakHandle<T> {}
unsafe impl<T> Sync for WeakHandle<T> {}
impl<T> Clone for WeakHandle<T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
any_handle: self.any_handle.clone(), any_handle: self.any_handle.clone(),
entity_type: self.entity_type, entity_type: self.entity_type,
downcast_entity: self.downcast_entity,
downcast_entity_mut: self.downcast_entity_mut,
} }
} }
} }
impl<T: Send + Sync + 'static> WeakHandle<T> { impl<T: 'static> WeakHandle<T> {
pub fn upgrade(&self) -> Option<Handle<T>> { pub fn upgrade(&self) -> Option<Handle<T>> {
Some(Handle { Some(Handle {
any_handle: self.any_handle.upgrade()?, any_handle: self.any_handle.upgrade()?,
entity_type: self.entity_type, entity_type: self.entity_type,
downcast_entity: self.downcast_entity,
downcast_entity_mut: self.downcast_entity_mut,
}) })
} }
@ -420,12 +421,13 @@ impl<T: Send + Sync + 'static> WeakHandle<T> {
/// The update function receives a context appropriate for its environment. /// The update function receives a context appropriate for its environment.
/// When updating in an `AppContext`, it receives a `ModelContext`. /// When updating in an `AppContext`, it receives a `ModelContext`.
/// When updating an a `WindowContext`, it receives a `ViewContext`. /// When updating an a `WindowContext`, it receives a `ViewContext`.
pub fn update<C: Context, R>( pub fn update<C, R>(
&self, &self,
cx: &mut C, cx: &mut C,
update: impl FnOnce(&mut T, &mut C::EntityContext<'_, '_, T>) -> R, update: impl FnOnce(&mut T, &mut C::EntityContext<'_, '_, T>) -> R,
) -> Result<R> ) -> Result<R>
where where
C: Context,
Result<C::Result<R>>: crate::Flatten<R>, Result<C::Result<R>>: crate::Flatten<R>,
{ {
crate::Flatten::flatten( crate::Flatten::flatten(
@ -436,16 +438,16 @@ impl<T: Send + Sync + 'static> WeakHandle<T> {
} }
} }
impl<T: Send + Sync + 'static> Hash for WeakHandle<T> { impl<T> Hash for WeakHandle<T> {
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
self.any_handle.hash(state); self.any_handle.hash(state);
} }
} }
impl<T: Send + Sync + 'static> PartialEq for WeakHandle<T> { impl<T> PartialEq for WeakHandle<T> {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.any_handle == other.any_handle self.any_handle == other.any_handle
} }
} }
impl<T: Send + Sync + 'static> Eq for WeakHandle<T> {} impl<T> Eq for WeakHandle<T> {}

View file

@ -4,28 +4,29 @@ use crate::{
}; };
use derive_more::{Deref, DerefMut}; use derive_more::{Deref, DerefMut};
use futures::FutureExt; use futures::FutureExt;
use std::{any::TypeId, future::Future, marker::PhantomData}; use std::{
any::{Any, TypeId},
future::Future,
};
#[derive(Deref, DerefMut)] #[derive(Deref, DerefMut)]
pub struct ModelContext<'a, T> { pub struct ModelContext<'a, T> {
#[deref] #[deref]
#[deref_mut] #[deref_mut]
app: Reference<'a, AppContext>, app: Reference<'a, AppContext>,
entity_type: PhantomData<T>, model_state: WeakHandle<T>,
entity_id: EntityId,
} }
impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> { impl<'a, T: 'static> ModelContext<'a, T> {
pub(crate) fn mutable(app: &'a mut AppContext, entity_id: EntityId) -> Self { pub(crate) fn mutable(app: &'a mut AppContext, model_state: WeakHandle<T>) -> Self {
Self { Self {
app: Reference::Mutable(app), app: Reference::Mutable(app),
entity_type: PhantomData, model_state,
entity_id,
} }
} }
pub fn entity_id(&self) -> EntityId { pub fn entity_id(&self) -> EntityId {
self.entity_id self.model_state.entity_id
} }
pub fn handle(&self) -> Handle<T> { pub fn handle(&self) -> Handle<T> {
@ -35,14 +36,17 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
} }
pub fn weak_handle(&self) -> WeakHandle<T> { pub fn weak_handle(&self) -> WeakHandle<T> {
self.app.entities.weak_handle(self.entity_id) self.model_state.clone()
} }
pub fn observe<E: Send + Sync + 'static>( pub fn observe<T2: 'static>(
&mut self, &mut self,
handle: &Handle<E>, handle: &Handle<T2>,
on_notify: impl Fn(&mut T, Handle<E>, &mut ModelContext<'_, T>) + Send + Sync + 'static, on_notify: impl Fn(&mut T, Handle<T2>, &mut ModelContext<'_, T>) + Send + Sync + 'static,
) -> Subscription { ) -> Subscription
where
T: Any + Send + Sync,
{
let this = self.weak_handle(); let this = self.weak_handle();
let handle = handle.downgrade(); let handle = handle.downgrade();
self.app.observers.insert( self.app.observers.insert(
@ -58,14 +62,17 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
) )
} }
pub fn subscribe<E: EventEmitter + Send + Sync + 'static>( pub fn subscribe<E: 'static + EventEmitter>(
&mut self, &mut self,
handle: &Handle<E>, handle: &Handle<E>,
on_event: impl Fn(&mut T, Handle<E>, &E::Event, &mut ModelContext<'_, T>) on_event: impl Fn(&mut T, Handle<E>, &E::Event, &mut ModelContext<'_, T>)
+ Send + Send
+ Sync + Sync
+ 'static, + 'static,
) -> Subscription { ) -> Subscription
where
T: Any + Send + Sync,
{
let this = self.weak_handle(); let this = self.weak_handle();
let handle = handle.downgrade(); let handle = handle.downgrade();
self.app.event_listeners.insert( self.app.event_listeners.insert(
@ -85,9 +92,12 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
pub fn on_release( pub fn on_release(
&mut self, &mut self,
on_release: impl Fn(&mut T, &mut AppContext) + Send + Sync + 'static, on_release: impl Fn(&mut T, &mut AppContext) + Send + Sync + 'static,
) -> Subscription { ) -> Subscription
where
T: 'static,
{
self.app.release_listeners.insert( self.app.release_listeners.insert(
self.entity_id, self.model_state.entity_id,
Box::new(move |this, cx| { Box::new(move |this, cx| {
let this = this.downcast_mut().expect("invalid entity type"); let this = this.downcast_mut().expect("invalid entity type");
on_release(this, cx); on_release(this, cx);
@ -95,11 +105,14 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
) )
} }
pub fn observe_release<E: Send + Sync + 'static>( pub fn observe_release<E: 'static>(
&mut self, &mut self,
handle: &Handle<E>, handle: &Handle<E>,
on_release: impl Fn(&mut T, &mut E, &mut ModelContext<'_, T>) + Send + Sync + 'static, on_release: impl Fn(&mut T, &mut E, &mut ModelContext<'_, T>) + Send + Sync + 'static,
) -> Subscription { ) -> Subscription
where
T: Any + Send + Sync,
{
let this = self.weak_handle(); let this = self.weak_handle();
self.app.release_listeners.insert( self.app.release_listeners.insert(
handle.entity_id, handle.entity_id,
@ -115,7 +128,10 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
pub fn observe_global<G: 'static>( pub fn observe_global<G: 'static>(
&mut self, &mut self,
f: impl Fn(&mut T, &mut ModelContext<'_, T>) + Send + Sync + 'static, f: impl Fn(&mut T, &mut ModelContext<'_, T>) + Send + Sync + 'static,
) -> Subscription { ) -> Subscription
where
T: Any + Send + Sync,
{
let handle = self.weak_handle(); let handle = self.weak_handle();
self.global_observers.insert( self.global_observers.insert(
TypeId::of::<G>(), TypeId::of::<G>(),
@ -129,6 +145,7 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
) -> Subscription ) -> Subscription
where where
Fut: 'static + Future<Output = ()> + Send, Fut: 'static + Future<Output = ()> + Send,
T: Any + Send + Sync,
{ {
let handle = self.weak_handle(); let handle = self.weak_handle();
self.app.quit_observers.insert( self.app.quit_observers.insert(
@ -146,9 +163,13 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
} }
pub fn notify(&mut self) { pub fn notify(&mut self) {
if self.app.pending_notifications.insert(self.entity_id) { if self
.app
.pending_notifications
.insert(self.model_state.entity_id)
{
self.app.pending_effects.push_back(Effect::Notify { self.app.pending_effects.push_back(Effect::Notify {
emitter: self.entity_id, emitter: self.model_state.entity_id,
}); });
} }
} }
@ -158,8 +179,8 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
G: 'static + Send + Sync, G: 'static + Send + Sync,
{ {
let mut global = self.app.lease_global::<G>(); let mut global = self.app.lease_global::<G>();
let result = f(global.as_mut(), self); let result = f(&mut global, self);
self.app.restore_global(global); self.app.end_global_lease(global);
result result
} }
@ -168,6 +189,7 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
f: impl FnOnce(WeakHandle<T>, AsyncAppContext) -> Fut + Send + 'static, f: impl FnOnce(WeakHandle<T>, AsyncAppContext) -> Fut + Send + 'static,
) -> Task<R> ) -> Task<R>
where where
T: 'static,
Fut: Future<Output = R> + Send + 'static, Fut: Future<Output = R> + Send + 'static,
R: Send + 'static, R: Send + 'static,
{ {
@ -176,27 +198,34 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
} }
} }
impl<'a, T: EventEmitter + Send + Sync + 'static> ModelContext<'a, T> { impl<'a, T> ModelContext<'a, T>
where
T: EventEmitter,
T::Event: Send + Sync,
{
pub fn emit(&mut self, event: T::Event) { pub fn emit(&mut self, event: T::Event) {
self.app.pending_effects.push_back(Effect::Emit { self.app.pending_effects.push_back(Effect::Emit {
emitter: self.entity_id, emitter: self.model_state.entity_id,
event: Box::new(event), event: Box::new(event),
}); });
} }
} }
impl<'a, T: 'static> Context for ModelContext<'a, T> { impl<'a, T> Context for ModelContext<'a, T> {
type EntityContext<'b, 'c, U: Send + Sync + 'static> = ModelContext<'b, U>; type EntityContext<'b, 'c, U> = ModelContext<'b, U>;
type Result<U> = U; type Result<U> = U;
fn entity<U: Send + Sync + 'static>( fn entity<U>(
&mut self, &mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, U>) -> U, build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, U>) -> U,
) -> Handle<U> { ) -> Handle<U>
where
U: 'static + Send + Sync,
{
self.app.entity(build_entity) self.app.entity(build_entity)
} }
fn update_entity<U: Send + Sync + 'static, R>( fn update_entity<U: 'static, R>(
&mut self, &mut self,
handle: &Handle<U>, handle: &Handle<U>,
update: impl FnOnce(&mut U, &mut Self::EntityContext<'_, '_, U>) -> R, update: impl FnOnce(&mut U, &mut Self::EntityContext<'_, '_, U>) -> R,

View file

@ -1,11 +1,11 @@
use crate::{BorrowWindow, Bounds, ElementId, LayoutId, Pixels, ViewContext}; use crate::{BorrowWindow, Bounds, ElementId, LayoutId, Pixels, ViewContext};
use derive_more::{Deref, DerefMut}; use derive_more::{Deref, DerefMut};
pub(crate) use smallvec::SmallVec; pub(crate) use smallvec::SmallVec;
use std::mem; use std::{any::Any, mem};
pub trait Element: 'static + Send + Sync + IntoAnyElement<Self::ViewState> { pub trait Element: IntoAnyElement<Self::ViewState> {
type ViewState: 'static + Send + Sync; type ViewState: 'static;
type ElementState: 'static + Send + Sync; type ElementState: 'static;
fn id(&self) -> Option<ElementId>; fn id(&self) -> Option<ElementId>;
@ -15,6 +15,8 @@ pub trait Element: 'static + Send + Sync + IntoAnyElement<Self::ViewState> {
element_state: Option<Self::ElementState>, element_state: Option<Self::ElementState>,
cx: &mut ViewContext<Self::ViewState>, cx: &mut ViewContext<Self::ViewState>,
) -> Self::ElementState; ) -> Self::ElementState;
// where
// Self::ViewState: Any + Send + Sync;
fn layout( fn layout(
&mut self, &mut self,
@ -22,6 +24,8 @@ pub trait Element: 'static + Send + Sync + IntoAnyElement<Self::ViewState> {
element_state: &mut Self::ElementState, element_state: &mut Self::ElementState,
cx: &mut ViewContext<Self::ViewState>, cx: &mut ViewContext<Self::ViewState>,
) -> LayoutId; ) -> LayoutId;
// where
// Self::ViewState: Any + Send + Sync;
fn paint( fn paint(
&mut self, &mut self,
@ -30,6 +34,9 @@ pub trait Element: 'static + Send + Sync + IntoAnyElement<Self::ViewState> {
element_state: &mut Self::ElementState, element_state: &mut Self::ElementState,
cx: &mut ViewContext<Self::ViewState>, cx: &mut ViewContext<Self::ViewState>,
); );
// where
// Self::ViewState: Any + Send + Sync;
} }
#[derive(Deref, DerefMut, Default, Clone, Debug, Eq, PartialEq, Hash)] #[derive(Deref, DerefMut, Default, Clone, Debug, Eq, PartialEq, Hash)]
@ -59,7 +66,7 @@ pub trait ParentElement: Element {
} }
} }
trait ElementObject<V>: 'static + Send + Sync { trait ElementObject<V> {
fn initialize(&mut self, view_state: &mut V, cx: &mut ViewContext<V>); fn initialize(&mut self, view_state: &mut V, cx: &mut ViewContext<V>);
fn layout(&mut self, view_state: &mut V, cx: &mut ViewContext<V>) -> LayoutId; fn layout(&mut self, view_state: &mut V, cx: &mut ViewContext<V>) -> LayoutId;
fn paint(&mut self, view_state: &mut V, cx: &mut ViewContext<V>); fn paint(&mut self, view_state: &mut V, cx: &mut ViewContext<V>);
@ -99,6 +106,8 @@ impl<E: Element> RenderedElement<E> {
impl<E> ElementObject<E::ViewState> for RenderedElement<E> impl<E> ElementObject<E::ViewState> for RenderedElement<E>
where where
E: Element, E: Element,
// E::ViewState: Any + Send + Sync,
E::ElementState: Any + Send + Sync,
{ {
fn initialize(&mut self, view_state: &mut E::ViewState, cx: &mut ViewContext<E::ViewState>) { fn initialize(&mut self, view_state: &mut E::ViewState, cx: &mut ViewContext<E::ViewState>) {
let frame_state = if let Some(id) = self.element.id() { let frame_state = if let Some(id) = self.element.id() {
@ -171,10 +180,15 @@ where
} }
} }
pub struct AnyElement<V>(Box<dyn ElementObject<V>>); pub struct AnyElement<V>(Box<dyn ElementObject<V> + Send + Sync>);
impl<V: 'static + Send + Sync> AnyElement<V> { impl<V> AnyElement<V> {
pub fn new<E: Element<ViewState = V>>(element: E) -> Self { pub fn new<E>(element: E) -> Self
where
E: 'static + Send + Sync,
E: Element<ViewState = V>,
E::ElementState: Any + Send + Sync,
{
AnyElement(Box::new(RenderedElement::new(element))) AnyElement(Box::new(RenderedElement::new(element)))
} }

View file

@ -9,7 +9,7 @@ use refineable::Refineable;
use smallvec::SmallVec; use smallvec::SmallVec;
pub struct Div< pub struct Div<
V: 'static + Send + Sync, V: 'static,
I: ElementInteraction<V> = StatelessInteraction<V>, I: ElementInteraction<V> = StatelessInteraction<V>,
F: ElementFocus<V> = FocusDisabled, F: ElementFocus<V> = FocusDisabled,
> { > {
@ -20,10 +20,7 @@ pub struct Div<
base_style: StyleRefinement, base_style: StyleRefinement,
} }
pub fn div<V>() -> Div<V, StatelessInteraction<V>, FocusDisabled> pub fn div<V: 'static>() -> Div<V, StatelessInteraction<V>, FocusDisabled> {
where
V: 'static + Send + Sync,
{
Div { Div {
interaction: StatelessInteraction::default(), interaction: StatelessInteraction::default(),
focus: FocusDisabled, focus: FocusDisabled,
@ -35,8 +32,8 @@ where
impl<V, F> Div<V, StatelessInteraction<V>, F> impl<V, F> Div<V, StatelessInteraction<V>, F>
where where
V: 'static,
F: ElementFocus<V>, F: ElementFocus<V>,
V: 'static + Send + Sync,
{ {
pub fn id(self, id: impl Into<ElementId>) -> Div<V, StatefulInteraction<V>, F> { pub fn id(self, id: impl Into<ElementId>) -> Div<V, StatefulInteraction<V>, F> {
Div { Div {
@ -53,7 +50,6 @@ impl<V, I, F> Div<V, I, F>
where where
I: ElementInteraction<V>, I: ElementInteraction<V>,
F: ElementFocus<V>, F: ElementFocus<V>,
V: 'static + Send + Sync,
{ {
pub fn group(mut self, group: impl Into<SharedString>) -> Self { pub fn group(mut self, group: impl Into<SharedString>) -> Self {
self.group = Some(group.into()); self.group = Some(group.into());
@ -108,10 +104,7 @@ where
} }
} }
impl<V> Div<V, StatefulInteraction<V>, FocusDisabled> impl<V: 'static> Div<V, StatefulInteraction<V>, FocusDisabled> {
where
V: 'static + Send + Sync,
{
pub fn focusable(self) -> Div<V, StatefulInteraction<V>, FocusEnabled<V>> { pub fn focusable(self) -> Div<V, StatefulInteraction<V>, FocusEnabled<V>> {
Div { Div {
interaction: self.interaction, interaction: self.interaction,
@ -152,10 +145,7 @@ where
} }
} }
impl<V> Div<V, StatelessInteraction<V>, FocusDisabled> impl<V: 'static> Div<V, StatelessInteraction<V>, FocusDisabled> {
where
V: 'static + Send + Sync,
{
pub fn track_focus( pub fn track_focus(
self, self,
handle: &FocusHandle, handle: &FocusHandle,
@ -172,8 +162,8 @@ where
impl<V, I> Focusable for Div<V, I, FocusEnabled<V>> impl<V, I> Focusable for Div<V, I, FocusEnabled<V>>
where where
V: 'static,
I: ElementInteraction<V>, I: ElementInteraction<V>,
V: 'static + Send + Sync,
{ {
fn focus_listeners(&mut self) -> &mut FocusListeners<V> { fn focus_listeners(&mut self) -> &mut FocusListeners<V> {
&mut self.focus.focus_listeners &mut self.focus.focus_listeners
@ -203,7 +193,6 @@ impl<V, I, F> Element for Div<V, I, F>
where where
I: ElementInteraction<V>, I: ElementInteraction<V>,
F: ElementFocus<V>, F: ElementFocus<V>,
V: 'static + Send + Sync,
{ {
type ViewState = V; type ViewState = V;
type ElementState = DivState; type ElementState = DivState;
@ -317,9 +306,9 @@ where
impl<V, I, F> IntoAnyElement<V> for Div<V, I, F> impl<V, I, F> IntoAnyElement<V> for Div<V, I, F>
where where
// V: Any + Send + Sync,
I: ElementInteraction<V>, I: ElementInteraction<V>,
F: ElementFocus<V>, F: ElementFocus<V>,
V: 'static + Send + Sync,
{ {
fn into_any(self) -> AnyElement<V> { fn into_any(self) -> AnyElement<V> {
AnyElement::new(self) AnyElement::new(self)
@ -330,7 +319,6 @@ impl<V, I, F> ParentElement for Div<V, I, F>
where where
I: ElementInteraction<V>, I: ElementInteraction<V>,
F: ElementFocus<V>, F: ElementFocus<V>,
V: 'static + Send + Sync,
{ {
fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<Self::ViewState>; 2]> { fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<Self::ViewState>; 2]> {
&mut self.children &mut self.children
@ -341,7 +329,6 @@ impl<V, I, F> Styled for Div<V, I, F>
where where
I: ElementInteraction<V>, I: ElementInteraction<V>,
F: ElementFocus<V>, F: ElementFocus<V>,
V: 'static + Send + Sync,
{ {
fn style(&mut self) -> &mut StyleRefinement { fn style(&mut self) -> &mut StyleRefinement {
&mut self.base_style &mut self.base_style
@ -352,7 +339,6 @@ impl<V, I, F> StatelessInteractive for Div<V, I, F>
where where
I: ElementInteraction<V>, I: ElementInteraction<V>,
F: ElementFocus<V>, F: ElementFocus<V>,
V: 'static + Send + Sync,
{ {
fn stateless_interaction(&mut self) -> &mut StatelessInteraction<V> { fn stateless_interaction(&mut self) -> &mut StatelessInteraction<V> {
self.interaction.as_stateless_mut() self.interaction.as_stateless_mut()
@ -362,7 +348,6 @@ where
impl<V, F> StatefulInteractive for Div<V, StatefulInteraction<V>, F> impl<V, F> StatefulInteractive for Div<V, StatefulInteraction<V>, F>
where where
F: ElementFocus<V>, F: ElementFocus<V>,
V: 'static + Send + Sync,
{ {
fn stateful_interaction(&mut self) -> &mut StatefulInteraction<Self::ViewState> { fn stateful_interaction(&mut self) -> &mut StatefulInteraction<Self::ViewState> {
&mut self.interaction &mut self.interaction

View file

@ -8,7 +8,7 @@ use futures::FutureExt;
use util::ResultExt; use util::ResultExt;
pub struct Img< pub struct Img<
V: 'static + Send + Sync, V: 'static,
I: ElementInteraction<V> = StatelessInteraction<V>, I: ElementInteraction<V> = StatelessInteraction<V>,
F: ElementFocus<V> = FocusDisabled, F: ElementFocus<V> = FocusDisabled,
> { > {
@ -17,10 +17,7 @@ pub struct Img<
grayscale: bool, grayscale: bool,
} }
pub fn img<V>() -> Img<V, StatelessInteraction<V>, FocusDisabled> pub fn img<V: 'static>() -> Img<V, StatelessInteraction<V>, FocusDisabled> {
where
V: 'static + Send + Sync,
{
Img { Img {
base: div(), base: div(),
uri: None, uri: None,
@ -30,7 +27,7 @@ where
impl<V, I, F> Img<V, I, F> impl<V, I, F> Img<V, I, F>
where where
V: 'static + Send + Sync, V: 'static,
I: ElementInteraction<V>, I: ElementInteraction<V>,
F: ElementFocus<V>, F: ElementFocus<V>,
{ {
@ -47,7 +44,6 @@ where
impl<V, F> Img<V, StatelessInteraction<V>, F> impl<V, F> Img<V, StatelessInteraction<V>, F>
where where
V: 'static + Send + Sync,
F: ElementFocus<V>, F: ElementFocus<V>,
{ {
pub fn id(self, id: impl Into<ElementId>) -> Img<V, StatefulInteraction<V>, F> { pub fn id(self, id: impl Into<ElementId>) -> Img<V, StatefulInteraction<V>, F> {
@ -61,7 +57,6 @@ where
impl<V, I, F> IntoAnyElement<V> for Img<V, I, F> impl<V, I, F> IntoAnyElement<V> for Img<V, I, F>
where where
V: 'static + Send + Sync,
I: ElementInteraction<V>, I: ElementInteraction<V>,
F: ElementFocus<V>, F: ElementFocus<V>,
{ {
@ -72,7 +67,6 @@ where
impl<V, I, F> Element for Img<V, I, F> impl<V, I, F> Element for Img<V, I, F>
where where
V: Send + Sync + 'static,
I: ElementInteraction<V>, I: ElementInteraction<V>,
F: ElementFocus<V>, F: ElementFocus<V>,
{ {
@ -141,7 +135,6 @@ where
impl<V, I, F> Styled for Img<V, I, F> impl<V, I, F> Styled for Img<V, I, F>
where where
V: 'static + Send + Sync,
I: ElementInteraction<V>, I: ElementInteraction<V>,
F: ElementFocus<V>, F: ElementFocus<V>,
{ {
@ -152,7 +145,6 @@ where
impl<V, I, F> StatelessInteractive for Img<V, I, F> impl<V, I, F> StatelessInteractive for Img<V, I, F>
where where
V: 'static + Send + Sync,
I: ElementInteraction<V>, I: ElementInteraction<V>,
F: ElementFocus<V>, F: ElementFocus<V>,
{ {
@ -163,7 +155,6 @@ where
impl<V, F> StatefulInteractive for Img<V, StatefulInteraction<V>, F> impl<V, F> StatefulInteractive for Img<V, StatefulInteraction<V>, F>
where where
V: 'static + Send + Sync,
F: ElementFocus<V>, F: ElementFocus<V>,
{ {
fn stateful_interaction(&mut self) -> &mut StatefulInteraction<Self::ViewState> { fn stateful_interaction(&mut self) -> &mut StatefulInteraction<Self::ViewState> {
@ -173,7 +164,7 @@ where
impl<V, I> Focusable for Img<V, I, FocusEnabled<V>> impl<V, I> Focusable for Img<V, I, FocusEnabled<V>>
where where
V: 'static + Send + Sync, V: 'static,
I: ElementInteraction<V>, I: ElementInteraction<V>,
{ {
fn focus_listeners(&mut self) -> &mut FocusListeners<Self::ViewState> { fn focus_listeners(&mut self) -> &mut FocusListeners<Self::ViewState> {

View file

@ -7,7 +7,7 @@ use crate::{
use util::ResultExt; use util::ResultExt;
pub struct Svg< pub struct Svg<
V: 'static + Send + Sync, V: 'static,
I: ElementInteraction<V> = StatelessInteraction<V>, I: ElementInteraction<V> = StatelessInteraction<V>,
F: ElementFocus<V> = FocusDisabled, F: ElementFocus<V> = FocusDisabled,
> { > {
@ -15,10 +15,7 @@ pub struct Svg<
path: Option<SharedString>, path: Option<SharedString>,
} }
pub fn svg<V>() -> Svg<V, StatelessInteraction<V>, FocusDisabled> pub fn svg<V: 'static>() -> Svg<V, StatelessInteraction<V>, FocusDisabled> {
where
V: 'static + Send + Sync,
{
Svg { Svg {
base: div(), base: div(),
path: None, path: None,
@ -27,7 +24,6 @@ where
impl<V, I, F> Svg<V, I, F> impl<V, I, F> Svg<V, I, F>
where where
V: 'static + Send + Sync,
I: ElementInteraction<V>, I: ElementInteraction<V>,
F: ElementFocus<V>, F: ElementFocus<V>,
{ {
@ -39,7 +35,6 @@ where
impl<V, F> Svg<V, StatelessInteraction<V>, F> impl<V, F> Svg<V, StatelessInteraction<V>, F>
where where
V: 'static + Send + Sync,
F: ElementFocus<V>, F: ElementFocus<V>,
{ {
pub fn id(self, id: impl Into<ElementId>) -> Svg<V, StatefulInteraction<V>, F> { pub fn id(self, id: impl Into<ElementId>) -> Svg<V, StatefulInteraction<V>, F> {
@ -52,7 +47,6 @@ where
impl<V, I, F> IntoAnyElement<V> for Svg<V, I, F> impl<V, I, F> IntoAnyElement<V> for Svg<V, I, F>
where where
V: 'static + Send + Sync,
I: ElementInteraction<V>, I: ElementInteraction<V>,
F: ElementFocus<V>, F: ElementFocus<V>,
{ {
@ -63,7 +57,6 @@ where
impl<V, I, F> Element for Svg<V, I, F> impl<V, I, F> Element for Svg<V, I, F>
where where
V: 'static + Send + Sync,
I: ElementInteraction<V>, I: ElementInteraction<V>,
F: ElementFocus<V>, F: ElementFocus<V>,
{ {
@ -115,7 +108,6 @@ where
impl<V, I, F> Styled for Svg<V, I, F> impl<V, I, F> Styled for Svg<V, I, F>
where where
V: 'static + Send + Sync,
I: ElementInteraction<V>, I: ElementInteraction<V>,
F: ElementFocus<V>, F: ElementFocus<V>,
{ {
@ -126,7 +118,6 @@ where
impl<V, I, F> StatelessInteractive for Svg<V, I, F> impl<V, I, F> StatelessInteractive for Svg<V, I, F>
where where
V: 'static + Send + Sync,
I: ElementInteraction<V>, I: ElementInteraction<V>,
F: ElementFocus<V>, F: ElementFocus<V>,
{ {
@ -137,7 +128,7 @@ where
impl<V, F> StatefulInteractive for Svg<V, StatefulInteraction<V>, F> impl<V, F> StatefulInteractive for Svg<V, StatefulInteraction<V>, F>
where where
V: 'static + Send + Sync, V: 'static,
F: ElementFocus<V>, F: ElementFocus<V>,
{ {
fn stateful_interaction(&mut self) -> &mut StatefulInteraction<Self::ViewState> { fn stateful_interaction(&mut self) -> &mut StatefulInteraction<Self::ViewState> {
@ -145,9 +136,8 @@ where
} }
} }
impl<V, I> Focusable for Svg<V, I, FocusEnabled<V>> impl<V: 'static, I> Focusable for Svg<V, I, FocusEnabled<V>>
where where
V: 'static + Send + Sync,
I: ElementInteraction<V>, I: ElementInteraction<V>,
{ {
fn focus_listeners(&mut self) -> &mut FocusListeners<Self::ViewState> { fn focus_listeners(&mut self) -> &mut FocusListeners<Self::ViewState> {

View file

@ -7,8 +7,8 @@ use smallvec::SmallVec;
use std::{marker::PhantomData, sync::Arc}; use std::{marker::PhantomData, sync::Arc};
use util::ResultExt; use util::ResultExt;
impl<S: 'static + Send + Sync> IntoAnyElement<S> for SharedString { impl<V: 'static> IntoAnyElement<V> for SharedString {
fn into_any(self) -> AnyElement<S> { fn into_any(self) -> AnyElement<V> {
Text { Text {
text: self, text: self,
state_type: PhantomData, state_type: PhantomData,
@ -17,7 +17,7 @@ impl<S: 'static + Send + Sync> IntoAnyElement<S> for SharedString {
} }
} }
impl<V: 'static + Send + Sync> IntoAnyElement<V> for &'static str { impl<V: 'static> IntoAnyElement<V> for &'static str {
fn into_any(self) -> AnyElement<V> { fn into_any(self) -> AnyElement<V> {
Text { Text {
text: self.into(), text: self.into(),
@ -29,8 +29,8 @@ impl<V: 'static + Send + Sync> IntoAnyElement<V> for &'static str {
// TODO: Figure out how to pass `String` to `child` without this. // TODO: Figure out how to pass `String` to `child` without this.
// This impl doesn't exist in the `gpui2` crate. // This impl doesn't exist in the `gpui2` crate.
impl<S: 'static + Send + Sync> IntoAnyElement<S> for String { impl<V: 'static> IntoAnyElement<V> for String {
fn into_any(self) -> AnyElement<S> { fn into_any(self) -> AnyElement<V> {
Text { Text {
text: self.into(), text: self.into(),
state_type: PhantomData, state_type: PhantomData,
@ -44,13 +44,16 @@ pub struct Text<V> {
state_type: PhantomData<V>, state_type: PhantomData<V>,
} }
impl<V: 'static + Send + Sync> IntoAnyElement<V> for Text<V> { unsafe impl<V> Send for Text<V> {}
unsafe impl<V> Sync for Text<V> {}
impl<V: 'static> IntoAnyElement<V> for Text<V> {
fn into_any(self) -> AnyElement<V> { fn into_any(self) -> AnyElement<V> {
AnyElement::new(self) AnyElement::new(self)
} }
} }
impl<V: 'static + Send + Sync> Element for Text<V> { impl<V: 'static> Element for Text<V> {
type ViewState = V; type ViewState = V;
type ElementState = Arc<Mutex<Option<TextElementState>>>; type ElementState = Arc<Mutex<Option<TextElementState>>>;

View file

@ -135,7 +135,7 @@ pub trait Focusable: Element {
} }
} }
pub trait ElementFocus<V: 'static + Send + Sync>: 'static + Send + Sync { pub trait ElementFocus<V: 'static>: 'static + Send + Sync {
fn as_focusable(&self) -> Option<&FocusEnabled<V>>; fn as_focusable(&self) -> Option<&FocusEnabled<V>>;
fn as_focusable_mut(&mut self) -> Option<&mut FocusEnabled<V>>; fn as_focusable_mut(&mut self) -> Option<&mut FocusEnabled<V>>;
@ -200,7 +200,7 @@ pub trait ElementFocus<V: 'static + Send + Sync>: 'static + Send + Sync {
} }
} }
pub struct FocusEnabled<V: 'static + Send + Sync> { pub struct FocusEnabled<V> {
pub focus_handle: Option<FocusHandle>, pub focus_handle: Option<FocusHandle>,
pub focus_listeners: FocusListeners<V>, pub focus_listeners: FocusListeners<V>,
pub focus_style: StyleRefinement, pub focus_style: StyleRefinement,
@ -208,10 +208,7 @@ pub struct FocusEnabled<V: 'static + Send + Sync> {
pub in_focus_style: StyleRefinement, pub in_focus_style: StyleRefinement,
} }
impl<V> FocusEnabled<V> impl<V> FocusEnabled<V> {
where
V: 'static + Send + Sync,
{
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
focus_handle: None, focus_handle: None,
@ -233,10 +230,7 @@ where
} }
} }
impl<V> ElementFocus<V> for FocusEnabled<V> impl<V: 'static> ElementFocus<V> for FocusEnabled<V> {
where
V: 'static + Send + Sync,
{
fn as_focusable(&self) -> Option<&FocusEnabled<V>> { fn as_focusable(&self) -> Option<&FocusEnabled<V>> {
Some(self) Some(self)
} }
@ -246,10 +240,7 @@ where
} }
} }
impl<V> From<FocusHandle> for FocusEnabled<V> impl<V> From<FocusHandle> for FocusEnabled<V> {
where
V: 'static + Send + Sync,
{
fn from(value: FocusHandle) -> Self { fn from(value: FocusHandle) -> Self {
Self { Self {
focus_handle: Some(value), focus_handle: Some(value),
@ -263,10 +254,7 @@ where
pub struct FocusDisabled; pub struct FocusDisabled;
impl<V> ElementFocus<V> for FocusDisabled impl<V: 'static> ElementFocus<V> for FocusDisabled {
where
V: 'static + Send + Sync,
{
fn as_focusable(&self) -> Option<&FocusEnabled<V>> { fn as_focusable(&self) -> Option<&FocusEnabled<V>> {
None None
} }

View file

@ -66,15 +66,17 @@ use taffy::TaffyLayoutEngine;
type AnyBox = Box<dyn Any + Send + Sync>; type AnyBox = Box<dyn Any + Send + Sync>;
pub trait Context { pub trait Context {
type EntityContext<'a, 'w, T: 'static + Send + Sync>; type EntityContext<'a, 'w, T>;
type Result<T>; type Result<T>;
fn entity<T: Send + Sync + 'static>( fn entity<T>(
&mut self, &mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T, build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
) -> Self::Result<Handle<T>>; ) -> Self::Result<Handle<T>>
where
T: 'static + Send + Sync;
fn update_entity<T: Send + Sync + 'static, R>( fn update_entity<T: 'static, R>(
&mut self, &mut self,
handle: &Handle<T>, handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R, update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
@ -105,13 +107,16 @@ impl<T> DerefMut for MainThread<T> {
} }
impl<C: Context> Context for MainThread<C> { impl<C: Context> Context for MainThread<C> {
type EntityContext<'a, 'w, T: 'static + Send + Sync> = MainThread<C::EntityContext<'a, 'w, T>>; type EntityContext<'a, 'w, T> = MainThread<C::EntityContext<'a, 'w, T>>;
type Result<T> = C::Result<T>; type Result<T> = C::Result<T>;
fn entity<T: Send + Sync + 'static>( fn entity<T>(
&mut self, &mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T, build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
) -> Self::Result<Handle<T>> { ) -> Self::Result<Handle<T>>
where
T: Any + Send + Sync,
{
self.0.entity(|cx| { self.0.entity(|cx| {
let cx = unsafe { let cx = unsafe {
mem::transmute::< mem::transmute::<
@ -123,7 +128,7 @@ impl<C: Context> Context for MainThread<C> {
}) })
} }
fn update_entity<T: Send + Sync + 'static, R>( fn update_entity<T: 'static, R>(
&mut self, &mut self,
handle: &Handle<T>, handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R, update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
@ -153,13 +158,13 @@ pub trait BorrowAppContext {
result result
} }
fn set_global<T: Send + Sync + 'static>(&mut self, global: T) { fn set_global<G: Any + Send + Sync>(&mut self, global: G) {
self.app_mut().set_global(global) self.app_mut().set_global(global)
} }
} }
pub trait EventEmitter { pub trait EventEmitter: 'static {
type Event: Any + Send + Sync + 'static; type Event: Any;
} }
pub trait Flatten<T> { pub trait Flatten<T> {

View file

@ -360,8 +360,9 @@ pub trait StatefulInteractive: StatelessInteractive {
) -> Self ) -> Self
where where
Self: Sized, Self: Sized,
S: 'static + Send + Sync, S: Any + Send + Sync,
R: 'static + Fn(&mut Self::ViewState, &mut ViewContext<Self::ViewState>) -> E + Send + Sync, R: Fn(&mut Self::ViewState, &mut ViewContext<Self::ViewState>) -> E,
R: 'static + Send + Sync,
E: Element<ViewState = Self::ViewState>, E: Element<ViewState = Self::ViewState>,
{ {
debug_assert!( debug_assert!(
@ -387,7 +388,7 @@ pub trait StatefulInteractive: StatelessInteractive {
} }
} }
pub trait ElementInteraction<V: 'static + Send + Sync>: 'static + Send + Sync { pub trait ElementInteraction<V: 'static>: 'static + Send + Sync {
fn as_stateless(&self) -> &StatelessInteraction<V>; fn as_stateless(&self) -> &StatelessInteraction<V>;
fn as_stateless_mut(&mut self) -> &mut StatelessInteraction<V>; fn as_stateless_mut(&mut self) -> &mut StatelessInteraction<V>;
fn as_stateful(&self) -> Option<&StatefulInteraction<V>>; fn as_stateful(&self) -> Option<&StatefulInteraction<V>>;
@ -681,7 +682,7 @@ pub trait ElementInteraction<V: 'static + Send + Sync>: 'static + Send + Sync {
} }
#[derive(Deref, DerefMut)] #[derive(Deref, DerefMut)]
pub struct StatefulInteraction<V: 'static + Send + Sync> { pub struct StatefulInteraction<V> {
pub id: ElementId, pub id: ElementId,
#[deref] #[deref]
#[deref_mut] #[deref_mut]
@ -692,10 +693,7 @@ pub struct StatefulInteraction<V: 'static + Send + Sync> {
drag_listener: Option<DragListener<V>>, drag_listener: Option<DragListener<V>>,
} }
impl<V> ElementInteraction<V> for StatefulInteraction<V> impl<V: 'static> ElementInteraction<V> for StatefulInteraction<V> {
where
V: 'static + Send + Sync,
{
fn as_stateful(&self) -> Option<&StatefulInteraction<V>> { fn as_stateful(&self) -> Option<&StatefulInteraction<V>> {
Some(self) Some(self)
} }
@ -713,10 +711,7 @@ where
} }
} }
impl<V> From<ElementId> for StatefulInteraction<V> impl<V> From<ElementId> for StatefulInteraction<V> {
where
V: 'static + Send + Sync,
{
fn from(id: ElementId) -> Self { fn from(id: ElementId) -> Self {
Self { Self {
id, id,
@ -729,7 +724,7 @@ where
} }
} }
type DropListener<V> = dyn Fn(&mut V, AnyBox, &mut ViewContext<V>) + Send + Sync; type DropListener<V> = dyn Fn(&mut V, AnyBox, &mut ViewContext<V>) + 'static + Send + Sync;
pub struct StatelessInteraction<V> { pub struct StatelessInteraction<V> {
pub dispatch_context: DispatchContext, pub dispatch_context: DispatchContext,
@ -745,10 +740,7 @@ pub struct StatelessInteraction<V> {
drop_listeners: SmallVec<[(TypeId, Arc<DropListener<V>>); 2]>, drop_listeners: SmallVec<[(TypeId, Arc<DropListener<V>>); 2]>,
} }
impl<V> StatelessInteraction<V> impl<V> StatelessInteraction<V> {
where
V: 'static + Send + Sync,
{
pub fn into_stateful(self, id: impl Into<ElementId>) -> StatefulInteraction<V> { pub fn into_stateful(self, id: impl Into<ElementId>) -> StatefulInteraction<V> {
StatefulInteraction { StatefulInteraction {
id: id.into(), id: id.into(),
@ -840,10 +832,7 @@ impl<V> Default for StatelessInteraction<V> {
} }
} }
impl<V> ElementInteraction<V> for StatelessInteraction<V> impl<V: 'static> ElementInteraction<V> for StatelessInteraction<V> {
where
V: 'static + Send + Sync,
{
fn as_stateful(&self) -> Option<&StatefulInteraction<V>> { fn as_stateful(&self) -> Option<&StatefulInteraction<V>> {
None None
} }
@ -918,9 +907,7 @@ pub struct ClickEvent {
pub struct Drag<S, R, V, E> pub struct Drag<S, R, V, E>
where where
S: 'static + Send + Sync,
R: Fn(&mut V, &mut ViewContext<V>) -> E, R: Fn(&mut V, &mut ViewContext<V>) -> E,
V: 'static + Send + Sync,
E: Element<ViewState = V>, E: Element<ViewState = V>,
{ {
pub state: S, pub state: S,
@ -930,9 +917,7 @@ where
impl<S, R, V, E> Drag<S, R, V, E> impl<S, R, V, E> Drag<S, R, V, E>
where where
S: 'static + Send + Sync, R: Fn(&mut V, &mut ViewContext<V>) -> E,
R: Fn(&mut V, &mut ViewContext<V>) -> E + Send + Sync,
V: 'static + Send + Sync,
E: Element<ViewState = V>, E: Element<ViewState = V>,
{ {
pub fn new(state: S, render_drag_handle: R) -> Self { pub fn new(state: S, render_drag_handle: R) -> Self {

View file

@ -102,7 +102,7 @@ pub(crate) trait Platform: 'static {
fn delete_credentials(&self, url: &str) -> Result<()>; fn delete_credentials(&self, url: &str) -> Result<()>;
} }
pub trait PlatformDisplay: Debug { pub trait PlatformDisplay: Send + Sync + Debug {
fn id(&self) -> DisplayId; fn id(&self) -> DisplayId;
fn as_any(&self) -> &dyn Any; fn as_any(&self) -> &dyn Any;
fn bounds(&self) -> Bounds<GlobalPixels>; fn bounds(&self) -> Bounds<GlobalPixels>;

View file

@ -21,7 +21,7 @@ struct SubscriberSetState<EmitterKey, Callback> {
impl<EmitterKey, Callback> SubscriberSet<EmitterKey, Callback> impl<EmitterKey, Callback> SubscriberSet<EmitterKey, Callback>
where where
EmitterKey: 'static + Send + Sync + Ord + Clone + Debug, EmitterKey: 'static + Ord + Clone + Debug,
Callback: 'static + Send + Sync, Callback: 'static + Send + Sync,
{ {
pub fn new() -> Self { pub fn new() -> Self {
@ -96,7 +96,7 @@ where
#[must_use] #[must_use]
pub struct Subscription { pub struct Subscription {
unsubscribe: Option<Box<dyn FnOnce() + Send + Sync>>, unsubscribe: Option<Box<dyn FnOnce()>>,
} }
impl Subscription { impl Subscription {

View file

@ -6,12 +6,12 @@ use crate::{
}; };
use std::{marker::PhantomData, sync::Arc}; use std::{marker::PhantomData, sync::Arc};
pub struct View<V: Send + Sync> { pub struct View<V> {
state: Handle<V>, state: Handle<V>,
render: Arc<dyn Fn(&mut V, &mut ViewContext<V>) -> AnyElement<V> + Send + Sync + 'static>, render: Arc<dyn Fn(&mut V, &mut ViewContext<V>) -> AnyElement<V> + Send + Sync + 'static>,
} }
impl<V: 'static + Send + Sync> View<V> { impl<V: 'static> View<V> {
pub fn into_any(self) -> AnyView { pub fn into_any(self) -> AnyView {
AnyView { AnyView {
view: Arc::new(Mutex::new(self)), view: Arc::new(Mutex::new(self)),
@ -19,7 +19,7 @@ impl<V: 'static + Send + Sync> View<V> {
} }
} }
impl<V: Send + Sync> Clone for View<V> { impl<V> Clone for View<V> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
state: self.state.clone(), state: self.state.clone(),
@ -34,7 +34,6 @@ pub fn view<V, E>(
) -> View<V> ) -> View<V>
where where
E: IntoAnyElement<V>, E: IntoAnyElement<V>,
V: 'static + Send + Sync,
{ {
View { View {
state, state,
@ -42,9 +41,7 @@ where
} }
} }
impl<V: 'static + Send + Sync, ParentViewState: 'static + Send + Sync> impl<V: 'static, ParentViewState: 'static> IntoAnyElement<ParentViewState> for View<V> {
IntoAnyElement<ParentViewState> for View<V>
{
fn into_any(self) -> AnyElement<ParentViewState> { fn into_any(self) -> AnyElement<ParentViewState> {
AnyElement::new(EraseViewState { AnyElement::new(EraseViewState {
view: self, view: self,
@ -53,7 +50,7 @@ impl<V: 'static + Send + Sync, ParentViewState: 'static + Send + Sync>
} }
} }
impl<V: 'static + Send + Sync> Element for View<V> { impl<V: 'static> Element for View<V> {
type ViewState = (); type ViewState = ();
type ElementState = AnyElement<V>; type ElementState = AnyElement<V>;
@ -94,26 +91,21 @@ impl<V: 'static + Send + Sync> Element for View<V> {
} }
} }
struct EraseViewState<V: 'static + Send + Sync, ParentV> { struct EraseViewState<V, ParentV> {
view: View<V>, view: View<V>,
parent_view_state_type: PhantomData<ParentV>, parent_view_state_type: PhantomData<ParentV>,
} }
impl<V, ParentV> IntoAnyElement<ParentV> for EraseViewState<V, ParentV> unsafe impl<V, ParentV> Send for EraseViewState<V, ParentV> {}
where unsafe impl<V, ParentV> Sync for EraseViewState<V, ParentV> {}
V: 'static + Send + Sync,
ParentV: 'static + Send + Sync, impl<V: 'static, ParentV: 'static> IntoAnyElement<ParentV> for EraseViewState<V, ParentV> {
{
fn into_any(self) -> AnyElement<ParentV> { fn into_any(self) -> AnyElement<ParentV> {
AnyElement::new(self) AnyElement::new(self)
} }
} }
impl<V, ParentV> Element for EraseViewState<V, ParentV> impl<V: 'static, ParentV: 'static> Element for EraseViewState<V, ParentV> {
where
V: 'static + Send + Sync,
ParentV: 'static + Send + Sync,
{
type ViewState = ParentV; type ViewState = ParentV;
type ElementState = AnyBox; type ElementState = AnyBox;
@ -150,14 +142,14 @@ where
} }
} }
trait ViewObject: 'static + Send + Sync { trait ViewObject: Send + Sync {
fn entity_id(&self) -> EntityId; fn entity_id(&self) -> EntityId;
fn initialize(&mut self, cx: &mut WindowContext) -> AnyBox; fn initialize(&mut self, cx: &mut WindowContext) -> AnyBox;
fn layout(&mut self, element: &mut AnyBox, cx: &mut WindowContext) -> LayoutId; fn layout(&mut self, element: &mut AnyBox, cx: &mut WindowContext) -> LayoutId;
fn paint(&mut self, bounds: Bounds<Pixels>, element: &mut AnyBox, cx: &mut WindowContext); fn paint(&mut self, bounds: Bounds<Pixels>, element: &mut AnyBox, cx: &mut WindowContext);
} }
impl<V: Send + Sync + 'static> ViewObject for View<V> { impl<V: 'static> ViewObject for View<V> {
fn entity_id(&self) -> EntityId { fn entity_id(&self) -> EntityId {
self.state.entity_id self.state.entity_id
} }
@ -195,10 +187,7 @@ pub struct AnyView {
view: Arc<Mutex<dyn ViewObject>>, view: Arc<Mutex<dyn ViewObject>>,
} }
impl<ParentV> IntoAnyElement<ParentV> for AnyView impl<ParentV: 'static> IntoAnyElement<ParentV> for AnyView {
where
ParentV: 'static + Send + Sync,
{
fn into_any(self) -> AnyElement<ParentV> { fn into_any(self) -> AnyElement<ParentV> {
AnyElement::new(EraseAnyViewState { AnyElement::new(EraseAnyViewState {
view: self, view: self,
@ -249,19 +238,16 @@ struct EraseAnyViewState<ParentViewState> {
parent_view_state_type: PhantomData<ParentViewState>, parent_view_state_type: PhantomData<ParentViewState>,
} }
impl<ParentV> IntoAnyElement<ParentV> for EraseAnyViewState<ParentV> unsafe impl<ParentV> Send for EraseAnyViewState<ParentV> {}
where unsafe impl<ParentV> Sync for EraseAnyViewState<ParentV> {}
ParentV: 'static + Send + Sync,
{ impl<ParentV: 'static> IntoAnyElement<ParentV> for EraseAnyViewState<ParentV> {
fn into_any(self) -> AnyElement<ParentV> { fn into_any(self) -> AnyElement<ParentV> {
AnyElement::new(self) AnyElement::new(self)
} }
} }
impl<ParentV> Element for EraseAnyViewState<ParentV> impl<ParentV: 'static> Element for EraseAnyViewState<ParentV> {
where
ParentV: 'static + Send + Sync,
{
type ViewState = ParentV; type ViewState = ParentV;
type ElementState = AnyBox; type ElementState = AnyBox;

View file

@ -428,11 +428,11 @@ impl<'a, 'w> WindowContext<'a, 'w> {
pub fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R pub fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
where where
G: 'static + Send + Sync, G: 'static,
{ {
let mut global = self.app.lease_global::<G>(); let mut global = self.app.lease_global::<G>();
let result = f(global.as_mut(), self); let result = f(&mut global, self);
self.app.set_global(global); self.app.end_global_lease(global);
result result
} }
@ -1129,23 +1129,26 @@ impl<'a, 'w> MainThread<WindowContext<'a, 'w>> {
} }
impl Context for WindowContext<'_, '_> { impl Context for WindowContext<'_, '_> {
type EntityContext<'a, 'w, T: 'static + Send + Sync> = ViewContext<'a, 'w, T>; type EntityContext<'a, 'w, T> = ViewContext<'a, 'w, T>;
type Result<T> = T; type Result<T> = T;
fn entity<T: Send + Sync + 'static>( fn entity<T>(
&mut self, &mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T, build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
) -> Handle<T> { ) -> Handle<T>
where
T: Any + Send + Sync,
{
let slot = self.app.entities.reserve(); let slot = self.app.entities.reserve();
let entity = build_entity(&mut ViewContext::mutable( let entity = build_entity(&mut ViewContext::mutable(
&mut *self.app, &mut *self.app,
&mut self.window, &mut self.window,
slot.entity_id, slot.downgrade(),
)); ));
self.entities.insert(slot, entity) self.entities.insert(slot, entity)
} }
fn update_entity<T: Send + Sync + 'static, R>( fn update_entity<T: 'static, R>(
&mut self, &mut self,
handle: &Handle<T>, handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R, update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
@ -1153,7 +1156,7 @@ impl Context for WindowContext<'_, '_> {
let mut entity = self.entities.lease(handle); let mut entity = self.entities.lease(handle);
let result = update( let result = update(
&mut *entity, &mut *entity,
&mut ViewContext::mutable(&mut *self.app, &mut *self.window, handle.entity_id), &mut ViewContext::mutable(&mut *self.app, &mut *self.window, handle.downgrade()),
); );
self.entities.end_lease(entity); self.entities.end_lease(entity);
result result
@ -1245,11 +1248,14 @@ pub trait BorrowWindow: BorrowAppContext {
.unwrap_or_default() .unwrap_or_default()
} }
fn with_element_state<S: 'static + Send + Sync, R>( fn with_element_state<S, R>(
&mut self, &mut self,
id: ElementId, id: ElementId,
f: impl FnOnce(Option<S>, &mut Self) -> (R, S), f: impl FnOnce(Option<S>, &mut Self) -> (R, S),
) -> R { ) -> R
where
S: Any + Send + Sync,
{
self.with_element_id(id, |global_id, cx| { self.with_element_id(id, |global_id, cx| {
if let Some(any) = cx if let Some(any) = cx
.window_mut() .window_mut()
@ -1278,11 +1284,14 @@ pub trait BorrowWindow: BorrowAppContext {
}) })
} }
fn with_optional_element_state<S: 'static + Send + Sync, R>( fn with_optional_element_state<S, R>(
&mut self, &mut self,
element_id: Option<ElementId>, element_id: Option<ElementId>,
f: impl FnOnce(Option<S>, &mut Self) -> (R, S), f: impl FnOnce(Option<S>, &mut Self) -> (R, S),
) -> R { ) -> R
where
S: Any + Send + Sync,
{
if let Some(element_id) = element_id { if let Some(element_id) = element_id {
self.with_element_state(element_id, f) self.with_element_state(element_id, f)
} else { } else {
@ -1318,13 +1327,12 @@ impl BorrowWindow for WindowContext<'_, '_> {
} }
} }
pub struct ViewContext<'a, 'w, S> { pub struct ViewContext<'a, 'w, V> {
window_cx: WindowContext<'a, 'w>, window_cx: WindowContext<'a, 'w>,
entity_type: PhantomData<S>, view_state: WeakHandle<V>,
entity_id: EntityId,
} }
impl<S> BorrowAppContext for ViewContext<'_, '_, S> { impl<V> BorrowAppContext for ViewContext<'_, '_, V> {
fn app_mut(&mut self) -> &mut AppContext { fn app_mut(&mut self) -> &mut AppContext {
&mut *self.window_cx.app &mut *self.window_cx.app
} }
@ -1340,17 +1348,16 @@ impl<S> BorrowWindow for ViewContext<'_, '_, S> {
} }
} }
impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> { impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
fn mutable(app: &'a mut AppContext, window: &'w mut Window, entity_id: EntityId) -> Self { fn mutable(app: &'a mut AppContext, window: &'w mut Window, view_state: WeakHandle<V>) -> Self {
Self { Self {
window_cx: WindowContext::mutable(app, window), window_cx: WindowContext::mutable(app, window),
entity_id, view_state,
entity_type: PhantomData,
} }
} }
pub fn handle(&self) -> WeakHandle<V> { pub fn handle(&self) -> WeakHandle<V> {
self.entities.weak_handle(self.entity_id) self.view_state.clone()
} }
pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R { pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
@ -1360,18 +1367,25 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> {
result result
} }
pub fn on_next_frame(&mut self, f: impl FnOnce(&mut V, &mut ViewContext<V>) + Send + 'static) { pub fn on_next_frame(&mut self, f: impl FnOnce(&mut V, &mut ViewContext<V>) + Send + 'static)
where
V: Any + Send + Sync,
{
let entity = self.handle(); let entity = self.handle();
self.window_cx.on_next_frame(move |cx| { self.window_cx.on_next_frame(move |cx| {
entity.update(cx, f).ok(); entity.update(cx, f).ok();
}); });
} }
pub fn observe<E: Send + Sync + 'static>( pub fn observe<E>(
&mut self, &mut self,
handle: &Handle<E>, handle: &Handle<E>,
on_notify: impl Fn(&mut V, Handle<E>, &mut ViewContext<'_, '_, V>) + Send + Sync + 'static, on_notify: impl Fn(&mut V, Handle<E>, &mut ViewContext<'_, '_, V>) + Send + Sync + 'static,
) -> Subscription { ) -> Subscription
where
E: 'static,
V: Any + Send + Sync,
{
let this = self.handle(); let this = self.handle();
let handle = handle.downgrade(); let handle = handle.downgrade();
let window_handle = self.window.handle; let window_handle = self.window.handle;
@ -1391,7 +1405,7 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> {
) )
} }
pub fn subscribe<E: EventEmitter + Send + Sync + 'static>( pub fn subscribe<E: EventEmitter>(
&mut self, &mut self,
handle: &Handle<E>, handle: &Handle<E>,
on_event: impl Fn(&mut V, Handle<E>, &E::Event, &mut ViewContext<'_, '_, V>) on_event: impl Fn(&mut V, Handle<E>, &E::Event, &mut ViewContext<'_, '_, V>)
@ -1425,7 +1439,7 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> {
) -> Subscription { ) -> Subscription {
let window_handle = self.window.handle; let window_handle = self.window.handle;
self.app.release_listeners.insert( self.app.release_listeners.insert(
self.entity_id, self.view_state.entity_id,
Box::new(move |this, cx| { Box::new(move |this, cx| {
let this = this.downcast_mut().expect("invalid entity type"); let this = this.downcast_mut().expect("invalid entity type");
// todo!("are we okay with silently swallowing the error?") // todo!("are we okay with silently swallowing the error?")
@ -1434,11 +1448,14 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> {
) )
} }
pub fn observe_release<E: Send + Sync + 'static>( pub fn observe_release<T: 'static>(
&mut self, &mut self,
handle: &Handle<E>, handle: &Handle<T>,
on_release: impl Fn(&mut V, &mut E, &mut ViewContext<'_, '_, V>) + Send + Sync + 'static, on_release: impl Fn(&mut V, &mut T, &mut ViewContext<'_, '_, V>) + Send + Sync + 'static,
) -> Subscription { ) -> Subscription
where
V: Any + Send + Sync,
{
let this = self.handle(); let this = self.handle();
let window_handle = self.window.handle; let window_handle = self.window.handle;
self.app.release_listeners.insert( self.app.release_listeners.insert(
@ -1456,7 +1473,7 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> {
pub fn notify(&mut self) { pub fn notify(&mut self) {
self.window_cx.notify(); self.window_cx.notify();
self.window_cx.app.push_effect(Effect::Notify { self.window_cx.app.push_effect(Effect::Notify {
emitter: self.entity_id, emitter: self.view_state.entity_id,
}); });
} }
@ -1595,8 +1612,8 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> {
G: 'static + Send + Sync, G: 'static + Send + Sync,
{ {
let mut global = self.app.lease_global::<G>(); let mut global = self.app.lease_global::<G>();
let result = f(global.as_mut(), self); let result = f(&mut global, self);
self.app.restore_global(global); self.app.end_global_lease(global);
result result
} }
@ -1630,9 +1647,13 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> {
} }
} }
impl<'a, 'w, V: EventEmitter + Send + Sync + 'static> ViewContext<'a, 'w, V> { impl<'a, 'w, V> ViewContext<'a, 'w, V>
where
V: EventEmitter,
V::Event: Any + Send + Sync,
{
pub fn emit(&mut self, event: V::Event) { pub fn emit(&mut self, event: V::Event) {
let emitter = self.entity_id; let emitter = self.view_state.entity_id;
self.app.push_effect(Effect::Emit { self.app.push_effect(Effect::Emit {
emitter, emitter,
event: Box::new(event), event: Box::new(event),
@ -1640,30 +1661,30 @@ impl<'a, 'w, V: EventEmitter + Send + Sync + 'static> ViewContext<'a, 'w, V> {
} }
} }
impl<'a, 'w, V> Context for ViewContext<'a, 'w, V> impl<'a, 'w, V> Context for ViewContext<'a, 'w, V> {
where type EntityContext<'b, 'c, U> = ViewContext<'b, 'c, U>;
V: 'static + Send + Sync,
{
type EntityContext<'b, 'c, U: 'static + Send + Sync> = ViewContext<'b, 'c, U>;
type Result<U> = U; type Result<U> = U;
fn entity<T2: Send + Sync + 'static>( fn entity<T>(
&mut self, &mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T2>) -> T2, build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
) -> Handle<T2> { ) -> Handle<T>
where
T: 'static + Send + Sync,
{
self.window_cx.entity(build_entity) self.window_cx.entity(build_entity)
} }
fn update_entity<U: 'static + Send + Sync, R>( fn update_entity<T: 'static, R>(
&mut self, &mut self,
handle: &Handle<U>, handle: &Handle<T>,
update: impl FnOnce(&mut U, &mut Self::EntityContext<'_, '_, U>) -> R, update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
) -> R { ) -> R {
self.window_cx.update_entity(handle, update) self.window_cx.update_entity(handle, update)
} }
} }
impl<'a, 'w, S: 'static> std::ops::Deref for ViewContext<'a, 'w, S> { impl<'a, 'w, V> std::ops::Deref for ViewContext<'a, 'w, V> {
type Target = WindowContext<'a, 'w>; type Target = WindowContext<'a, 'w>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
@ -1671,7 +1692,7 @@ impl<'a, 'w, S: 'static> std::ops::Deref for ViewContext<'a, 'w, S> {
} }
} }
impl<'a, 'w, S: 'static> std::ops::DerefMut for ViewContext<'a, 'w, S> { impl<'a, 'w, V> std::ops::DerefMut for ViewContext<'a, 'w, V> {
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.window_cx &mut self.window_cx
} }
@ -1687,9 +1708,9 @@ impl WindowId {
} }
#[derive(PartialEq, Eq)] #[derive(PartialEq, Eq)]
pub struct WindowHandle<S> { pub struct WindowHandle<V> {
id: WindowId, id: WindowId,
state_type: PhantomData<S>, state_type: PhantomData<V>,
} }
impl<S> Copy for WindowHandle<S> {} impl<S> Copy for WindowHandle<S> {}