From 8fadafcd24720102870115287cff4e655df0ef5a Mon Sep 17 00:00:00 2001 From: Lucien Greathouse Date: Mon, 17 Dec 2018 14:18:32 -0800 Subject: [PATCH] Track instance changes inside rbx_snapshot --- server/src/rbx_session.rs | 30 ++++++++++++++++++---------- server/src/rbx_snapshot.rs | 41 +++++++++++++++++++++++++++----------- 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/server/src/rbx_session.rs b/server/src/rbx_session.rs index 1d4b7855..08ffb590 100644 --- a/server/src/rbx_session.rs +++ b/server/src/rbx_session.rs @@ -16,13 +16,19 @@ use crate::{ rbx_snapshot::{RbxSnapshotInstance, reify_root, reconcile_subtree}, }; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct InstanceChanges { pub added: HashSet, pub removed: HashSet, pub updated: HashSet, } +impl InstanceChanges { + pub fn is_empty(&self) -> bool { + self.added.is_empty() && self.removed.is_empty() && self.updated.is_empty() + } +} + pub struct RbxSession { tree: RbxTree, paths_to_node_ids: PathMap, @@ -67,7 +73,9 @@ impl RbxSession { let snapshot = snapshot_instances_from_imfs(&imfs, &closest_path) .expect("Could not generate instance snapshot"); - reconcile_subtree(&mut self.tree, instance_id, &snapshot); + + let mut changes = InstanceChanges::default(); + reconcile_subtree(&mut self.tree, instance_id, &snapshot, &mut changes); } pub fn path_created(&mut self, path: &Path) { @@ -108,15 +116,13 @@ impl RbxSession { }, }; - let removed_ids: HashSet = removed_subtree.iter_all_ids().collect(); + let changes = InstanceChanges { + added: HashSet::new(), + removed: removed_subtree.iter_all_ids().collect(), + updated: HashSet::new(), + }; - self.message_queue.push_messages(&[ - InstanceChanges { - added: HashSet::new(), - removed: removed_ids, - updated: HashSet::new(), - } - ]); + self.message_queue.push_messages(&[changes]); } pub fn path_renamed(&mut self, from_path: &Path, to_path: &Path) { @@ -148,7 +154,9 @@ fn construct_initial_tree( &project.tree, ); - reify_root(&snapshot) + let mut changes = InstanceChanges::default(); + + reify_root(&snapshot, &mut changes) } fn construct_project_node<'a>( diff --git a/server/src/rbx_snapshot.rs b/server/src/rbx_snapshot.rs index 5d226fda..4a45afd0 100644 --- a/server/src/rbx_snapshot.rs +++ b/server/src/rbx_snapshot.rs @@ -7,6 +7,8 @@ use std::{ use rbx_tree::{RbxTree, RbxId, RbxInstance, RbxValue}; +use crate::rbx_session::InstanceChanges; + pub struct RbxSnapshotInstance<'a> { pub name: Cow<'a, str>, pub class_name: Cow<'a, str>, @@ -15,30 +17,37 @@ pub struct RbxSnapshotInstance<'a> { pub source_path: Option, } -pub fn reify_root(snapshot: &RbxSnapshotInstance) -> RbxTree { +pub fn reify_root(snapshot: &RbxSnapshotInstance, changes: &mut InstanceChanges) -> RbxTree { let instance = reify_core(snapshot); let mut tree = RbxTree::new(instance); let root_id = tree.get_root_id(); + changes.added.insert(root_id); + for child in &snapshot.children { - reify_subtree(child, &mut tree, root_id); + reify_subtree(child, &mut tree, root_id, changes); } tree } -pub fn reify_subtree(snapshot: &RbxSnapshotInstance, tree: &mut RbxTree, parent_id: RbxId) { +pub fn reify_subtree(snapshot: &RbxSnapshotInstance, tree: &mut RbxTree, parent_id: RbxId, changes: &mut InstanceChanges) { let instance = reify_core(snapshot); let id = tree.insert_instance(instance, parent_id); + changes.added.insert(id); + for child in &snapshot.children { - reify_subtree(child, tree, id); + reify_subtree(child, tree, id, changes); } } -pub fn reconcile_subtree(tree: &mut RbxTree, id: RbxId, snapshot: &RbxSnapshotInstance) { - reconcile_instance_properties(tree.get_instance_mut(id).unwrap(), snapshot); - reconcile_instance_children(tree, id, snapshot); +pub fn reconcile_subtree(tree: &mut RbxTree, id: RbxId, snapshot: &RbxSnapshotInstance, changes: &mut InstanceChanges) { + if reconcile_instance_properties(tree.get_instance_mut(id).unwrap(), snapshot) { + changes.updated.insert(id); + } + + reconcile_instance_children(tree, id, snapshot, changes); } fn reify_core(snapshot: &RbxSnapshotInstance) -> RbxInstance { @@ -114,8 +123,12 @@ fn reconcile_instance_properties(instance: &mut RbxInstance, snapshot: &RbxSnaps has_diffs } -fn reconcile_instance_children(tree: &mut RbxTree, id: RbxId, snapshot: &RbxSnapshotInstance) { - // TODO: enumerate and match up children, update props, construct and delete IDs +fn reconcile_instance_children( + tree: &mut RbxTree, + id: RbxId, + snapshot: &RbxSnapshotInstance, + changes: &mut InstanceChanges +) { let children_ids = tree.get_instance(id).unwrap().get_children_ids().to_vec(); let child_count = children_ids.len().max(snapshot.children.len()); @@ -144,14 +157,18 @@ fn reconcile_instance_children(tree: &mut RbxTree, id: RbxId, snapshot: &RbxSnap } for child_snapshot in &children_to_add { - reify_subtree(child_snapshot, tree, id); + reify_subtree(child_snapshot, tree, id, changes); } for child_id in &children_to_remove { - tree.remove_instance(*child_id); + if let Some(subtree) = tree.remove_instance(*child_id) { + for id in subtree.iter_all_ids() { + changes.removed.insert(id); + } + } } for (child_id, child_snapshot) in &children_to_update { - reconcile_subtree(tree, *child_id, child_snapshot); + reconcile_subtree(tree, *child_id, child_snapshot, changes); } } \ No newline at end of file