use std::{error::Error, fmt::Display};
use bevy::asset::{io::Reader, AssetLoader, AsyncReadExt, LoadContext};
use polyanya::PolyanyaFile;
use crate::NavMesh;
#[derive(Debug)]
pub enum NavMeshLoaderError {
Io(std::io::Error),
MeshError(polyanya::MeshError),
}
impl Display for NavMeshLoaderError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
NavMeshLoaderError::Io(io_error) => write!(f, "IO error: {}", io_error),
NavMeshLoaderError::MeshError(mesh_error) => write!(f, "Mesh error: {}", mesh_error),
}
}
}
impl Error for NavMeshLoaderError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
NavMeshLoaderError::Io(io_error) => Some(io_error),
NavMeshLoaderError::MeshError(mesh_error) => Some(mesh_error),
}
}
}
#[derive(Default, Debug, Clone, Copy)]
pub struct NavMeshPolyanyaLoader;
impl AssetLoader for NavMeshPolyanyaLoader {
type Asset = NavMesh;
type Settings = ();
type Error = NavMeshLoaderError;
async fn load<'a>(
&'a self,
reader: &'a mut Reader<'_>,
_settings: &'a Self::Settings,
_load_context: &'a mut LoadContext<'_>,
) -> Result<Self::Asset, Self::Error> {
let mut bytes = Vec::new();
reader
.read_to_end(&mut bytes)
.await
.map_err(NavMeshLoaderError::Io)?;
let navmesh = NavMesh::from_polyanya_mesh(
PolyanyaFile::from_bytes(bytes.as_slice())
.try_into()
.map_err(NavMeshLoaderError::MeshError)?,
);
Ok(navmesh)
}
fn extensions(&self) -> &[&str] {
&["polyanya.mesh"]
}
}