use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use crate::inner::{CallbackEntry, TextDocumentInner};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum InsertionOrigin {
#[default]
Unspecified,
Typed,
Composed,
Pasted,
Dropped,
Imported,
Replayed,
Programmatic,
Assistive,
}
impl InsertionOrigin {
pub fn token(self) -> &'static str {
match self {
InsertionOrigin::Unspecified => "unspecified",
InsertionOrigin::Typed => "typed",
InsertionOrigin::Composed => "composed",
InsertionOrigin::Pasted => "pasted",
InsertionOrigin::Dropped => "dropped",
InsertionOrigin::Imported => "imported",
InsertionOrigin::Replayed => "replayed",
InsertionOrigin::Programmatic => "programmatic",
InsertionOrigin::Assistive => "assistive",
}
}
pub const ALL: [InsertionOrigin; 9] = [
InsertionOrigin::Unspecified,
InsertionOrigin::Typed,
InsertionOrigin::Composed,
InsertionOrigin::Pasted,
InsertionOrigin::Dropped,
InsertionOrigin::Imported,
InsertionOrigin::Replayed,
InsertionOrigin::Programmatic,
InsertionOrigin::Assistive,
];
}
#[derive(Debug, Clone, PartialEq)]
pub enum DocumentEvent {
ContentsChanged {
position: usize,
chars_removed: usize,
chars_added: usize,
blocks_affected: usize,
},
TextInserted {
position: usize,
chars_inserted: usize,
origin: InsertionOrigin,
},
FormatChanged {
position: usize,
length: usize,
kind: crate::flow::FormatChangeKind,
},
HighlightPaintChanged { position: usize, length: usize },
BlockCountChanged(usize),
FlowElementsInserted { flow_index: usize, count: usize },
FlowElementsRemoved { flow_index: usize, count: usize },
DocumentReset,
UndoRedoChanged { can_undo: bool, can_redo: bool },
ModificationChanged(bool),
LongOperationProgress {
operation_id: String,
percent: f64,
message: String,
},
LongOperationFinished {
operation_id: String,
success: bool,
error: Option<String>,
},
}
pub struct Subscription {
alive: Arc<AtomicBool>,
}
impl Drop for Subscription {
fn drop(&mut self) {
self.alive
.store(false, std::sync::atomic::Ordering::Relaxed);
}
}
pub(crate) fn subscribe_inner<F>(inner: &mut TextDocumentInner, callback: F) -> Subscription
where
F: Fn(DocumentEvent) + Send + Sync + 'static,
{
let alive = Arc::new(AtomicBool::new(true));
inner.callbacks.push(CallbackEntry {
alive: Arc::downgrade(&alive),
callback: Arc::new(callback),
});
Subscription { alive }
}