diff --git a/Cargo.lock b/Cargo.lock index 12d98bff..9b25678f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1034,12 +1034,12 @@ dependencies = [ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "lz4 1.23.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rbx_dom_weak 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rbx_dom_weak 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rbx_dom_weak" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1055,7 +1055,7 @@ dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rbx_dom_weak 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rbx_dom_weak 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1068,7 +1068,7 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rbx_dom_weak 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rbx_dom_weak 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1200,7 +1200,7 @@ dependencies = [ "paste 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rbx_binary 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rbx_dom_weak 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rbx_dom_weak 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rbx_reflection 2.0.374 (registry+https://github.com/rust-lang/crates.io-index)", "rbx_xml 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1874,7 +1874,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" "checksum rbx_binary 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b147f236284747ac1b4643476265dd36b402877d97adb7cbd0fafc1d247de0a5" -"checksum rbx_dom_weak 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e31ec3223caeb1a57254a8a10b33614a2d457517be01ef93694f83d995833b04" +"checksum rbx_dom_weak 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f2a2ba185abc08fa3fce3de6dc5446ccf82b759583aee20fc07fced859dcc31f" "checksum rbx_reflection 2.0.374 (registry+https://github.com/rust-lang/crates.io-index)" = "8a826ff869b33b54db727f9776f1dc7a8a779791f5a46ddd4941b8334bf909fe" "checksum rbx_xml 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a240c155684b744c4985f283702b61f6ab0a2d4479694051d875844632c9f454" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" diff --git a/server/Cargo.toml b/server/Cargo.toml index e005a52d..d7732f3d 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -30,7 +30,7 @@ log = "0.4" maplit = "1.0.1" notify = "4.0" rbx_binary = "0.4.0" -rbx_dom_weak = "1.2.0" +rbx_dom_weak = "1.3.0" rbx_xml = "0.5.0" rbx_reflection = "2.0.374" regex = "1.0" diff --git a/server/src/snapshot_reconciler.rs b/server/src/snapshot_reconciler.rs index 2b52ca52..baaa3309 100644 --- a/server/src/snapshot_reconciler.rs +++ b/server/src/snapshot_reconciler.rs @@ -153,7 +153,7 @@ pub fn reify_subtree( instance_per_path: &mut PathMap>, metadata_per_instance: &mut HashMap, changes: &mut InstanceChanges, -) { +) -> RbxId { let instance = reify_core(snapshot); let id = tree.insert_instance(instance, parent_id); @@ -164,6 +164,8 @@ pub fn reify_subtree( for child in &snapshot.children { reify_subtree(child, tree, id, instance_per_path, metadata_per_instance, changes); } + + id } fn reify_metadata( @@ -222,6 +224,9 @@ fn reify_core(snapshot: &RbxSnapshotInstance) -> RbxInstanceProperties { instance } +/// Updates the given instance to match the properties defined on the snapshot. +/// +/// Returns whether any changes were applied. fn reconcile_instance_properties(instance: &mut RbxInstanceProperties, snapshot: &RbxSnapshotInstance) -> bool { let mut has_diffs = false; @@ -279,6 +284,8 @@ fn reconcile_instance_properties(instance: &mut RbxInstanceProperties, snapshot: has_diffs } +/// Updates the children of the instance in the `RbxTree` to match the children +/// of the `RbxSnapshotInstance`. Order will be updated to match. fn reconcile_instance_children( tree: &mut RbxTree, id: RbxId, @@ -287,12 +294,21 @@ fn reconcile_instance_children( metadata_per_instance: &mut HashMap, changes: &mut InstanceChanges, ) { - let mut visited_snapshot_indices = HashSet::new(); - - let mut children_to_update: Vec<(RbxId, &RbxSnapshotInstance)> = Vec::new(); - let mut children_to_add: Vec<&RbxSnapshotInstance> = Vec::new(); + // These lists are kept so that we can apply all the changes we figure out + let mut children_to_maybe_update: Vec<(RbxId, &RbxSnapshotInstance)> = Vec::new(); + let mut children_to_add: Vec<(usize, &RbxSnapshotInstance)> = Vec::new(); let mut children_to_remove: Vec = Vec::new(); + // This map is used once we're done mutating children to sort them according + // to the order specified in the snapshot. Without it, a snapshot with a new + // child prepended will cause the RbxTree instance to have out-of-order + // children and would make Rojo non-deterministic. + let mut ids_to_snapshot_indices = HashMap::new(); + + // Since we have to enumerate the children of both the RbxTree instance and + // our snapshot, we keep a set of the snapshot children we've seen. + let mut visited_snapshot_indices = vec![false; snapshot.children.len()]; + let children_ids = tree.get_instance(id).unwrap().get_children_ids(); // Find all instances that were removed or updated, which we derive by @@ -303,7 +319,7 @@ fn reconcile_instance_children( // Locate a matching snapshot for this instance let mut matching_snapshot = None; for (snapshot_index, child_snapshot) in snapshot.children.iter().enumerate() { - if visited_snapshot_indices.contains(&snapshot_index) { + if visited_snapshot_indices[snapshot_index] { continue; } @@ -311,7 +327,8 @@ fn reconcile_instance_children( // similar. This heuristic is similar to React's reconciliation // strategy. if child_snapshot.name == child_instance.name { - visited_snapshot_indices.insert(snapshot_index); + ids_to_snapshot_indices.insert(child_id, snapshot_index); + visited_snapshot_indices[snapshot_index] = true; matching_snapshot = Some(child_snapshot); break; } @@ -319,26 +336,23 @@ fn reconcile_instance_children( match matching_snapshot { Some(child_snapshot) => { - children_to_update.push((child_instance.get_id(), child_snapshot)); - }, + children_to_maybe_update.push((child_instance.get_id(), child_snapshot)); + } None => { children_to_remove.push(child_instance.get_id()); - }, + } } } // Find all instancs that were added, which is just the snapshots we didn't // match up to existing instances above. for (snapshot_index, child_snapshot) in snapshot.children.iter().enumerate() { - if !visited_snapshot_indices.contains(&snapshot_index) { - children_to_add.push(child_snapshot); + if !visited_snapshot_indices[snapshot_index] { + children_to_add.push((snapshot_index, child_snapshot)); } } - for child_snapshot in &children_to_add { - reify_subtree(child_snapshot, tree, id, instance_per_path, metadata_per_instance, changes); - } - + // Apply all of our removals we gathered from our diff for child_id in &children_to_remove { if let Some(subtree) = tree.remove_instance(*child_id) { for id in subtree.iter_all_ids() { @@ -348,7 +362,18 @@ fn reconcile_instance_children( } } - for (child_id, child_snapshot) in &children_to_update { + // Apply all of our children additions + for (snapshot_index, child_snapshot) in &children_to_add { + let id = reify_subtree(child_snapshot, tree, id, instance_per_path, metadata_per_instance, changes); + ids_to_snapshot_indices.insert(id, *snapshot_index); + } + + // Apply any updates that might have updates + for (child_id, child_snapshot) in &children_to_maybe_update { reconcile_subtree(tree, *child_id, child_snapshot, instance_per_path, metadata_per_instance, changes); } + + // Apply the sort mapping defined by ids_to_snapshot_indices above + let instance = tree.get_instance_mut(id).unwrap(); + instance.sort_children_unstable_by_key(|id| ids_to_snapshot_indices.get(&id).unwrap()); } \ No newline at end of file diff --git a/server/tests/snapshot_reconciler.rs b/server/tests/snapshot_reconciler.rs index 4888e917..34dec829 100644 --- a/server/tests/snapshot_reconciler.rs +++ b/server/tests/snapshot_reconciler.rs @@ -11,10 +11,7 @@ use librojo::{ use test_util::tree::trees_equal; -// TODO: Snapshot application isn't communicative right now with the current -// snapshot reconciler. In practice this mostly isn't a problem, but presents -// a problem trying to rely on determinism to make snapshot tests. -// #[test] +#[test] fn patch_communicativity() { let base_tree = RbxTree::new(RbxInstanceProperties { name: "DataModel".into(), diff --git a/test-projects/multi_partition_game/initial.tree.json b/test-projects/multi_partition_game/initial.tree.json index b6a2208c..9b5d5f08 100644 --- a/test-projects/multi_partition_game/initial.tree.json +++ b/test-projects/multi_partition_game/initial.tree.json @@ -1,6 +1,6 @@ { "instances": { - "8d44bb30-db3c-4366-a6c5-633bd1441885": { + "00f207b1-fc18-4088-a45e-caf8cd98f5dd": { "Name": "main", "ClassName": "ModuleScript", "Properties": { @@ -9,69 +9,32 @@ "Value": "-- hello, from a/main.lua" } }, - "Id": "8d44bb30-db3c-4366-a6c5-633bd1441885", + "Id": "00f207b1-fc18-4088-a45e-caf8cd98f5dd", "Children": [], - "Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce" + "Parent": "14fed1a3-ba97-46a6-ae93-ac26bd9471df" }, - "b1c9928c-bf11-427f-90eb-b672c811d859": { + "14fed1a3-ba97-46a6-ae93-ac26bd9471df": { + "Name": "Ack", + "ClassName": "Folder", + "Properties": {}, + "Id": "14fed1a3-ba97-46a6-ae93-ac26bd9471df", + "Children": [ + "c55fd55c-258e-4a93-a63a-ea243038c9b9", + "00f207b1-fc18-4088-a45e-caf8cd98f5dd" + ], + "Parent": "99eefe5f-ef74-49e6-8a8b-c833e00ca56b" + }, + "c910510c-37a8-4fd8-ae41-01169ccb739c": { "Name": "Bar", "ClassName": "Folder", "Properties": {}, - "Id": "b1c9928c-bf11-427f-90eb-b672c811d859", + "Id": "c910510c-37a8-4fd8-ae41-01169ccb739c", "Children": [ - "8d690a2a-e987-4c86-b9ac-18e6d3a98503" + "71a95983-c856-4cf2-aee6-bd8a523e80e4" ], - "Parent": "9f141826-14c2-492b-b360-2558712f0c08" + "Parent": "99eefe5f-ef74-49e6-8a8b-c833e00ca56b" }, - "645ba594-4482-441f-9f41-5bb9c444405b": { - "Name": "multi_partition_game", - "ClassName": "DataModel", - "Properties": {}, - "Id": "645ba594-4482-441f-9f41-5bb9c444405b", - "Children": [ - "b1298bcc-e370-44a6-9ef4-fbefa290124c", - "9f141826-14c2-492b-b360-2558712f0c08" - ], - "Parent": null - }, - "9f141826-14c2-492b-b360-2558712f0c08": { - "Name": "ReplicatedStorage", - "ClassName": "ReplicatedStorage", - "Properties": {}, - "Id": "9f141826-14c2-492b-b360-2558712f0c08", - "Children": [ - "1aafa29b-bdca-40a0-a677-7ead327b84ce", - "b1c9928c-bf11-427f-90eb-b672c811d859" - ], - "Parent": "645ba594-4482-441f-9f41-5bb9c444405b" - }, - "8d690a2a-e987-4c86-b9ac-18e6d3a98503": { - "Name": "something", - "ClassName": "ModuleScript", - "Properties": { - "Source": { - "Type": "String", - "Value": "-- b/something.lua" - } - }, - "Id": "8d690a2a-e987-4c86-b9ac-18e6d3a98503", - "Children": [], - "Parent": "b1c9928c-bf11-427f-90eb-b672c811d859" - }, - "b1298bcc-e370-44a6-9ef4-fbefa290124c": { - "Name": "HttpService", - "ClassName": "HttpService", - "Properties": { - "HttpEnabled": { - "Type": "Bool", - "Value": true - } - }, - "Id": "b1298bcc-e370-44a6-9ef4-fbefa290124c", - "Children": [], - "Parent": "645ba594-4482-441f-9f41-5bb9c444405b" - }, - "54f2f276-964f-4c60-87d8-5fb2209c97c9": { + "c55fd55c-258e-4a93-a63a-ea243038c9b9": { "Name": "foo", "ClassName": "StringValue", "Properties": { @@ -80,25 +43,153 @@ "Value": "Hello world, from a/foo.txt" } }, - "Id": "54f2f276-964f-4c60-87d8-5fb2209c97c9", + "Id": "c55fd55c-258e-4a93-a63a-ea243038c9b9", "Children": [], - "Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce" + "Parent": "14fed1a3-ba97-46a6-ae93-ac26bd9471df" }, - "1aafa29b-bdca-40a0-a677-7ead327b84ce": { - "Name": "Ack", - "ClassName": "Folder", + "71a95983-c856-4cf2-aee6-bd8a523e80e4": { + "Name": "something", + "ClassName": "ModuleScript", + "Properties": { + "Source": { + "Type": "String", + "Value": "-- b/something.lua" + } + }, + "Id": "71a95983-c856-4cf2-aee6-bd8a523e80e4", + "Children": [], + "Parent": "c910510c-37a8-4fd8-ae41-01169ccb739c" + }, + "3b5af13f-c997-4009-915c-0810b0e83032": { + "Name": "multi_partition_game", + "ClassName": "DataModel", "Properties": {}, - "Id": "1aafa29b-bdca-40a0-a677-7ead327b84ce", + "Id": "3b5af13f-c997-4009-915c-0810b0e83032", "Children": [ - "54f2f276-964f-4c60-87d8-5fb2209c97c9", - "8d44bb30-db3c-4366-a6c5-633bd1441885" + "bf8e2d4f-33a0-42a0-8168-1b62d6ac050c", + "99eefe5f-ef74-49e6-8a8b-c833e00ca56b" ], - "Parent": "9f141826-14c2-492b-b360-2558712f0c08" + "Parent": null + }, + "bf8e2d4f-33a0-42a0-8168-1b62d6ac050c": { + "Name": "HttpService", + "ClassName": "HttpService", + "Properties": { + "HttpEnabled": { + "Type": "Bool", + "Value": true + } + }, + "Id": "bf8e2d4f-33a0-42a0-8168-1b62d6ac050c", + "Children": [], + "Parent": "3b5af13f-c997-4009-915c-0810b0e83032" + }, + "99eefe5f-ef74-49e6-8a8b-c833e00ca56b": { + "Name": "ReplicatedStorage", + "ClassName": "ReplicatedStorage", + "Properties": {}, + "Id": "99eefe5f-ef74-49e6-8a8b-c833e00ca56b", + "Children": [ + "14fed1a3-ba97-46a6-ae93-ac26bd9471df", + "c910510c-37a8-4fd8-ae41-01169ccb739c" + ], + "Parent": "3b5af13f-c997-4009-915c-0810b0e83032" } }, - "root_id": "645ba594-4482-441f-9f41-5bb9c444405b", + "root_id": "3b5af13f-c997-4009-915c-0810b0e83032", "metadata": { - "645ba594-4482-441f-9f41-5bb9c444405b": { + "00f207b1-fc18-4088-a45e-caf8cd98f5dd": { + "ignore_unknown_instances": false, + "source_path": "a/main.lua", + "project_definition": null + }, + "bf8e2d4f-33a0-42a0-8168-1b62d6ac050c": { + "ignore_unknown_instances": true, + "source_path": null, + "project_definition": [ + "HttpService", + { + "class_name": "HttpService", + "children": {}, + "properties": { + "HttpEnabled": { + "Type": "Bool", + "Value": true + } + }, + "ignore_unknown_instances": null, + "path": null + } + ] + }, + "14fed1a3-ba97-46a6-ae93-ac26bd9471df": { + "ignore_unknown_instances": false, + "source_path": "a", + "project_definition": [ + "Ack", + { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "a" + } + ] + }, + "c55fd55c-258e-4a93-a63a-ea243038c9b9": { + "ignore_unknown_instances": false, + "source_path": "a/foo.txt", + "project_definition": null + }, + "71a95983-c856-4cf2-aee6-bd8a523e80e4": { + "ignore_unknown_instances": false, + "source_path": "b/something.lua", + "project_definition": null + }, + "c910510c-37a8-4fd8-ae41-01169ccb739c": { + "ignore_unknown_instances": false, + "source_path": "b", + "project_definition": [ + "Bar", + { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "b" + } + ] + }, + "99eefe5f-ef74-49e6-8a8b-c833e00ca56b": { + "ignore_unknown_instances": true, + "source_path": null, + "project_definition": [ + "ReplicatedStorage", + { + "class_name": "ReplicatedStorage", + "children": { + "Ack": { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "a" + }, + "Bar": { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "b" + } + }, + "properties": {}, + "ignore_unknown_instances": null, + "path": null + } + ] + }, + "3b5af13f-c997-4009-915c-0810b0e83032": { "ignore_unknown_instances": true, "source_path": null, "project_definition": [ @@ -146,97 +237,6 @@ "path": null } ] - }, - "1aafa29b-bdca-40a0-a677-7ead327b84ce": { - "ignore_unknown_instances": false, - "source_path": "a", - "project_definition": [ - "Ack", - { - "class_name": null, - "children": {}, - "properties": {}, - "ignore_unknown_instances": null, - "path": "a" - } - ] - }, - "b1c9928c-bf11-427f-90eb-b672c811d859": { - "ignore_unknown_instances": false, - "source_path": "b", - "project_definition": [ - "Bar", - { - "class_name": null, - "children": {}, - "properties": {}, - "ignore_unknown_instances": null, - "path": "b" - } - ] - }, - "54f2f276-964f-4c60-87d8-5fb2209c97c9": { - "ignore_unknown_instances": false, - "source_path": "a/foo.txt", - "project_definition": null - }, - "9f141826-14c2-492b-b360-2558712f0c08": { - "ignore_unknown_instances": true, - "source_path": null, - "project_definition": [ - "ReplicatedStorage", - { - "class_name": "ReplicatedStorage", - "children": { - "Ack": { - "class_name": null, - "children": {}, - "properties": {}, - "ignore_unknown_instances": null, - "path": "a" - }, - "Bar": { - "class_name": null, - "children": {}, - "properties": {}, - "ignore_unknown_instances": null, - "path": "b" - } - }, - "properties": {}, - "ignore_unknown_instances": null, - "path": null - } - ] - }, - "8d44bb30-db3c-4366-a6c5-633bd1441885": { - "ignore_unknown_instances": false, - "source_path": "a/main.lua", - "project_definition": null - }, - "b1298bcc-e370-44a6-9ef4-fbefa290124c": { - "ignore_unknown_instances": true, - "source_path": null, - "project_definition": [ - "HttpService", - { - "class_name": "HttpService", - "children": {}, - "properties": { - "HttpEnabled": { - "Type": "Bool", - "Value": true - } - }, - "ignore_unknown_instances": null, - "path": null - } - ] - }, - "8d690a2a-e987-4c86-b9ac-18e6d3a98503": { - "ignore_unknown_instances": false, - "source_path": "b/something.lua", - "project_definition": null } } } \ No newline at end of file diff --git a/test-projects/multi_partition_game/with_dir.tree.json b/test-projects/multi_partition_game/with_dir.tree.json index 5237c507..c8875416 100644 --- a/test-projects/multi_partition_game/with_dir.tree.json +++ b/test-projects/multi_partition_game/with_dir.tree.json @@ -1,6 +1,14 @@ { "instances": { - "8d44bb30-db3c-4366-a6c5-633bd1441885": { + "b48b369f-5706-4029-9fa6-90651a4910ea": { + "Name": "added", + "ClassName": "Folder", + "Properties": {}, + "Id": "b48b369f-5706-4029-9fa6-90651a4910ea", + "Children": [], + "Parent": "14fed1a3-ba97-46a6-ae93-ac26bd9471df" + }, + "00f207b1-fc18-4088-a45e-caf8cd98f5dd": { "Name": "main", "ClassName": "ModuleScript", "Properties": { @@ -9,77 +17,33 @@ "Value": "-- hello, from a/main.lua" } }, - "Id": "8d44bb30-db3c-4366-a6c5-633bd1441885", + "Id": "00f207b1-fc18-4088-a45e-caf8cd98f5dd", "Children": [], - "Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce" + "Parent": "14fed1a3-ba97-46a6-ae93-ac26bd9471df" }, - "b1c9928c-bf11-427f-90eb-b672c811d859": { + "14fed1a3-ba97-46a6-ae93-ac26bd9471df": { + "Name": "Ack", + "ClassName": "Folder", + "Properties": {}, + "Id": "14fed1a3-ba97-46a6-ae93-ac26bd9471df", + "Children": [ + "b48b369f-5706-4029-9fa6-90651a4910ea", + "c55fd55c-258e-4a93-a63a-ea243038c9b9", + "00f207b1-fc18-4088-a45e-caf8cd98f5dd" + ], + "Parent": "99eefe5f-ef74-49e6-8a8b-c833e00ca56b" + }, + "c910510c-37a8-4fd8-ae41-01169ccb739c": { "Name": "Bar", "ClassName": "Folder", "Properties": {}, - "Id": "b1c9928c-bf11-427f-90eb-b672c811d859", + "Id": "c910510c-37a8-4fd8-ae41-01169ccb739c", "Children": [ - "8d690a2a-e987-4c86-b9ac-18e6d3a98503" + "71a95983-c856-4cf2-aee6-bd8a523e80e4" ], - "Parent": "9f141826-14c2-492b-b360-2558712f0c08" + "Parent": "99eefe5f-ef74-49e6-8a8b-c833e00ca56b" }, - "645ba594-4482-441f-9f41-5bb9c444405b": { - "Name": "multi_partition_game", - "ClassName": "DataModel", - "Properties": {}, - "Id": "645ba594-4482-441f-9f41-5bb9c444405b", - "Children": [ - "b1298bcc-e370-44a6-9ef4-fbefa290124c", - "9f141826-14c2-492b-b360-2558712f0c08" - ], - "Parent": null - }, - "9f141826-14c2-492b-b360-2558712f0c08": { - "Name": "ReplicatedStorage", - "ClassName": "ReplicatedStorage", - "Properties": {}, - "Id": "9f141826-14c2-492b-b360-2558712f0c08", - "Children": [ - "1aafa29b-bdca-40a0-a677-7ead327b84ce", - "b1c9928c-bf11-427f-90eb-b672c811d859" - ], - "Parent": "645ba594-4482-441f-9f41-5bb9c444405b" - }, - "8d690a2a-e987-4c86-b9ac-18e6d3a98503": { - "Name": "something", - "ClassName": "ModuleScript", - "Properties": { - "Source": { - "Type": "String", - "Value": "-- b/something.lua" - } - }, - "Id": "8d690a2a-e987-4c86-b9ac-18e6d3a98503", - "Children": [], - "Parent": "b1c9928c-bf11-427f-90eb-b672c811d859" - }, - "b1298bcc-e370-44a6-9ef4-fbefa290124c": { - "Name": "HttpService", - "ClassName": "HttpService", - "Properties": { - "HttpEnabled": { - "Type": "Bool", - "Value": true - } - }, - "Id": "b1298bcc-e370-44a6-9ef4-fbefa290124c", - "Children": [], - "Parent": "645ba594-4482-441f-9f41-5bb9c444405b" - }, - "46353305-8818-48fe-94fd-80cf0c5d974c": { - "Name": "added", - "ClassName": "Folder", - "Properties": {}, - "Id": "46353305-8818-48fe-94fd-80cf0c5d974c", - "Children": [], - "Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce" - }, - "54f2f276-964f-4c60-87d8-5fb2209c97c9": { + "c55fd55c-258e-4a93-a63a-ea243038c9b9": { "Name": "foo", "ClassName": "StringValue", "Properties": { @@ -88,50 +52,67 @@ "Value": "Hello world, from a/foo.txt" } }, - "Id": "54f2f276-964f-4c60-87d8-5fb2209c97c9", + "Id": "c55fd55c-258e-4a93-a63a-ea243038c9b9", "Children": [], - "Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce" + "Parent": "14fed1a3-ba97-46a6-ae93-ac26bd9471df" }, - "1aafa29b-bdca-40a0-a677-7ead327b84ce": { - "Name": "Ack", - "ClassName": "Folder", + "71a95983-c856-4cf2-aee6-bd8a523e80e4": { + "Name": "something", + "ClassName": "ModuleScript", + "Properties": { + "Source": { + "Type": "String", + "Value": "-- b/something.lua" + } + }, + "Id": "71a95983-c856-4cf2-aee6-bd8a523e80e4", + "Children": [], + "Parent": "c910510c-37a8-4fd8-ae41-01169ccb739c" + }, + "3b5af13f-c997-4009-915c-0810b0e83032": { + "Name": "multi_partition_game", + "ClassName": "DataModel", "Properties": {}, - "Id": "1aafa29b-bdca-40a0-a677-7ead327b84ce", + "Id": "3b5af13f-c997-4009-915c-0810b0e83032", "Children": [ - "54f2f276-964f-4c60-87d8-5fb2209c97c9", - "8d44bb30-db3c-4366-a6c5-633bd1441885", - "46353305-8818-48fe-94fd-80cf0c5d974c" + "bf8e2d4f-33a0-42a0-8168-1b62d6ac050c", + "99eefe5f-ef74-49e6-8a8b-c833e00ca56b" ], - "Parent": "9f141826-14c2-492b-b360-2558712f0c08" + "Parent": null + }, + "bf8e2d4f-33a0-42a0-8168-1b62d6ac050c": { + "Name": "HttpService", + "ClassName": "HttpService", + "Properties": { + "HttpEnabled": { + "Type": "Bool", + "Value": true + } + }, + "Id": "bf8e2d4f-33a0-42a0-8168-1b62d6ac050c", + "Children": [], + "Parent": "3b5af13f-c997-4009-915c-0810b0e83032" + }, + "99eefe5f-ef74-49e6-8a8b-c833e00ca56b": { + "Name": "ReplicatedStorage", + "ClassName": "ReplicatedStorage", + "Properties": {}, + "Id": "99eefe5f-ef74-49e6-8a8b-c833e00ca56b", + "Children": [ + "14fed1a3-ba97-46a6-ae93-ac26bd9471df", + "c910510c-37a8-4fd8-ae41-01169ccb739c" + ], + "Parent": "3b5af13f-c997-4009-915c-0810b0e83032" } }, - "root_id": "645ba594-4482-441f-9f41-5bb9c444405b", + "root_id": "3b5af13f-c997-4009-915c-0810b0e83032", "metadata": { - "b1c9928c-bf11-427f-90eb-b672c811d859": { - "ignore_unknown_instances": false, - "source_path": "b", - "project_definition": [ - "Bar", - { - "class_name": null, - "children": {}, - "properties": {}, - "ignore_unknown_instances": null, - "path": "b" - } - ] - }, - "54f2f276-964f-4c60-87d8-5fb2209c97c9": { + "c55fd55c-258e-4a93-a63a-ea243038c9b9": { "ignore_unknown_instances": false, "source_path": "a/foo.txt", "project_definition": null }, - "8d44bb30-db3c-4366-a6c5-633bd1441885": { - "ignore_unknown_instances": false, - "source_path": "a/main.lua", - "project_definition": null - }, - "9f141826-14c2-492b-b360-2558712f0c08": { + "99eefe5f-ef74-49e6-8a8b-c833e00ca56b": { "ignore_unknown_instances": true, "source_path": null, "project_definition": [ @@ -160,7 +141,17 @@ } ] }, - "b1298bcc-e370-44a6-9ef4-fbefa290124c": { + "71a95983-c856-4cf2-aee6-bd8a523e80e4": { + "ignore_unknown_instances": false, + "source_path": "b/something.lua", + "project_definition": null + }, + "00f207b1-fc18-4088-a45e-caf8cd98f5dd": { + "ignore_unknown_instances": false, + "source_path": "a/main.lua", + "project_definition": null + }, + "bf8e2d4f-33a0-42a0-8168-1b62d6ac050c": { "ignore_unknown_instances": true, "source_path": null, "project_definition": [ @@ -179,31 +170,12 @@ } ] }, - "46353305-8818-48fe-94fd-80cf0c5d974c": { + "b48b369f-5706-4029-9fa6-90651a4910ea": { "ignore_unknown_instances": false, "source_path": "a/added", "project_definition": null }, - "1aafa29b-bdca-40a0-a677-7ead327b84ce": { - "ignore_unknown_instances": false, - "source_path": "a", - "project_definition": [ - "Ack", - { - "class_name": null, - "children": {}, - "properties": {}, - "ignore_unknown_instances": null, - "path": "a" - } - ] - }, - "8d690a2a-e987-4c86-b9ac-18e6d3a98503": { - "ignore_unknown_instances": false, - "source_path": "b/something.lua", - "project_definition": null - }, - "645ba594-4482-441f-9f41-5bb9c444405b": { + "3b5af13f-c997-4009-915c-0810b0e83032": { "ignore_unknown_instances": true, "source_path": null, "project_definition": [ @@ -251,6 +223,34 @@ "path": null } ] + }, + "c910510c-37a8-4fd8-ae41-01169ccb739c": { + "ignore_unknown_instances": false, + "source_path": "b", + "project_definition": [ + "Bar", + { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "b" + } + ] + }, + "14fed1a3-ba97-46a6-ae93-ac26bd9471df": { + "ignore_unknown_instances": false, + "source_path": "a", + "project_definition": [ + "Ack", + { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "a" + } + ] } } } \ No newline at end of file diff --git a/test-projects/multi_partition_game/with_moved_dir.tree.json b/test-projects/multi_partition_game/with_moved_dir.tree.json index 4da8884a..4e996829 100644 --- a/test-projects/multi_partition_game/with_moved_dir.tree.json +++ b/test-projects/multi_partition_game/with_moved_dir.tree.json @@ -1,6 +1,14 @@ { "instances": { - "8d44bb30-db3c-4366-a6c5-633bd1441885": { + "866071d6-465a-4b88-8c63-07489d950916": { + "Name": "added", + "ClassName": "Folder", + "Properties": {}, + "Id": "866071d6-465a-4b88-8c63-07489d950916", + "Children": [], + "Parent": "c910510c-37a8-4fd8-ae41-01169ccb739c" + }, + "00f207b1-fc18-4088-a45e-caf8cd98f5dd": { "Name": "main", "ClassName": "ModuleScript", "Properties": { @@ -9,70 +17,33 @@ "Value": "-- hello, from a/main.lua" } }, - "Id": "8d44bb30-db3c-4366-a6c5-633bd1441885", + "Id": "00f207b1-fc18-4088-a45e-caf8cd98f5dd", "Children": [], - "Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce" + "Parent": "14fed1a3-ba97-46a6-ae93-ac26bd9471df" }, - "b1c9928c-bf11-427f-90eb-b672c811d859": { + "14fed1a3-ba97-46a6-ae93-ac26bd9471df": { + "Name": "Ack", + "ClassName": "Folder", + "Properties": {}, + "Id": "14fed1a3-ba97-46a6-ae93-ac26bd9471df", + "Children": [ + "c55fd55c-258e-4a93-a63a-ea243038c9b9", + "00f207b1-fc18-4088-a45e-caf8cd98f5dd" + ], + "Parent": "99eefe5f-ef74-49e6-8a8b-c833e00ca56b" + }, + "c910510c-37a8-4fd8-ae41-01169ccb739c": { "Name": "Bar", "ClassName": "Folder", "Properties": {}, - "Id": "b1c9928c-bf11-427f-90eb-b672c811d859", + "Id": "c910510c-37a8-4fd8-ae41-01169ccb739c", "Children": [ - "8d690a2a-e987-4c86-b9ac-18e6d3a98503", - "a8566e76-0495-45a3-a713-1c59ab39453b" + "866071d6-465a-4b88-8c63-07489d950916", + "71a95983-c856-4cf2-aee6-bd8a523e80e4" ], - "Parent": "9f141826-14c2-492b-b360-2558712f0c08" + "Parent": "99eefe5f-ef74-49e6-8a8b-c833e00ca56b" }, - "645ba594-4482-441f-9f41-5bb9c444405b": { - "Name": "multi_partition_game", - "ClassName": "DataModel", - "Properties": {}, - "Id": "645ba594-4482-441f-9f41-5bb9c444405b", - "Children": [ - "b1298bcc-e370-44a6-9ef4-fbefa290124c", - "9f141826-14c2-492b-b360-2558712f0c08" - ], - "Parent": null - }, - "9f141826-14c2-492b-b360-2558712f0c08": { - "Name": "ReplicatedStorage", - "ClassName": "ReplicatedStorage", - "Properties": {}, - "Id": "9f141826-14c2-492b-b360-2558712f0c08", - "Children": [ - "1aafa29b-bdca-40a0-a677-7ead327b84ce", - "b1c9928c-bf11-427f-90eb-b672c811d859" - ], - "Parent": "645ba594-4482-441f-9f41-5bb9c444405b" - }, - "8d690a2a-e987-4c86-b9ac-18e6d3a98503": { - "Name": "something", - "ClassName": "ModuleScript", - "Properties": { - "Source": { - "Type": "String", - "Value": "-- b/something.lua" - } - }, - "Id": "8d690a2a-e987-4c86-b9ac-18e6d3a98503", - "Children": [], - "Parent": "b1c9928c-bf11-427f-90eb-b672c811d859" - }, - "b1298bcc-e370-44a6-9ef4-fbefa290124c": { - "Name": "HttpService", - "ClassName": "HttpService", - "Properties": { - "HttpEnabled": { - "Type": "Bool", - "Value": true - } - }, - "Id": "b1298bcc-e370-44a6-9ef4-fbefa290124c", - "Children": [], - "Parent": "645ba594-4482-441f-9f41-5bb9c444405b" - }, - "54f2f276-964f-4c60-87d8-5fb2209c97c9": { + "c55fd55c-258e-4a93-a63a-ea243038c9b9": { "Name": "foo", "ClassName": "StringValue", "Properties": { @@ -81,33 +52,158 @@ "Value": "Hello world, from a/foo.txt" } }, - "Id": "54f2f276-964f-4c60-87d8-5fb2209c97c9", + "Id": "c55fd55c-258e-4a93-a63a-ea243038c9b9", "Children": [], - "Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce" + "Parent": "14fed1a3-ba97-46a6-ae93-ac26bd9471df" }, - "a8566e76-0495-45a3-a713-1c59ab39453b": { - "Name": "added", - "ClassName": "Folder", - "Properties": {}, - "Id": "a8566e76-0495-45a3-a713-1c59ab39453b", + "71a95983-c856-4cf2-aee6-bd8a523e80e4": { + "Name": "something", + "ClassName": "ModuleScript", + "Properties": { + "Source": { + "Type": "String", + "Value": "-- b/something.lua" + } + }, + "Id": "71a95983-c856-4cf2-aee6-bd8a523e80e4", "Children": [], - "Parent": "b1c9928c-bf11-427f-90eb-b672c811d859" + "Parent": "c910510c-37a8-4fd8-ae41-01169ccb739c" }, - "1aafa29b-bdca-40a0-a677-7ead327b84ce": { - "Name": "Ack", - "ClassName": "Folder", + "3b5af13f-c997-4009-915c-0810b0e83032": { + "Name": "multi_partition_game", + "ClassName": "DataModel", "Properties": {}, - "Id": "1aafa29b-bdca-40a0-a677-7ead327b84ce", + "Id": "3b5af13f-c997-4009-915c-0810b0e83032", "Children": [ - "54f2f276-964f-4c60-87d8-5fb2209c97c9", - "8d44bb30-db3c-4366-a6c5-633bd1441885" + "bf8e2d4f-33a0-42a0-8168-1b62d6ac050c", + "99eefe5f-ef74-49e6-8a8b-c833e00ca56b" ], - "Parent": "9f141826-14c2-492b-b360-2558712f0c08" + "Parent": null + }, + "bf8e2d4f-33a0-42a0-8168-1b62d6ac050c": { + "Name": "HttpService", + "ClassName": "HttpService", + "Properties": { + "HttpEnabled": { + "Type": "Bool", + "Value": true + } + }, + "Id": "bf8e2d4f-33a0-42a0-8168-1b62d6ac050c", + "Children": [], + "Parent": "3b5af13f-c997-4009-915c-0810b0e83032" + }, + "99eefe5f-ef74-49e6-8a8b-c833e00ca56b": { + "Name": "ReplicatedStorage", + "ClassName": "ReplicatedStorage", + "Properties": {}, + "Id": "99eefe5f-ef74-49e6-8a8b-c833e00ca56b", + "Children": [ + "14fed1a3-ba97-46a6-ae93-ac26bd9471df", + "c910510c-37a8-4fd8-ae41-01169ccb739c" + ], + "Parent": "3b5af13f-c997-4009-915c-0810b0e83032" } }, - "root_id": "645ba594-4482-441f-9f41-5bb9c444405b", + "root_id": "3b5af13f-c997-4009-915c-0810b0e83032", "metadata": { - "645ba594-4482-441f-9f41-5bb9c444405b": { + "bf8e2d4f-33a0-42a0-8168-1b62d6ac050c": { + "ignore_unknown_instances": true, + "source_path": null, + "project_definition": [ + "HttpService", + { + "class_name": "HttpService", + "children": {}, + "properties": { + "HttpEnabled": { + "Type": "Bool", + "Value": true + } + }, + "ignore_unknown_instances": null, + "path": null + } + ] + }, + "c910510c-37a8-4fd8-ae41-01169ccb739c": { + "ignore_unknown_instances": false, + "source_path": "b", + "project_definition": [ + "Bar", + { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "b" + } + ] + }, + "866071d6-465a-4b88-8c63-07489d950916": { + "ignore_unknown_instances": false, + "source_path": "b/added", + "project_definition": null + }, + "14fed1a3-ba97-46a6-ae93-ac26bd9471df": { + "ignore_unknown_instances": false, + "source_path": "a", + "project_definition": [ + "Ack", + { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "a" + } + ] + }, + "00f207b1-fc18-4088-a45e-caf8cd98f5dd": { + "ignore_unknown_instances": false, + "source_path": "a/main.lua", + "project_definition": null + }, + "99eefe5f-ef74-49e6-8a8b-c833e00ca56b": { + "ignore_unknown_instances": true, + "source_path": null, + "project_definition": [ + "ReplicatedStorage", + { + "class_name": "ReplicatedStorage", + "children": { + "Ack": { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "a" + }, + "Bar": { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "b" + } + }, + "properties": {}, + "ignore_unknown_instances": null, + "path": null + } + ] + }, + "71a95983-c856-4cf2-aee6-bd8a523e80e4": { + "ignore_unknown_instances": false, + "source_path": "b/something.lua", + "project_definition": null + }, + "c55fd55c-258e-4a93-a63a-ea243038c9b9": { + "ignore_unknown_instances": false, + "source_path": "a/foo.txt", + "project_definition": null + }, + "3b5af13f-c997-4009-915c-0810b0e83032": { "ignore_unknown_instances": true, "source_path": null, "project_definition": [ @@ -155,102 +251,6 @@ "path": null } ] - }, - "1aafa29b-bdca-40a0-a677-7ead327b84ce": { - "ignore_unknown_instances": false, - "source_path": "a", - "project_definition": [ - "Ack", - { - "class_name": null, - "children": {}, - "properties": {}, - "ignore_unknown_instances": null, - "path": "a" - } - ] - }, - "a8566e76-0495-45a3-a713-1c59ab39453b": { - "ignore_unknown_instances": false, - "source_path": "b/added", - "project_definition": null - }, - "8d690a2a-e987-4c86-b9ac-18e6d3a98503": { - "ignore_unknown_instances": false, - "source_path": "b/something.lua", - "project_definition": null - }, - "8d44bb30-db3c-4366-a6c5-633bd1441885": { - "ignore_unknown_instances": false, - "source_path": "a/main.lua", - "project_definition": null - }, - "9f141826-14c2-492b-b360-2558712f0c08": { - "ignore_unknown_instances": true, - "source_path": null, - "project_definition": [ - "ReplicatedStorage", - { - "class_name": "ReplicatedStorage", - "children": { - "Ack": { - "class_name": null, - "children": {}, - "properties": {}, - "ignore_unknown_instances": null, - "path": "a" - }, - "Bar": { - "class_name": null, - "children": {}, - "properties": {}, - "ignore_unknown_instances": null, - "path": "b" - } - }, - "properties": {}, - "ignore_unknown_instances": null, - "path": null - } - ] - }, - "b1c9928c-bf11-427f-90eb-b672c811d859": { - "ignore_unknown_instances": false, - "source_path": "b", - "project_definition": [ - "Bar", - { - "class_name": null, - "children": {}, - "properties": {}, - "ignore_unknown_instances": null, - "path": "b" - } - ] - }, - "54f2f276-964f-4c60-87d8-5fb2209c97c9": { - "ignore_unknown_instances": false, - "source_path": "a/foo.txt", - "project_definition": null - }, - "b1298bcc-e370-44a6-9ef4-fbefa290124c": { - "ignore_unknown_instances": true, - "source_path": null, - "project_definition": [ - "HttpService", - { - "class_name": "HttpService", - "children": {}, - "properties": { - "HttpEnabled": { - "Type": "Bool", - "Value": true - } - }, - "ignore_unknown_instances": null, - "path": null - } - ] } } } \ No newline at end of file