From e897f524dc31b7e13d7406fdd78d14588972e4a9 Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Fri, 13 Oct 2023 10:38:21 -0500 Subject: [PATCH] Skip sourcemap generation when unaffected by changes in watch mode (#800) --- CHANGELOG.md | 3 +++ src/cli/sourcemap.rs | 45 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 873a5f5f7..da732630d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Rojo Changelog ## Unreleased Changes +* Changed `sourcemap --watch` to only generate the sourcemap when it's necessary ([#800]) + +[#800]: https://github.com/rojo-rbx/rojo/pull/800 ## [7.4.0-rc2] - October 3, 2023 * Fixed bug with parsing version for plugin validation ([#797]) diff --git a/src/cli/sourcemap.rs b/src/cli/sourcemap.rs index f7bc1691a..ec4e95280 100644 --- a/src/cli/sourcemap.rs +++ b/src/cli/sourcemap.rs @@ -14,7 +14,7 @@ use tokio::runtime::Runtime; use crate::{ serve_session::ServeSession, - snapshot::{InstanceWithMeta, RojoTree}, + snapshot::{AppliedPatchSet, InstanceWithMeta, RojoTree}, }; use super::resolve_path; @@ -90,10 +90,12 @@ impl SourcemapCommand { loop { let receiver = session.message_queue().subscribe(cursor); - let (new_cursor, _patch_set) = rt.block_on(receiver).unwrap(); + let (new_cursor, patch_set) = rt.block_on(receiver).unwrap(); cursor = new_cursor; - write_sourcemap(&session, self.output.as_deref(), filter)?; + if patch_set_affects_sourcemap(&session, &patch_set, filter) { + write_sourcemap(&session, self.output.as_deref(), filter)?; + } } } @@ -116,6 +118,43 @@ fn filter_non_scripts(instance: &InstanceWithMeta) -> bool { ) } +fn patch_set_affects_sourcemap( + session: &ServeSession, + patch_set: &[AppliedPatchSet], + filter: fn(&InstanceWithMeta) -> bool, +) -> bool { + let tree = session.tree(); + + // A sourcemap has probably changed when: + patch_set.par_iter().any(|set| { + // 1. An instance was removed, in which case it will no + // longer exist in the tree and we cant check the filter + !set.removed.is_empty() + // 2. A newly added instance passes the filter + || set.added.iter().any(|referent| { + let instance = tree + .get_instance(*referent) + .expect("instance did not exist when updating sourcemap"); + filter(&instance) + }) + // 3. An existing instance has its class name, name, + // or file paths changed, and passes the filter + || set.updated.iter().any(|updated| { + let changed = updated.changed_class_name.is_some() + || updated.changed_name.is_some() + || updated.changed_metadata.is_some(); + if changed { + let instance = tree + .get_instance(updated.id) + .expect("instance did not exist when updating sourcemap"); + filter(&instance) + } else { + false + } + }) + }) +} + fn recurse_create_node<'a>( tree: &'a RojoTree, referent: Ref,