From 477c4f621663e60f0744a53fa1a8118ccf6f9fdd Mon Sep 17 00:00:00 2001 From: Leon Zhao Date: Mon, 6 Jan 2025 15:22:45 +0800 Subject: [PATCH] fix: pass DiffEvent to onPush --- crates/loro-ffi/src/undo.rs | 34 ++++++++----------- crates/loro/src/lib.rs | 16 ++++++--- .../loro/tests/integration_test/undo_test.rs | 16 ++++----- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/crates/loro-ffi/src/undo.rs b/crates/loro-ffi/src/undo.rs index 0673e346..4ff276e9 100644 --- a/crates/loro-ffi/src/undo.rs +++ b/crates/loro-ffi/src/undo.rs @@ -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); @@ -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>) { - 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) { + 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>) { - 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) { + 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, + diff_event: Option, ) -> UndoItemMeta; } diff --git a/crates/loro/src/lib.rs b/crates/loro/src/lib.rs index 0c0a02ee..45d173b3 100644 --- a/crates/loro/src/lib.rs +++ b/crates/loro/src/lib.rs @@ -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) { - 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) { - 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 Fn(UndoOrRedo, CounterSpan, Option) -> UndoItemMeta + Send + Sync>; diff --git a/crates/loro/tests/integration_test/undo_test.rs b/crates/loro/tests/integration_test/undo_test.rs index a164f52b..83b2ec6a 100644 --- a/crates/loro/tests/integration_test/undo_test.rs +++ b/crates/loro/tests/integration_test/undo_test.rs @@ -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>> = 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