Implement ExcerptList::subscribe
Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
co-authored by
Max Brunsfeld
parent
a02a29944c
commit
4578938ea1
@@ -210,6 +210,15 @@ impl<'a, T: Clone> IntoIterator for &'a Patch<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Clone> IntoIterator for &'a mut Patch<T> {
|
||||
type Item = Edit<T>;
|
||||
type IntoIter = std::iter::Cloned<std::slice::Iter<'a, Edit<T>>>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.0.iter().cloned()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
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
|
||||
}
|
||||
});
|
||||
}
|
||||
+8
-34
@@ -7,6 +7,7 @@ mod point_utf16;
|
||||
pub mod random_char_iter;
|
||||
pub mod rope;
|
||||
mod selection;
|
||||
pub mod subscription;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
@@ -15,7 +16,6 @@ use anyhow::{anyhow, Result};
|
||||
use clock::ReplicaId;
|
||||
use collections::{HashMap, HashSet};
|
||||
use operation_queue::OperationQueue;
|
||||
use parking_lot::Mutex;
|
||||
pub use patch::Patch;
|
||||
pub use point::*;
|
||||
pub use point_utf16::*;
|
||||
@@ -29,9 +29,10 @@ use std::{
|
||||
iter::Iterator,
|
||||
ops::{self, Deref, Range, Sub},
|
||||
str,
|
||||
sync::{Arc, Weak},
|
||||
sync::Arc,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use subscription::{Subscription, Topic};
|
||||
pub use sum_tree::Bias;
|
||||
use sum_tree::{FilterCursor, SumTree};
|
||||
|
||||
@@ -46,7 +47,7 @@ pub struct Buffer {
|
||||
remote_id: u64,
|
||||
local_clock: clock::Local,
|
||||
lamport_clock: clock::Lamport,
|
||||
subscriptions: Vec<Weak<Mutex<Vec<Patch<usize>>>>>,
|
||||
subscriptions: Topic,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -343,20 +344,6 @@ impl<D1, D2> Edit<(D1, D2)> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct Subscription(Arc<Mutex<Vec<Patch<usize>>>>);
|
||||
|
||||
impl Subscription {
|
||||
pub fn consume(&self) -> Patch<usize> {
|
||||
let mut patches = self.0.lock();
|
||||
let mut changes = Patch::default();
|
||||
for patch in patches.drain(..) {
|
||||
changes = changes.compose(&patch);
|
||||
}
|
||||
changes
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
|
||||
pub struct InsertionTimestamp {
|
||||
pub replica_id: ReplicaId,
|
||||
@@ -699,7 +686,7 @@ impl Buffer {
|
||||
self.snapshot.fragments = new_fragments;
|
||||
self.snapshot.visible_text = visible_text;
|
||||
self.snapshot.deleted_text = deleted_text;
|
||||
self.update_subscriptions(edits);
|
||||
self.subscriptions.publish_mut(&edits);
|
||||
edit_op.new_text = new_text;
|
||||
edit_op
|
||||
}
|
||||
@@ -955,7 +942,7 @@ impl Buffer {
|
||||
self.snapshot.deleted_text = deleted_text;
|
||||
self.local_clock.observe(timestamp.local());
|
||||
self.lamport_clock.observe(timestamp.lamport());
|
||||
self.update_subscriptions(edits);
|
||||
self.subscriptions.publish_mut(&edits);
|
||||
}
|
||||
|
||||
fn apply_undo(&mut self, undo: &UndoOperation) -> Result<()> {
|
||||
@@ -1045,7 +1032,7 @@ impl Buffer {
|
||||
self.snapshot.fragments = new_fragments;
|
||||
self.snapshot.visible_text = visible_text;
|
||||
self.snapshot.deleted_text = deleted_text;
|
||||
self.update_subscriptions(edits);
|
||||
self.subscriptions.publish_mut(&edits);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1203,20 +1190,7 @@ impl Buffer {
|
||||
}
|
||||
|
||||
pub fn subscribe(&mut self) -> Subscription {
|
||||
let subscription = Subscription(Default::default());
|
||||
self.subscriptions.push(Arc::downgrade(&subscription.0));
|
||||
subscription
|
||||
}
|
||||
|
||||
fn update_subscriptions(&mut self, edits: Patch<usize>) {
|
||||
self.subscriptions.retain(|subscription| {
|
||||
if let Some(subscription) = subscription.upgrade() {
|
||||
subscription.lock().push(edits.clone());
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
self.subscriptions.subscribe()
|
||||
}
|
||||
|
||||
pub fn selection_set(&self, set_id: SelectionSetId) -> Result<&SelectionSet> {
|
||||
|
||||
Reference in New Issue
Block a user