Move SUPPORTED_FILE_EXTENSIONS to ImageLoader and remove unsupported formats. (#15917)

# Objective

Fixes #15730.

## Solution

As part of #15586, we made a constant to store all the supported image
formats. However since the `ImageFormat` does actually include Hdr and
OpenExr, it also included the `"hdr"` and `"exr"` file extensions. These
are supported by separate loaders though: `HdrTextureLoader` and
`ExrTextureLoader`. This led to a warning about duplicate asset loaders.

Therefore, instead of having the constant for `ImageFormat`, I made the
constant just for `ImageLoader`. This lets us correctly remove `"hdr"`
and `"exr"` from the image formats supported by `ImageLoader`, returning
us to having a single asset loader for every image format.

Note: we could have just removed `hdr` and `exr` from
`ImageFormat::SUPPORTED_FILE_EXTENSIONS`, but this would be very
confusing. Then the list of `ImageFormat`s would not match the list of
supported formats!

## Testing

- I ran the `sprite` example and got no warning! I also replaced the
sprite in that example with an HDR file and everything worked as
expected.
This commit is contained in:
andriyDev 2024-10-15 11:06:34 -07:00 committed by GitHub
parent 812e599f77
commit 15440c189b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 133 additions and 145 deletions

View file

@ -78,147 +78,6 @@ macro_rules! feature_gate {
} }
impl ImageFormat { impl ImageFormat {
/// Number of image formats, used for computing other constants.
const COUNT: usize = {
let mut count = 0;
#[cfg(feature = "avif")]
{
count += 1;
}
#[cfg(feature = "basis-universal")]
{
count += 1;
}
#[cfg(feature = "bmp")]
{
count += 1;
}
#[cfg(feature = "dds")]
{
count += 1;
}
#[cfg(feature = "ff")]
{
count += 1;
}
#[cfg(feature = "gif")]
{
count += 1;
}
#[cfg(feature = "exr")]
{
count += 1;
}
#[cfg(feature = "hdr")]
{
count += 1;
}
#[cfg(feature = "ico")]
{
count += 1;
}
#[cfg(feature = "jpeg")]
{
count += 1;
}
#[cfg(feature = "ktx2")]
{
count += 1;
}
#[cfg(feature = "pnm")]
{
count += 1;
}
#[cfg(feature = "png")]
{
count += 1;
}
#[cfg(feature = "qoi")]
{
count += 1;
}
#[cfg(feature = "tga")]
{
count += 1;
}
#[cfg(feature = "tiff")]
{
count += 1;
}
#[cfg(feature = "webp")]
{
count += 1;
}
count
};
/// Full list of supported formats.
pub const SUPPORTED: &'static [ImageFormat] = &[
#[cfg(feature = "avif")]
ImageFormat::Avif,
#[cfg(feature = "basis-universal")]
ImageFormat::Basis,
#[cfg(feature = "bmp")]
ImageFormat::Bmp,
#[cfg(feature = "dds")]
ImageFormat::Dds,
#[cfg(feature = "ff")]
ImageFormat::Farbfeld,
#[cfg(feature = "gif")]
ImageFormat::Gif,
#[cfg(feature = "exr")]
ImageFormat::OpenExr,
#[cfg(feature = "hdr")]
ImageFormat::Hdr,
#[cfg(feature = "ico")]
ImageFormat::Ico,
#[cfg(feature = "jpeg")]
ImageFormat::Jpeg,
#[cfg(feature = "ktx2")]
ImageFormat::Ktx2,
#[cfg(feature = "png")]
ImageFormat::Png,
#[cfg(feature = "pnm")]
ImageFormat::Pnm,
#[cfg(feature = "qoi")]
ImageFormat::Qoi,
#[cfg(feature = "tga")]
ImageFormat::Tga,
#[cfg(feature = "tiff")]
ImageFormat::Tiff,
#[cfg(feature = "webp")]
ImageFormat::WebP,
];
/// Total count of file extensions, for computing supported file extensions list.
const COUNT_FILE_EXTENSIONS: usize = {
let mut count = 0;
let mut idx = 0;
while idx < ImageFormat::COUNT {
count += ImageFormat::SUPPORTED[idx].to_file_extensions().len();
idx += 1;
}
count
};
/// Gets the list of file extensions for all formats.
pub const SUPPORTED_FILE_EXTENSIONS: &'static [&'static str] = &{
let mut exts = [""; ImageFormat::COUNT_FILE_EXTENSIONS];
let mut ext_idx = 0;
let mut fmt_idx = 0;
while fmt_idx < ImageFormat::COUNT {
let mut off = 0;
let fmt_exts = ImageFormat::SUPPORTED[fmt_idx].to_file_extensions();
while off < fmt_exts.len() {
exts[ext_idx] = fmt_exts[off];
off += 1;
ext_idx += 1;
}
fmt_idx += 1;
}
exts
};
/// Gets the file extensions for a given format. /// Gets the file extensions for a given format.
pub const fn to_file_extensions(&self) -> &'static [&'static str] { pub const fn to_file_extensions(&self) -> &'static [&'static str] {
match self { match self {

View file

@ -12,6 +12,135 @@ pub struct ImageLoader {
} }
impl ImageLoader { impl ImageLoader {
/// Number of image formats, used for computing other constants.
const COUNT: usize = {
let mut count = 0;
#[cfg(feature = "avif")]
{
count += 1;
}
#[cfg(feature = "basis-universal")]
{
count += 1;
}
#[cfg(feature = "bmp")]
{
count += 1;
}
#[cfg(feature = "dds")]
{
count += 1;
}
#[cfg(feature = "ff")]
{
count += 1;
}
#[cfg(feature = "gif")]
{
count += 1;
}
#[cfg(feature = "ico")]
{
count += 1;
}
#[cfg(feature = "jpeg")]
{
count += 1;
}
#[cfg(feature = "ktx2")]
{
count += 1;
}
#[cfg(feature = "pnm")]
{
count += 1;
}
#[cfg(feature = "png")]
{
count += 1;
}
#[cfg(feature = "qoi")]
{
count += 1;
}
#[cfg(feature = "tga")]
{
count += 1;
}
#[cfg(feature = "tiff")]
{
count += 1;
}
#[cfg(feature = "webp")]
{
count += 1;
}
count
};
/// Full list of supported formats.
pub const SUPPORTED_FORMATS: &'static [ImageFormat] = &[
#[cfg(feature = "avif")]
ImageFormat::Avif,
#[cfg(feature = "basis-universal")]
ImageFormat::Basis,
#[cfg(feature = "bmp")]
ImageFormat::Bmp,
#[cfg(feature = "dds")]
ImageFormat::Dds,
#[cfg(feature = "ff")]
ImageFormat::Farbfeld,
#[cfg(feature = "gif")]
ImageFormat::Gif,
#[cfg(feature = "ico")]
ImageFormat::Ico,
#[cfg(feature = "jpeg")]
ImageFormat::Jpeg,
#[cfg(feature = "ktx2")]
ImageFormat::Ktx2,
#[cfg(feature = "png")]
ImageFormat::Png,
#[cfg(feature = "pnm")]
ImageFormat::Pnm,
#[cfg(feature = "qoi")]
ImageFormat::Qoi,
#[cfg(feature = "tga")]
ImageFormat::Tga,
#[cfg(feature = "tiff")]
ImageFormat::Tiff,
#[cfg(feature = "webp")]
ImageFormat::WebP,
];
/// Total count of file extensions, for computing supported file extensions list.
const COUNT_FILE_EXTENSIONS: usize = {
let mut count = 0;
let mut idx = 0;
while idx < Self::COUNT {
count += Self::SUPPORTED_FORMATS[idx].to_file_extensions().len();
idx += 1;
}
count
};
/// Gets the list of file extensions for all formats.
pub const SUPPORTED_FILE_EXTENSIONS: &'static [&'static str] = &{
let mut exts = [""; Self::COUNT_FILE_EXTENSIONS];
let mut ext_idx = 0;
let mut fmt_idx = 0;
while fmt_idx < Self::COUNT {
let mut off = 0;
let fmt_exts = Self::SUPPORTED_FORMATS[fmt_idx].to_file_extensions();
while off < fmt_exts.len() {
exts[ext_idx] = fmt_exts[off];
off += 1;
ext_idx += 1;
}
fmt_idx += 1;
}
exts
};
/// Creates a new image loader that supports the provided formats. /// Creates a new image loader that supports the provided formats.
pub fn new(supported_compressed_formats: CompressedImageFormats) -> Self { pub fn new(supported_compressed_formats: CompressedImageFormats) -> Self {
Self { Self {
@ -105,7 +234,7 @@ impl AssetLoader for ImageLoader {
} }
fn extensions(&self) -> &[&str] { fn extensions(&self) -> &[&str] {
ImageFormat::SUPPORTED_FILE_EXTENSIONS Self::SUPPORTED_FILE_EXTENSIONS
} }
} }

View file

@ -111,13 +111,13 @@ impl Plugin for ImagePlugin {
); );
} }
if !ImageFormat::SUPPORTED_FILE_EXTENSIONS.is_empty() { if !ImageLoader::SUPPORTED_FILE_EXTENSIONS.is_empty() {
app.preregister_asset_loader::<ImageLoader>(ImageFormat::SUPPORTED_FILE_EXTENSIONS); app.preregister_asset_loader::<ImageLoader>(ImageLoader::SUPPORTED_FILE_EXTENSIONS);
} }
} }
fn finish(&self, app: &mut App) { fn finish(&self, app: &mut App) {
if !ImageFormat::SUPPORTED.is_empty() { if !ImageLoader::SUPPORTED_FORMATS.is_empty() {
let supported_compressed_formats = match app.world().get_resource::<RenderDevice>() { let supported_compressed_formats = match app.world().get_resource::<RenderDevice>() {
Some(render_device) => { Some(render_device) => {
CompressedImageFormats::from_features(render_device.features()) CompressedImageFormats::from_features(render_device.features())