#[cfg(feature = "ldtk_1_2_5")] mod data_1_2_5; #[cfg(feature = "ldtk_1_2_4")] mod data_1_2_4; use bevy::asset::{AssetLoader, BoxedFuture, LoadContext, LoadedAsset}; use bevy::reflect::{TypeUuid, Uuid}; #[cfg(feature = "ldtk_1_2_4")] pub use data_1_2_4::*; #[cfg(feature = "ldtk_1_2_5")] pub use data_1_2_5::*; #[derive(thiserror::Error)] pub enum ParseError { #[error("Failed to parse file: {0}")] SerdeError(#[from] String), } impl TypeUuid for Project { const TYPE_UUID: Uuid = Uuid::from_u128(87988914102923589138720617793417023455); } impl Project { pub fn from_bytes(bytes: &[u8]) -> Result<Self, ParseError> { serde_json::from_slice(bytes).map_err(|e| ParseError::SerdeError(format!("{}", e))) } } pub type LdtkProject = Project; impl<'a> TryFrom<&'a [u8]> for Project { type Error = ParseError; fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> { Project::from_bytes(value) } } impl<'a> From<&'a [u8]> for Project { fn from(value: &'a [u8]) -> Self { #[cfg(feature = "no_panic")] { match Project::from_bytes(value) { Ok(val) => val, Err(e) => { log::error!("{}", e); std::process::abort(); } } } #[cfg(not(feature = "no_panic"))] { Project::from_bytes(value).expect("Failed to parse ldtk project file") } } } #[derive(Default)] pub struct LdtkLoader; impl AssetLoader for LdtkLoader { fn load<'a>( &'a self, bytes: &'a [u8], load_context: &'a mut LoadContext, ) -> BoxedFuture<'a, anyhow::Result<(), anyhow::Error>> { Box::pin(async move { load_context.set_default_asset(LoadedAsset::new(Project::from_bytes(bytes)?)); Ok(()) }) } fn extensions(&self) -> &[&str] { &["ldtk"] } }