use std::{error::Error, fmt::Display};
use bevy::asset::{AssetLoader, LoadContext, io::Reader};
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(
&self,
reader: &mut dyn Reader,
_settings: &(),
_load_context: &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"]
}
}