use crate::{Edit, Patch};use parking_lot::Mutex;use std::{ mem, sync::{Arc, Weak},}; #[derive(Default)]pub struct Topic(Mutex<Vec<Weak<Mutex<Patch<usize>>>>>); pub struct Subscription(Arc<Mutex<Patch<usize>>>); impl Topic { pub fn subscribe(&mut self) -> Subscription { let subscription = Subscription(Default::default()); self.0.get_mut().push(Arc::downgrade(&subscription.0)); subscription } pub fn publish(&self, edits: impl Clone + IntoIterator<Item = Edit<usize>>) { publish(&mut self.0.lock(), edits); } pub fn publish_mut(&mut self, edits: impl Clone + IntoIterator<Item = Edit<usize>>) { publish(self.0.get_mut(), edits); }} impl Subscription { pub fn consume(&self) -> Patch<usize> { mem::take(&mut *self.0.lock()) }} fn publish( subscriptions: &mut Vec<Weak<Mutex<Patch<usize>>>>, edits: impl Clone + IntoIterator<Item = Edit<usize>>,) { subscriptions.retain(|subscription| { if let Some(subscription) = subscription.upgrade() { let mut patch = subscription.lock(); *patch = patch.compose(edits.clone()); true } else { false } });}
use crate::{Edit, Patch};
use parking_lot::Mutex;
use std::{
mem,
sync::{Arc, Weak},
};
#[derive(Default)]
pub struct Topic(Mutex<Vec<Weak<Mutex<Patch<usize>>>>>);
pub struct Subscription(Arc<Mutex<Patch<usize>>>);
impl Topic {
pub fn subscribe(&mut self) -> Subscription {
let subscription = Subscription(Default::default());
self.0.get_mut().push(Arc::downgrade(&subscription.0));
subscription
}
pub fn publish(&self, edits: impl Clone + IntoIterator<Item = Edit<usize>>) {
publish(&mut self.0.lock(), edits);
}
pub fn publish_mut(&mut self, edits: impl Clone + IntoIterator<Item = Edit<usize>>) {
publish(self.0.get_mut(), edits);
}
}
impl Subscription {
pub fn consume(&self) -> Patch<usize> {
mem::take(&mut *self.0.lock())
}
}
fn publish(
subscriptions: &mut Vec<Weak<Mutex<Patch<usize>>>>,
edits: impl Clone + IntoIterator<Item = Edit<usize>>,
) {
subscriptions.retain(|subscription| {
if let Some(subscription) = subscription.upgrade() {
let mut patch = subscription.lock();
*patch = patch.compose(edits.clone());
true
} else {
false
}
});
}