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));
 | 
					        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> {
 | 
					    pub fn watch_for_changes(&self) -> Result<(), AssetServerError> {
 | 
				
			||||||
        self.server.asset_io.watch_for_changes()?;
 | 
					        self.server.asset_io.watch_for_changes()?;
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
@ -622,7 +624,7 @@ mod test {
 | 
				
			|||||||
                handle_to_path: Default::default(),
 | 
					                handle_to_path: Default::default(),
 | 
				
			||||||
                asset_lifecycles: Default::default(),
 | 
					                asset_lifecycles: Default::default(),
 | 
				
			||||||
                task_pool: 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 {
 | 
					impl FileAssetIo {
 | 
				
			||||||
    pub fn new<P: AsRef<Path>>(path: P) -> Self {
 | 
					    pub fn new<P: AsRef<Path>>(path: P, watch_for_changes: bool) -> Self {
 | 
				
			||||||
        FileAssetIo {
 | 
					        let file_asset_io = FileAssetIo {
 | 
				
			||||||
            #[cfg(feature = "filesystem_watcher")]
 | 
					            #[cfg(feature = "filesystem_watcher")]
 | 
				
			||||||
            filesystem_watcher: Default::default(),
 | 
					            filesystem_watcher: Default::default(),
 | 
				
			||||||
            root_path: Self::get_root_path().join(path.as_ref()),
 | 
					            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 {
 | 
					    pub fn get_root_path() -> PathBuf {
 | 
				
			||||||
 | 
				
			|||||||
@ -44,12 +44,16 @@ pub struct AssetPlugin;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
pub struct AssetServerSettings {
 | 
					pub struct AssetServerSettings {
 | 
				
			||||||
    pub asset_folder: String,
 | 
					    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 {
 | 
					impl Default for AssetServerSettings {
 | 
				
			||||||
    fn default() -> Self {
 | 
					    fn default() -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            asset_folder: "assets".to_string(),
 | 
					            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);
 | 
					        .get_resource_or_insert_with(AssetServerSettings::default);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[cfg(all(not(target_arch = "wasm32"), not(target_os = "android")))]
 | 
					    #[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")]
 | 
					    #[cfg(target_arch = "wasm32")]
 | 
				
			||||||
    let source = WasmAssetIo::new(&settings.asset_folder);
 | 
					    let source = WasmAssetIo::new(&settings.asset_folder);
 | 
				
			||||||
    #[cfg(target_os = "android")]
 | 
					    #[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
 | 
					/// 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
 | 
					/// game is running. This lets you immediately see the results of your changes without restarting
 | 
				
			||||||
/// the game. This example illustrates hot reloading mesh changes.
 | 
					/// the game. This example illustrates hot reloading mesh changes.
 | 
				
			||||||
fn main() {
 | 
					fn main() {
 | 
				
			||||||
    App::new()
 | 
					    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_plugins(DefaultPlugins)
 | 
				
			||||||
        .add_startup_system(setup)
 | 
					        .add_startup_system(setup)
 | 
				
			||||||
        .run();
 | 
					        .run();
 | 
				
			||||||
@ -14,9 +19,6 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
 | 
				
			|||||||
    // Load our mesh:
 | 
					    // Load our mesh:
 | 
				
			||||||
    let scene_handle = asset_server.load("models/monkey/Monkey.gltf#Scene0");
 | 
					    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.
 | 
					    // 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.
 | 
					    // You should see the changes immediately show up in your app.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user