Skip to content

Commit dac4a5b

Browse files
Depreciate LoadAndSave Asset Processor (#15090)
# Objective - Fixes #15060 ## Solution - Added `IdentityAssetTransformer<A>` which is an `AssetTransformer` which infallibly returns the input `Asset` unmodified. - Replaced `LoadAndSave` and `LoadAndSaveSettings` with type definitions linking back to `LoadTransformAndSave` and `LoadTransformAndSaveSettings` respectively. - Marked `LoadAndSave` and `LoadAndSaveSettings` as depreciated with a migration guide included, hinting to the user to use the underlying type instead. ## Testing - Ran CI locally --- ## Migration Guide - Replace `LoadAndSave<L, S>` with `LoadTransformAndSave<L, IdentityAssetTransformer<<L as AssetLoader>::Asset>, S>` - Replace `LoadAndSaveSettings<L, S>` with `LoadTransformAndSaveSettings<L, (), S>`
1 parent ce32b5c commit dac4a5b

File tree

3 files changed

+70
-55
lines changed

3 files changed

+70
-55
lines changed

crates/bevy_asset/src/processor/process.rs

Lines changed: 24 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::io::SliceReader;
2+
use crate::transformer::IdentityAssetTransformer;
23
use crate::{
34
io::{
45
AssetReaderError, AssetWriterError, MissingAssetWriterError,
@@ -47,6 +48,11 @@ pub trait Process: Send + Sync + Sized + 'static {
4748
/// an [`AssetSaver`] that allows you save any `S` asset. However you can
4849
/// also implement [`Process`] directly if [`LoadTransformAndSave`] feels limiting or unnecessary.
4950
///
51+
/// If your [`Process`] does not need to transform the [`Asset`], you can use [`IdentityAssetTransformer`] as `T`.
52+
/// This will directly return the input [`Asset`], allowing your [`Process`] to directly load and then save an [`Asset`].
53+
/// However, this pattern should only be used for cases such as file format conversion.
54+
/// Otherwise, consider refactoring your [`AssetLoader`] and [`AssetSaver`] to isolate the transformation step into an explicit [`AssetTransformer`].
55+
///
5056
/// This uses [`LoadTransformAndSaveSettings`] to configure the processor.
5157
///
5258
/// [`Asset`]: crate::Asset
@@ -60,6 +66,18 @@ pub struct LoadTransformAndSave<
6066
marker: PhantomData<fn() -> L>,
6167
}
6268

69+
impl<L: AssetLoader, S: AssetSaver<Asset = L::Asset>> From<S>
70+
for LoadTransformAndSave<L, IdentityAssetTransformer<L::Asset>, S>
71+
{
72+
fn from(value: S) -> Self {
73+
LoadTransformAndSave {
74+
transformer: IdentityAssetTransformer::new(),
75+
saver: value,
76+
marker: PhantomData,
77+
}
78+
}
79+
}
80+
6381
/// Settings for the [`LoadTransformAndSave`] [`Process::Settings`] implementation.
6482
///
6583
/// `LoaderSettings` corresponds to [`AssetLoader::Settings`], `TransformerSettings` corresponds to [`AssetTransformer::Settings`],
@@ -98,30 +116,16 @@ impl<
98116
/// This uses [`LoadAndSaveSettings`] to configure the processor.
99117
///
100118
/// [`Asset`]: crate::Asset
101-
pub struct LoadAndSave<L: AssetLoader, S: AssetSaver<Asset = L::Asset>> {
102-
saver: S,
103-
marker: PhantomData<fn() -> L>,
104-
}
105-
106-
impl<L: AssetLoader, S: AssetSaver<Asset = L::Asset>> From<S> for LoadAndSave<L, S> {
107-
fn from(value: S) -> Self {
108-
LoadAndSave {
109-
saver: value,
110-
marker: PhantomData,
111-
}
112-
}
113-
}
119+
#[deprecated = "Use `LoadTransformAndSave<L, IdentityAssetTransformer<<L as AssetLoader>::Asset>, S>` instead"]
120+
pub type LoadAndSave<L, S> =
121+
LoadTransformAndSave<L, IdentityAssetTransformer<<L as AssetLoader>::Asset>, S>;
114122

115123
/// Settings for the [`LoadAndSave`] [`Process::Settings`] implementation.
116124
///
117125
/// `LoaderSettings` corresponds to [`AssetLoader::Settings`] and `SaverSettings` corresponds to [`AssetSaver::Settings`].
118-
#[derive(Serialize, Deserialize, Default)]
119-
pub struct LoadAndSaveSettings<LoaderSettings, SaverSettings> {
120-
/// The [`AssetLoader::Settings`] for [`LoadAndSave`].
121-
pub loader_settings: LoaderSettings,
122-
/// The [`AssetSaver::Settings`] for [`LoadAndSave`].
123-
pub saver_settings: SaverSettings,
124-
}
126+
#[deprecated = "Use `LoadTransformAndSaveSettings<LoaderSettings, (), SaverSettings>` instead"]
127+
pub type LoadAndSaveSettings<LoaderSettings, SaverSettings> =
128+
LoadTransformAndSaveSettings<LoaderSettings, (), SaverSettings>;
125129

126130
/// An error that is encountered during [`Process::process`].
127131
#[derive(Error, Debug)]
@@ -213,36 +217,6 @@ where
213217
}
214218
}
215219

