mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 15:14:50 +00:00
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
4 changed files with 30 additions and 8 deletions
|
@ -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 a new issue