forked from rojo-rbx/rojo
Track instance changes inside rbx_snapshot
This commit is contained in:
@@ -16,13 +16,19 @@ use crate::{
|
|||||||
rbx_snapshot::{RbxSnapshotInstance, reify_root, reconcile_subtree},
|
rbx_snapshot::{RbxSnapshotInstance, reify_root, reconcile_subtree},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
pub struct InstanceChanges {
|
pub struct InstanceChanges {
|
||||||
pub added: HashSet<RbxId>,
|
pub added: HashSet<RbxId>,
|
||||||
pub removed: HashSet<RbxId>,
|
pub removed: HashSet<RbxId>,
|
||||||
pub updated: 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 {
|
pub struct RbxSession {
|
||||||
tree: RbxTree,
|
tree: RbxTree,
|
||||||
paths_to_node_ids: PathMap<RbxId>,
|
paths_to_node_ids: PathMap<RbxId>,
|
||||||
@@ -67,7 +73,9 @@ impl RbxSession {
|
|||||||
|
|
||||||
let snapshot = snapshot_instances_from_imfs(&imfs, &closest_path)
|
let snapshot = snapshot_instances_from_imfs(&imfs, &closest_path)
|
||||||
.expect("Could not generate instance snapshot");
|
.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) {
|
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(&[
|
self.message_queue.push_messages(&[changes]);
|
||||||
InstanceChanges {
|
|
||||||
added: HashSet::new(),
|
|
||||||
removed: removed_ids,
|
|
||||||
updated: HashSet::new(),
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn path_renamed(&mut self, from_path: &Path, to_path: &Path) {
|
pub fn path_renamed(&mut self, from_path: &Path, to_path: &Path) {
|
||||||
@@ -148,7 +154,9 @@ fn construct_initial_tree(
|
|||||||
&project.tree,
|
&project.tree,
|
||||||
);
|
);
|
||||||
|
|
||||||
reify_root(&snapshot)
|
let mut changes = InstanceChanges::default();
|
||||||
|
|
||||||
|
reify_root(&snapshot, &mut changes)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn construct_project_node<'a>(
|
fn construct_project_node<'a>(
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ use std::{
|
|||||||
|
|
||||||
use rbx_tree::{RbxTree, RbxId, RbxInstance, RbxValue};
|
use rbx_tree::{RbxTree, RbxId, RbxInstance, RbxValue};
|
||||||
|
|
||||||
|
use crate::rbx_session::InstanceChanges;
|
||||||
|
|
||||||
pub struct RbxSnapshotInstance<'a> {
|
pub struct RbxSnapshotInstance<'a> {
|
||||||
pub name: Cow<'a, str>,
|
pub name: Cow<'a, str>,
|
||||||
pub class_name: Cow<'a, str>,
|
pub class_name: Cow<'a, str>,
|
||||||
@@ -15,30 +17,37 @@ pub struct RbxSnapshotInstance<'a> {
|
|||||||
pub source_path: Option<PathBuf>,
|
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 instance = reify_core(snapshot);
|
||||||
let mut tree = RbxTree::new(instance);
|
let mut tree = RbxTree::new(instance);
|
||||||
let root_id = tree.get_root_id();
|
let root_id = tree.get_root_id();
|
||||||
|
|
||||||
|
changes.added.insert(root_id);
|
||||||
|
|
||||||
for child in &snapshot.children {
|
for child in &snapshot.children {
|
||||||
reify_subtree(child, &mut tree, root_id);
|
reify_subtree(child, &mut tree, root_id, changes);
|
||||||
}
|
}
|
||||||
|
|
||||||
tree
|
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 instance = reify_core(snapshot);
|
||||||
let id = tree.insert_instance(instance, parent_id);
|
let id = tree.insert_instance(instance, parent_id);
|
||||||
|
|
||||||
|
changes.added.insert(id);
|
||||||
|
|
||||||
for child in &snapshot.children {
|
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) {
|
pub fn reconcile_subtree(tree: &mut RbxTree, id: RbxId, snapshot: &RbxSnapshotInstance, changes: &mut InstanceChanges) {
|
||||||
reconcile_instance_properties(tree.get_instance_mut(id).unwrap(), snapshot);
|
if reconcile_instance_properties(tree.get_instance_mut(id).unwrap(), snapshot) {
|
||||||
reconcile_instance_children(tree, id, snapshot);
|
changes.updated.insert(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
reconcile_instance_children(tree, id, snapshot, changes);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reify_core(snapshot: &RbxSnapshotInstance) -> RbxInstance {
|
fn reify_core(snapshot: &RbxSnapshotInstance) -> RbxInstance {
|
||||||
@@ -114,8 +123,12 @@ fn reconcile_instance_properties(instance: &mut RbxInstance, snapshot: &RbxSnaps
|
|||||||
has_diffs
|
has_diffs
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reconcile_instance_children(tree: &mut RbxTree, id: RbxId, snapshot: &RbxSnapshotInstance) {
|
fn reconcile_instance_children(
|
||||||
// TODO: enumerate and match up children, update props, construct and delete IDs
|
tree: &mut RbxTree,
|
||||||
|
id: RbxId,
|
||||||
|
snapshot: &RbxSnapshotInstance,
|
||||||
|
changes: &mut InstanceChanges
|
||||||
|
) {
|
||||||
let children_ids = tree.get_instance(id).unwrap().get_children_ids().to_vec();
|
let children_ids = tree.get_instance(id).unwrap().get_children_ids().to_vec();
|
||||||
let child_count = children_ids.len().max(snapshot.children.len());
|
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 {
|
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 {
|
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 {
|
for (child_id, child_snapshot) in &children_to_update {
|
||||||
reconcile_subtree(tree, *child_id, child_snapshot);
|
reconcile_subtree(tree, *child_id, child_snapshot, changes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user