use std::io::Read; #[derive(Debug)] pub enum ReadError{ Roblox(strafesnet_rbx_loader::ReadError), Source(strafesnet_bsp_loader::ReadError), Io(std::io::Error), UnknownFileFormat, } impl std::fmt::Display for ReadError{ fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ write!(f,"{self:?}") } } impl std::error::Error for ReadError{} pub enum DataStructure{ Roblox(strafesnet_rbx_loader::Dom), Source(strafesnet_bsp_loader::Bsp) } pub fn read(input:R)->Result{ let mut buf=std::io::BufReader::new(input); let peek=std::io::BufRead::fill_buf(&mut buf).map_err(ReadError::Io)?; match &peek[0..4]{ b"Ok(DataStructure::Roblox(strafesnet_rbx_loader::read(buf).map_err(ReadError::Roblox)?)), b"VBSP"=>Ok(DataStructure::Source(strafesnet_bsp_loader::read(buf).map_err(ReadError::Source)?)), _=>Err(ReadError::UnknownFileFormat), } } #[derive(Debug)] pub enum LoadError{ ReadError(ReadError), File(std::io::Error), Io(std::io::Error), } impl std::fmt::Display for LoadError{ fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ write!(f,"{self:?}") } } impl std::error::Error for LoadError{} pub fn load>(path:P)->Result{ //blocking because it's simpler... let file=std::fs::File::open(path).map_err(LoadError::File)?; match read(file).map_err(LoadError::ReadError)?{ DataStructure::Roblox(dom)=>{ let mut loader=strafesnet_deferred_loader::roblox_legacy(); let (texture_loader,mesh_loader)=loader.get_inner_mut(); let map_step1=strafesnet_rbx_loader::convert( &dom, |name|texture_loader.acquire_render_config_id(name), |name|mesh_loader.acquire_mesh_id(name), ); let meshpart_meshes=mesh_loader.load_meshes().map_err(LoadError::Io)?; let map_step2=map_step1.add_meshpart_meshes_and_calculate_attributes( meshpart_meshes.into_iter().map(|(mesh_id,loader_model)| (mesh_id,strafesnet_rbx_loader::data::RobloxMeshBytes::new(loader_model.get())) ) ); let (textures,render_configs)=loader.into_render_configs().map_err(LoadError::Io)?.consume(); let map=map_step2.add_render_configs_and_textures( render_configs.into_iter(), textures.into_iter().map(|(texture_id,texture)| (texture_id,match texture{ strafesnet_deferred_loader::texture::Texture::ImageDDS(data)=>data, }) ) ); Ok(map) }, DataStructure::Source(bsp)=>{ let mut loader=strafesnet_deferred_loader::source_legacy(); let (texture_loader,mesh_loader)=loader.get_inner_mut(); let map_step1=strafesnet_bsp_loader::convert( &bsp, |name|texture_loader.acquire_render_config_id(name), |name|mesh_loader.acquire_mesh_id(name), ); let prop_meshes=mesh_loader.load_meshes(&bsp.as_ref()); let map_step2=map_step1.add_prop_meshes( //the type conflagulator 9000 prop_meshes.into_iter().map(|(mesh_id,loader_model)| (mesh_id,strafesnet_bsp_loader::data::ModelData{ mdl:strafesnet_bsp_loader::data::MdlData::new(loader_model.mdl.get()), vtx:strafesnet_bsp_loader::data::VtxData::new(loader_model.vtx.get()), vvd:strafesnet_bsp_loader::data::VvdData::new(loader_model.vvd.get()), }) ), |name|texture_loader.acquire_render_config_id(name), ); let (textures,render_configs)=loader.into_render_configs().map_err(LoadError::Io)?.consume(); let map=map_step2.add_render_configs_and_textures( render_configs.into_iter(), textures.into_iter().map(|(texture_id,texture)| (texture_id,match texture{ strafesnet_deferred_loader::texture::Texture::ImageDDS(data)=>data, }) ), ); Ok(map) }, } }