From 8a8532bb53470296ff32c45892386b69ff7a9c2e Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Tue, 28 Nov 2023 16:35:13 -0800 Subject: [PATCH] Print precise and correct watch warnings (and only when necessary) (#10787) # Objective Fixes #10401 ## Solution * Allow sources to register specific processed/unprocessed watch warnings. * Specify per-platform watch warnings. This removes the need to cover all platform cases in one warning message. * Only register watch warnings for the _processed_ embedded source, as warning about watching unprocessed embedded isn't helpful. --- ## Changelog - Asset sources can now register specific watch warnings. --- crates/bevy_asset/src/io/embedded/mod.rs | 7 +++- crates/bevy_asset/src/io/source.rs | 48 ++++++++++++++++++++---- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/crates/bevy_asset/src/io/embedded/mod.rs b/crates/bevy_asset/src/io/embedded/mod.rs index e5470cd3d5..b8d9ff1a0f 100644 --- a/crates/bevy_asset/src/io/embedded/mod.rs +++ b/crates/bevy_asset/src/io/embedded/mod.rs @@ -66,7 +66,12 @@ impl EmbeddedAssetRegistry { Box::new(MemoryAssetReader { root: processed_dir.clone(), }) - }); + }) + // Note that we only add a processed watch warning because we don't want to warn + // noisily about embedded watching (which is niche) when users enable file watching. + .with_processed_watch_warning( + "Consider enabling the `embedded_watcher` cargo feature.", + ); #[cfg(feature = "embedded_watcher")] { diff --git a/crates/bevy_asset/src/io/source.rs b/crates/bevy_asset/src/io/source.rs index 8ee192462a..b409579344 100644 --- a/crates/bevy_asset/src/io/source.rs +++ b/crates/bevy_asset/src/io/source.rs @@ -128,6 +128,8 @@ pub struct AssetSourceBuilder { + Sync, >, >, + pub watch_warning: Option<&'static str>, + pub processed_watch_warning: Option<&'static str>, } impl AssetSourceBuilder { @@ -156,23 +158,31 @@ impl AssetSourceBuilder { if watch { let (sender, receiver) = crossbeam_channel::unbounded(); - match self.watcher.as_mut().and_then(|w|(w)(sender)) { + match self.watcher.as_mut().and_then(|w| (w)(sender)) { Some(w) => { source.watcher = Some(w); source.event_receiver = Some(receiver); - }, - None => warn!("{id} does not have an AssetWatcher configured. Consider enabling the `file_watcher` feature. Note that Web and Android do not currently support watching assets."), + } + None => { + if let Some(warning) = self.watch_warning { + warn!("{id} does not have an AssetWatcher configured. {warning}"); + } + } } } if watch_processed { let (sender, receiver) = crossbeam_channel::unbounded(); - match self.processed_watcher.as_mut().and_then(|w|(w)(sender)) { + match self.processed_watcher.as_mut().and_then(|w| (w)(sender)) { Some(w) => { source.processed_watcher = Some(w); source.processed_event_receiver = Some(receiver); - }, - None => warn!("{id} does not have a processed AssetWatcher configured. Consider enabling the `file_watcher` feature. Note that Web and Android do not currently support watching assets."), + } + None => { + if let Some(warning) = self.processed_watch_warning { + warn!("{id} does not have a processed AssetWatcher configured. {warning}"); + } + } } } Some(source) @@ -238,6 +248,18 @@ impl AssetSourceBuilder { self } + /// Enables a warning for the unprocessed source watcher, which will print when watching is enabled and the unprocessed source doesn't have a watcher. + pub fn with_watch_warning(mut self, warning: &'static str) -> Self { + self.watch_warning = Some(warning); + self + } + + /// Enables a warning for the processed source watcher, which will print when watching is enabled and the processed source doesn't have a watcher. + pub fn with_processed_watch_warning(mut self, warning: &'static str) -> Self { + self.processed_watch_warning = Some(warning); + self + } + /// Returns a builder containing the "platform default source" for the given `path` and `processed_path`. /// For most platforms, this will use [`FileAssetReader`](crate::io::file::FileAssetReader) / [`FileAssetWriter`](crate::io::file::FileAssetWriter), /// but some platforms (such as Android) have their own default readers / writers / watchers. @@ -248,7 +270,8 @@ impl AssetSourceBuilder { .with_watcher(AssetSource::get_default_watcher( path.to_string(), Duration::from_millis(300), - )); + )) + .with_watch_warning(AssetSource::get_default_watch_warning()); if let Some(processed_path) = processed_path { default .with_processed_reader(AssetSource::get_default_reader(processed_path.to_string())) @@ -257,6 +280,7 @@ impl AssetSourceBuilder { processed_path.to_string(), Duration::from_millis(300), )) + .with_processed_watch_warning(AssetSource::get_default_watch_warning()) } else { default } @@ -428,6 +452,16 @@ impl AssetSource { } } + /// Returns the default non-existent [`AssetWatcher`] warning for the current platform. + pub fn get_default_watch_warning() -> &'static str { + #[cfg(target_arch = "wasm32")] + return "Web does not currently support watching assets."; + #[cfg(target_os = "android")] + return "Android does not currently support watching assets."; + #[cfg(all(not(target_arch = "wasm32"), not(target_os = "android")))] + return "Consider enabling the `file_watcher` feature."; + } + /// Returns a builder function for this platform's default [`AssetWatcher`]. `path` is the relative path to /// the asset root. This will return [`None`] if this platform does not support watching assets by default. /// `file_debounce_time` is the amount of time to wait (and debounce duplicate events) before returning an event.