mod data;
mod id;
mod serialize;
pub use data::*;
pub use id::*;
pub use serialize::*;
use std::sync::Weak;
use crate::asset_type::AssetType;
use crate::loader::AssetLoadError;
use crate::manager::AssetManager;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum AssetError {
#[error("Error loading asset data from bytes: {0}")]
Loader(#[from] AssetLoadError),
#[error("A weak pointer to an AssetType could not be upgraded")]
TypeDropped,
#[error("Asset type was not found: {0}")]
TypeNotFound(String),
#[error(transparent)]
Other(#[from] anyhow::Error),
}
pub struct Asset {
id: AssetId,
asset_type: Weak<dyn AssetType>,
data: Box<dyn AssetData>,
}
impl Asset {
#[inline]
pub fn new(asset_type: Weak<dyn AssetType>, data: Box<dyn AssetData>) -> Self {
Self {
id: AssetId::from(0),
asset_type,
data,
}
}
pub fn from_serialized(
mgr: &AssetManager,
serialized: SerializedAsset,
) -> Result<Self, AssetError> {
let id = serialized.id;
let asset_type = mgr
.asset_type_by_name(&serialized.asset_type)
.ok_or_else(|| AssetError::TypeNotFound(serialized.asset_type))?;
let asset_type_ptr = asset_type.upgrade().ok_or(AssetError::TypeDropped)?;
let decompressed_data;
let data_bytes = if let Some(compression_mode) = serialized.data.compression_mode() {
decompressed_data = compression_mode
.decompress(serialized.data.data())
.ok_or_else(|| {
AssetError::Other(anyhow::anyhow!("Failed to decompress asset data"))
})?;
&decompressed_data
} else {
serialized.data.data()
};
let data = asset_type_ptr
.loader()
.asset_from_bytes(data_bytes, mgr.context())
.map_err(AssetError::from)?;
Ok(Self {
id,
asset_type,
data,
})
}
#[inline]
pub fn id(&self) -> AssetId {
self.id
}
#[inline]
pub(crate) fn set_id(&mut self, new_id: AssetId) {
self.id = new_id;
}
#[inline]
pub fn asset_type(&self) -> Weak<dyn AssetType> {
Weak::clone(&self.asset_type)
}
#[inline]
pub fn data(&self) -> &dyn AssetData {
self.data.as_ref()
}
}