mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-25 01:34:02 +00:00
Add generic subscribe and observe methods to contexts
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
8e191f27d9
commit
43bb38206f
2 changed files with 190 additions and 324 deletions
504
gpui/src/app.rs
504
gpui/src/app.rs
|
@ -649,8 +649,8 @@ pub struct MutableAppContext {
|
|||
keystroke_matcher: keymap::Matcher,
|
||||
next_entity_id: usize,
|
||||
next_window_id: usize,
|
||||
subscriptions: HashMap<usize, Vec<Subscription>>,
|
||||
observations: HashMap<usize, Vec<Observation>>,
|
||||
subscriptions: HashMap<usize, Vec<Box<dyn FnMut(&dyn Any, &mut MutableAppContext) -> bool>>>,
|
||||
observations: HashMap<usize, Vec<Box<dyn FnMut(&mut MutableAppContext) -> bool>>>,
|
||||
presenters_and_platform_windows:
|
||||
HashMap<usize, (Rc<RefCell<Presenter>>, Box<dyn platform::Window>)>,
|
||||
debug_elements_callbacks: HashMap<usize, Box<dyn Fn(&AppContext) -> crate::json::Value>>,
|
||||
|
@ -877,91 +877,71 @@ impl MutableAppContext {
|
|||
);
|
||||
}
|
||||
|
||||
pub fn subscribe_to_model<E, F>(&mut self, handle: &ModelHandle<E>, mut callback: F)
|
||||
pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F)
|
||||
where
|
||||
E: Entity,
|
||||
E::Event: 'static,
|
||||
F: 'static + FnMut(ModelHandle<E>, &E::Event, &mut Self),
|
||||
H: Handle<E>,
|
||||
F: 'static + FnMut(H, &E::Event, &mut Self),
|
||||
{
|
||||
let emitter_handle = handle.downgrade();
|
||||
self.subscribe(handle, move |payload, cx| {
|
||||
if let Some(emitter_handle) = emitter_handle.upgrade(cx.as_ref()) {
|
||||
callback(emitter_handle, payload, cx);
|
||||
}
|
||||
});
|
||||
self.subscribe_internal(handle, move |handle, event, cx| {
|
||||
callback(handle, event, cx);
|
||||
true
|
||||
})
|
||||
}
|
||||
|
||||
pub fn subscribe_to_view<V, F>(&mut self, handle: &ViewHandle<V>, mut callback: F)
|
||||
where
|
||||
V: View,
|
||||
V::Event: 'static,
|
||||
F: 'static + FnMut(ViewHandle<V>, &V::Event, &mut Self),
|
||||
{
|
||||
let emitter_handle = handle.downgrade();
|
||||
self.subscribe(handle, move |payload, cx| {
|
||||
if let Some(emitter_handle) = emitter_handle.upgrade(cx.as_ref()) {
|
||||
callback(emitter_handle, payload, cx);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn observe_model<E, F>(&mut self, handle: &ModelHandle<E>, mut callback: F)
|
||||
fn observe<E, H, F>(&mut self, handle: &H, mut callback: F)
|
||||
where
|
||||
E: Entity,
|
||||
E::Event: 'static,
|
||||
F: 'static + FnMut(ModelHandle<E>, &mut Self),
|
||||
H: Handle<E>,
|
||||
F: 'static + FnMut(H, &mut Self),
|
||||
{
|
||||
let emitter_handle = handle.downgrade();
|
||||
self.observe(handle, move |cx| {
|
||||
if let Some(emitter_handle) = emitter_handle.upgrade(cx.as_ref()) {
|
||||
callback(emitter_handle, cx);
|
||||
}
|
||||
});
|
||||
self.observe_internal(handle, move |handle, cx| {
|
||||
callback(handle, cx);
|
||||
true
|
||||
})
|
||||
}
|
||||
|
||||
pub fn observe_view<V, F>(&mut self, handle: &ViewHandle<V>, mut callback: F)
|
||||
where
|
||||
V: View,
|
||||
V::Event: 'static,
|
||||
F: 'static + FnMut(ViewHandle<V>, &mut Self),
|
||||
{
|
||||
let emitter_handle = handle.downgrade();
|
||||
self.observe(handle, move |cx| {
|
||||
if let Some(emitter_handle) = emitter_handle.upgrade(cx.as_ref()) {
|
||||
callback(emitter_handle, cx);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn subscribe<E, F>(&mut self, handle: &impl Handle<E>, mut callback: F)
|
||||
pub fn subscribe_internal<E, H, F>(&mut self, handle: &H, mut callback: F)
|
||||
where
|
||||
E: Entity,
|
||||
E::Event: 'static,
|
||||
F: 'static + FnMut(&E::Event, &mut Self),
|
||||
H: Handle<E>,
|
||||
F: 'static + FnMut(H, &E::Event, &mut Self) -> bool,
|
||||
{
|
||||
let emitter = handle.downgrade();
|
||||
self.subscriptions
|
||||
.entry(handle.id())
|
||||
.or_default()
|
||||
.push(Subscription::Global {
|
||||
callback: Box::new(move |payload, cx| {
|
||||
.push(Box::new(move |payload, cx| {
|
||||
if let Some(emitter) = H::upgrade_from(&emitter, cx.as_ref()) {
|
||||
let payload = payload.downcast_ref().expect("downcast is type safe");
|
||||
callback(payload, cx);
|
||||
}),
|
||||
});
|
||||
callback(emitter, payload, cx)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn observe<E, F>(&mut self, handle: &impl Handle<E>, callback: F)
|
||||
fn observe_internal<E, H, F>(&mut self, handle: &H, mut callback: F)
|
||||
where
|
||||
E: Entity,
|
||||
E::Event: 'static,
|
||||
F: 'static + FnMut(&mut Self),
|
||||
H: Handle<E>,
|
||||
F: 'static + FnMut(H, &mut Self) -> bool,
|
||||
{
|
||||
let observed = handle.downgrade();
|
||||
self.observations
|
||||
.entry(handle.id())
|
||||
.or_default()
|
||||
.push(Observation::Global {
|
||||
callback: Box::new(callback),
|
||||
});
|
||||
.push(Box::new(move |cx| {
|
||||
if let Some(observed) = H::upgrade_from(&observed, cx) {
|
||||
callback(observed, cx)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
pub(crate) fn notify_view(&mut self, window_id: usize, view_id: usize) {
|
||||
|
@ -1363,91 +1343,29 @@ impl MutableAppContext {
|
|||
}
|
||||
|
||||
fn emit_event(&mut self, entity_id: usize, payload: Box<dyn Any>) {
|
||||
if let Some(subscriptions) = self.subscriptions.remove(&entity_id) {
|
||||
for mut subscription in subscriptions {
|
||||
let alive = match &mut subscription {
|
||||
Subscription::Global { callback } => {
|
||||
callback(payload.as_ref(), self);
|
||||
true
|
||||
}
|
||||
Subscription::FromModel { model_id, callback } => {
|
||||
if let Some(mut model) = self.cx.models.remove(model_id) {
|
||||
callback(model.as_any_mut(), payload.as_ref(), self, *model_id);
|
||||
self.cx.models.insert(*model_id, model);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
Subscription::FromView {
|
||||
window_id,
|
||||
view_id,
|
||||
callback,
|
||||
} => {
|
||||
if let Some(mut view) = self.cx.views.remove(&(*window_id, *view_id)) {
|
||||
callback(
|
||||
view.as_any_mut(),
|
||||
payload.as_ref(),
|
||||
self,
|
||||
*window_id,
|
||||
*view_id,
|
||||
);
|
||||
self.cx.views.insert((*window_id, *view_id), view);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(callbacks) = self.subscriptions.remove(&entity_id) {
|
||||
for mut callback in callbacks {
|
||||
let alive = callback(payload.as_ref(), self);
|
||||
if alive {
|
||||
self.subscriptions
|
||||
.entry(entity_id)
|
||||
.or_default()
|
||||
.push(subscription);
|
||||
.push(callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn notify_model_observers(&mut self, observed_id: usize) {
|
||||
if let Some(observations) = self.observations.remove(&observed_id) {
|
||||
if let Some(callbacks) = self.observations.remove(&observed_id) {
|
||||
if self.cx.models.contains_key(&observed_id) {
|
||||
for mut observation in observations {
|
||||
let alive = match &mut observation {
|
||||
Observation::Global { callback } => {
|
||||
callback(self);
|
||||
true
|
||||
}
|
||||
Observation::FromModel { model_id, callback } => {
|
||||
if let Some(mut model) = self.cx.models.remove(model_id) {
|
||||
callback(model.as_any_mut(), self, *model_id);
|
||||
self.cx.models.insert(*model_id, model);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
Observation::FromView {
|
||||
window_id,
|
||||
view_id,
|
||||
callback,
|
||||
} => {
|
||||
if let Some(mut view) = self.cx.views.remove(&(*window_id, *view_id)) {
|
||||
callback(view.as_any_mut(), self, *window_id, *view_id);
|
||||
self.cx.views.insert((*window_id, *view_id), view);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for mut callback in callbacks {
|
||||
let alive = callback(self);
|
||||
if alive {
|
||||
self.observations
|
||||
.entry(observed_id)
|
||||
.or_default()
|
||||
.push(observation);
|
||||
.push(callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1463,46 +1381,19 @@ impl MutableAppContext {
|
|||
.insert(observed_view_id);
|
||||
}
|
||||
|
||||
if let Some(observations) = self.observations.remove(&observed_view_id) {
|
||||
if let Some(callbacks) = self.observations.remove(&observed_view_id) {
|
||||
if self
|
||||
.cx
|
||||
.views
|
||||
.contains_key(&(observed_window_id, observed_view_id))
|
||||
{
|
||||
for mut observation in observations {
|
||||
if let Observation::FromView {
|
||||
window_id: observing_window_id,
|
||||
view_id: observing_view_id,
|
||||
callback,
|
||||
} = &mut observation
|
||||
{
|
||||
let alive = if let Some(mut view) = self
|
||||
.cx
|
||||
.views
|
||||
.remove(&(*observing_window_id, *observing_view_id))
|
||||
{
|
||||
(callback)(
|
||||
view.as_any_mut(),
|
||||
self,
|
||||
*observing_window_id,
|
||||
*observing_view_id,
|
||||
);
|
||||
self.cx
|
||||
.views
|
||||
.insert((*observing_window_id, *observing_view_id), view);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if alive {
|
||||
self.observations
|
||||
.entry(observed_view_id)
|
||||
.or_default()
|
||||
.push(observation);
|
||||
}
|
||||
} else {
|
||||
unreachable!()
|
||||
for mut callback in callbacks {
|
||||
let alive = callback(self);
|
||||
if alive {
|
||||
self.observations
|
||||
.entry(observed_view_id)
|
||||
.or_default()
|
||||
.push(callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1967,26 +1858,6 @@ impl<'a, T: Entity> ModelContext<'a, T> {
|
|||
self.app.add_model(build_model)
|
||||
}
|
||||
|
||||
pub fn subscribe<S: Entity, F>(&mut self, handle: &ModelHandle<S>, mut callback: F)
|
||||
where
|
||||
S::Event: 'static,
|
||||
F: 'static + FnMut(&mut T, &S::Event, &mut ModelContext<T>),
|
||||
{
|
||||
self.app
|
||||
.subscriptions
|
||||
.entry(handle.model_id)
|
||||
.or_default()
|
||||
.push(Subscription::FromModel {
|
||||
model_id: self.model_id,
|
||||
callback: Box::new(move |model, payload, app, model_id| {
|
||||
let model = model.downcast_mut().expect("downcast is type safe");
|
||||
let payload = payload.downcast_ref().expect("downcast is type safe");
|
||||
let mut cx = ModelContext::new(app, model_id);
|
||||
callback(model, payload, &mut cx);
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
pub fn emit(&mut self, payload: T::Event) {
|
||||
self.app.pending_effects.push_back(Effect::Event {
|
||||
entity_id: self.model_id,
|
||||
|
@ -1994,28 +1865,6 @@ impl<'a, T: Entity> ModelContext<'a, T> {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn observe<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F)
|
||||
where
|
||||
S: Entity,
|
||||
F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ModelContext<T>),
|
||||
{
|
||||
let observed_handle = handle.downgrade();
|
||||
self.app
|
||||
.observations
|
||||
.entry(handle.model_id)
|
||||
.or_default()
|
||||
.push(Observation::FromModel {
|
||||
model_id: self.model_id,
|
||||
callback: Box::new(move |model, app, model_id| {
|
||||
if let Some(observed) = observed_handle.upgrade(app) {
|
||||
let model = model.downcast_mut().expect("downcast is type safe");
|
||||
let mut cx = ModelContext::new(app, model_id);
|
||||
callback(model, observed, &mut cx);
|
||||
}
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
pub fn notify(&mut self) {
|
||||
self.app
|
||||
.pending_effects
|
||||
|
@ -2024,6 +1873,43 @@ impl<'a, T: Entity> ModelContext<'a, T> {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn subscribe<S: Entity, F>(&mut self, handle: &ModelHandle<S>, mut callback: F)
|
||||
where
|
||||
S::Event: 'static,
|
||||
F: 'static + FnMut(&mut T, ModelHandle<S>, &S::Event, &mut ModelContext<T>),
|
||||
{
|
||||
let subscriber = self.handle().downgrade();
|
||||
self.app
|
||||
.subscribe_internal(handle, move |emitter, event, cx| {
|
||||
if let Some(subscriber) = subscriber.upgrade(cx) {
|
||||
subscriber.update(cx, |subscriber, cx| {
|
||||
callback(subscriber, emitter, event, cx);
|
||||
});
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn observe<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F)
|
||||
where
|
||||
S: Entity,
|
||||
F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ModelContext<T>),
|
||||
{
|
||||
let observer = self.handle().downgrade();
|
||||
self.app.observe_internal(handle, move |observed, cx| {
|
||||
if let Some(observer) = observer.upgrade(cx) {
|
||||
observer.update(cx, |observer, cx| {
|
||||
callback(observer, observed, cx);
|
||||
});
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn handle(&self) -> ModelHandle<T> {
|
||||
ModelHandle::new(self.model_id, &self.app.cx.ref_counts)
|
||||
}
|
||||
|
@ -2211,56 +2097,80 @@ impl<'a, T: View> ViewContext<'a, T> {
|
|||
self.app.add_option_view(self.window_id, build_view)
|
||||
}
|
||||
|
||||
pub fn subscribe_to_model<E, F>(&mut self, handle: &ModelHandle<E>, mut callback: F)
|
||||
pub fn subscribe_to_model<E, F>(&mut self, handle: &ModelHandle<E>, callback: F)
|
||||
where
|
||||
E: Entity,
|
||||
E::Event: 'static,
|
||||
F: 'static + FnMut(&mut T, ModelHandle<E>, &E::Event, &mut ViewContext<T>),
|
||||
{
|
||||
let emitter_handle = handle.downgrade();
|
||||
self.subscribe(handle, move |model, payload, cx| {
|
||||
if let Some(emitter_handle) = emitter_handle.upgrade(cx.as_ref()) {
|
||||
callback(model, emitter_handle, payload, cx);
|
||||
}
|
||||
});
|
||||
self.subscribe(handle, callback)
|
||||
}
|
||||
|
||||
pub fn subscribe_to_view<V, F>(&mut self, handle: &ViewHandle<V>, mut callback: F)
|
||||
pub fn subscribe_to_view<V, F>(&mut self, handle: &ViewHandle<V>, callback: F)
|
||||
where
|
||||
V: View,
|
||||
V::Event: 'static,
|
||||
F: 'static + FnMut(&mut T, ViewHandle<V>, &V::Event, &mut ViewContext<T>),
|
||||
{
|
||||
let emitter_handle = handle.downgrade();
|
||||
self.subscribe(handle, move |view, payload, cx| {
|
||||
if let Some(emitter_handle) = emitter_handle.upgrade(cx.as_ref()) {
|
||||
callback(view, emitter_handle, payload, cx);
|
||||
}
|
||||
});
|
||||
self.subscribe(handle, callback)
|
||||
}
|
||||
|
||||
pub fn subscribe<E, F>(&mut self, handle: &impl Handle<E>, mut callback: F)
|
||||
pub fn observe_model<S, F>(&mut self, handle: &ModelHandle<S>, callback: F)
|
||||
where
|
||||
S: Entity,
|
||||
F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ViewContext<T>),
|
||||
{
|
||||
self.observe(handle, callback)
|
||||
}
|
||||
|
||||
pub fn observe_view<S, F>(&mut self, handle: &ViewHandle<S>, callback: F)
|
||||
where
|
||||
S: View,
|
||||
F: 'static + FnMut(&mut T, ViewHandle<S>, &mut ViewContext<T>),
|
||||
{
|
||||
self.observe(handle, callback)
|
||||
}
|
||||
|
||||
pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F)
|
||||
where
|
||||
E: Entity,
|
||||
E::Event: 'static,
|
||||
F: 'static + FnMut(&mut T, &E::Event, &mut ViewContext<T>),
|
||||
H: Handle<E>,
|
||||
F: 'static + FnMut(&mut T, H, &E::Event, &mut ViewContext<T>),
|
||||
{
|
||||
let subscriber = self.handle().downgrade();
|
||||
self.app
|
||||
.subscriptions
|
||||
.entry(handle.id())
|
||||
.or_default()
|
||||
.push(Subscription::FromView {
|
||||
window_id: self.window_id,
|
||||
view_id: self.view_id,
|
||||
callback: Box::new(move |entity, payload, app, window_id, view_id| {
|
||||
let entity = entity.downcast_mut().expect("downcast is type safe");
|
||||
let payload = payload.downcast_ref().expect("downcast is type safe");
|
||||
let mut cx = ViewContext::new(app, window_id, view_id);
|
||||
callback(entity, payload, &mut cx);
|
||||
}),
|
||||
.subscribe_internal(handle, move |emitter, event, cx| {
|
||||
if let Some(subscriber) = subscriber.upgrade(cx) {
|
||||
subscriber.update(cx, |subscriber, cx| {
|
||||
callback(subscriber, emitter, event, cx);
|
||||
});
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn observe<E, F, H>(&mut self, handle: &H, mut callback: F)
|
||||
where
|
||||
E: Entity,
|
||||
H: Handle<E>,
|
||||
F: 'static + FnMut(&mut T, H, &mut ViewContext<T>),
|
||||
{
|
||||
let observer = self.handle().downgrade();
|
||||
self.app.observe_internal(handle, move |observed, cx| {
|
||||
if let Some(observer) = observer.upgrade(cx) {
|
||||
observer.update(cx, |observer, cx| {
|
||||
callback(observer, observed, cx);
|
||||
});
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn emit(&mut self, payload: T::Event) {
|
||||
self.app.pending_effects.push_back(Effect::Event {
|
||||
entity_id: self.view_id,
|
||||
|
@ -2268,52 +2178,6 @@ impl<'a, T: View> ViewContext<'a, T> {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn observe_model<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F)
|
||||
where
|
||||
S: Entity,
|
||||
F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ViewContext<T>),
|
||||
{
|
||||
let observed_handle = handle.downgrade();
|
||||
self.app
|
||||
.observations
|
||||
.entry(handle.id())
|
||||
.or_default()
|
||||
.push(Observation::FromView {
|
||||
window_id: self.window_id,
|
||||
view_id: self.view_id,
|
||||
callback: Box::new(move |view, app, window_id, view_id| {
|
||||
if let Some(observed) = observed_handle.upgrade(app) {
|
||||
let view = view.downcast_mut().expect("downcast is type safe");
|
||||
let mut cx = ViewContext::new(app, window_id, view_id);
|
||||
callback(view, observed, &mut cx);
|
||||
}
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
pub fn observe_view<S, F>(&mut self, handle: &ViewHandle<S>, mut callback: F)
|
||||
where
|
||||
S: View,
|
||||
F: 'static + FnMut(&mut T, ViewHandle<S>, &mut ViewContext<T>),
|
||||
{
|
||||
let observed_handle = handle.downgrade();
|
||||
self.app
|
||||
.observations
|
||||
.entry(handle.id())
|
||||
.or_default()
|
||||
.push(Observation::FromView {
|
||||
window_id: self.window_id,
|
||||
view_id: self.view_id,
|
||||
callback: Box::new(move |view, app, observing_window_id, observing_view_id| {
|
||||
if let Some(observed) = observed_handle.upgrade(app) {
|
||||
let view = view.downcast_mut().expect("downcast is type safe");
|
||||
let mut cx = ViewContext::new(app, observing_window_id, observing_view_id);
|
||||
callback(view, observed, &mut cx);
|
||||
}
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
pub fn notify(&mut self) {
|
||||
self.app.notify_view(self.window_id, self.view_id);
|
||||
}
|
||||
|
@ -2433,8 +2297,13 @@ impl<V: View> UpdateView for ViewContext<'_, V> {
|
|||
}
|
||||
|
||||
pub trait Handle<T> {
|
||||
type Weak: 'static;
|
||||
fn id(&self) -> usize;
|
||||
fn location(&self) -> EntityLocation;
|
||||
fn downgrade(&self) -> Self::Weak;
|
||||
fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||
|
@ -2495,13 +2364,13 @@ impl<T: Entity> ModelHandle<T> {
|
|||
let (tx, mut rx) = mpsc::channel(1024);
|
||||
|
||||
let mut cx = cx.cx.borrow_mut();
|
||||
cx.observe_model(self, {
|
||||
cx.observe(self, {
|
||||
let mut tx = tx.clone();
|
||||
move |_, _| {
|
||||
tx.blocking_send(()).ok();
|
||||
}
|
||||
});
|
||||
cx.subscribe_to_model(self, {
|
||||
cx.subscribe(self, {
|
||||
let mut tx = tx.clone();
|
||||
move |_, _, _| {
|
||||
tx.blocking_send(()).ok();
|
||||
|
@ -2592,7 +2461,9 @@ impl<T> Drop for ModelHandle<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> Handle<T> for ModelHandle<T> {
|
||||
impl<T: Entity> Handle<T> for ModelHandle<T> {
|
||||
type Weak = WeakModelHandle<T>;
|
||||
|
||||
fn id(&self) -> usize {
|
||||
self.model_id
|
||||
}
|
||||
|
@ -2600,7 +2471,19 @@ impl<T> Handle<T> for ModelHandle<T> {
|
|||
fn location(&self) -> EntityLocation {
|
||||
EntityLocation::Model(self.model_id)
|
||||
}
|
||||
|
||||
fn downgrade(&self) -> Self::Weak {
|
||||
self.downgrade()
|
||||
}
|
||||
|
||||
fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
weak.upgrade(cx)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WeakModelHandle<T> {
|
||||
model_id: usize,
|
||||
model_type: PhantomData<T>,
|
||||
|
@ -2718,9 +2601,9 @@ impl<T: View> ViewHandle<T> {
|
|||
}
|
||||
});
|
||||
|
||||
cx.subscribe(self, {
|
||||
cx.subscribe_to_view(self, {
|
||||
let mut tx = tx.clone();
|
||||
move |_, _, _| {
|
||||
move |_, _, _, _| {
|
||||
tx.blocking_send(()).ok();
|
||||
}
|
||||
})
|
||||
|
@ -2801,7 +2684,9 @@ impl<T> Drop for ViewHandle<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> Handle<T> for ViewHandle<T> {
|
||||
impl<T: View> Handle<T> for ViewHandle<T> {
|
||||
type Weak = WeakViewHandle<T>;
|
||||
|
||||
fn id(&self) -> usize {
|
||||
self.view_id
|
||||
}
|
||||
|
@ -2809,6 +2694,17 @@ impl<T> Handle<T> for ViewHandle<T> {
|
|||
fn location(&self) -> EntityLocation {
|
||||
EntityLocation::View(self.window_id, self.view_id)
|
||||
}
|
||||
|
||||
fn downgrade(&self) -> Self::Weak {
|
||||
self.downgrade()
|
||||
}
|
||||
|
||||
fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
weak.upgrade(cx)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AnyViewHandle {
|
||||
|
@ -3097,36 +2993,6 @@ impl RefCounts {
|
|||
}
|
||||
}
|
||||
|
||||
enum Subscription {
|
||||
Global {
|
||||
callback: Box<dyn FnMut(&dyn Any, &mut MutableAppContext)>,
|
||||
},
|
||||
FromModel {
|
||||
model_id: usize,
|
||||
callback: Box<dyn FnMut(&mut dyn Any, &dyn Any, &mut MutableAppContext, usize)>,
|
||||
},
|
||||
FromView {
|
||||
window_id: usize,
|
||||
view_id: usize,
|
||||
callback: Box<dyn FnMut(&mut dyn Any, &dyn Any, &mut MutableAppContext, usize, usize)>,
|
||||
},
|
||||
}
|
||||
|
||||
enum Observation {
|
||||
Global {
|
||||
callback: Box<dyn FnMut(&mut MutableAppContext)>,
|
||||
},
|
||||
FromModel {
|
||||
model_id: usize,
|
||||
callback: Box<dyn FnMut(&mut dyn Any, &mut MutableAppContext, usize)>,
|
||||
},
|
||||
FromView {
|
||||
window_id: usize,
|
||||
view_id: usize,
|
||||
callback: Box<dyn FnMut(&mut dyn Any, &mut MutableAppContext, usize, usize)>,
|
||||
},
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -3151,7 +3017,7 @@ mod tests {
|
|||
cx.observe(other, |me, _, _| {
|
||||
me.events.push("notified".into());
|
||||
});
|
||||
cx.subscribe(other, |me, event, _| {
|
||||
cx.subscribe(other, |me, _, event, _| {
|
||||
me.events.push(format!("observed event {}", event));
|
||||
});
|
||||
}
|
||||
|
@ -3209,10 +3075,10 @@ mod tests {
|
|||
let handle_2b = handle_2.clone();
|
||||
|
||||
handle_1.update(cx, |_, c| {
|
||||
c.subscribe(&handle_2, move |model: &mut Model, event, c| {
|
||||
c.subscribe(&handle_2, move |model: &mut Model, _, event, c| {
|
||||
model.events.push(*event);
|
||||
|
||||
c.subscribe(&handle_2b, |model, event, _| {
|
||||
c.subscribe(&handle_2b, |model, _, event, _| {
|
||||
model.events.push(*event * 2);
|
||||
});
|
||||
});
|
||||
|
@ -3519,7 +3385,7 @@ mod tests {
|
|||
cx.subscribe_to_model(&observed_model, |_, _, _, _| {});
|
||||
});
|
||||
observing_model.update(cx, |_, cx| {
|
||||
cx.subscribe(&observed_model, |_, _, _| {});
|
||||
cx.subscribe(&observed_model, |_, _, _, _| {});
|
||||
});
|
||||
|
||||
cx.update(|| {
|
||||
|
|
|
@ -2940,11 +2940,11 @@ mod tests {
|
|||
let buffer2 = cx.add_model(|cx| Buffer::new(1, "abcdef", cx));
|
||||
let buffer_ops = buffer1.update(cx, |buffer, cx| {
|
||||
let buffer_1_events = buffer_1_events.clone();
|
||||
cx.subscribe(&buffer1, move |_, event, _| {
|
||||
cx.subscribe(&buffer1, move |_, _, event, _| {
|
||||
buffer_1_events.borrow_mut().push(event.clone())
|
||||
});
|
||||
let buffer_2_events = buffer_2_events.clone();
|
||||
cx.subscribe(&buffer2, move |_, event, _| {
|
||||
cx.subscribe(&buffer2, move |_, _, event, _| {
|
||||
buffer_2_events.borrow_mut().push(event.clone())
|
||||
});
|
||||
|
||||
|
@ -3380,7 +3380,7 @@ mod tests {
|
|||
buffer1.update(&mut cx, |buffer, cx| {
|
||||
cx.subscribe(&buffer1, {
|
||||
let events = events.clone();
|
||||
move |_, event, _| events.borrow_mut().push(event.clone())
|
||||
move |_, _, event, _| events.borrow_mut().push(event.clone())
|
||||
});
|
||||
|
||||
assert!(!buffer.is_dirty());
|
||||
|
@ -3436,7 +3436,7 @@ mod tests {
|
|||
buffer2.update(&mut cx, |_, cx| {
|
||||
cx.subscribe(&buffer2, {
|
||||
let events = events.clone();
|
||||
move |_, event, _| events.borrow_mut().push(event.clone())
|
||||
move |_, _, event, _| events.borrow_mut().push(event.clone())
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -3456,7 +3456,7 @@ mod tests {
|
|||
buffer3.update(&mut cx, |_, cx| {
|
||||
cx.subscribe(&buffer3, {
|
||||
let events = events.clone();
|
||||
move |_, event, _| events.borrow_mut().push(event.clone())
|
||||
move |_, _, event, _| events.borrow_mut().push(event.clone())
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue