Skip to content

Commit

Permalink
feat: make dependency bevy_asset optional (behind bevy-07 feature…
Browse files Browse the repository at this point in the history
… flag) (#77)
  • Loading branch information
jcornaz committed Jul 15, 2022
1 parent 8de5931 commit 75aa334
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 31 deletions.
2 changes: 1 addition & 1 deletion .gitpod.yml
Expand Up @@ -16,7 +16,7 @@ tasks:
cargo test --all-features
cargo test
command: |
cargo watch -x 'test --tests' -x 'test --all-features' -x 'clippy --all-features --all-targets' -x '+nightly doc --all-features --no-deps'
cargo watch -x 'test --tests' -x 'test --features bevy-07' -x 'test --all-features' -x 'clippy --all-features --all-targets' -x '+nightly doc --all-features --no-deps'
vscode:
extensions:
Expand Down
9 changes: 6 additions & 3 deletions Cargo.toml
Expand Up @@ -16,7 +16,7 @@ all-features = true
[features]
default = []
unstable-load-from-file = ["serde", "anyhow", "bevy_utils"]
bevy-07 = ["bevy-app-07", "bevy-sprite-07"]
bevy-07 = ["bevy-app-07", "bevy-asset-07", "bevy-sprite-07"]

[dependencies]
# Private dependencies (do not leak into the public API)
Expand All @@ -31,10 +31,13 @@ anyhow = { version = "1.0", default-features = false, optional = true }
bevy_core = { version = "0.7.0", default-features = false }
bevy_ecs = { version = "0.7.0", default-features = false }
bevy_reflect = { version = "0.7.0", default-features = false }
bevy_asset = { version = "0.7.0", default-features = false }

bevy_utils = { version = "0.7.0", default-features = false, optional = true }

# Bevy 0.7
bevy-app-07 = { package = "bevy_app",version = "0.7.0", default-features = false, optional = true }
bevy-asset-07 = { package = "bevy_asset", version = "0.7.0", default-features = false, optional = true }
bevy-sprite-07 = { package = "bevy_sprite", version = "0.7.0", default-features = false, optional = true }
bevy_utils = { version = "0.7.0", default-features = false, optional = true }

[dev-dependencies]
bevy = { version = "0.7.0", default-features = false, features = ["render", "x11", "png"] }
Expand Down
73 changes: 48 additions & 25 deletions src/animation/load.rs
@@ -1,9 +1,15 @@
use super::SpriteSheetAnimation;
use bevy_asset::{AssetLoader, LoadContext, LoadedAsset};
use bevy_utils::BoxedFuture;
use std::{error::Error, fmt::Display};

use crate::SpriteSheetAnimation;

use super::AnimationParseError;

/// Loader of animation file
///
/// It is not necessary to use this directly if you are using the bevy plugin,
/// as it is already registered as an asset loader.
#[derive(Debug)]
pub(crate) struct SpriteSheetAnimationLoader {
pub struct SpriteSheetAnimationLoader {
extensions: Vec<&'static str>,
}

Expand All @@ -25,28 +31,45 @@ impl Default for SpriteSheetAnimationLoader {
}
}

impl AssetLoader for SpriteSheetAnimationLoader {
fn load<'a>(
&'a self,
bytes: &'a [u8],
load_context: &'a mut LoadContext<'_>,
) -> BoxedFuture<'a, Result<(), anyhow::Error>> {
Box::pin(async move {
let custom_asset = match load_context.path().extension().unwrap().to_str().unwrap() {
#[cfg(feature = "yaml")]
"yaml" | "yml" => SpriteSheetAnimation::from_yaml_bytes(bytes)?,

#[cfg(feature = "ron")]
"ron" => SpriteSheetAnimation::from_ron_bytes(bytes)?,

_ => unreachable!(),
};
load_context.set_default_asset(LoadedAsset::new(custom_asset));
Ok(())
})
impl SpriteSheetAnimationLoader {
/// Returns supported extensions
///
/// [`SpriteSheetAnimationLoader::load`] can only succeed one of the returned extensions
#[must_use]
pub fn supported_extensions(&self) -> &[&str] {
&self.extensions
}

fn extensions(&self) -> &[&str] {
&self.extensions
/// Load animation from file content
///
/// # Errors
///
/// Returns an error if the extension is not supported or if the data content is not valid for that extension
#[allow(clippy::unused_self)]
pub fn load(
&self,
extension: &str,
data: &[u8],
) -> Result<SpriteSheetAnimation, AnimationParseError> {
match extension {
#[cfg(feature = "yaml")]
"yaml" | "yml" => SpriteSheetAnimation::from_yaml_bytes(data),

#[cfg(feature = "ron")]
"ron" => SpriteSheetAnimation::from_ron_bytes(data),

_ => Err(AnimationParseError(UnexpectedExtension.into())),
}
}
}

#[derive(Debug, Clone, Copy)]
struct UnexpectedExtension;

impl Display for UnexpectedExtension {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Unexpected extension")
}
}

impl Error for UnexpectedExtension {}
3 changes: 3 additions & 0 deletions src/animation.rs → src/animation/mod.rs
Expand Up @@ -8,6 +8,9 @@ use std::{ops::RangeInclusive, time::Duration};

use bevy_reflect::TypeUuid;

#[cfg(feature = "unstable-load-from-file")]
pub use load::SpriteSheetAnimationLoader;

#[cfg(feature = "unstable-load-from-file")]
pub use parse::AnimationParseError;

Expand Down
3 changes: 2 additions & 1 deletion src/animation/parse.rs
Expand Up @@ -252,9 +252,10 @@ impl SpriteSheetAnimation {
}
}

