|
| 1 | +use bevy::{ |
| 2 | + asset::{AssetIo, AssetIoError}, |
| 3 | + prelude::*, |
| 4 | + utils::BoxedFuture, |
| 5 | +}; |
| 6 | +use std::path::{Path, PathBuf}; |
| 7 | + |
| 8 | +/// A custom asset io implementation that simply defers to the platform default |
| 9 | +/// implementation. |
| 10 | +/// |
| 11 | +/// This can be used as a starting point for developing a useful implementation |
| 12 | +/// that can defer to the default when needed. |
| 13 | +struct CustomAssetIo(Box<dyn AssetIo>); |
| 14 | + |
| 15 | +impl AssetIo for CustomAssetIo { |
| 16 | + fn load_path<'a>(&'a self, path: &'a Path) -> BoxedFuture<'a, Result<Vec<u8>, AssetIoError>> { |
| 17 | + println!("load_path({:?})", path); |
| 18 | + self.0.load_path(path) |
| 19 | + } |
| 20 | + |
| 21 | + fn read_directory( |
| 22 | + &self, |
| 23 | + path: &Path, |
| 24 | + ) -> Result<Box<dyn Iterator<Item = PathBuf>>, AssetIoError> { |
| 25 | + println!("read_directory({:?})", path); |
| 26 | + self.0.read_directory(path) |
| 27 | + } |
| 28 | + |
| 29 | + fn is_directory(&self, path: &Path) -> bool { |
| 30 | + println!("is_directory({:?})", path); |
| 31 | + self.0.is_directory(path) |
| 32 | + } |
| 33 | + |
| 34 | + fn watch_path_for_changes(&self, path: &Path) -> Result<(), AssetIoError> { |
| 35 | + println!("watch_path_for_changes({:?})", path); |
| 36 | + self.0.watch_path_for_changes(path) |
| 37 | + } |
| 38 | + |
| 39 | + fn watch_for_changes(&self) -> Result<(), AssetIoError> { |
| 40 | + println!("watch_for_changes()"); |
| 41 | + self.0.watch_for_changes() |
| 42 | + } |
| 43 | +} |
| 44 | + |
| 45 | +/// A plugin used to execute the override of the asset io |
| 46 | +struct CustomAssetIoPlugin; |
| 47 | + |
| 48 | +impl Plugin for CustomAssetIoPlugin { |
| 49 | + fn build(&self, app: &mut AppBuilder) { |
| 50 | + // must get a hold of the task pool in order to create the asset server |
| 51 | + |
| 52 | + let task_pool = app |
| 53 | + .resources() |
| 54 | + .get::<bevy::tasks::IoTaskPool>() |
| 55 | + .expect("`IoTaskPool` resource not found.") |
| 56 | + .0 |
| 57 | + .clone(); |
| 58 | + |
| 59 | + let asset_io = { |
| 60 | + // the platform default asset io requires a reference to the app |
| 61 | + // builder to find its configuration |
| 62 | + |
| 63 | + let default_io = bevy::asset::create_platform_default_asset_io(app); |
| 64 | + |
| 65 | + // create the custom asset io instance |
| 66 | + |
| 67 | + CustomAssetIo(default_io) |
| 68 | + }; |
| 69 | + |
| 70 | + // the asset server is constructed and added the resource manager |
| 71 | + |
| 72 | + app.add_resource(AssetServer::new(asset_io, task_pool)); |
| 73 | + } |
| 74 | +} |
| 75 | + |
| 76 | +fn main() { |
| 77 | + App::build() |
| 78 | + .add_plugins_with(DefaultPlugins, |group| { |
| 79 | + // the custom asset io plugin must be inserted in-between the |
| 80 | + // `CorePlugin' and `AssetPlugin`. It needs to be after the |
| 81 | + // CorePlugin, so that the IO task pool has already been constructed. |
| 82 | + // And it must be before the `AssetPlugin` so that the asset plugin |
| 83 | + // doesn't create another instance of an assert server. In general, |
| 84 | + // the AssetPlugin should still run so that other aspects of the |
| 85 | + // asset system are initialized correctly. |
| 86 | + group.add_before::<bevy::asset::AssetPlugin, _>(CustomAssetIoPlugin) |
| 87 | + }) |
| 88 | + .add_startup_system(setup) |
| 89 | + .run(); |
| 90 | +} |
| 91 | + |
| 92 | +fn setup( |
| 93 | + commands: &mut Commands, |
| 94 | + asset_server: Res<AssetServer>, |
| 95 | + mut materials: ResMut<Assets<ColorMaterial>>, |
| 96 | +) { |
| 97 | + let texture_handle = asset_server.load("branding/icon.png"); |
| 98 | + commands |
| 99 | + .spawn(Camera2dBundle::default()) |
| 100 | + .spawn(SpriteBundle { |
| 101 | + material: materials.add(texture_handle.into()), |
| 102 | + ..Default::default() |
| 103 | + }); |
| 104 | +} |
0 commit comments