use crate::{
database::{
handle::{AssetDependency, AssetHandle},
path::{AssetPath, AssetPathStatic},
},
fetch::{AssetAwaitsResolution, AssetBytesAreReadyToProcess},
protocol::AssetProtocol,
};
use anput::world::World;
use std::error::Error;
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub struct GroupAsset;
pub struct GroupAssetProtocol;
impl AssetProtocol for GroupAssetProtocol {
fn name(&self) -> &str {
"group"
}
fn process_asset_bytes(
&mut self,
handle: AssetHandle,
storage: &mut World,
) -> Result<(), Box<dyn Error>> {
let bytes = {
let mut bytes =
storage.component_mut::<true, AssetBytesAreReadyToProcess>(handle.entity())?;
std::mem::take(&mut bytes.0)
};
storage.remove::<(AssetBytesAreReadyToProcess,)>(handle.entity())?;
for line in std::str::from_utf8(&bytes)?
.lines()
.map(|line| line.trim())
.filter(|line| !line.is_empty() && !line.starts_with('#') && !line.starts_with(';'))
{
let path = AssetPath::new(line.to_owned()).into_static();
let entity = if let Some(entity) = storage.find_by::<true, _>(&path) {
entity
} else {
storage.spawn((path.clone(), AssetAwaitsResolution))?
};
storage.relate::<true, _>(AssetDependency, handle.entity(), entity)?;
}
storage.insert(handle.entity(), (GroupAsset,))?;
Ok(())
}
fn produce_bytes(
&mut self,
handle: AssetHandle,
storage: &mut World,
) -> Result<Vec<u8>, Box<dyn Error>> {
let mut lines = String::default();
for (_, _, entity) in storage.relations_outgoing::<true, AssetDependency>(handle.entity()) {
let path = storage.component::<true, AssetPathStatic>(entity)?;
lines.push_str(path.content());
lines.push('\n');
}
Ok(lines.trim().as_bytes().to_owned())
}
}