diff --git a/rojo-test/serve-test-snapshots/end_to_end__tests__serve__ref_properties_subscribe.snap b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__ref_properties_subscribe.snap index da543083..eceecd9d 100644 --- a/rojo-test/serve-test-snapshots/end_to_end__tests__serve__ref_properties_subscribe.snap +++ b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__ref_properties_subscribe.snap @@ -29,19 +29,7 @@ body: changedName: ~ changedProperties: Attributes: - "!Attributes": - Rojo_Id: - "!String": model target 2 + "!Attributes": {} id: id-7 - - changedClassName: ~ - changedMetadata: ~ - changedName: ~ - changedProperties: - Attributes: - "!Attributes": - Rojo_Target_PrimaryPart: - "!String": model target 2 - PrimaryPart: ~ - id: id-8 packetType: messages sessionId: id-1 diff --git a/src/serve_session.rs b/src/serve_session.rs index 198d2c94..459410f2 100644 --- a/src/serve_session.rs +++ b/src/serve_session.rs @@ -281,7 +281,7 @@ impl ServeSession { let prefetch_start = Instant::now(); match prefetch_project_files(&root_project) { Ok(cache) => { - log::info!( + log::debug!( "Prefetch total: {} files + {} canonical paths in {:.1?}", cache.files.len(), cache.canonical.len(), diff --git a/src/snapshot/patch_compute.rs b/src/snapshot/patch_compute.rs index bf2e5f0b..ec585784 100644 --- a/src/snapshot/patch_compute.rs +++ b/src/snapshot/patch_compute.rs @@ -44,6 +44,10 @@ pub fn compute_patch_set(snapshot: Option, tree: &RojoTree, id #[derive(Default)] struct ComputePatchContext { snapshot_id_to_instance_id: HashMap, + /// Maps `Rojo_Id` attribute values (from snapshots being patched) to the + /// tree Ref of the instance that carries them. Populated top-down so that + /// parent IDs are available when children try to resolve `Rojo_Target_*`. + snapshot_specified_ids: HashMap, } fn rewrite_refs_in_updates(context: &ComputePatchContext, updates: &mut [PatchUpdate]) { @@ -92,15 +96,32 @@ fn compute_patch_set_internal( .insert(snapshot.snapshot_id, id); } + if let Some(Variant::Attributes(attrs)) = snapshot.properties.get(&ustr("Attributes")) { + if let Some(id_value) = attrs.get(REF_ID_ATTRIBUTE_NAME) { + if let Some(id_str) = crate::variant_as_str(id_value, REF_ID_ATTRIBUTE_NAME) { + context + .snapshot_specified_ids + .insert(id_str.to_string(), id); + } + } + } + let instance = tree .get_instance(id) .expect("Instance did not exist in tree"); - compute_property_patches(&mut snapshot, &instance, patch_set, tree); + compute_property_patches( + &context.snapshot_specified_ids, + &mut snapshot, + &instance, + patch_set, + tree, + ); compute_children_patches(context, &mut snapshot, tree, id, patch_set, session); } fn compute_property_patches( + snapshot_specified_ids: &HashMap, snapshot: &mut InstanceSnapshot, instance: &InstanceWithMeta, patch_set: &mut PatchSet, @@ -109,7 +130,8 @@ fn compute_property_patches( let mut visited_properties = UstrSet::default(); let mut changed_properties = UstrMap::new(); - let attribute_ref_properties = compute_ref_properties(snapshot, tree, instance.id()); + let attribute_ref_properties = + compute_ref_properties(snapshot, tree, instance.id(), snapshot_specified_ids); // Strip Rojo ref transport attributes from the snapshot before comparison. // finalize_patch_application strips these from the tree after resolving refs, @@ -287,6 +309,7 @@ fn compute_ref_properties( snapshot: &InstanceSnapshot, tree: &RojoTree, source_ref: Ref, + snapshot_specified_ids: &HashMap, ) -> UstrMap> { let mut map = UstrMap::new(); let attributes = match snapshot.properties.get(&ustr("Attributes")) { @@ -312,6 +335,8 @@ fn compute_ref_properties( let rojo_ref = RojoRef::new(id_str.to_string()); if let Some(target_id) = tree.get_specified_id(&rojo_ref) { map.insert(key, Some(Variant::Ref(target_id))); + } else if let Some(&target_id) = snapshot_specified_ids.get(id_str) { + map.insert(key, Some(Variant::Ref(target_id))); } else { map.insert(key, None); }