mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-20 20:55:50 +00:00
Track instance changes inside rbx_snapshot
This commit is contained in:
@@ -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>(
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user