216-
impl<Loader: AssetLoader, Saver: AssetSaver<Asset = Loader::Asset>> Process
217-
for LoadAndSave<Loader, Saver>
218-
{
219-
type Settings = LoadAndSaveSettings<Loader::Settings, Saver::Settings>;
220-
type OutputLoader = Saver::OutputLoader;
221-
222-
async fn process<'a>(
223-
&'a self,
224-
context: &'a mut ProcessContext<'_>,
225-
meta: AssetMeta<(), Self>,
226-
writer: &'a mut Writer,
227-
) -> Result<<Self::OutputLoader as AssetLoader>::Settings, ProcessError> {
228-
let AssetAction::Process { settings, .. } = meta.asset else {
229-
return Err(ProcessError::WrongMetaType);
230-
};
231-
let loader_meta = AssetMeta::<Loader, ()>::new(AssetAction::Load {
232-
loader: std::any::type_name::<Loader>().to_string(),
233-
settings: settings.loader_settings,
234-
});
235-
let loaded_asset = context.load_source_asset(loader_meta).await?;
236-
let saved_asset = SavedAsset::<Loader::Asset>::from_loaded(&loaded_asset).unwrap();
237-
let output_settings = self
238-
.saver
239-
.save(writer, saved_asset, &settings.saver_settings)
240-
.await
241-
.map_err(|error| ProcessError::AssetSaveError(error.into()))?;
242-
Ok(output_settings)
243-
}
244-
}
245-
246220
/// A type-erased variant of [`Process`] that enables interacting with processor implementations without knowing
247221
/// their type.
248222
pub trait ErasedProcessor: Send + Sync {

crates/bevy_asset/src/transformer.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use bevy_utils::{ConditionalSendFuture, HashMap};
44
use serde::{Deserialize, Serialize};
55
use std::{
66
borrow::Borrow,
7+
convert::Infallible,
78
hash::Hash,
9+
marker::PhantomData,
810
ops::{Deref, DerefMut},
911
};
1012

@@ -241,3 +243,37 @@ impl<'a, A: Asset> TransformedSubAsset<'a, A> {
241243
self.labeled_assets.keys().map(|s| &**s)
242244
}
243245
}
246+
247+
/// An identity [`AssetTransformer`] which infallibly returns the input [`Asset`] on transformation.]
248+
pub struct IdentityAssetTransformer<A: Asset> {
249+
_phantom: PhantomData<fn(A) -> A>,
250+
}
251+
252+
impl<A: Asset> IdentityAssetTransformer<A> {
253+
pub const fn new() -> Self {
254+
Self {
255+
_phantom: PhantomData,
256+
}
257+
}
258+
}
259+
260+
impl<A: Asset> Default for IdentityAssetTransformer<A> {
261+
fn default() -> Self {
262+
Self::new()
263+
}
264+
}
265+
266+
impl<A: Asset> AssetTransformer for IdentityAssetTransformer<A> {
267+
type AssetInput = A;
268+
type AssetOutput = A;
269+
type Settings = ();
270+
type Error = Infallible;
271+
272+
async fn transform<'a>(
273+
&'a self,
274+
asset: TransformedAsset<Self::AssetInput>,
275+
_settings: &'a Self::Settings,
276+
) -> Result<TransformedAsset<Self::AssetOutput>, Self::Error> {
277+
Ok(asset)
278+
}
279+
}

crates/bevy_render/src/texture/mod.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,16 @@ impl Plugin for ImagePlugin {
107107
.world()
108108
.get_resource::<bevy_asset::processor::AssetProcessor>()
109109
{
110-
processor.register_processor::<bevy_asset::processor::LoadAndSave<ImageLoader, CompressedImageSaver>>(
111-
CompressedImageSaver.into(),
112-
);
113-
processor
114-
.set_default_processor::<bevy_asset::processor::LoadAndSave<ImageLoader, CompressedImageSaver>>("png");
110+
processor.register_processor::<bevy_asset::processor::LoadTransformAndSave<
111+
ImageLoader,
112+
bevy_asset::transformer::IdentityAssetTransformer<Image>,
113+
CompressedImageSaver,
114+
>>(CompressedImageSaver.into());
115+
processor.set_default_processor::<bevy_asset::processor::LoadTransformAndSave<
116+
ImageLoader,
117+
bevy_asset::transformer::IdentityAssetTransformer<Image>,
118+
CompressedImageSaver,
119+
>>("png");
115120
}
116121

117122
if let Some(render_app) = app.get_sub_app_mut(RenderApp) {

0 commit comments

Comments
 (0)