mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-10 04:09:37 +00:00
Merge branch 'fewer-bounds' into zed2
This commit is contained in:
commit
2285a35016
17 changed files with 400 additions and 361 deletions
|
@ -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()
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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>();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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> {}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)))
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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>>>;
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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> {}
|
||||
|
|
Loading…
Reference in a new issue