bevy_asset: Add AssetServerSettings watch_for_changes member (#3643)
# Objective - `asset_server.watch_for_changes().unwrap()` only watches changes for assets loaded **_after_** that call. - Technically, the `hot_asset_reloading` example is racey as the watch on the asset path is set up in an async task scheduled from the asset `load()`, but the filesystem watcher is only constructed in a call that comes **_after_** the call to `load()`. ## Solution - It feels safest to allow enabling watching the filesystem for changes on the asset server from the point of its construction. Therefore, adding such an option to `AssetServerSettings` seemed to be the correct solution. - Fix `hot_asset_reloading` by inserting the `AssetServerSettings` resource with `watch_for_changes: true` instead of calling `asset_server.watch_for_changes().unwrap()`. - Document the shortcomings of `.watch_for_changes()`
This commit is contained in:
		
							parent
							
								
									ca83e8a6de
								
							
						
					
					
						commit
						e928acb9ff
					
				@ -115,6 +115,8 @@ impl AssetServer {
 | 
			
		||||
        loaders.push(Arc::new(loader));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Enable watching of the filesystem for changes, if support is available, starting from after
 | 
			
		||||
    /// the point of calling this function.
 | 
			
		||||
    pub fn watch_for_changes(&self) -> Result<(), AssetServerError> {
 | 
			
		||||
        self.server.asset_io.watch_for_changes()?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
@ -622,7 +624,7 @@ mod test {
 | 
			
		||||
                handle_to_path: Default::default(),
 | 
			
		||||
                asset_lifecycles: Default::default(),
 | 
			
		||||
                task_pool: Default::default(),
 | 
			
		||||
                asset_io: Box::new(FileAssetIo::new(asset_path)),
 | 
			
		||||
                asset_io: Box::new(FileAssetIo::new(asset_path, false)),
 | 
			
		||||
            }),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -27,12 +27,26 @@ pub struct FileAssetIo {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl FileAssetIo {
 | 
			
		||||
    pub fn new<P: AsRef<Path>>(path: P) -> Self {
 | 
			
		||||
        FileAssetIo {
 | 
			
		||||
    pub fn new<P: AsRef<Path>>(path: P, watch_for_changes: bool) -> Self {
 | 
			
		||||
        let file_asset_io = FileAssetIo {
 | 
			
		||||
            #[cfg(feature = "filesystem_watcher")]
 | 
			
		||||
            filesystem_watcher: Default::default(),
 | 
			
		||||
            root_path: Self::get_root_path().join(path.as_ref()),
 | 
			
		||||
        };
 | 
			
		||||
        if watch_for_changes {
 | 
			
		||||
            #[cfg(any(
 | 
			
		||||
                not(feature = "filesystem_watcher"),
 | 
			
		||||
                target_arch = "wasm32",
 | 
			
		||||
                target_os = "android"
 | 
			
		||||
            ))]
 | 
			
		||||
            panic!(
 | 
			
		||||
                "Watch for changes requires the filesystem_watcher feature and cannot be used on \
 | 
			
		||||
                wasm32 / android targets"
 | 
			
		||||
            );
 | 
			
		||||
            #[cfg(feature = "filesystem_watcher")]
 | 
			
		||||
            file_asset_io.watch_for_changes().unwrap();
 | 
			
		||||
        }
 | 
			
		||||
        file_asset_io
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn get_root_path() -> PathBuf {
 | 
			
		||||
 | 
			
		||||
@ -44,12 +44,16 @@ pub struct AssetPlugin;
 | 
			
		||||
 | 
			
		||||
pub struct AssetServerSettings {
 | 
			
		||||
    pub asset_folder: String,
 | 
			
		||||
    /// Whether to watch for changes in asset files. Requires the `filesystem_watcher` feature,
 | 
			
		||||
    /// and cannot be supported on the wasm32 arch nor android os.
 | 
			
		||||
    pub watch_for_changes: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Default for AssetServerSettings {
 | 
			
		||||
    fn default() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            asset_folder: "assets".to_string(),
 | 
			
		||||
            watch_for_changes: false,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -64,7 +68,7 @@ pub fn create_platform_default_asset_io(app: &mut App) -> Box<dyn AssetIo> {
 | 
			
		||||
        .get_resource_or_insert_with(AssetServerSettings::default);
 | 
			
		||||
 | 
			
		||||
    #[cfg(all(not(target_arch = "wasm32"), not(target_os = "android")))]
 | 
			
		||||
    let source = FileAssetIo::new(&settings.asset_folder);
 | 
			
		||||
    let source = FileAssetIo::new(&settings.asset_folder, settings.watch_for_changes);
 | 
			
		||||
    #[cfg(target_arch = "wasm32")]
 | 
			
		||||
    let source = WasmAssetIo::new(&settings.asset_folder);
 | 
			
		||||
    #[cfg(target_os = "android")]
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,15 @@
 | 
			
		||||
use bevy::prelude::*;
 | 
			
		||||
use bevy::{asset::AssetServerSettings, prelude::*};
 | 
			
		||||
 | 
			
		||||
/// Hot reloading allows you to modify assets on disk and they will be "live reloaded" while your
 | 
			
		||||
/// game is running. This lets you immediately see the results of your changes without restarting
 | 
			
		||||
/// the game. This example illustrates hot reloading mesh changes.
 | 
			
		||||
fn main() {
 | 
			
		||||
    App::new()
 | 
			
		||||
        // Tell the asset server to watch for asset changes on disk:
 | 
			
		||||
        .insert_resource(AssetServerSettings {
 | 
			
		||||
            watch_for_changes: true,
 | 
			
		||||
            ..Default::default()
 | 
			
		||||
        })
 | 
			
		||||
        .add_plugins(DefaultPlugins)
 | 
			
		||||
        .add_startup_system(setup)
 | 
			
		||||
        .run();
 | 
			
		||||
@ -14,9 +19,6 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
 | 
			
		||||
    // Load our mesh:
 | 
			
		||||
    let scene_handle = asset_server.load("models/monkey/Monkey.gltf#Scene0");
 | 
			
		||||
 | 
			
		||||
    // Tell the asset server to watch for asset changes on disk:
 | 
			
		||||
    asset_server.watch_for_changes().unwrap();
 | 
			
		||||
 | 
			
		||||
    // Any changes to the mesh will be reloaded automatically! Try making a change to Monkey.gltf.
 | 
			
		||||
    // You should see the changes immediately show up in your app.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user