Track instance changes inside rbx_snapshot

This commit is contained in:
Lucien Greathouse
2018-12-17 14:18:32 -08:00
parent 57442a4848
commit 8fadafcd24
2 changed files with 48 additions and 23 deletions

View File

@@ -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<RbxId>,
pub removed: HashSet<RbxId>,
pub updated: HashSet<RbxId>,
}
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<RbxId>,
@@ -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<RbxId> = 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>(

View File

@@ -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<PathBuf>,
}
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);
}
}