From 52f01da40069c05fab92cebf8ad58a1ca762c319 Mon Sep 17 00:00:00 2001 From: Lucien Greathouse Date: Wed, 12 Dec 2018 23:11:59 -0800 Subject: [PATCH] Flesh out reconciler routine --- server/src/rbx_session.rs | 10 +++--- server/src/rbx_snapshot.rs | 69 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/server/src/rbx_session.rs b/server/src/rbx_session.rs index a6028cb6..c697ee7f 100644 --- a/server/src/rbx_session.rs +++ b/server/src/rbx_session.rs @@ -18,7 +18,7 @@ use crate::{ pub struct RbxSession { tree: RbxTree, - path_id_tree: PathMap, + paths_to_node_ids: PathMap, ids_to_project_paths: HashMap, message_queue: Arc, imfs: Arc>, @@ -33,12 +33,12 @@ impl RbxSession { }; // TODO: Restore these? - let path_id_tree = PathMap::new(); + let paths_to_node_ids = PathMap::new(); let ids_to_project_paths = HashMap::new(); RbxSession { tree, - path_id_tree, + paths_to_node_ids, ids_to_project_paths, message_queue, imfs, @@ -47,7 +47,7 @@ impl RbxSession { } fn path_created_or_updated(&mut self, path: &Path) { - if let Some(instance_id) = self.path_id_tree.get(path) { + if let Some(instance_id) = self.paths_to_node_ids.get(path) { // TODO: Replace instance with ID `instance_id` with new instance } @@ -81,7 +81,7 @@ impl RbxSession { pub fn path_removed(&mut self, path: &Path) { info!("Path removed: {}", path.display()); - let instance_id = match self.path_id_tree.remove(path) { + let instance_id = match self.paths_to_node_ids.remove(path) { Some(id) => id, None => return, }; diff --git a/server/src/rbx_snapshot.rs b/server/src/rbx_snapshot.rs index 05654cad..28fb0137 100644 --- a/server/src/rbx_snapshot.rs +++ b/server/src/rbx_snapshot.rs @@ -64,4 +64,73 @@ fn reify_child(snapshot: &RbxSnapshotInstance, tree: &mut RbxTree, parent_id: Rb for child in &snapshot.children { reify_child(child, tree, id); } +} + +fn reconcile_instance_properties(instance: &mut RbxInstance, snapshot: &RbxSnapshotInstance) -> bool { + let mut has_diffs = false; + + if instance.name != snapshot.name { + instance.name = snapshot.name.to_string(); + has_diffs = true; + } + + if instance.class_name != snapshot.class_name { + instance.class_name = snapshot.class_name.to_string(); + has_diffs = true; + } + + let mut property_updates = HashMap::new(); + + for (key, instance_value) in &instance.properties { + match snapshot.properties.get(key) { + Some(snapshot_value) => { + if &snapshot_value.to_rbx_value() != instance_value { + property_updates.insert(key.clone(), Some(snapshot_value.clone())); + } + }, + None => { + property_updates.insert(key.clone(), None); + }, + } + } + + for (key, snapshot_value) in &snapshot.properties { + if property_updates.contains_key(key) { + continue; + } + + match instance.properties.get(key) { + Some(instance_value) => { + if &snapshot_value.to_rbx_value() != instance_value { + property_updates.insert(key.clone(), Some(snapshot_value.clone())); + } + }, + None => { + property_updates.insert(key.clone(), Some(snapshot_value.clone())); + }, + } + } + + has_diffs = has_diffs || !property_updates.is_empty(); + + for (key, change) in property_updates.drain() { + match change { + Some(value) => instance.properties.insert(key, value.to_rbx_value()), + None => instance.properties.remove(&key), + }; + } + + has_diffs +} + +fn reconcile_instance_children(tree: &mut RbxTree, id: RbxId, snapshot: &RbxSnapshotInstance, changed_ids: &mut Vec) { + // TODO: enumerate and match up children, update props, construct and delete IDs +} + +pub fn reconcile_subtree(tree: &mut RbxTree, id: RbxId, snapshot: &RbxSnapshotInstance, changed_ids: &mut Vec) { + if reconcile_instance_properties(tree.get_instance_mut().unwrap(), snapshot) { + changed_ids.push(id); + } + + reconcile_instance_children(tree, id, snapshot, changed_ids); } \ No newline at end of file