mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: apply transactions
This commit is contained in:
parent
ba160c8026
commit
c207bf3679
@ -1,25 +1,25 @@
|
||||
use crate::core::document::position::Position;
|
||||
use crate::core::{DeleteOperation, DocumentOperation, InsertOperation, NodeAttributes, NodeData, TextEditOperation, Transaction, UpdateOperation};
|
||||
use crate::core::{
|
||||
DeleteOperation, DocumentOperation, InsertOperation, NodeAttributes, NodeData, TextEditOperation, Transaction,
|
||||
UpdateOperation,
|
||||
};
|
||||
use indextree::{Arena, NodeId};
|
||||
|
||||
pub struct DocumentTree {
|
||||
arena: Arena<NodeData>,
|
||||
root: NodeId,
|
||||
pub arena: Arena<NodeData>,
|
||||
pub root: NodeId,
|
||||
}
|
||||
|
||||
impl DocumentTree {
|
||||
pub fn new() -> DocumentTree {
|
||||
let mut arena = Arena::new();
|
||||
let root = arena.new_node(NodeData::new("root".into()));
|
||||
DocumentTree {
|
||||
arena: Arena::new(),
|
||||
root,
|
||||
}
|
||||
DocumentTree { arena, root }
|
||||
}
|
||||
|
||||
pub fn node_at_path(&self, position: &Position) -> Option<NodeId> {
|
||||
if position.is_empty() {
|
||||
return None;
|
||||
return Some(self.root);
|
||||
}
|
||||
|
||||
let mut iterate_node = self.root;
|
||||
@ -93,7 +93,7 @@ impl DocumentTree {
|
||||
}
|
||||
|
||||
fn apply_op(&mut self, op: &DocumentOperation) {
|
||||
match op {
|
||||
match op {
|
||||
DocumentOperation::Insert(op) => self.apply_insert(op),
|
||||
DocumentOperation::Update(op) => self.apply_update(op),
|
||||
DocumentOperation::Delete(op) => self.apply_delete(op),
|
||||
@ -106,12 +106,18 @@ impl DocumentTree {
|
||||
let last_index = op.path.0[op.path.0.len() - 1];
|
||||
let parent_node = self.node_at_path(&Position(parent_path.to_vec()));
|
||||
if let Some(parent_node) = parent_node {
|
||||
self.insert_child_at_index(parent_node, last_index, &op.nodes);
|
||||
let mut inserted_nodes = Vec::new();
|
||||
|
||||
for node in &op.nodes {
|
||||
inserted_nodes.push(self.arena.new_node(node.clone()));
|
||||
}
|
||||
|
||||
self.insert_child_at_index(parent_node, last_index, &inserted_nodes);
|
||||
}
|
||||
}
|
||||
|
||||
fn insert_child_at_index(&mut self, parent: NodeId, index: usize, insert_children: &[NodeId]) {
|
||||
if index == 0 && insert_children.len() == 0 {
|
||||
if index == 0 && parent.children(&self.arena).next().is_none() {
|
||||
for id in insert_children {
|
||||
parent.append(*id, &mut self.arena);
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::core::document::position::Position;
|
||||
use crate::core::{NodeAttributes, TextDelta};
|
||||
use indextree::NodeId;
|
||||
use crate::core::{NodeAttributes, NodeData, TextDelta};
|
||||
|
||||
pub enum DocumentOperation {
|
||||
Insert(InsertOperation),
|
||||
@ -36,7 +35,7 @@ impl DocumentOperation {
|
||||
|
||||
pub struct InsertOperation {
|
||||
pub path: Position,
|
||||
pub nodes: Vec<NodeId>,
|
||||
pub nodes: Vec<NodeData>,
|
||||
}
|
||||
|
||||
pub struct UpdateOperation {
|
||||
@ -47,7 +46,7 @@ pub struct UpdateOperation {
|
||||
|
||||
pub struct DeleteOperation {
|
||||
pub path: Position,
|
||||
pub nodes: Vec<NodeId>,
|
||||
pub nodes: Vec<NodeData>,
|
||||
}
|
||||
|
||||
pub struct TextEditOperation {
|
||||
|
@ -9,4 +9,5 @@ pub use attributes::*;
|
||||
pub use document::*;
|
||||
pub use document_operation::*;
|
||||
pub use node::*;
|
||||
pub use position::*;
|
||||
pub use transaction::*;
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::core::{NodeAttributes, TextDelta};
|
||||
use std::cell::RefCell;
|
||||
use crate::core::{TextDelta, NodeAttributes};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct NodeData {
|
||||
pub node_type: String,
|
||||
pub attributes: RefCell<NodeAttributes>,
|
||||
|
@ -1,17 +1,14 @@
|
||||
use crate::core::{DocumentOperation, DocumentTree};
|
||||
use crate::core::document::position::Position;
|
||||
use crate::core::{DeleteOperation, DocumentOperation, DocumentTree, InsertOperation, NodeData};
|
||||
|
||||
pub struct Transaction {
|
||||
pub operations: Vec<DocumentOperation>,
|
||||
}
|
||||
|
||||
impl Transaction {
|
||||
|
||||
fn new(operations: Vec<DocumentOperation>) -> Transaction {
|
||||
Transaction {
|
||||
operations,
|
||||
}
|
||||
Transaction { operations }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub struct TransactionBuilder<'a> {
|
||||
@ -23,17 +20,42 @@ impl<'a> TransactionBuilder<'a> {
|
||||
pub fn new(document: &'a DocumentTree) -> TransactionBuilder {
|
||||
TransactionBuilder {
|
||||
document,
|
||||
operations: Vec::new()
|
||||
operations: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_nodes(&mut self, path: &Position, nodes: &[NodeData]) {
|
||||
self.push(DocumentOperation::Insert(InsertOperation {
|
||||
path: path.clone(),
|
||||
nodes: nodes.to_vec(),
|
||||
}));
|
||||
}
|
||||
|
||||
pub fn delete_node(&mut self, path: &Position) {
|
||||
self.delete_nodes(path, 1);
|
||||
}
|
||||
|
||||
pub fn delete_nodes(&mut self, path: &Position, length: usize) {
|
||||
let mut node = self.document.node_at_path(path).unwrap();
|
||||
let mut deleted_nodes: Vec<NodeData> = Vec::new();
|
||||
|
||||
for _ in 0..length {
|
||||
let data = self.document.arena.get(node).unwrap();
|
||||
deleted_nodes.push(data.get().clone());
|
||||
node = node.following_siblings(&self.document.arena).next().unwrap();
|
||||
}
|
||||
|
||||
self.operations.push(DocumentOperation::Delete(DeleteOperation {
|
||||
path: path.clone(),
|
||||
nodes: deleted_nodes,
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn push(&mut self, op: DocumentOperation) {
|
||||
self.operations.push(op);
|
||||
}
|
||||
|
||||
pub fn finalize(self) -> Transaction {
|
||||
Transaction {
|
||||
operations: self.operations,
|
||||
}
|
||||
Transaction::new(self.operations)
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use lib_ot::core::{DocumentTree, TransactionBuilder};
|
||||
use lib_ot::core::{DocumentTree, NodeData, Position, TransactionBuilder};
|
||||
|
||||
#[test]
|
||||
fn main() {
|
||||
@ -9,7 +9,8 @@ fn main() {
|
||||
#[test]
|
||||
fn test_documents() {
|
||||
let mut document = DocumentTree::new();
|
||||
let tb = TransactionBuilder::new(&document);
|
||||
let mut tb = TransactionBuilder::new(&document);
|
||||
tb.insert_nodes(&Position(vec![0]), &vec![NodeData::new("type")]);
|
||||
let transaction = tb.finalize();
|
||||
document.apply(transaction);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user