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