refactor Loader trait to use generics

This commit is contained in:
Quaternions 2025-02-03 10:02:15 -08:00
parent b4f1b017f7
commit ae48542626
5 changed files with 83 additions and 99 deletions
lib
bsp_loader/src
deferred_loader/src
rbx_loader/src

@ -3,7 +3,7 @@ use std::{borrow::Cow, io::Read};
use strafesnet_common::model::Mesh;
use strafesnet_deferred_loader::{loader::Loader,texture::Texture};
use crate::{mesh::ModelData, Bsp};
use crate::Bsp;
#[allow(dead_code)]
#[derive(Debug)]
@ -28,11 +28,10 @@ impl TextureLoader<'_>{
Self(std::marker::PhantomData)
}
}
impl<'a> Loader for TextureLoader<'a>{
impl<'a> Loader<Texture> for TextureLoader<'a>{
type Error=TextureError;
type Index=Cow<'a,str>;
type Resource=Texture;
fn load(&mut self,index:Self::Index)->Result<Self::Resource,Self::Error>{
fn load(&mut self,index:Self::Index)->Result<Texture,Self::Error>{
let file_name=format!("textures/{}.dds",index);
let mut file=std::fs::File::open(file_name)?;
let mut data=Vec::new();
@ -88,11 +87,10 @@ impl MeshLoader<'_,'_>{
}
}
}
impl<'a> Loader for MeshLoader<'a,'_>{
impl<'a> Loader<Mesh> for MeshLoader<'a,'_>{
type Error=MeshError;
type Index=&'a str;
type Resource=Mesh;
fn load(&mut self,index:Self::Index)->Result<Self::Resource,Self::Error>{
fn load(&mut self,index:Self::Index)->Result<Mesh,Self::Error>{
let mdl_path_lower=index.to_lowercase();
//.mdl, .vvd, .dx90.vtx
let path=std::path::PathBuf::from(mdl_path_lower.as_str());
@ -105,8 +103,12 @@ impl<'a> Loader for MeshLoader<'a,'_>{
let mdl=bsp.pack.get(mdl_path_lower.as_str())?.ok_or(MeshError::MissingMdl)?;
let vtx=bsp.pack.get(vtx_path.as_os_str().to_str().unwrap())?.ok_or(MeshError::MissingVtx)?;
let vvd=bsp.pack.get(vvd_path.as_os_str().to_str().unwrap())?.ok_or(MeshError::MissingVvd)?;
let model=ModelData{mdl,vtx,vvd};
let mesh=model.convert_mesh(&mut self.deferred_loader)?;
let model=vmdl::Model::from_parts(
vmdl::mdl::Mdl::read(mdl.as_ref())?,
vmdl::vtx::Vtx::read(vtx.as_ref())?,
vmdl::vvd::Vvd::read(vvd.as_ref())?,
);
let mesh=crate::mesh::convert_mesh(model,&mut self.deferred_loader);
Ok(mesh)
}
}

@ -5,21 +5,7 @@ use strafesnet_deferred_loader::deferred_loader::RenderConfigDeferredLoader;
use crate::valve_transform;
pub struct ModelData{
pub mdl:Vec<u8>,
pub vtx:Vec<u8>,
pub vvd:Vec<u8>,
}
impl ModelData{
fn read_model(&self)->Result<vmdl::Model,vmdl::ModelError>{
Ok(vmdl::Model::from_parts(
vmdl::mdl::Mdl::read(self.mdl.as_ref())?,
vmdl::vtx::Vtx::read(self.vtx.as_ref())?,
vmdl::vvd::Vvd::read(self.vvd.as_ref())?,
))
}
pub fn convert_mesh<'a>(self,deferred_loader:&mut RenderConfigDeferredLoader<Cow<'a,str>>)->Result<model::Mesh,vmdl::ModelError>{
let model=self.read_model()?;
pub fn convert_mesh<'a>(model:vmdl::Model,deferred_loader:&mut RenderConfigDeferredLoader<Cow<'a,str>>)->model::Mesh{
let texture_paths=model.texture_directories();
if texture_paths.len()!=1{
println!("WARNING: multiple texture paths");
@ -75,7 +61,7 @@ impl ModelData{
).collect()
))
}).collect();
Ok(model::Mesh{
model::Mesh{
unique_pos:spam_pos,
unique_normal:spam_normal,
unique_tex:spam_tex,
@ -84,6 +70,5 @@ impl ModelData{
polygon_groups,
graphics_groups,
physics_groups,
})
}
}

