Add test for notifying and dropping subscriptions in an update cycle

This commit is contained in:
Max Brunsfeld 2023-01-06 10:44:37 -08:00
parent a165cd596b
commit 4708f5d88f
2 changed files with 28 additions and 9 deletions

View file

@ -6097,6 +6097,31 @@ mod tests {
assert_eq!(view.read(cx).events, ["before notify"]);
}
#[crate::test(self)]
fn test_notify_and_drop_observe_subscription_in_same_update_cycle(cx: &mut MutableAppContext) {
struct Model;
impl Entity for Model {
type Event = ();
}
let model = cx.add_model(|_| Model);
let (_, view) = cx.add_window(Default::default(), |_| TestView::default());
view.update(cx, |_, cx| {
model.update(cx, |_, cx| cx.notify());
drop(cx.observe(&model, move |this, _, _| {
this.events.push("model notified".into());
}));
model.update(cx, |_, cx| cx.notify());
});
for _ in 0..3 {
model.update(cx, |_, cx| cx.notify());
}
assert_eq!(view.read(cx).events, Vec::<String>::new());
}
#[crate::test(self)]
fn test_dropping_observers(cx: &mut MutableAppContext) {
struct Model;

View file

@ -58,14 +58,6 @@ impl<K: Clone + Hash + Eq + Copy, F> CallbackCollection<K, F> {
}
}
pub fn count(&mut self, key: K) -> usize {
self.internal
.lock()
.callbacks
.get(&key)
.map_or(0, |callbacks| callbacks.len())
}
pub fn add_callback(&mut self, key: K, subscription_id: usize, callback: F) {
let mut this = self.internal.lock();
if !this.dropped_subscriptions.contains(&(key, subscription_id)) {
@ -77,7 +69,9 @@ impl<K: Clone + Hash + Eq + Copy, F> CallbackCollection<K, F> {
}
pub fn remove(&mut self, key: K) {
self.internal.lock().callbacks.remove(&key);
let callbacks = self.internal.lock().callbacks.remove(&key);
// drop these after releasing the lock
drop(callbacks);
}
pub fn emit<C: FnMut(&mut F, &mut MutableAppContext) -> bool>(