changed name of subscription mapping and moved out to file

Co-authored-by: Keith <keith@zed.dev>
This commit is contained in:
Mikayla Maki 2022-08-09 16:59:13 -07:00
parent 3d9821b430
commit 45c0539de0
3 changed files with 165 additions and 153 deletions

View file

@ -0,0 +1,106 @@
use std::sync::Arc;
use std::{hash::Hash, sync::Weak};
use parking_lot::Mutex;
use collections::{btree_map, BTreeMap, HashMap};
use crate::MutableAppContext;
pub type Mapping<K, F> = Mutex<HashMap<K, BTreeMap<usize, Option<F>>>>;
pub struct CallbackCollection<K: Hash + Eq, F> {
internal: Arc<Mapping<K, F>>,
}
impl<K: Hash + Eq, F> Clone for CallbackCollection<K, F> {
fn clone(&self) -> Self {
Self {
internal: self.internal.clone(),
}
}
}
impl<K: Hash + Eq + Copy, F> Default for CallbackCollection<K, F> {
fn default() -> Self {
CallbackCollection {
internal: Arc::new(Mutex::new(Default::default())),
}
}
}
impl<K: Hash + Eq + Copy, F> CallbackCollection<K, F> {
pub fn downgrade(&self) -> Weak<Mapping<K, F>> {
Arc::downgrade(&self.internal)
}
#[cfg(test)]
pub fn is_empty(&self) -> bool {
self.internal.lock().is_empty()
}
pub fn add_callback(&mut self, id: K, subscription_id: usize, callback: F) {
self.internal
.lock()
.entry(id)
.or_default()
.insert(subscription_id, Some(callback));
}
pub fn remove(&mut self, id: K) {
self.internal.lock().remove(&id);
}
pub fn add_or_remove_callback(&mut self, id: K, subscription_id: usize, callback: F) {
match self
.internal
.lock()
.entry(id)
.or_default()
.entry(subscription_id)
{
btree_map::Entry::Vacant(entry) => {
entry.insert(Some(callback));
}
btree_map::Entry::Occupied(entry) => {
// TODO: This seems like it should never be called because no code
// should ever attempt to remove an existing callback
debug_assert!(entry.get().is_none());
entry.remove();
}
}
}
pub fn emit_and_cleanup<C: FnMut(&mut F, &mut MutableAppContext) -> bool>(
&mut self,
id: K,
cx: &mut MutableAppContext,
mut call_callback: C,
) {
let callbacks = self.internal.lock().remove(&id);
if let Some(callbacks) = callbacks {
for (subscription_id, callback) in callbacks {
if let Some(mut callback) = callback {
let alive = call_callback(&mut callback, cx);
if alive {
match self
.internal
.lock()
.entry(id)
.or_default()
.entry(subscription_id)
{
btree_map::Entry::Vacant(entry) => {
entry.insert(Some(callback));
}
btree_map::Entry::Occupied(entry) => {
entry.remove();
}
}
}
}
}
}
}
}