diff --git a/crates/gpui2/src/action.rs b/crates/gpui2/src/action.rs
index 9e3db6f83e..b6420c2b82 100644
--- a/crates/gpui2/src/action.rs
+++ b/crates/gpui2/src/action.rs
@@ -19,7 +19,7 @@ pub trait Action: Any + Send + Sync {
impl 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::().into()
diff --git a/crates/gpui2/src/app.rs b/crates/gpui2/src/app.rs
index 4674893693..2dc5e1510c 100644
--- a/crates/gpui2/src/app.rs
+++ b/crates/gpui2/src/app.rs
@@ -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,
- pub(crate) globals_by_type: HashMap>,
+ pub(crate) globals_by_type: HashMap,
pub(crate) unit_entity: Handle<()>,
pub(crate) entities: EntityMap,
pub(crate) windows: SlotMap>,
@@ -554,19 +556,16 @@ impl AppContext {
.unwrap()
}
- pub fn set_global(&mut self, global: T) {
- let global_type = TypeId::of::();
+ pub fn set_global(&mut self, global: G) {
+ let global_type = TypeId::of::();
self.push_effect(Effect::NotifyGlobalObservers { global_type });
self.globals_by_type.insert(global_type, Box::new(global));
}
- pub fn update_global(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
- where
- G: 'static + Send + Sync,
- {
+ pub fn update_global(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R {
let mut global = self.lease_global::();
- 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(&mut self) -> Box {
- self.globals_by_type
- .remove(&TypeId::of::())
- .ok_or_else(|| anyhow!("no global registered of type {}", type_name::()))
- .unwrap()
- .downcast()
- .unwrap()
+ pub(crate) fn lease_global(&mut self) -> GlobalLease {
+ GlobalLease::new(
+ self.globals_by_type
+ .remove(&TypeId::of::())
+ .ok_or_else(|| anyhow!("no global registered of type {}", type_name::()))
+ .unwrap(),
+ )
}
- pub(crate) fn restore_global(&mut self, global: Box) {
+ pub(crate) fn end_global_lease(&mut self, lease: GlobalLease) {
let global_type = TypeId::of::();
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;
- fn entity(
+ fn entity(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
) -> Handle {
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(
+ fn update_entity(
&mut self,
handle: &Handle,
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 {
})
}
- pub fn open_window(
+ pub fn open_window(
&mut self,
options: crate::WindowOptions,
- build_root_view: impl FnOnce(&mut WindowContext) -> View + Send + 'static,
- ) -> WindowHandle {
+ build_root_view: impl FnOnce(&mut WindowContext) -> View + Send + 'static,
+ ) -> WindowHandle {
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 {
+ global: AnyBox,
+ global_type: PhantomData,
+}
+
+impl GlobalLease {
+ fn new(global: AnyBox) -> Self {
+ GlobalLease {
+ global,
+ global_type: PhantomData,
+ }
+ }
+}
+
+impl Deref for GlobalLease {
+ type Target = G;
+
+ fn deref(&self) -> &Self::Target {
+ self.global.downcast_ref().unwrap()
+ }
+}
+
+impl DerefMut for GlobalLease {
+ 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,
diff --git a/crates/gpui2/src/app/async_context.rs b/crates/gpui2/src/app/async_context.rs
index 0fea00ed1f..42c9e96dd0 100644
--- a/crates/gpui2/src/app/async_context.rs
+++ b/crates/gpui2/src/app/async_context.rs
@@ -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 = Result;
- fn entity(
+ fn entity(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
- ) -> Self::Result> {
+ ) -> Self::Result>
+ 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(
+ fn update_entity(
&mut self,
handle: &Handle,
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(&self) -> Result {
+ pub fn has_global(&self) -> Result {
let app = self
.app
.upgrade()
@@ -138,10 +141,7 @@ impl AsyncAppContext {
Ok(lock.has_global::())
}
- pub fn read_global(
- &self,
- read: impl FnOnce(&G, &AppContext) -> R,
- ) -> Result {
+ pub fn read_global(&self, read: impl FnOnce(&G, &AppContext) -> R) -> Result {
let app = self
.app
.upgrade()
@@ -150,7 +150,7 @@ impl AsyncAppContext {
Ok(read(lock.global(), &lock))
}
- pub fn try_read_global(
+ pub fn try_read_global(
&self,
read: impl FnOnce(&G, &AppContext) -> R,
) -> Option {
@@ -159,7 +159,7 @@ impl AsyncAppContext {
Some(read(lock.try_global()?, &lock))
}
- pub fn update_global(
+ pub fn update_global(
&mut self,
update: impl FnOnce(&mut G, &mut AppContext) -> R,
) -> Result {
@@ -195,7 +195,7 @@ impl AsyncWindowContext {
.ok();
}
- pub fn read_global(
+ pub fn read_global(
&self,
read: impl FnOnce(&G, &WindowContext) -> R,
) -> Result {
@@ -203,28 +203,34 @@ impl AsyncWindowContext {
.read_window(self.window, |cx| read(cx.global(), cx))
}
- pub fn update_global(
+ pub fn update_global(
&mut self,
update: impl FnOnce(&mut G, &mut WindowContext) -> R,
- ) -> Result {
+ ) -> Result
+ 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 = Result;
- fn entity(
+ fn entity(
&mut self,
- build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, R>) -> R,
- ) -> Result> {
+ build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
+ ) -> Result>
+ where
+ T: Any + Send + Sync,
+ {
self.app
.update_window(self.window, |cx| cx.entity(build_entity))
}
- fn update_entity(
+ fn update_entity(
&mut self,
handle: &Handle,
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() {}
+ assert_send_sync::();
+ }
+}
diff --git a/crates/gpui2/src/app/entity_map.rs b/crates/gpui2/src/app/entity_map.rs
index a8ef9bb87b..b593fd3745 100644
--- a/crates/gpui2/src/app/entity_map.rs
+++ b/crates/gpui2/src/app/entity_map.rs
@@ -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>,
+ entities: SecondaryMap,
ref_counts: Arc>,
}
@@ -51,56 +51,46 @@ impl EntityMap {
}
/// Reserve a slot for an entity, which you can subsequently use with `insert`.
- pub fn reserve(&self) -> Slot {
+ pub fn reserve(&self) -> Slot {
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(
- &mut self,
- slot: Slot,
- entity: T,
- ) -> Handle {
+ pub fn insert(&mut self, slot: Slot, entity: T) -> Handle
+ 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) -> Lease<'a, T> {
+ pub fn lease<'a, T>(&mut self, handle: &'a Handle) -> Lease<'a, T> {
let entity = Some(
self.entities
.remove(handle.entity_id)
- .expect("Circular entity lease. Is the entity already being updated?")
- .downcast::()
- .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(&mut self, mut lease: Lease) {
- self.entities
- .insert(lease.handle.entity_id, lease.entity.take().unwrap());
- }
-
- pub fn read(&self, handle: &Handle) -> &T {
- self.entities[handle.entity_id].downcast_ref().unwrap()
- }
-
- pub fn weak_handle(&self, id: EntityId) -> WeakHandle {
- WeakHandle {
- any_handle: AnyWeakHandle {
- entity_id: id,
- entity_type: TypeId::of::(),
- entity_ref_counts: Arc::downgrade(&self.ref_counts),
- },
+ Lease {
+ handle,
+ entity,
entity_type: PhantomData,
}
}
- pub fn take_dropped(&mut self) -> Vec<(EntityId, Box)> {
+ /// Return an entity after moving it to the stack.
+ pub fn end_lease(&mut self, mut lease: Lease) {
+ self.entities
+ .insert(lease.handle.entity_id, lease.entity.take().unwrap());
+ }
+
+ pub fn read(&self, handle: &Handle) -> &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>,
+pub struct Lease<'a, T> {
+ entity: Option,
pub handle: &'a Handle,
+ entity_type: PhantomData,
}
-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(Handle);
+pub struct Slot(Handle);
pub struct AnyHandle {
pub(crate) entity_id: EntityId,
@@ -176,14 +158,13 @@ impl AnyHandle {
}
}
- pub fn downcast(&self) -> Option>
- where
- T: 'static + Send + Sync,
- {
+ pub fn downcast(&self) -> Option> {
if TypeId::of::() == 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 From> for AnyHandle
-where
- T: 'static + Send + Sync,
-{
+impl From> for AnyHandle {
fn from(handle: Handle) -> Self {
handle.any_handle
}
@@ -255,18 +233,28 @@ impl PartialEq for AnyHandle {
impl Eq for AnyHandle {}
#[derive(Deref, DerefMut)]
-pub struct Handle {
+pub struct Handle {
#[deref]
#[deref_mut]
any_handle: AnyHandle,
entity_type: PhantomData,
+ downcast_entity: fn(&dyn Any) -> &T,
+ downcast_entity_mut: fn(&mut dyn Any) -> &mut T,
}
-impl Handle {
- fn new(id: EntityId, entity_map: Weak>) -> Self {
+unsafe impl Send for Handle {}
+unsafe impl Sync for Handle {}
+
+impl Handle {
+ fn new(id: EntityId, entity_map: Weak>) -> Self
+ where
+ T: 'static,
+ {
Self {
any_handle: AnyHandle::new(id, TypeId::of::(), 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 Handle {
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 Handle {
/// 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(
+ pub fn update(
&self,
cx: &mut C,
update: impl FnOnce(&mut T, &mut C::EntityContext<'_, '_, T>) -> R,
- ) -> C::Result {
+ ) -> C::Result
+ where
+ C: Context,
+ {
cx.update_entity(self, update)
}
}
-impl Clone for Handle {
+impl Clone for Handle {
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 std::fmt::Debug for Handle {
+impl std::fmt::Debug for Handle {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
@@ -315,19 +310,19 @@ impl std::fmt::Debug for Handle {
}
}
-impl Hash for Handle {
+impl Hash for Handle {
fn hash(&self, state: &mut H) {
self.any_handle.hash(state);
}
}
-impl PartialEq for Handle {
+impl PartialEq for Handle {
fn eq(&self, other: &Self) -> bool {
self.any_handle == other.any_handle
}
}
-impl Eq for Handle {}
+impl Eq for Handle {}
#[derive(Clone)]
pub struct AnyWeakHandle {
@@ -365,10 +360,7 @@ impl AnyWeakHandle {
}
}
-impl From> for AnyWeakHandle
-where
- T: 'static + Send + Sync,
-{
+impl From> for AnyWeakHandle {
fn from(handle: WeakHandle) -> Self {
handle.any_handle
}
@@ -394,22 +386,31 @@ pub struct WeakHandle {
#[deref_mut]
any_handle: AnyWeakHandle,
entity_type: PhantomData,
+ downcast_entity: fn(&dyn Any) -> &T,
+ pub(crate) downcast_entity_mut: fn(&mut dyn Any) -> &mut T,
}
-impl Clone for WeakHandle {
+unsafe impl Send for WeakHandle {}
+unsafe impl Sync for WeakHandle {}
+
+impl Clone for WeakHandle {
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 WeakHandle {
+impl WeakHandle {
pub fn upgrade(&self) -> Option> {
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 WeakHandle {
/// 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(
+ pub fn update(
&self,
cx: &mut C,
update: impl FnOnce(&mut T, &mut C::EntityContext<'_, '_, T>) -> R,
) -> Result
where
+ C: Context,
Result>: crate::Flatten,
{
crate::Flatten::flatten(
@@ -436,16 +438,16 @@ impl WeakHandle {
}
}
-impl Hash for WeakHandle {
+impl Hash for WeakHandle {
fn hash(&self, state: &mut H) {
self.any_handle.hash(state);
}
}
-impl PartialEq for WeakHandle {
+impl PartialEq for WeakHandle {
fn eq(&self, other: &Self) -> bool {
self.any_handle == other.any_handle
}
}
-impl Eq for WeakHandle {}
+impl Eq for WeakHandle {}
diff --git a/crates/gpui2/src/app/model_context.rs b/crates/gpui2/src/app/model_context.rs
index 35237d91cf..faf766ea7f 100644
--- a/crates/gpui2/src/app/model_context.rs
+++ b/crates/gpui2/src/app/model_context.rs
@@ -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,
- entity_id: EntityId,
+ model_state: WeakHandle,
}
-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) -> 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 {
@@ -40,14 +37,17 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
}
pub fn weak_handle(&self) -> WeakHandle {
- self.app.entities.weak_handle(self.entity_id)
+ self.model_state.clone()
}
- pub fn observe(
+ pub fn observe(
&mut self,
- handle: &Handle,
- on_notify: impl Fn(&mut T, Handle, &mut ModelContext<'_, T>) + Send + Sync + 'static,
- ) -> Subscription {
+ handle: &Handle,
+ on_notify: impl Fn(&mut T, Handle, &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(
+ pub fn subscribe(
&mut self,
handle: &Handle,
on_event: impl Fn(&mut T, Handle, &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(
+ pub fn observe_release(
&mut self,
handle: &Handle,
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(
&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::(),
@@ -134,6 +146,7 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
) -> Subscription
where
Fut: 'static + Future