#![warn(missing_docs)]
#![cfg_attr(doc, allow(unknown_lints))]
#![deny(rustdoc::all)]
use std::marker::PhantomData;
use bevy_app::App;
use bevy_asset::{prelude::*, Asset};
pub mod prelude {
pub use crate::*;
pub use bones_lib::prelude as bones;
pub use type_ulid::TypeUlid;
}
use bones_bevy_utils::BevyWorld;
use prelude::*;
pub use bones_bevy_asset_macros::{BonesBevyAsset, BonesBevyAssetLoad};
#[doc(hidden)]
pub mod _private {
pub use serde_json;
pub use serde_yaml;
}
pub trait BonesBevyAsset: TypeUlid + Asset {
fn install_asset(app: &mut App);
}
pub trait BonesBevyAssetAppExt {
fn add_bones_asset<T: BonesBevyAsset>(&mut self) -> &mut Self;
}
impl BonesBevyAssetAppExt for App {
fn add_bones_asset<T: BonesBevyAsset>(&mut self) -> &mut Self {
T::install_asset(self);
self
}
}
pub trait BonesBevyAssetLoad {
fn load(
&mut self,
load_context: &mut bevy_asset::LoadContext,
dependencies: &mut Vec<bevy_asset::AssetPath<'static>>,
) {
let _ = (load_context, dependencies);
}
}
impl<T: TypeUlid> BonesBevyAssetLoad for bones::Handle<T> {
fn load(
&mut self,
load_context: &mut bevy_asset::LoadContext,
dependencies: &mut Vec<bevy_asset::AssetPath<'static>>,
) {
self.path.normalize_relative_to(load_context.path());
let asset_path = bevy_asset::AssetPath::new(
self.path.path.to_path_buf(),
self.path.clone().label.map(|x| x.to_string()),
);
let path_id = asset_path.get_id();
dependencies.push(asset_path);
let handle = load_context.get_handle::<_, DummyAsset>(path_id);
std::mem::forget(handle);
}
}
impl<T: BonesBevyAssetLoad> BonesBevyAssetLoad for Vec<T> {
fn load(
&mut self,
load_context: &mut bevy_asset::LoadContext,
dependencies: &mut Vec<bevy_asset::AssetPath<'static>>,
) {
self.iter_mut()
.for_each(|x| x.load(load_context, dependencies))
}
}
impl<T: BonesBevyAssetLoad> BonesBevyAssetLoad for Option<T> {
fn load(
&mut self,
load_context: &mut bevy_asset::LoadContext,
dependencies: &mut Vec<bevy_asset::AssetPath<'static>>,
) {
if let Some(x) = self.as_mut() {
x.load(load_context, dependencies)
}
}
}
impl<K, H, T: BonesBevyAssetLoad> BonesBevyAssetLoad for std::collections::HashMap<K, T, H> {
fn load(
&mut self,
load_context: &mut bevy_asset::LoadContext,
dependencies: &mut Vec<bevy_asset::AssetPath<'static>>,
) {
self.iter_mut()
.for_each(|(_k, v)| v.load(load_context, dependencies))
}
}
impl<K, V: BonesBevyAssetLoad> BonesBevyAssetLoad for bevy_utils::HashMap<K, V> {
fn load(
&mut self,
load_context: &mut bevy_asset::LoadContext,
dependencies: &mut Vec<bevy_asset::AssetPath<'static>>,
) {
self.iter_mut()
.for_each(|(_k, v)| v.load(load_context, dependencies))
}
}
macro_rules! impl_default_traits {
( $($type:ty),* $(,)? ) => {
$(
impl BonesBevyAssetLoad for $type {}
)*
};
}
impl_default_traits!(
String,
f32,
f64,
usize,
u8,
u16,
u32,
u64,
u128,
i8,
i16,
i32,
i64,
i128,
glam::Vec2,
glam::Vec3,
glam::UVec2,
bool
);
pub struct BevyAssets<'a, T: bevy_asset::Asset> {
cell: bones::AtomicRef<'a, BevyWorld>,
_phantom: PhantomData<T>,
}
impl<'a, T: bevy_asset::Asset> std::ops::Deref for BevyAssets<'a, T> {
type Target = bevy_asset::Assets<T>;
fn deref(&self) -> &Self::Target {
self.cell
.as_ref()
.expect("Bevy world not present in `BevyWorld` resource.")
.resource::<Assets<T>>()
}
}
impl<'a, T: bevy_asset::Asset> bones_lib::ecs::system::SystemParam for BevyAssets<'a, T> {
type State = bones::AtomicResource<BevyWorld>;
type Param<'s> = BevyAssets<'s, T>;
fn initialize(_world: &mut bones::World) {}
fn get_state(world: &bones::World) -> Self::State {
world.resources.get::<BevyWorld>()
}
fn borrow(state: &mut Self::State) -> Self::Param<'_> {
BevyAssets {
cell: state.borrow(),
_phantom: PhantomData,
}
}
}
#[derive(bevy_reflect::TypeUuid)]
#[uuid = "ece514f7-4ffe-4251-9c25-d568acd696eb"]
struct DummyAsset;