Merge branch 'fewer-bounds' into zed2

This commit is contained in:
Nathan Sobo 2023-10-24 14:24:06 +02:00
commit 2285a35016
17 changed files with 400 additions and 361 deletions

View file

@ -19,7 +19,7 @@ pub trait Action: Any + Send + Sync {
impl<A> Action for A
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 {
type_name::<A>().into()

View file

@ -23,7 +23,9 @@ use slotmap::SlotMap;
use std::{
any::{type_name, Any, TypeId},
borrow::Borrow,
marker::PhantomData,
mem,
ops::{Deref, DerefMut},
sync::{atomic::Ordering::SeqCst, Arc, Weak},
time::Duration,
};
@ -179,7 +181,7 @@ pub struct AppContext {
pub(crate) svg_renderer: SvgRenderer,
pub(crate) image_cache: ImageCache,
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) entities: EntityMap,
pub(crate) windows: SlotMap<WindowId, Option<Window>>,
@ -554,19 +556,16 @@ impl AppContext {
.unwrap()
}
pub fn set_global<T: Send + Sync + 'static>(&mut self, global: T) {
let global_type = TypeId::of::<T>();
pub fn set_global<G: Any + Send + Sync>(&mut self, global: G) {
let global_type = TypeId::of::<G>();
self.push_effect(Effect::NotifyGlobalObservers { global_type });
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
where
G: 'static + Send + Sync,
{
pub fn update_global<G: 'static, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R {
let mut global = self.lease_global::<G>();
let result = f(global.as_mut(), self);
self.restore_global(global);
let result = f(&mut global, self);
self.end_global_lease(global);
result
}
@ -583,19 +582,19 @@ impl AppContext {
)
}
pub(crate) fn lease_global<G: 'static + Send + Sync>(&mut self) -> Box<G> {
self.globals_by_type
.remove(&TypeId::of::<G>())
.ok_or_else(|| anyhow!("no global registered of type {}", type_name::<G>()))
.unwrap()
.downcast()
.unwrap()
pub(crate) fn lease_global<G: 'static>(&mut self) -> GlobalLease<G> {
GlobalLease::new(
self.globals_by_type
.remove(&TypeId::of::<G>())
.ok_or_else(|| anyhow!("no global registered of type {}", type_name::<G>()))
.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>();
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) {
@ -648,21 +647,21 @@ impl 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;
fn entity<T: Send + Sync + 'static>(
fn entity<T: Any + Send + Sync>(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
) -> Handle<T> {
self.update(|cx| {
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)
})
}
fn update_entity<T: Send + Sync + 'static, R>(
fn update_entity<T: 'static, R>(
&mut self,
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
@ -671,7 +670,7 @@ impl Context for AppContext {
let mut entity = cx.entities.lease(handle);
let result = update(
&mut entity,
&mut ModelContext::mutable(cx, handle.entity_id),
&mut ModelContext::mutable(cx, handle.downgrade()),
);
cx.entities.end_lease(entity);
result
@ -737,11 +736,11 @@ impl MainThread<AppContext> {
})
}
pub fn open_window<S: 'static + Send + Sync>(
pub fn open_window<V: 'static>(
&mut self,
options: crate::WindowOptions,
build_root_view: impl FnOnce(&mut WindowContext) -> View<S> + Send + 'static,
) -> WindowHandle<S> {
build_root_view: impl FnOnce(&mut WindowContext) -> View<V> + Send + 'static,
) -> WindowHandle<V> {
self.update(|cx| {
let id = cx.windows.insert(None);
let handle = WindowHandle::new(id);
@ -785,6 +784,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 drag_handle_view: AnyView,
pub cursor_offset: Point<Pixels>,

View file

@ -5,7 +5,7 @@ use crate::{
use anyhow::anyhow;
use derive_more::{Deref, DerefMut};
use parking_lot::Mutex;
use std::{future::Future, sync::Weak};
use std::{any::Any, future::Future, sync::Weak};
#[derive(Clone)]
pub struct AsyncAppContext {
@ -14,13 +14,16 @@ pub struct 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>;
fn entity<T: Send + Sync + 'static>(
fn entity<T: 'static>(
&mut self,
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
.app
.upgrade()
@ -29,7 +32,7 @@ impl Context for AsyncAppContext {
Ok(lock.entity(build_entity))
}
fn update_entity<T: Send + Sync + 'static, R>(
fn update_entity<T: 'static, R>(
&mut self,
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
@ -129,7 +132,7 @@ impl AsyncAppContext {
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
.app
.upgrade()
@ -138,10 +141,7 @@ impl AsyncAppContext {
Ok(lock.has_global::<G>())
}
pub fn read_global<G: 'static + Send + Sync, R>(
&self,
read: impl FnOnce(&G, &AppContext) -> R,
) -> Result<R> {
pub fn read_global<G: 'static, R>(&self, read: impl FnOnce(&G, &AppContext) -> R) -> Result<R> {
let app = self
.app
.upgrade()
@ -150,7 +150,7 @@ impl AsyncAppContext {
Ok(read(lock.global(), &lock))
}
pub fn try_read_global<G: 'static + Send + Sync, R>(
pub fn try_read_global<G: 'static, R>(
&self,
read: impl FnOnce(&G, &AppContext) -> R,
) -> Option<R> {
@ -159,7 +159,7 @@ impl AsyncAppContext {
Some(read(lock.try_global()?, &lock))
}
pub fn update_global<G: 'static + Send + Sync, R>(
pub fn update_global<G: 'static, R>(
&mut self,
update: impl FnOnce(&mut G, &mut AppContext) -> R,
) -> Result<R> {
@ -195,7 +195,7 @@ impl AsyncWindowContext {
.ok();
}
pub fn read_global<G: 'static + Send + Sync, R>(
pub fn read_global<G: 'static, R>(
&self,
read: impl FnOnce(&G, &WindowContext) -> R,
) -> Result<R> {
@ -203,28 +203,34 @@ impl AsyncWindowContext {
.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,
update: impl FnOnce(&mut G, &mut WindowContext) -> R,
) -> Result<R> {
) -> Result<R>
where
G: 'static,
{
self.app
.update_window(self.window, |cx| cx.update_global(update))
}
}
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>;
fn entity<R: Send + Sync + 'static>(
fn entity<T>(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, R>) -> R,
) -> Result<Handle<R>> {
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
) -> Result<Handle<T>>
where
T: Any + Send + Sync,
{
self.app
.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,
handle: &Handle<T>,
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))
}
}
#[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 derive_more::{Deref, DerefMut};
use parking_lot::{RwLock, RwLockUpgradableReadGuard};
@ -30,7 +30,7 @@ impl Display for EntityId {
}
pub(crate) struct EntityMap {
entities: SecondaryMap<EntityId, Box<dyn Any + Send + Sync>>,
entities: SecondaryMap<EntityId, AnyBox>,
ref_counts: Arc<RwLock<EntityRefCounts>>,
}
@ -51,56 +51,46 @@ impl EntityMap {
}
/// 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());
Slot(Handle::new(id, Arc::downgrade(&self.ref_counts)))
}
/// Insert an entity into a slot obtained by calling `reserve`.
pub fn insert<T: 'static + Any + Send + Sync>(
&mut self,
slot: Slot<T>,
entity: T,
) -> Handle<T> {
pub fn insert<T>(&mut self, slot: Slot<T>, entity: T) -> Handle<T>
where
T: Any + Send + Sync,
{
let handle = slot.0;
self.entities.insert(handle.entity_id, Box::new(entity));
handle
}
/// 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(
self.entities
.remove(handle.entity_id)
.expect("Circular entity lease. Is the entity already being updated?")
.downcast::<T>()
.unwrap(),
.expect("Circular entity lease. Is the entity already being updated?"),
);
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),
},
Lease {
handle,
entity,
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);
dropped_entity_ids
.into_iter()
@ -109,35 +99,27 @@ impl EntityMap {
}
}
pub struct Lease<'a, T: Send + Sync> {
entity: Option<Box<T>>,
pub struct Lease<'a, T> {
entity: Option<AnyBox>,
pub handle: &'a Handle<T>,
entity_type: PhantomData<T>,
}
impl<'a, T> core::ops::Deref for Lease<'a, T>
where
T: Send + Sync,
{
impl<'a, T> core::ops::Deref for Lease<'a, T> {
type Target = T;
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>
where
T: Send + Sync,
{
impl<'a, T> core::ops::DerefMut for Lease<'a, T> {
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>
where
T: Send + Sync,
{
impl<'a, T> Drop for Lease<'a, T> {
fn drop(&mut self) {
if self.entity.is_some() {
// 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)]
pub struct Slot<T: Send + Sync + 'static>(Handle<T>);
pub struct Slot<T>(Handle<T>);
pub struct AnyHandle {
pub(crate) entity_id: EntityId,
@ -176,14 +158,13 @@ impl AnyHandle {
}
}
pub fn downcast<T>(&self) -> Option<Handle<T>>
where
T: 'static + Send + Sync,
{
pub fn downcast<T: 'static>(&self) -> Option<Handle<T>> {
if TypeId::of::<T>() == self.entity_type {
Some(Handle {
any_handle: self.clone(),
entity_type: PhantomData,
downcast_entity: |any| any.downcast_ref().unwrap(),
downcast_entity_mut: |any| any.downcast_mut().unwrap(),
})
} else {
None
@ -231,10 +212,7 @@ impl Drop for AnyHandle {
}
}
impl<T> From<Handle<T>> for AnyHandle
where
T: 'static + Send + Sync,
{
impl<T> From<Handle<T>> for AnyHandle {
fn from(handle: Handle<T>) -> Self {
handle.any_handle
}
@ -255,18 +233,28 @@ impl PartialEq for AnyHandle {
impl Eq for AnyHandle {}
#[derive(Deref, DerefMut)]
pub struct Handle<T: Send + Sync> {
pub struct Handle<T> {
#[deref]
#[deref_mut]
any_handle: AnyHandle,
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> {
fn new(id: EntityId, entity_map: Weak<RwLock<EntityRefCounts>>) -> Self {
unsafe impl<T> Send for Handle<T> {}
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 {
any_handle: AnyHandle::new(id, TypeId::of::<T>(), entity_map),
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 {
any_handle: self.any_handle.downgrade(),
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.
/// When updating in an `AppContext`, it receives a `ModelContext`.
/// When updating an a `WindowContext`, it receives a `ViewContext`.
pub fn update<C: Context, R>(
pub fn update<C, R>(
&self,
cx: &mut C,
update: impl FnOnce(&mut T, &mut C::EntityContext<'_, '_, T>) -> R,
) -> C::Result<R> {
) -> C::Result<R>
where
C: Context,
{
cx.update_entity(self, update)
}
}
impl<T: Send + Sync> Clone for Handle<T> {
impl<T> Clone for Handle<T> {
fn clone(&self) -> Self {
Self {
any_handle: self.any_handle.clone(),
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 {
write!(
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) {
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 {
self.any_handle == other.any_handle
}
}
impl<T: Send + Sync + 'static> Eq for Handle<T> {}
impl<T> Eq for Handle<T> {}
#[derive(Clone)]
pub struct AnyWeakHandle {
@ -365,10 +360,7 @@ impl AnyWeakHandle {
}
}
impl<T> From<WeakHandle<T>> for AnyWeakHandle
where
T: 'static + Send + Sync,
{
impl<T> From<WeakHandle<T>> for AnyWeakHandle {
fn from(handle: WeakHandle<T>) -> Self {
handle.any_handle
}
@ -394,22 +386,31 @@ pub struct WeakHandle<T> {
#[deref_mut]
any_handle: AnyWeakHandle,
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 {
Self {
any_handle: self.any_handle.clone(),
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>> {
Some(Handle {
any_handle: self.any_handle.upgrade()?,
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.
/// When updating in an `AppContext`, it receives a `ModelContext`.
/// When updating an a `WindowContext`, it receives a `ViewContext`.
pub fn update<C: Context, R>(
pub fn update<C, R>(
&self,
cx: &mut C,
update: impl FnOnce(&mut T, &mut C::EntityContext<'_, '_, T>) -> R,
) -> Result<R>
where
C: Context,
Result<C::Result<R>>: crate::Flatten<R>,
{
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) {
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 {
self.any_handle == other.any_handle
}
}
impl<T: Send + Sync + 'static> Eq for WeakHandle<T> {}
impl<T> Eq for WeakHandle<T> {}

View file

@ -5,10 +5,9 @@ use crate::{
use derive_more::{Deref, DerefMut};
use futures::FutureExt;
use std::{
any::TypeId,
any::{Any, TypeId},
borrow::{Borrow, BorrowMut},
future::Future,
marker::PhantomData,
};
#[derive(Deref, DerefMut)]
@ -16,21 +15,19 @@ pub struct ModelContext<'a, T> {
#[deref]
#[deref_mut]
app: Reference<'a, AppContext>,
entity_type: PhantomData<T>,
entity_id: EntityId,
model_state: WeakHandle<T>,
}
impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
pub(crate) fn mutable(app: &'a mut AppContext, entity_id: EntityId) -> Self {
impl<'a, T: 'static> ModelContext<'a, T> {
pub(crate) fn mutable(app: &'a mut AppContext, model_state: WeakHandle<T>) -> Self {
Self {
app: Reference::Mutable(app),
entity_type: PhantomData,
entity_id,
model_state,
}
}
pub fn entity_id(&self) -> EntityId {
self.entity_id
self.model_state.entity_id
}
pub fn handle(&self) -> Handle<T> {
@ -40,14 +37,17 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, 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,
handle: &Handle<E>,
on_notify: impl Fn(&mut T, Handle<E>, &mut ModelContext<'_, T>) + Send + Sync + 'static,
) -> Subscription {
handle: &Handle<T2>,
on_notify: impl Fn(&mut T, Handle<T2>, &mut ModelContext<'_, T>) + Send + Sync + 'static,
) -> Subscription
where
T: Any + Send + Sync,
{
let this = self.weak_handle();
let handle = handle.downgrade();
self.app.observers.insert(
@ -63,14 +63,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,
handle: &Handle<E>,
on_event: impl Fn(&mut T, Handle<E>, &E::Event, &mut ModelContext<'_, T>)
+ Send
+ Sync
+ 'static,
) -> Subscription {
) -> Subscription
where
T: Any + Send + Sync,
{
let this = self.weak_handle();
let handle = handle.downgrade();
self.app.event_listeners.insert(
@ -90,9 +93,12 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
pub fn on_release(
&mut self,
on_release: impl Fn(&mut T, &mut AppContext) + Send + Sync + 'static,
) -> Subscription {
) -> Subscription
where
T: 'static,
{
self.app.release_listeners.insert(
self.entity_id,
self.model_state.entity_id,
Box::new(move |this, cx| {
let this = this.downcast_mut().expect("invalid entity type");
on_release(this, cx);
@ -100,11 +106,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,
handle: &Handle<E>,
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();
self.app.release_listeners.insert(
handle.entity_id,
@ -120,7 +129,10 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
pub fn observe_global<G: 'static>(
&mut self,
f: impl Fn(&mut T, &mut ModelContext<'_, T>) + Send + Sync + 'static,
) -> Subscription {
) -> Subscription
where
T: Any + Send + Sync,
{
let handle = self.weak_handle();
self.global_observers.insert(
TypeId::of::<G>(),
@ -134,6 +146,7 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
) -> Subscription
where
Fut: 'static + Future<Output = ()> + Send,
T: Any + Send + Sync,
{
let handle = self.weak_handle();
self.app.quit_observers.insert(
@ -151,9 +164,13 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
}
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 {
emitter: self.entity_id,
emitter: self.model_state.entity_id,
});
}
}
@ -163,8 +180,8 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
G: 'static + Send + Sync,
{
let mut global = self.app.lease_global::<G>();
let result = f(global.as_mut(), self);
self.app.restore_global(global);
let result = f(&mut global, self);
self.app.end_global_lease(global);
result
}
@ -173,6 +190,7 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
f: impl FnOnce(WeakHandle<T>, AsyncAppContext) -> Fut + Send + 'static,
) -> Task<R>
where
T: 'static,
Fut: Future<Output = R> + Send + 'static,
R: Send + 'static,
{
@ -193,27 +211,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) {
self.app.pending_effects.push_back(Effect::Emit {
emitter: self.entity_id,
emitter: self.model_state.entity_id,
event: Box::new(event),
});
}
}
impl<'a, T: 'static> Context for ModelContext<'a, T> {
type EntityContext<'b, 'c, U: Send + Sync + 'static> = ModelContext<'b, U>;
impl<'a, T> Context for ModelContext<'a, T> {
type EntityContext<'b, 'c, U> = ModelContext<'b, U>;
type Result<U> = U;
fn entity<U: Send + Sync + 'static>(
fn entity<U>(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, U>) -> U,
) -> Handle<U> {
) -> Handle<U>
where
U: 'static + Send + Sync,
{
self.app.entity(build_entity)
}
fn update_entity<U: Send + Sync + 'static, R>(
fn update_entity<U: 'static, R>(
&mut self,
handle: &Handle<U>,
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 derive_more::{Deref, DerefMut};
pub(crate) use smallvec::SmallVec;
use std::mem;
use std::{any::Any, mem};
pub trait Element: 'static + Send + Sync + IntoAnyElement<Self::ViewState> {
type ViewState: 'static + Send + Sync;
type ElementState: 'static + Send + Sync;
pub trait Element: IntoAnyElement<Self::ViewState> {
type ViewState: 'static;
type ElementState: 'static;
fn id(&self) -> Option<ElementId>;
@ -15,6 +15,8 @@ pub trait Element: 'static + Send + Sync + IntoAnyElement<Self::ViewState> {
element_state: Option<Self::ElementState>,
cx: &mut ViewContext<Self::ViewState>,
) -> Self::ElementState;
// where
// Self::ViewState: Any + Send + Sync;
fn layout(
&mut self,
@ -22,6 +24,8 @@ pub trait Element: 'static + Send + Sync + IntoAnyElement<Self::ViewState> {
element_state: &mut Self::ElementState,
cx: &mut ViewContext<Self::ViewState>,
) -> LayoutId;
// where
// Self::ViewState: Any + Send + Sync;
fn paint(
&mut self,
@ -30,6 +34,9 @@ pub trait Element: 'static + Send + Sync + IntoAnyElement<Self::ViewState> {
element_state: &mut Self::ElementState,
cx: &mut ViewContext<Self::ViewState>,
);
// where
// Self::ViewState: Any + Send + Sync;
}
#[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 layout(&mut self, view_state: &mut V, cx: &mut ViewContext<V>) -> LayoutId;
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>
where
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>) {
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> {
pub fn new<E: Element<ViewState = V>>(element: E) -> Self {
impl<V> AnyElement<V> {
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)))
}

View file

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

View file

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

View file

@ -7,7 +7,7 @@ use crate::{
use util::ResultExt;
pub struct Svg<
V: 'static + Send + Sync,
V: 'static,
I: ElementInteraction<V> = StatelessInteraction<V>,
F: ElementFocus<V> = FocusDisabled,
> {
@ -15,10 +15,7 @@ pub struct Svg<
path: Option<SharedString>,
}
pub fn svg<V>() -> Svg<V, StatelessInteraction<V>, FocusDisabled>
where
V: 'static + Send + Sync,
{
pub fn svg<V: 'static>() -> Svg<V, StatelessInteraction<V>, FocusDisabled> {
Svg {
base: div(),
path: None,
@ -27,7 +24,6 @@ where
impl<V, I, F> Svg<V, I, F>
where
V: 'static + Send + Sync,
I: ElementInteraction<V>,
F: ElementFocus<V>,
{
@ -39,7 +35,6 @@ where
impl<V, F> Svg<V, StatelessInteraction<V>, F>
where
V: 'static + Send + Sync,
F: ElementFocus<V>,
{
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>
where
V: 'static + Send + Sync,
I: ElementInteraction<V>,
F: ElementFocus<V>,
{
@ -63,7 +57,6 @@ where
impl<V, I, F> Element for Svg<V, I, F>
where
V: 'static + Send + Sync,
I: ElementInteraction<V>,
F: ElementFocus<V>,
{
@ -115,7 +108,6 @@ where
impl<V, I, F> Styled for Svg<V, I, F>
where
V: 'static + Send + Sync,
I: ElementInteraction<V>,
F: ElementFocus<V>,
{
@ -126,7 +118,6 @@ where
impl<V, I, F> StatelessInteractive for Svg<V, I, F>
where
V: 'static + Send + Sync,
I: ElementInteraction<V>,
F: ElementFocus<V>,
{
@ -137,7 +128,7 @@ where
impl<V, F> StatefulInteractive for Svg<V, StatefulInteraction<V>, F>
where
V: 'static + Send + Sync,
V: 'static,
F: ElementFocus<V>,
{
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
V: 'static + Send + Sync,
I: ElementInteraction<V>,
{
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 util::ResultExt;
impl<S: 'static + Send + Sync> IntoAnyElement<S> for SharedString {
fn into_any(self) -> AnyElement<S> {
impl<V: 'static> IntoAnyElement<V> for SharedString {
fn into_any(self) -> AnyElement<V> {
Text {
text: self,
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> {
Text {
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.
// This impl doesn't exist in the `gpui2` crate.
impl<S: 'static + Send + Sync> IntoAnyElement<S> for String {
fn into_any(self) -> AnyElement<S> {
impl<V: 'static> IntoAnyElement<V> for String {
fn into_any(self) -> AnyElement<V> {
Text {
text: self.into(),
state_type: PhantomData,
@ -44,13 +44,16 @@ pub struct Text<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> {
AnyElement::new(self)
}
}
impl<V: 'static + Send + Sync> Element for Text<V> {
impl<V: 'static> Element for Text<V> {
type ViewState = V;
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_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_listeners: FocusListeners<V>,
pub focus_style: StyleRefinement,
@ -208,10 +208,7 @@ pub struct FocusEnabled<V: 'static + Send + Sync> {
pub in_focus_style: StyleRefinement,
}
impl<V> FocusEnabled<V>
where
V: 'static + Send + Sync,
{
impl<V> FocusEnabled<V> {
pub fn new() -> Self {
Self {
focus_handle: None,
@ -233,10 +230,7 @@ where
}
}
impl<V> ElementFocus<V> for FocusEnabled<V>
where
V: 'static + Send + Sync,
{
impl<V: 'static> ElementFocus<V> for FocusEnabled<V> {
fn as_focusable(&self) -> Option<&FocusEnabled<V>> {
Some(self)
}
@ -246,10 +240,7 @@ where
}
}
impl<V> From<FocusHandle> for FocusEnabled<V>
where
V: 'static + Send + Sync,
{
impl<V> From<FocusHandle> for FocusEnabled<V> {
fn from(value: FocusHandle) -> Self {
Self {
focus_handle: Some(value),
@ -263,10 +254,7 @@ where
pub struct FocusDisabled;
impl<V> ElementFocus<V> for FocusDisabled
where
V: 'static + Send + Sync,
{
impl<V: 'static> ElementFocus<V> for FocusDisabled {
fn as_focusable(&self) -> Option<&FocusEnabled<V>> {
None
}

View file

@ -66,15 +66,17 @@ use taffy::TaffyLayoutEngine;
type AnyBox = Box<dyn Any + Send + Sync>;
pub trait Context {
type EntityContext<'a, 'w, T: 'static + Send + Sync>;
type EntityContext<'a, 'w, T>;
type Result<T>;
fn entity<T: Send + Sync + 'static>(
fn entity<T>(
&mut self,
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,
handle: &Handle<T>,
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> {
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>;
fn entity<T: Send + Sync + 'static>(
fn entity<T>(
&mut self,
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| {
let cx = unsafe {
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,
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
@ -162,13 +167,13 @@ where
result
}
fn set_global<T: Send + Sync + 'static>(&mut self, global: T) {
fn set_global<G: 'static + Send + Sync>(&mut self, global: G) {
self.borrow_mut().set_global(global)
}
}
pub trait EventEmitter {
type Event: Any + Send + Sync + 'static;
pub trait EventEmitter: 'static {
type Event: Any;
}
pub trait Flatten<T> {

View file

@ -361,8 +361,9 @@ pub trait StatefulInteractive: StatelessInteractive {
) -> Self
where
Self: Sized,
S: 'static + Send + Sync,
R: 'static + Fn(&mut Self::ViewState, &mut ViewContext<Self::ViewState>) -> E + Send + Sync,
S: Any + Send + Sync,
R: Fn(&mut Self::ViewState, &mut ViewContext<Self::ViewState>) -> E,
R: 'static + Send + Sync,
E: Element<ViewState = Self::ViewState>,
{
debug_assert!(
@ -388,7 +389,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_mut(&mut self) -> &mut StatelessInteraction<V>;
fn as_stateful(&self) -> Option<&StatefulInteraction<V>>;
@ -682,7 +683,7 @@ pub trait ElementInteraction<V: 'static + Send + Sync>: 'static + Send + Sync {
}
#[derive(Deref, DerefMut)]
pub struct StatefulInteraction<V: 'static + Send + Sync> {
pub struct StatefulInteraction<V> {
pub id: ElementId,
#[deref]
#[deref_mut]
@ -693,10 +694,7 @@ pub struct StatefulInteraction<V: 'static + Send + Sync> {
drag_listener: Option<DragListener<V>>,
}
impl<V> ElementInteraction<V> for StatefulInteraction<V>
where
V: 'static + Send + Sync,
{
impl<V: 'static> ElementInteraction<V> for StatefulInteraction<V> {
fn as_stateful(&self) -> Option<&StatefulInteraction<V>> {
Some(self)
}
@ -714,10 +712,7 @@ where
}
}
impl<V> From<ElementId> for StatefulInteraction<V>
where
V: 'static + Send + Sync,
{
impl<V> From<ElementId> for StatefulInteraction<V> {
fn from(id: ElementId) -> Self {
Self {
id,
@ -730,7 +725,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 dispatch_context: DispatchContext,
@ -746,10 +741,7 @@ pub struct StatelessInteraction<V> {
drop_listeners: SmallVec<[(TypeId, Arc<DropListener<V>>); 2]>,
}
impl<V> StatelessInteraction<V>
where
V: 'static + Send + Sync,
{
impl<V> StatelessInteraction<V> {
pub fn into_stateful(self, id: impl Into<ElementId>) -> StatefulInteraction<V> {
StatefulInteraction {
id: id.into(),
@ -841,10 +833,7 @@ impl<V> Default for StatelessInteraction<V> {
}
}
impl<V> ElementInteraction<V> for StatelessInteraction<V>
where
V: 'static + Send + Sync,
{
impl<V: 'static> ElementInteraction<V> for StatelessInteraction<V> {
fn as_stateful(&self) -> Option<&StatefulInteraction<V>> {
None
}
@ -919,9 +908,7 @@ pub struct ClickEvent {
pub struct Drag<S, R, V, E>
where
S: 'static + Send + Sync,
R: Fn(&mut V, &mut ViewContext<V>) -> E,
V: 'static + Send + Sync,
E: Element<ViewState = V>,
{
pub state: S,
@ -931,9 +918,7 @@ where
impl<S, R, V, E> Drag<S, R, V, E>
where
S: 'static + Send + Sync,
R: Fn(&mut V, &mut ViewContext<V>) -> E + Send + Sync,
V: 'static + Send + Sync,
R: Fn(&mut V, &mut ViewContext<V>) -> E,
E: Element<ViewState = V>,
{
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<()>;
}
pub trait PlatformDisplay: Debug {
pub trait PlatformDisplay: Send + Sync + Debug {
fn id(&self) -> DisplayId;
fn as_any(&self) -> &dyn Any;
fn bounds(&self) -> Bounds<GlobalPixels>;

View file

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

View file

@ -6,12 +6,12 @@ use crate::{
};
use std::{marker::PhantomData, sync::Arc};
pub struct View<V: Send + Sync> {
pub struct View<V> {
state: Handle<V>,
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 {
AnyView {
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 {
Self {
state: self.state.clone(),
@ -34,7 +34,6 @@ pub fn view<V, E>(
) -> View<V>
where
E: IntoAnyElement<V>,
V: 'static + Send + Sync,
{
View {
state,
@ -42,9 +41,7 @@ where
}
}
impl<V: 'static + Send + Sync, ParentViewState: 'static + Send + Sync>
IntoAnyElement<ParentViewState> for View<V>
{
impl<V: 'static, ParentViewState: 'static> IntoAnyElement<ParentViewState> for View<V> {
fn into_any(self) -> AnyElement<ParentViewState> {
AnyElement::new(EraseViewState {
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 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>,
parent_view_state_type: PhantomData<ParentV>,
}
impl<V, ParentV> IntoAnyElement<ParentV> for EraseViewState<V, ParentV>
where
V: 'static + Send + Sync,
ParentV: 'static + Send + Sync,
{
unsafe impl<V, ParentV> Send for EraseViewState<V, ParentV> {}
unsafe impl<V, ParentV> Sync for EraseViewState<V, ParentV> {}
impl<V: 'static, ParentV: 'static> IntoAnyElement<ParentV> for EraseViewState<V, ParentV> {
fn into_any(self) -> AnyElement<ParentV> {
AnyElement::new(self)
}
}
impl<V, ParentV> Element for EraseViewState<V, ParentV>
where
V: 'static + Send + Sync,
ParentV: 'static + Send + Sync,
{
impl<V: 'static, ParentV: 'static> Element for EraseViewState<V, ParentV> {
type ViewState = ParentV;
type ElementState = AnyBox;
@ -150,14 +142,14 @@ where
}
}
trait ViewObject: 'static + Send + Sync {
trait ViewObject: Send + Sync {
fn entity_id(&self) -> EntityId;
fn initialize(&mut self, cx: &mut WindowContext) -> AnyBox;
fn layout(&mut self, element: &mut AnyBox, cx: &mut WindowContext) -> LayoutId;
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 {
self.state.entity_id
}
@ -195,10 +187,7 @@ pub struct AnyView {
view: Arc<Mutex<dyn ViewObject>>,
}
impl<ParentV> IntoAnyElement<ParentV> for AnyView
where
ParentV: 'static + Send + Sync,
{
impl<ParentV: 'static> IntoAnyElement<ParentV> for AnyView {
fn into_any(self) -> AnyElement<ParentV> {
AnyElement::new(EraseAnyViewState {
view: self,
@ -249,19 +238,16 @@ struct EraseAnyViewState<ParentViewState> {
parent_view_state_type: PhantomData<ParentViewState>,
}
impl<ParentV> IntoAnyElement<ParentV> for EraseAnyViewState<ParentV>
where
ParentV: 'static + Send + Sync,
{
unsafe impl<ParentV> Send for EraseAnyViewState<ParentV> {}
unsafe impl<ParentV> Sync for EraseAnyViewState<ParentV> {}
impl<ParentV: 'static> IntoAnyElement<ParentV> for EraseAnyViewState<ParentV> {
fn into_any(self) -> AnyElement<ParentV> {
AnyElement::new(self)
}
}
impl<ParentV> Element for EraseAnyViewState<ParentV>
where
ParentV: 'static + Send + Sync,
{
impl<ParentV: 'static> Element for EraseAnyViewState<ParentV> {
type ViewState = ParentV;
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
where
G: 'static + Send + Sync,
G: 'static,
{
let mut global = self.app.lease_global::<G>();
let result = f(global.as_mut(), self);
self.app.set_global(global);
let result = f(&mut global, self);
self.app.end_global_lease(global);
result
}
@ -1139,23 +1139,26 @@ impl<'a, 'w> WindowContext<'a, 'w> {
}
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;
fn entity<T: Send + Sync + 'static>(
fn entity<T>(
&mut self,
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 entity = build_entity(&mut ViewContext::mutable(
&mut *self.app,
&mut self.window,
slot.entity_id,
slot.downgrade(),
));
self.entities.insert(slot, entity)
}
fn update_entity<T: Send + Sync + 'static, R>(
fn update_entity<T: 'static, R>(
&mut self,
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
@ -1163,7 +1166,7 @@ impl Context for WindowContext<'_, '_> {
let mut entity = self.entities.lease(handle);
let result = update(
&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);
result
@ -1271,11 +1274,14 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
.unwrap_or_default()
}
fn with_element_state<S: 'static + Send + Sync, R>(
fn with_element_state<S, R>(
&mut self,
id: ElementId,
f: impl FnOnce(Option<S>, &mut Self) -> (R, S),
) -> R {
) -> R
where
S: Any + Send + Sync,
{
self.with_element_id(id, |global_id, cx| {
if let Some(any) = cx
.window_mut()
@ -1304,11 +1310,14 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
})
}
fn with_optional_element_state<S: 'static + Send + Sync, R>(
fn with_optional_element_state<S, R>(
&mut self,
element_id: Option<ElementId>,
f: impl FnOnce(Option<S>, &mut Self) -> (R, S),
) -> R {
) -> R
where
S: Any + Send + Sync,
{
if let Some(element_id) = element_id {
self.with_element_state(element_id, f)
} else {
@ -1350,8 +1359,7 @@ impl<T> BorrowWindow for T where T: BorrowMut<AppContext> + BorrowMut<Window> {}
pub struct ViewContext<'a, 'w, V> {
window_cx: WindowContext<'a, 'w>,
entity_type: PhantomData<V>,
entity_id: EntityId,
view_state: WeakHandle<V>,
}
impl<V> Borrow<AppContext> for ViewContext<'_, '_, V> {
@ -1378,17 +1386,16 @@ impl<V> BorrowMut<Window> for ViewContext<'_, '_, V> {
}
}
impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> {
fn mutable(app: &'a mut AppContext, window: &'w mut Window, entity_id: EntityId) -> Self {
impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
fn mutable(app: &'a mut AppContext, window: &'w mut Window, view_state: WeakHandle<V>) -> Self {
Self {
window_cx: WindowContext::mutable(app, window),
entity_id,
entity_type: PhantomData,
view_state,
}
}
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 {
@ -1398,18 +1405,25 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> {
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();
self.window_cx.on_next_frame(move |cx| {
entity.update(cx, f).ok();
});
}
pub fn observe<E: Send + Sync + 'static>(
pub fn observe<E>(
&mut self,
handle: &Handle<E>,
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 handle = handle.downgrade();
let window_handle = self.window.handle;
@ -1429,7 +1443,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,
handle: &Handle<E>,
on_event: impl Fn(&mut V, Handle<E>, &E::Event, &mut ViewContext<'_, '_, V>)
@ -1463,7 +1477,7 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> {
) -> Subscription {
let window_handle = self.window.handle;
self.app.release_listeners.insert(
self.entity_id,
self.view_state.entity_id,
Box::new(move |this, cx| {
let this = this.downcast_mut().expect("invalid entity type");
// todo!("are we okay with silently swallowing the error?")
@ -1472,11 +1486,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,
handle: &Handle<E>,
on_release: impl Fn(&mut V, &mut E, &mut ViewContext<'_, '_, V>) + Send + Sync + 'static,
) -> Subscription {
handle: &Handle<T>,
on_release: impl Fn(&mut V, &mut T, &mut ViewContext<'_, '_, V>) + Send + Sync + 'static,
) -> Subscription
where
V: Any + Send + Sync,
{
let this = self.handle();
let window_handle = self.window.handle;
self.app.release_listeners.insert(
@ -1494,7 +1511,7 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> {
pub fn notify(&mut self) {
self.window_cx.notify();
self.window_cx.app.push_effect(Effect::Notify {
emitter: self.entity_id,
emitter: self.view_state.entity_id,
});
}
@ -1633,8 +1650,8 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> {
G: 'static + Send + Sync,
{
let mut global = self.app.lease_global::<G>();
let result = f(global.as_mut(), self);
self.app.restore_global(global);
let result = f(&mut global, self);
self.app.end_global_lease(global);
result
}
@ -1668,9 +1685,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) {
let emitter = self.entity_id;
let emitter = self.view_state.entity_id;
self.app.push_effect(Effect::Emit {
emitter,
event: Box::new(event),
@ -1678,30 +1699,30 @@ impl<'a, 'w, V: EventEmitter + Send + Sync + 'static> ViewContext<'a, 'w, V> {
}
}
impl<'a, 'w, V> Context for ViewContext<'a, 'w, V>
where
V: 'static + Send + Sync,
{
type EntityContext<'b, 'c, U: 'static + Send + Sync> = ViewContext<'b, 'c, U>;
impl<'a, 'w, V> Context for ViewContext<'a, 'w, V> {
type EntityContext<'b, 'c, U> = ViewContext<'b, 'c, U>;
type Result<U> = U;
fn entity<T2: Send + Sync + 'static>(
fn entity<T>(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T2>) -> T2,
) -> Handle<T2> {
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
) -> Handle<T>
where
T: 'static + Send + Sync,
{
self.window_cx.entity(build_entity)
}
fn update_entity<U: 'static + Send + Sync, R>(
fn update_entity<T: 'static, R>(
&mut self,
handle: &Handle<U>,
update: impl FnOnce(&mut U, &mut Self::EntityContext<'_, '_, U>) -> R,
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
) -> R {
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>;
fn deref(&self) -> &Self::Target {
@ -1709,7 +1730,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 {
&mut self.window_cx
}
@ -1725,9 +1746,9 @@ impl WindowId {
}
#[derive(PartialEq, Eq)]
pub struct WindowHandle<S> {
pub struct WindowHandle<V> {
id: WindowId,
state_type: PhantomData<S>,
state_type: PhantomData<V>,
}
impl<S> Copy for WindowHandle<S> {}