1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
pub mod load;
pub mod mat;
pub mod prelude {
pub use crate::load::*;
pub use crate::mat::*;
pub use crate::*;
}
use crate::load::LoadOptions;
use load::{Loader, MeshDescriptor, SceneDescriptor};
use std::{collections::HashMap, error::Error, fmt::Display, path::PathBuf, write};
#[derive(Debug, Clone)]
pub enum LoadResult {
Mesh(MeshDescriptor),
Scene(SceneDescriptor),
None(LoadError),
}
#[derive(Debug, Clone)]
pub enum LoadError {
NoFileExtension,
UnsupportedExtension(String),
FileDoesNotExist(PathBuf),
InvalidFile(PathBuf),
TextureDoesNotExist(PathBuf),
}
impl Display for LoadError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
LoadError::FileDoesNotExist(file) =>
format!("File does not exist: {}", file.display()),
LoadError::TextureDoesNotExist(file) =>
format!("Texture does not exist: {}", file.display()),
LoadError::InvalidFile(file) =>
format!("File might be corrupted: {}", file.display()),
LoadError::NoFileExtension => String::from("No file extension"),
LoadError::UnsupportedExtension(ext) =>
format!("Unsupported file extension: {}", ext),
}
)
}
}
impl Error for LoadError {}
pub struct LoadInstance {
loaders: HashMap<String, Box<dyn Loader>>,
}
impl LoadInstance {
pub fn new() -> Self {
Self {
loaders: HashMap::new(),
}
}
pub fn with_default(mut self) -> Self {
let obj_loader = load::obj::ObjLoader::default();
for f in obj_loader.file_extensions() {
self.loaders
.insert(f, Box::new(load::obj::ObjLoader::default()));
}
let gltf_loader = load::gltf::GltfLoader::default();
for f in gltf_loader.file_extensions() {
self.loaders
.insert(f, Box::new(load::gltf::GltfLoader::default()));
}
self
}
pub fn with_loader<T: Loader + Sized + Clone + 'static>(mut self, loader: T) -> Self {
let file_names = loader.file_extensions();
for f in file_names {
let f = String::from(f);
let loader: Box<dyn Loader> = Box::new(loader.clone());
self.loaders.insert(f, loader);
}
self
}
pub fn load(&self, options: LoadOptions) -> LoadResult {
let ext = match options.path.extension() {
Some(e) => e,
None => return LoadResult::None(LoadError::NoFileExtension),
};
let ext = ext.to_str().unwrap().to_string();
if let Some(loader) = self.loaders.get(&ext) {
loader.load(options)
} else {
return LoadResult::None(LoadError::UnsupportedExtension(ext));
}
}
}