/// Error when parsing an animation file content
#[derive(Debug)]
#[non_exhaustive]
pub struct AnimationParseError(anyhow::Error);
pub struct AnimationParseError(pub(crate) anyhow::Error);

impl AnimationParseError {
fn new(err: impl Error + Send + Sync + 'static) -> Self {
Expand Down
26 changes: 25 additions & 1 deletion src/integration/bevy_07.rs
Expand Up @@ -4,7 +4,9 @@ use crate::{
state::SpriteState, Play, PlaySpeedMultiplier, SpriteSheetAnimation, SpriteSheetAnimationState,
};
use bevy_app_07::prelude::*;
use bevy_asset::prelude::*;
use bevy_asset_07::prelude::*;
#[cfg(feature = "unstable-load-from-file")]
use bevy_asset_07::{AssetLoader, BoxedFuture, LoadContext, LoadedAsset};
use bevy_core::prelude::*;
use bevy_ecs::prelude::*;
use bevy_sprite_07::prelude::*;
Expand Down Expand Up @@ -115,3 +117,25 @@ impl<'w, T: SpriteState> SpriteState for Mut<'w, T> {
self.deref_mut().set_current_index(index);
}
}

#[cfg(feature = "unstable-load-from-file")]
impl AssetLoader for crate::animation::load::SpriteSheetAnimationLoader {
fn load<'a>(
&'a self,
bytes: &'a [u8],
load_context: &'a mut LoadContext<'_>,
) -> BoxedFuture<'a, Result<(), anyhow::Error>> {
Box::pin(async move {
let custom_asset = self.load(
load_context.path().extension().unwrap().to_str().unwrap(),
bytes,
)?;
load_context.set_default_asset(LoadedAsset::new(custom_asset));
Ok(())
})
}

fn extensions(&self) -> &[&str] {
self.supported_extensions()
}
}
3 changes: 3 additions & 0 deletions src/lib.rs
Expand Up @@ -165,6 +165,9 @@ pub use state::SpriteSheetAnimationState;
#[allow(deprecated)]
pub use animation::AnimationMode;

#[cfg(feature = "unstable-load-from-file")]
pub use animation::{AnimationParseError, SpriteSheetAnimationLoader};

mod animation;
pub mod integration;
mod state;
Expand Down

0 comments on commit 75aa334

Please sign in to comment.