-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Asset type for arbitrary json/toml/etc documents #27
Comments
I guess that would fit here, yes. But in my opinion, typed assets should be the way to go in most cases. With Bevy 0.13, asset loaders no longer are picked for loading a certain asset purely on their extensions. You could register the loader without an extension and then load like so: let toml_doc: Handle<TomlAsset> = asset_server.load("my_toml_settings.toml"); That would at least prevent any conflicts of the generic loader with other asset loaders. |
I will add to this that untyped assets are on rare occasions needed. I've just hand written one for toml for myself, but i think it might be useful for others. This was my code largely based on this crate's:use std::ops::{Deref, DerefMut};
use std::str::from_utf8;
use bevy::app::Plugin;
use bevy::asset::AssetApp;
use bevy::{
asset::{Asset, AssetLoader, AsyncReadExt},
reflect::Reflect,
};
use thiserror::Error;
pub type TomlValue = toml::Value;
/// Representation of any Toml asset
#[derive(Asset, Reflect)]
pub struct AnyToml(
// Wrapped with option due to need for default implementation
#[reflect(ignore)] Option<TomlValue>,
);
impl AnyToml {
pub fn into_inner(self) -> TomlValue {
self.0.unwrap()
}
}
impl Deref for AnyToml {
type Target = TomlValue;
fn deref(&self) -> &Self::Target {
self.0.as_ref().unwrap()
}
}
impl DerefMut for AnyToml {
fn deref_mut(&mut self) -> &mut Self::Target {
self.0.as_mut().unwrap()
}
}
#[derive(Debug, Error)]
pub enum TomlLoaderError {
/// An [IO Error](std::io::Error)
#[error("Could not read the file: {0}")]
Io(#[from] std::io::Error),
/// A [conversion Error](std::str::Utf8Error)
#[error("Could not interpret as UTF-8: {0}")]
FormatError(#[from] std::str::Utf8Error),
/// A [TOML Error](serde_toml::de::Error)
#[error("Could not parse TOML: {0}")]
TomlError(#[from] toml::de::Error),
}
pub struct AnyTomlPlugin;
impl Plugin for AnyTomlPlugin {
fn build(&self, app: &mut bevy::prelude::App) {
app.init_asset::<AnyToml>()
.register_asset_loader(AnyTomlLoader);
}
}
#[derive(Default)]
struct AnyTomlLoader;
impl AssetLoader for AnyTomlLoader {
type Asset = AnyToml;
type Settings = ();
type Error = TomlLoaderError;
async fn load<'a>(
&'a self,
reader: &'a mut bevy::asset::io::Reader<'_>,
_settings: &'a Self::Settings,
_load_context: &'a mut bevy::asset::LoadContext<'_>,
) -> Result<Self::Asset, Self::Error> {
let mut bytes = Vec::new();
reader.read_to_end(&mut bytes).await?;
let asset = toml::from_str(from_utf8(&bytes)?)?;
Ok(AnyToml(Some(asset)))
}
fn extensions(&self) -> &[&str] {
&["toml"]
}
} |
TL;DR
Could this repository include a common asset type and loader for loading generic
serde_json::Value
,toml_edit::Document
, etc. types from files with the generic format extension like.json
/.toml
rather than a specific extension?Background
I built something closely related to this for loading plugin settings from specific configuration files: https://github.com/devnev/bevy_settings_loader
But in my plugin, the settings are resource singletons and not identified by file extensions but by the full path to the file. So I add a generic
.json
/.toml
loader and then deserialise from the loaded value into the destination type for the asset matching the settings path.For that I've added generic
JsonAsset
andTomlAsset
types that wrapserde_json::Value
andtoml_edit::Document
loaded from arbitrary files with the corresponding extension. However, my repository/package/plugin is too specific for something that generic, whereas this repository seems more suitable and has most of the code for it already.The main missing pieces is a wrapper implementing
Asset
forserde_json::Value
etc, which would allow other plugins to avoid duplicate registration of loaders for the corresponding extension.The text was updated successfully, but these errors were encountered: