Implement RefPathIndex for efficient handling of Rojo_Ref_* attributes

- Introduced the `RefPathIndex` structure to map `Rojo_Ref_*` attribute values to their corresponding meta/model file paths, enabling O(affected_files) lookups during instance renaming.
- Updated `ChangeProcessor`, `ServeSession`, and `ApiService` to utilize the new index for managing reference paths, improving performance and reliability during rename operations.
- Enhanced the `update_ref_paths_after_rename` function to leverage the index for efficient file updates, reducing the need for full tree scans.
- Added comprehensive tests for `RefPathIndex` to ensure correct functionality and robustness against edge cases.

These changes significantly enhance the efficiency of reference path management in the synchronization system.
This commit is contained in:
Joe 2026-02-14 13:28:29 -06:00
parent ca2a938902
commit faa12dc573
6 changed files with 445 additions and 103 deletions

View file

@ -486,9 +486,9 @@ fn ref_attr_empty_path_resolves_to_root() {
// Empty path should resolve to root (RojoTree.get_instance_by_path("") returns root)
let has_ref = patch_set.updated_instances.iter().any(|u| {
u.changed_properties.get(&ustr("PrimaryPart")).is_some_and(
|v| matches!(v, Some(Variant::Ref(r)) if *r == root_id),
)
u.changed_properties
.get(&ustr("PrimaryPart"))
.is_some_and(|v| matches!(v, Some(Variant::Ref(r)) if *r == root_id))
});
assert!(has_ref, "Empty path should resolve to root instance");
}
@ -531,11 +531,7 @@ fn ref_attr_priority_path_wins_over_target() {
.first()
.copied()
.unwrap();
let model_children: Vec<_> = tree
.get_instance(model_id)
.unwrap()
.children()
.to_vec();
let model_children: Vec<_> = tree.get_instance(model_id).unwrap().children().to_vec();
let target_id = model_children[0]; // Target
let other_id = model_children[1]; // OtherPart
@ -585,9 +581,6 @@ fn ref_attr_priority_path_wins_over_target() {
"Rojo_Ref_* should win over Rojo_Target_* -- PrimaryPart should point to Target, not OtherPart"
);
}
other => panic!(
"PrimaryPart should be Some(Variant::Ref), got {:?}",
other
),
other => panic!("PrimaryPart should be Some(Variant::Ref), got {:?}", other),
}
}