fix: pass DiffEvent to onPush

This commit is contained in:
Leon Zhao 2025-01-06 15:22:45 +08:00
parent 567067b4d1
commit 477c4f6216
3 changed files with 33 additions and 33 deletions

View file

@ -2,7 +2,7 @@ use std::sync::{Arc, RwLock};
use loro::LoroResult;
use crate::{Cursor, LoroDoc, LoroValue, Side};
use crate::{Cursor, DiffEvent, LoroDoc, LoroValue, Side};
pub struct UndoManager(RwLock<loro::UndoManager>);
@ -55,36 +55,30 @@ impl UndoManager {
/// Set the listener for push events.
/// The listener will be called when a new undo/redo item is pushed into the stack.
pub fn set_on_push(&self, on_push: Option<Arc<dyn OnPush>>) {
if let Some(on_push) = on_push {
self.0
.write()
.unwrap()
.set_on_push(Some(Box::new(move |u, c, e| {
loro::undo::UndoItemMeta::from(on_push.on_push(u, c, e))
})));
} else {
self.0.write().unwrap().set_on_push(None);
}
pub fn set_on_push(&self, on_push: Arc<dyn OnPush>) {
self.0
.write()
.unwrap()
.set_on_push(Box::new(move |u, c, e| {
loro::UndoItemMeta::from(on_push.on_push(u, c, e.map(|x| x.into())))
}));
}
/// Set the listener for pop events.
/// The listener will be called when an undo/redo item is popped from the stack.
pub fn set_on_pop(&self, on_pop: Option<Arc<dyn OnPop>>) {
let on_pop = on_pop.map(|x| {
Box::new(move |u, c, m| (x.on_pop(u, c, UndoItemMeta::from(m)))) as loro::undo::OnPop
});
self.0.write().unwrap().set_on_pop(on_pop)
pub fn set_on_pop(&self, on_pop: Arc<dyn OnPop>) {
self.0.write().unwrap().set_on_pop(Box::new(move |u, c, m| {
on_pop.on_pop(u, c, UndoItemMeta::from(m))
}))
}
}
pub trait OnPush: Send + Sync {
fn on_push(
&self,
undo_or_redo: loro::undo::UndoOrRedo,
undo_or_redo: loro::UndoOrRedo,
counter_span: loro::CounterSpan,
diff_event: Option<loro_internal::event::DiffEvent>,
diff_event: Option<DiffEvent>,
) -> UndoItemMeta;
}

View file

@ -11,7 +11,7 @@ use loro_internal::cursor::Side;
pub use loro_internal::encoding::ImportStatus;
use loro_internal::handler::HandlerTrait;
pub use loro_internal::loro::ChangeTravelError;
use loro_internal::undo::{OnPop, OnPush};
pub use loro_internal::undo::{OnPop, UndoItemMeta, UndoOrRedo};
use loro_internal::version::shrink_frontiers;
pub use loro_internal::version::ImVersionVector;
use loro_internal::DocState;
@ -2699,14 +2699,16 @@ impl UndoManager {
/// Set the listener for push events.
/// The listener will be called when a new undo/redo item is pushed into the stack.
pub fn set_on_push(&mut self, on_push: Option<OnPush>) {
self.0.set_on_push(on_push)
pub fn set_on_push(&mut self, on_push: OnPush) {
self.0.set_on_push(Some(Box::new(move |u, c, e| {
on_push(u, c, e.map(|x| x.into()))
})))
}
/// Set the listener for pop events.
/// The listener will be called when an undo/redo item is popped from the stack.
pub fn set_on_pop(&mut self, on_pop: Option<OnPop>) {
self.0.set_on_pop(on_pop)
pub fn set_on_pop(&mut self, on_pop: OnPop) {
self.0.set_on_pop(Some(on_pop));
}
/// Clear the undo stack and the redo stack
@ -2714,3 +2716,7 @@ impl UndoManager {
self.0.clear();
}
}
/// When a undo/redo item is pushed, the undo manager will call the on_push callback to get the meta data of the undo item.
/// The returned cursors will be recorded for a new pushed undo item.
pub type OnPush =
Box<dyn for<'a> Fn(UndoOrRedo, CounterSpan, Option<DiffEvent>) -> UndoItemMeta + Send + Sync>;

View file

@ -1536,17 +1536,17 @@ fn undo_manager_events() -> anyhow::Result<()> {
let pop_count_clone = pop_count.clone();
let popped_value = Arc::new(Mutex::new(LoroValue::Null));
let popped_value_clone = popped_value.clone();
undo.set_on_push(Some(Box::new(move |_source, span, _| {
undo.set_on_push(Box::new(move |_source, span, _| {
push_count_clone.fetch_add(1, atomic::Ordering::SeqCst);
UndoItemMeta {
value: LoroValue::I64(span.start as i64),
cursors: Default::default(),
}
})));
undo.set_on_pop(Some(Box::new(move |_source, _span, v| {
}));
undo.set_on_pop(Box::new(move |_source, _span, v| {
pop_count_clone.fetch_add(1, atomic::Ordering::SeqCst);
*popped_value_clone.try_lock().unwrap() = v.value;
})));
}));
text.insert(0, "Hello")?;
assert_eq!(push_count.load(atomic::Ordering::SeqCst), 0);
doc.commit();
@ -1583,19 +1583,19 @@ fn undo_transform_cursor_position() -> anyhow::Result<()> {
let mut undo = UndoManager::new(&doc);
let cursors: Arc<Mutex<Vec<Cursor>>> = Arc::new(Mutex::new(Vec::new()));
let cursors_clone = cursors.clone();
undo.set_on_push(Some(Box::new(move |_, _, _| {
undo.set_on_push(Box::new(move |_, _, _| {
let mut ans = UndoItemMeta::new();
let cursors = cursors_clone.try_lock().unwrap();
for c in cursors.iter() {
ans.add_cursor(c)
}
ans
})));
}));
let popped_cursors = Arc::new(Mutex::new(Vec::new()));
let popped_cursors_clone = popped_cursors.clone();
undo.set_on_pop(Some(Box::new(move |_, _, meta| {
undo.set_on_pop(Box::new(move |_, _, meta| {
*popped_cursors_clone.try_lock().unwrap() = meta.cursors;
})));
}));
text.insert(0, "Hello world!")?;
doc.commit();
cursors