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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
use image::{DynamicImage, GenericImageView};
use glium::texture::RawImage2d;
use std::collections::HashMap;
use std::fs::File;
use std::io::BufReader;
use serde_json::Value;
use Value::Object;
use glium::backend::Facade;
struct Texture {
pub image: DynamicImage,
}
impl Texture {
pub fn from_file(path: &str) -> Texture {
Texture {
image: image::open(path).unwrap(),
}
}
pub fn as_raw_image_2d(&self) -> RawImage2d<u8> {
return glium::texture::RawImage2d::from_raw_rgba_reversed(&self.image.to_rgba8().into_raw(), self.image.dimensions());
}
}
const DEFAULT_CONFIG_PATH: &str = "texture_config.json";
pub struct TextureBag {
config_data: HashMap<String, String>,
textures: HashMap<String, glium::texture::Texture2d>,
}
impl TextureBag {
pub fn init_eager<F>(facade: &F, config_path: Option<String>)
-> TextureBag where F: Facade
{
let path = match config_path {
Some(path) => path,
None => String::from(DEFAULT_CONFIG_PATH),
};
let file = File::open(&path).unwrap();
let buffered_reader = BufReader::new(file);
let file_data: Value = serde_json::from_reader(buffered_reader).unwrap();
let loaded_textures_config = file_data.get("textures").unwrap();
let mut converted_config: HashMap<String, String> = HashMap::new();
match loaded_textures_config {
Object(config) => {
for entry in config.clone() {
match entry.1 {
Value::String(path) => {
converted_config.insert(entry.0, path);
}
_ => panic!("Expected texture path for texture ID {}", entry.0)
}
}
}
_ => panic!("Invalid JSON structure. Expected 'textures' key-value object.")
}
let mut loaded_textures: HashMap<String, glium::texture::Texture2d> = HashMap::new();
for texture in converted_config.clone() {
loaded_textures.insert(
texture.0,
glium::texture::Texture2d::new(facade, Texture::from_file(texture.1.as_str()).as_raw_image_2d()).unwrap()
);
}
TextureBag {
config_data: converted_config,
textures: loaded_textures
}
}
pub fn init_lazy<F>(_facade: &F, config_path: Option<String>)
-> TextureBag where F: Facade
{
let path = match config_path {
Some(path) => path,
None => String::from(DEFAULT_CONFIG_PATH),
};
let file = File::open(&path).unwrap();
let buffered_reader = BufReader::new(file);
let file_data: Value = serde_json::from_reader(buffered_reader).unwrap();
let loaded_textures_config = file_data.get("textures").unwrap();
let mut converted_config: HashMap<String, String> = HashMap::new();
match loaded_textures_config {
Object(config) => {
for entry in config.clone() {
match entry.1 {
Value::String(path) => {
converted_config.insert(entry.0, path);
}
_ => panic!("Expected texture path for texture ID {}", entry.0)
}
}
}
_ => panic!("Invalid JSON structure. Expected 'textures' key-value object.")
}
TextureBag {
config_data: converted_config,
textures: HashMap::new(),
}
}
pub fn get_texture<F>(&mut self, texture_id: String, facade: &F)
-> &glium::texture::Texture2d where F: Facade
{
if self.textures.get(&texture_id).is_none() {
let texture_path = match self.config_data.get(&texture_id) {
Some(path) => path.clone(),
None => panic!("Unknown texture_id provided to bag: {}", &texture_id),
};
let loaded_texture = glium::texture::Texture2d::new(facade, Texture::from_file(texture_path.as_str()).as_raw_image_2d()).unwrap();
self.textures.insert(
texture_id.clone(),
loaded_texture
);
}
return self.textures.get(&texture_id).unwrap();
}
pub fn forget(&mut self, texture_id: String) {
self.textures.remove(texture_id.as_str());
}
}