@ -45,7 +45,7 @@ impl<H:core::hash::Hash+Eq> RenderConfigDeferredLoader<H>{
pub fn indices(&self)->impl Iterator<Item=&H>{
self.render_config_id_from_asset_id.keys().flatten()
}
pub fn into_render_configs<L:Loader<Index=H,Resource=Texture>>(mut self,loader:&mut L,failure_mode:LoadFailureMode)->Result<RenderConfigs,L::Error>{
pub fn into_render_configs<L:Loader<Texture,Index=H>>(mut self,loader:&mut L,failure_mode:LoadFailureMode)->Result<RenderConfigs,L::Error>{
let mut sorted_textures=vec![None;self.texture_count as usize];
for (index_option,render_config_id) in self.render_config_id_from_asset_id{
let render_config=&mut self.render_configs[render_config_id.get() as usize];
@ -93,7 +93,7 @@ impl<H:core::hash::Hash+Eq> MeshDeferredLoader<H>{
pub fn indices(&self)->impl Iterator<Item=&H>{
self.mesh_id_from_asset_id.keys()
}
pub fn into_meshes<L:Loader<Index=H,Resource=Mesh>>(self,loader:&mut L,failure_mode:LoadFailureMode)->Result<Meshes,L::Error>{
pub fn into_meshes<L:Loader<Mesh,Index=H>>(self,loader:&mut L,failure_mode:LoadFailureMode)->Result<Meshes,L::Error>{
let mut mesh_list=vec![None;self.mesh_id_from_asset_id.len()];
for (index,mesh_id) in self.mesh_id_from_asset_id{
let resource_result=loader.load(index);

@ -1,8 +1,7 @@
use std::error::Error;
pub trait Loader{
pub trait Loader<Resource>{
type Error:Error;
type Index;
type Resource;
fn load(&mut self,index:Self::Index)->Result<Self::Resource,Self::Error>;
fn load(&mut self,index:Self::Index)->Result<Resource,Self::Error>;
}

@ -42,11 +42,10 @@ impl TextureLoader<'_>{
Self(std::marker::PhantomData)
}
}
impl<'a> Loader for TextureLoader<'a>{
impl<'a> Loader<Texture> for TextureLoader<'a>{
type Error=TextureError;
type Index=&'a str;
type Resource=Texture;
fn load(&mut self,index:Self::Index)->Result<Self::Resource,Self::Error>{
fn load(&mut self,index:Self::Index)->Result<Texture,Self::Error>{
let RobloxAssetId(asset_id)=index.parse()?;
let file_name=format!("textures/{}.dds",asset_id);
let data=read_entire_file(file_name)?;
@ -144,11 +143,10 @@ impl MeshLoader<'_>{
Self(std::marker::PhantomData)
}
}
impl<'a> Loader for MeshLoader<'a>{
impl<'a> Loader<Mesh> for MeshLoader<'a>{
type Error=MeshError;
type Index=MeshIndex<'a>;
type Resource=Mesh;
fn load(&mut self,index:Self::Index)->Result<Self::Resource,Self::Error>{
fn load(&mut self,index:Self::Index)->Result<Mesh,Self::Error>{
let mesh=match index.mesh_type{
MeshType::FileMesh=>{
let RobloxAssetId(asset_id)=index.content.parse()?;