Unravel Engine C++ Reference
Loading...
Searching...
No Matches
asset_reader.cpp
Go to the documentation of this file.
1#include "asset_reader.h"
2#include "graphics/graphics.h"
3
15
18#include <cstdint>
20#include <graphics/shader.h>
21#include <graphics/texture.h>
22#include <logging/logging.h>
23#include <string_utils/utils.h>
24
26{
27
28auto resolve_compiled_key(const std::string& key) -> std::string
29{
31}
32
33auto resolve_compiled_path(const std::string& key) -> fs::path
34{
35 auto cache_key = resolve_compiled_key(key);
36 return fs::absolute(fs::resolve_protocol(cache_key));
37}
38
39auto resolve_path(const std::string& key) -> fs::path
40{
41 return fs::absolute(fs::resolve_protocol(key));
42}
43
44void log_missing_compiled_asset_for_key(const std::string& key)
45{
46 APPLOG_WARNING("Compiled asset {0} does not exist!"
47 "Falling back to raw asset.",
48 key);
49}
50
51void log_missing_raw_asset_for_key(const std::string& key)
52{
53 APPLOG_ERROR("Asset {0} does not exist!", key);
54}
55
56void log_unknown_protocol_for_key(const std::string& key)
57{
58 APPLOG_ERROR("Asset {0} has unknown protocol!", key);
59}
60
61auto validate(const std::string& key, const std::string& compiled_ext, std::string& out) -> bool
62{
64 {
66 return false;
67 }
68
69 auto compiled_absolute_path = resolve_compiled_path(key).string() + compiled_ext;
70
71 fs::error_code err;
72 if(!fs::exists(compiled_absolute_path, err))
73 {
74 log_missing_compiled_asset_for_key(compiled_absolute_path);
75
76 compiled_absolute_path = resolve_path(key).string();
77 }
78
79 if(!fs::exists(compiled_absolute_path, err))
80 {
82 return false;
83 }
84
85 out = compiled_absolute_path;
86 return true;
87}
88
89template<>
90auto load_from_file<gfx::texture>(tpp::thread_pool& pool, asset_handle<gfx::texture>& output, const std::string& key)
91 -> bool
92{
93 std::string compiled_absolute_path{};
94
95 if(!validate(key, {}, compiled_absolute_path))
96 {
97 return false;
98 }
99
100 auto create_resource_func = [compiled_absolute_path]()
101 {
102 return std::make_shared<gfx::texture>(compiled_absolute_path.c_str());
103 };
104
105 auto job = pool.schedule(get_job_name<gfx::texture>(), create_resource_func).share();
106
107 output.set_internal_job(job);
108
109 return true;
110}
111
112template<>
113auto load_from_file<gfx::shader>(tpp::thread_pool& pool, asset_handle<gfx::shader>& output, const std::string& key)
114 -> bool
115{
116 std::string compiled_absolute_path{};
117
118 if(!validate(key, gfx::get_current_renderer_filename_extension(), compiled_absolute_path))
119 {
120 return false;
121 }
122
123 auto create_resource_func = [compiled_absolute_path, key]()
124 {
125 auto stream = std::ifstream{compiled_absolute_path, std::ios::binary};
126 auto read_memory = fs::read_stream(stream);
127
128 const gfx::memory_view* mem = gfx::copy(read_memory.data(), static_cast<std::uint32_t>(read_memory.size()));
129
130 auto shader = std::make_shared<gfx::shader>(mem);
131
132 gfx::set_name(shader->native_handle(), key.c_str(), static_cast<int32_t>(key.size()));
133
134 return shader;
135 };
136
137 auto job = pool.schedule(get_job_name<gfx::shader>(), create_resource_func).share();
138 output.set_internal_job(job);
139
140 return true;
141}
142
143template<>
144auto load_from_file<material>(tpp::thread_pool& pool, asset_handle<material>& output, const std::string& key) -> bool
145{
146 std::string compiled_absolute_path{};
147
148 if(!validate(key, {}, compiled_absolute_path))
149 {
150 return false;
151 }
152
153 auto create_resource_func = [compiled_absolute_path]()
154 {
155 std::shared_ptr<unravel::material> material;
156 load_from_file_bin(compiled_absolute_path, material);
157 return material;
158 };
159
160 auto job = pool.schedule(get_job_name<material>(), create_resource_func).share();
161 output.set_internal_job(job);
162
163 return true;
164}
165
166template<>
167auto load_from_file<mesh>(tpp::thread_pool& pool, asset_handle<mesh>& output, const std::string& key) -> bool
168{
169 std::string compiled_absolute_path{};
170
171 if(!validate(key, {}, compiled_absolute_path))
172 {
173 return false;
174 }
175
176 auto create_resource_func = [compiled_absolute_path]()
177 {
178 mesh::load_data data;
179 load_from_file_bin(compiled_absolute_path, data);
180
181 auto mesh = std::make_shared<unravel::mesh>();
182 mesh->load_mesh(std::move(data));
183 return mesh;
184 };
185
186 auto job = pool.schedule(get_job_name<mesh>(), create_resource_func).share();
187 output.set_internal_job(job);
188
189 return true;
190}
191
192
193template<>
194auto load_from_file<animation_clip>(tpp::thread_pool& pool, asset_handle<animation_clip>& output, const std::string& key) -> bool
195{
196 std::string compiled_absolute_path{};
197
198 if(!validate(key, {}, compiled_absolute_path))
199 {
200 return false;
201 }
202
203 auto create_resource_func = [compiled_absolute_path]()
204 {
205 auto anim = std::make_shared<animation_clip>();
206 load_from_file_bin(compiled_absolute_path, *anim);
207
208 return anim;
209 };
210
211 auto job = pool.schedule(get_job_name<animation_clip>(), create_resource_func).share();
212 output.set_internal_job(job);
213
214 return true;
215}
216
217template<>
218auto load_from_file<prefab>(tpp::thread_pool& pool, asset_handle<prefab>& output, const std::string& key) -> bool
219{
220 std::string compiled_absolute_path{};
221
222 if(!validate(key, {}, compiled_absolute_path))
223 {
224 return false;
225 }
226
227 auto create_resource_func = [compiled_absolute_path]()
228 {
229 auto pfb = std::make_shared<prefab>();
230
231 auto stream = std::ifstream{compiled_absolute_path};
232 pfb->buffer = fs::read_stream_buffer(stream);
233 return pfb;
234 };
235
236 auto job = pool.schedule(get_job_name<prefab>(), create_resource_func).share();
237 output.set_internal_job(job);
238
239 return true;
240}
241
242template<>
243auto load_from_file<scene_prefab>(tpp::thread_pool& pool, asset_handle<scene_prefab>& output, const std::string& key)
244 -> bool
245{
246 std::string compiled_absolute_path{};
247
248 if(!validate(key, {}, compiled_absolute_path))
249 {
250 return false;
251 }
252
253 auto create_resource_func = [compiled_absolute_path]()
254 {
255 auto pfb = std::make_shared<scene_prefab>();
256
257 auto stream = std::ifstream{compiled_absolute_path};
258 pfb->buffer = fs::read_stream_buffer(stream);
259 return pfb;
260 };
261
262 auto job = pool.schedule(get_job_name<scene_prefab>(), create_resource_func).share();
263 output.set_internal_job(job);
264
265 return true;
266}
267
268template<>
269auto load_from_file<physics_material>(tpp::thread_pool& pool,
271 const std::string& key) -> bool
272{
273 std::string compiled_absolute_path{};
274
275 if(!validate(key, {}, compiled_absolute_path))
276 {
277 return false;
278 }
279
280 auto create_resource_func = [compiled_absolute_path]()
281 {
282 auto material = std::make_shared<physics_material>();
283 load_from_file_bin(compiled_absolute_path, material);
284 return material;
285 };
286
287 auto job = pool.schedule(get_job_name<physics_material>(), create_resource_func).share();
288 output.set_internal_job(job);
289
290 return true;
291}
292
293template<>
294auto load_from_file<audio_clip>(tpp::thread_pool& pool, asset_handle<audio_clip>& output, const std::string& key)
295 -> bool
296{
297 std::string compiled_absolute_path{};
298
299 if(!validate(key, {}, compiled_absolute_path))
300 {
301 return false;
302 }
303
304 auto create_load_func = [compiled_absolute_path]()
305 {
306 auto data = std::make_shared<audio::sound_data>();
307 load_from_file_bin(compiled_absolute_path, *data);
308 return data;
309 };
310
311 auto create_resource_func = [compiled_absolute_path]()
312 {
313 audio::sound_data data;
314 load_from_file_bin(compiled_absolute_path, data);
315
316 auto create_job = tpp::async(tpp::main_thread::get_id(),
317 [data = std::move(data)]() mutable
318 {
319 auto clip = std::make_shared<audio_clip>(std::move(data), false);
320 return clip;
321 });
322
323 return create_job.get();
324 };
325
326 auto job = pool.schedule(get_job_name<audio_clip>(), create_resource_func).share();
327
328 output.set_internal_job(job);
329
330 return true;
331}
332
333template<>
334auto load_from_file<font>(tpp::thread_pool& pool, asset_handle<font>& output, const std::string& key)
335 -> bool
336{
337 std::string compiled_absolute_path{};
338
339 if(!validate(key, {}, compiled_absolute_path))
340 {
341 return false;
342 }
343
344 auto create_resource_func = [compiled_absolute_path]()
345 {
346 auto create_job = tpp::async(tpp::main_thread::get_id(),
347 [compiled_absolute_path]() mutable
348 {
349 auto fnt = std::make_shared<font>(compiled_absolute_path.c_str(), 0, 86, FONT_TYPE_DISTANCE_OUTLINE_DROP_SHADOW_IMAGE, 8, 8);
350 return fnt;
351 });
352
353 return create_job.get();
354 };
355
356 auto job = pool.schedule(get_job_name<font>(), create_resource_func).share();
357
358 output.set_internal_job(job);
359
360 return true;
361}
362
363template<>
364auto load_from_file<script>(tpp::thread_pool& pool, asset_handle<script>& output, const std::string& key)
365 -> bool
366{
367 std::string compiled_absolute_path{};
368
369 if(!validate(key, {}, compiled_absolute_path))
370 {
371 return false;
372 }
373
374 auto create_resource_func = [compiled_absolute_path]()
375 {
376 auto scr = std::make_shared<script>();
377 load_from_file_bin(compiled_absolute_path, scr);
378 return scr;
379 };
380
381 auto job = pool.schedule(get_job_name<script>(), create_resource_func).share();
382 output.set_internal_job(job);
383
384 return true;
385}
386
387template<>
388auto load_from_file<ui_tree>(tpp::thread_pool& pool, asset_handle<ui_tree>& output, const std::string& key)
389 -> bool
390{
391 std::string compiled_absolute_path{};
392
393 if(!validate(key, {}, compiled_absolute_path))
394 {
395 return false;
396 }
397
398 auto create_resource_func = [compiled_absolute_path]()
399 {
400 auto tree = std::make_shared<ui_tree>();
401 load_from_file(compiled_absolute_path, tree);
402 return tree;
403 };
404
405 auto job = pool.schedule(get_job_name<ui_tree>(), create_resource_func).share();
406 output.set_internal_job(job);
407
408 return true;
409}
410
411template<>
412auto load_from_file<style_sheet>(tpp::thread_pool& pool, asset_handle<style_sheet>& output, const std::string& key)
413 -> bool
414{
415 std::string compiled_absolute_path{};
416
417 if(!validate(key, {}, compiled_absolute_path))
418 {
419 return false;
420 }
421
422 auto create_resource_func = [compiled_absolute_path]()
423 {
424 auto sheet = std::make_shared<style_sheet>();
425 load_from_file(compiled_absolute_path, sheet);
426 return sheet;
427 };
428
429 auto job = pool.schedule(get_job_name<style_sheet>(), create_resource_func).share();
430 output.set_internal_job(job);
431
432 return true;
433}
434
435} // namespace unravel::asset_reader
Base class for materials used in rendering.
Definition material.h:32
Main class representing a 3D mesh with support for different LODs, submeshes, and skinning.
Definition mesh.h:310
auto load_mesh(load_data &&data) -> bool
Definition mesh.cpp:723
#define FONT_TYPE_DISTANCE_OUTLINE_DROP_SHADOW_IMAGE
#define APPLOG_WARNING(...)
Definition logging.h:19
#define APPLOG_ERROR(...)
Definition logging.h:20
auto get_data_directory(const std::string &prefix={}) -> std::string
auto get_compiled_directory(const std::string &prefix={}) -> std::string
byte_array_t read_stream(std::istream &stream)
Load a byte_array_t with the contents of the specified file, be that file in a package or in the main...
path resolve_protocol(const path &_path)
Given the specified path/filename, resolve the final full filename. This will be based on either the ...
bool has_known_protocol(const path &_path)
Checks whether the path has a known protocol.
stream_buffer< byte_array_t > read_stream_buffer(std::istream &stream)
void set_name(shader_handle _handle, const char *_name, int32_t _len)
Definition graphics.cpp:462
const memory_view * copy(const void *_data, uint32_t _size)
Definition graphics.cpp:301
auto get_current_renderer_filename_extension() -> const std::string &
bgfx::Memory memory_view
Definition graphics.h:23
auto replace(const std::string &str, const std::string &search, const std::string &replace) -> std::string
Definition utils.cpp:28
auto load_from_file(tpp::thread_pool &pool, asset_handle< T > &output, const std::string &key) -> bool
auto resolve_path(const std::string &key) -> fs::path
auto load_from_file< font >(tpp::thread_pool &pool, asset_handle< font > &output, const std::string &key) -> bool
void log_unknown_protocol_for_key(const std::string &key)
void log_missing_compiled_asset_for_key(const std::string &key)
auto load_from_file< gfx::texture >(tpp::thread_pool &pool, asset_handle< gfx::texture > &output, const std::string &key) -> bool
auto load_from_file< scene_prefab >(tpp::thread_pool &pool, asset_handle< scene_prefab > &output, const std::string &key) -> bool
auto load_from_file< style_sheet >(tpp::thread_pool &pool, asset_handle< style_sheet > &output, const std::string &key) -> bool
auto load_from_file< mesh >(tpp::thread_pool &pool, asset_handle< mesh > &output, const std::string &key) -> bool
auto resolve_compiled_path(const std::string &key) -> fs::path
auto validate(const std::string &key, const std::string &compiled_ext, std::string &out) -> bool
auto load_from_file< material >(tpp::thread_pool &pool, asset_handle< material > &output, const std::string &key) -> bool
auto load_from_file< gfx::shader >(tpp::thread_pool &pool, asset_handle< gfx::shader > &output, const std::string &key) -> bool
auto load_from_file< physics_material >(tpp::thread_pool &pool, asset_handle< physics_material > &output, const std::string &key) -> bool
auto load_from_file< ui_tree >(tpp::thread_pool &pool, asset_handle< ui_tree > &output, const std::string &key) -> bool
auto resolve_compiled_key(const std::string &key) -> std::string
void log_missing_raw_asset_for_key(const std::string &key)
auto load_from_file< prefab >(tpp::thread_pool &pool, asset_handle< prefab > &output, const std::string &key) -> bool
auto load_from_file< script >(tpp::thread_pool &pool, asset_handle< script > &output, const std::string &key) -> bool
auto load_from_file< audio_clip >(tpp::thread_pool &pool, asset_handle< audio_clip > &output, const std::string &key) -> bool
auto load_from_file< animation_clip >(tpp::thread_pool &pool, asset_handle< animation_clip > &output, const std::string &key) -> bool
auto get_job_name() -> std::string
void load_from_file_bin(const std::string &absolute_path, animation_clip &obj)
Represents a handle to an asset, providing access and management functions.
Struct used for mesh construction.
Definition mesh.h:388