chore: updated docs, getter for buf name

This commit is contained in:
əlemi 2023-11-30 03:41:53 +01:00
parent 5401d837c7
commit 7ad1da0f27
3 changed files with 19 additions and 20 deletions

View file

@ -62,7 +62,7 @@ impl TextChange {
!self.span.is_empty() !self.span.is_empty()
} }
// returns true if this TextChange adds new text /// returns true if this TextChange adds new text
pub fn is_addition(&self) -> bool { pub fn is_addition(&self) -> bool {
!self.content.is_empty() !self.content.is_empty()
} }
@ -72,6 +72,7 @@ impl TextChange {
!self.is_deletion() && !self.is_addition() !self.is_deletion() && !self.is_addition()
} }
/// applies this text change to given text, returning a new string
pub fn apply(&self, txt: &str) -> String { pub fn apply(&self, txt: &str) -> String {
let pre_index = std::cmp::min(self.span.start, txt.len()); let pre_index = std::cmp::min(self.span.start, txt.len());
let pre = txt.get(..pre_index).unwrap_or("").to_string(); let pre = txt.get(..pre_index).unwrap_or("").to_string();

View file

@ -57,9 +57,6 @@ pub trait Controller<T : Sized + Send + Sync> : Sized + Send + Sync {
async fn poll(&self) -> Result<()>; async fn poll(&self) -> Result<()>;
/// attempt to receive a value without blocking, return None if nothing is available /// attempt to receive a value without blocking, return None if nothing is available
///
/// note that this function does not circumvent race conditions, returning errors if it would
/// block. it's usually safe to ignore such errors and retry
fn try_recv(&self) -> Result<Option<T>>; fn try_recv(&self) -> Result<Option<T>>;
/// sync variant of [Self::recv], blocking invoking thread /// sync variant of [Self::recv], blocking invoking thread

View file

@ -16,12 +16,6 @@ use crate::api::TextChange;
/// the buffer controller implementation /// the buffer controller implementation
/// ///
/// this contains
/// * a watch channel which always contains an updated view of the buffer content
/// * a sink to send buffer operations into
/// * a mutexed broadcast receiver for buffer operations
/// * a channel to stop the associated worker
///
/// for each controller a worker exists, managing outgoing and inbound /// for each controller a worker exists, managing outgoing and inbound
/// queues, transforming outbound delayed ops and applying remote changes /// queues, transforming outbound delayed ops and applying remote changes
/// to the local buffer /// to the local buffer
@ -29,10 +23,9 @@ use crate::api::TextChange;
/// upon dropping this handle will stop the associated worker /// upon dropping this handle will stop the associated worker
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct BufferController { pub struct BufferController {
/// unique identifier of buffer name: String,
pub name: String,
content: watch::Receiver<String>, content: watch::Receiver<String>,
seen: StatusCheck<String>, seen: StatusCheck<String>, // internal buffer previous state
operations: mpsc::UnboundedSender<TextChange>, operations: mpsc::UnboundedSender<TextChange>,
poller: mpsc::UnboundedSender<oneshot::Sender<()>>, poller: mpsc::UnboundedSender<oneshot::Sender<()>>,
_stop: Arc<StopOnDrop>, // just exist _stop: Arc<StopOnDrop>, // just exist
@ -54,6 +47,12 @@ impl BufferController {
} }
} }
/// unique identifier of buffer
pub fn name(&self) -> &str {
&self.name
}
/// return buffer whole content, updating internal buffer previous state
pub fn content(&self) -> String { pub fn content(&self) -> String {
self.seen.update(self.content.borrow().clone()); self.seen.update(self.content.borrow().clone());
self.content.borrow().clone() self.content.borrow().clone()
@ -73,7 +72,8 @@ impl Drop for StopOnDrop {
impl Controller<TextChange> for BufferController { impl Controller<TextChange> for BufferController {
type Input = TextChange; type Input = TextChange;
// block until a new text change is available /// block until a text change is available
/// this returns immediately if one is already available
async fn poll(&self) -> crate::Result<()> { async fn poll(&self) -> crate::Result<()> {
if self.seen.check() != *self.content.borrow() { if self.seen.check() != *self.content.borrow() {
return Ok(()); // short circuit: already available! return Ok(()); // short circuit: already available!
@ -84,7 +84,7 @@ impl Controller<TextChange> for BufferController {
Ok(()) Ok(())
} }
// if a new text change is available, return it immediately /// if a text change is available, return it immediately
fn try_recv(&self) -> crate::Result<Option<TextChange>> { fn try_recv(&self) -> crate::Result<Option<TextChange>> {
let seen = self.seen.check(); let seen = self.seen.check();
let actual = self.content.borrow().clone(); let actual = self.content.borrow().clone();
@ -96,7 +96,7 @@ impl Controller<TextChange> for BufferController {
Ok(Some(change)) Ok(Some(change))
} }
// block until a new text change is available, and return it /// block until a new text change is available, and return it
async fn recv(&self) -> crate::Result<TextChange> { async fn recv(&self) -> crate::Result<TextChange> {
self.poll().await?; self.poll().await?;
let seen = self.seen.check(); let seen = self.seen.check();
@ -106,7 +106,8 @@ impl Controller<TextChange> for BufferController {
Ok(change) Ok(change)
} }
/// enqueue an opseq for processing /// enqueue a text change for processing
/// this also updates internal buffer previous state
fn send(&self, op: TextChange) -> crate::Result<()> { fn send(&self, op: TextChange) -> crate::Result<()> {
let before = self.seen.check(); let before = self.seen.check();
self.seen.update(op.apply(&before)); self.seen.update(op.apply(&before));
@ -115,7 +116,7 @@ impl Controller<TextChange> for BufferController {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct StatusCheck<T : Clone> { struct StatusCheck<T : Clone> {
state: watch::Receiver<T>, state: watch::Receiver<T>,
updater: Arc<watch::Sender<T>>, updater: Arc<watch::Sender<T>>,
} }
@ -128,11 +129,11 @@ impl<T : Clone + Default> Default for StatusCheck<T> {
} }
impl<T : Clone> StatusCheck<T> { impl<T : Clone> StatusCheck<T> {
pub fn update(&self, state: T) -> T { fn update(&self, state: T) -> T {
self.updater.send_replace(state) self.updater.send_replace(state)
} }
pub fn check(&self) -> T { fn check(&self) -> T {
self.state.borrow().clone() self.state.borrow().clone()
} }
} }