## Objective Add a test that reproduces #11111 (and partially #18267). The bug is that asset loader settings are effectively ignored if the same asset is loaded multiple times with different settings. ## Solution Add a unit test to `bevy_assets/lib.rs`. The test will be marked as `#[ignore]` until #11111 is fixed. ```rust // Load the same asset with different settings. let handle_1 = load(asset_server, "test.u8", 1); let handle_2 = load(asset_server, "test.u8", 2); // Handles should be different. assert_ne!(handle_1, handle_2); ``` ## Concerns I'm not 100% sure that the current behaviour is actually broken - I can't see anything in the asset system design docs that explicitly says different settings should create different asset ids. UPDATE: Sentiment from issue comments and discord varies between "bug" and "undesirable consequence of design decisions, alternatives should be explored". So I've concluded that the test is valid and desirable. ## Testing ```sh cargo test -p bevy_asset --features multi_threaded # Or to repro the issue: cargo test -p bevy_asset --features multi_threaded -- --ignored ```
This commit is contained in:
parent
8098cf21ca
commit
05d954e1ab
@ -2000,4 +2000,92 @@ mod tests {
|
||||
|
||||
app.world_mut().run_schedule(Update);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "blocked on https://github.com/bevyengine/bevy/issues/11111"]
|
||||
fn same_asset_different_settings() {
|
||||
// Test loading the same asset twice with different settings. This should
|
||||
// produce two distinct assets.
|
||||
|
||||
// First, implement an asset that's a single u8, whose value is copied from
|
||||
// the loader settings.
|
||||
|
||||
#[derive(Asset, TypePath)]
|
||||
struct U8Asset(u8);
|
||||
|
||||
#[derive(Serialize, Deserialize, Default)]
|
||||
struct U8LoaderSettings(u8);
|
||||
|
||||
struct U8Loader;
|
||||
|
||||
impl AssetLoader for U8Loader {
|
||||
type Asset = U8Asset;
|
||||
type Settings = U8LoaderSettings;
|
||||
type Error = crate::loader::LoadDirectError;
|
||||
|
||||
async fn load(
|
||||
&self,
|
||||
_: &mut dyn Reader,
|
||||
settings: &Self::Settings,
|
||||
_: &mut LoadContext<'_>,
|
||||
) -> Result<Self::Asset, Self::Error> {
|
||||
Ok(U8Asset(settings.0))
|
||||
}
|
||||
|
||||
fn extensions(&self) -> &[&str] {
|
||||
&["u8"]
|
||||
}
|
||||
}
|
||||
|
||||
// Create a test asset.
|
||||
|
||||
let dir = Dir::default();
|
||||
dir.insert_asset(Path::new("test.u8"), &[]);
|
||||
|
||||
let asset_source = AssetSource::build()
|
||||
.with_reader(move || Box::new(MemoryAssetReader { root: dir.clone() }));
|
||||
|
||||
// Set up the app.
|
||||
|
||||
let mut app = App::new();
|
||||
|
||||
app.register_asset_source(AssetSourceId::Default, asset_source)
|
||||
.add_plugins((TaskPoolPlugin::default(), AssetPlugin::default()))
|
||||
.init_asset::<U8Asset>()
|
||||
.register_asset_loader(U8Loader);
|
||||
|
||||
let asset_server = app.world().resource::<AssetServer>();
|
||||
|
||||
// Load the test asset twice but with different settings.
|
||||
|
||||
fn load(asset_server: &AssetServer, path: &str, value: u8) -> Handle<U8Asset> {
|
||||
asset_server.load_with_settings::<U8Asset, U8LoaderSettings>(
|
||||
path,
|
||||
move |s: &mut U8LoaderSettings| s.0 = value,
|
||||
)
|
||||
}
|
||||
|
||||
let handle_1 = load(asset_server, "test.u8", 1);
|
||||
let handle_2 = load(asset_server, "test.u8", 2);
|
||||
|
||||
// Handles should be different.
|
||||
|
||||
assert_ne!(handle_1, handle_2);
|
||||
|
||||
run_app_until(&mut app, |world| {
|
||||
let (Some(asset_1), Some(asset_2)) = (
|
||||
world.resource::<Assets<U8Asset>>().get(&handle_1),
|
||||
world.resource::<Assets<U8Asset>>().get(&handle_2),
|
||||
) else {
|
||||
return None;
|
||||
};
|
||||
|
||||
// Values should match the settings.
|
||||
|
||||
assert_eq!(asset_1.0, 1);
|
||||
assert_eq!(asset_2.0, 2);
|
||||
|
||||
Some(())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user