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>
21#include <graphics/shader.h>
22#include <graphics/texture.h>
23#include <logging/logging.h>
24#include <string_utils/utils.h>
25
27{
28
29auto resolve_compiled_key(const std::string& key) -> std::string
30{
32}
33
34auto resolve_compiled_path(const std::string& key) -> fs::path
35{
36 auto cache_key = resolve_compiled_key(key);
37 return fs::absolute(fs::resolve_protocol(cache_key));
38}
39
40auto resolve_compiled_asset_path(const std::string& key, const std::string& source_extension) -> fs::path
41{
43 {
44 return {};
45 }
46
47 std::string compiled_ext;
48 if(ex::is_format<gfx::shader>(source_extension))
49 {
51 }
52 else
53 {
54 bool known_source = false;
55 for(const auto& formats : ex::get_all_formats())
56 {
57 for(const auto& format : formats)
58 {
59 if(format == source_extension)
60 {
61 known_source = true;
62 break;
63 }
64 }
65 if(known_source)
66 {
67 break;
68 }
69 }
70
71 if(!known_source)
72 {
73 return {};
74 }
75 }
76
77 return fs::path(resolve_compiled_path(key).string() + compiled_ext);
78}
79
80auto resolve_path(const std::string& key) -> fs::path
81{
82 return fs::absolute(fs::resolve_protocol(key));
83}
84
85void log_missing_compiled_asset_for_key(const std::string& key)
86{
87 APPLOG_WARNING("Compiled asset {0} does not exist!"
88 "Falling back to raw asset.",
89 key);
90}
91
92void log_missing_raw_asset_for_key(const std::string& key)
93{
94 APPLOG_ERROR("Asset {0} does not exist!", key);
95}
96
97void log_unknown_protocol_for_key(const std::string& key)
98{
99 APPLOG_ERROR("Asset {0} has unknown protocol!", key);
100}
101
102auto validate(const std::string& key, const std::string& compiled_ext, std::string& out) -> bool
103{
104 if(!fs::has_known_protocol(key))
105 {
107 return false;
108 }
109
110 auto compiled_absolute_path = resolve_compiled_path(key).string() + compiled_ext;
111
112 fs::error_code err;
113 if(!fs::exists(compiled_absolute_path, err))
114 {
115 log_missing_compiled_asset_for_key(compiled_absolute_path);
116
117 compiled_absolute_path = resolve_path(key).string();
118 }
119
120 if(!fs::exists(compiled_absolute_path, err))
121 {
123 return false;
124 }
125
126 out = compiled_absolute_path;
127 return true;
128}
129
130namespace detail
131{
132
133template<typename T, typename CreateFromPathFn>
134auto schedule_load(tpp::thread_pool& pool, asset_handle<T>& output, const std::string& key,
135 const std::string& compiled_ext, CreateFromPathFn create_fn, load_mode mode) -> bool
136{
137 if(mode == load_mode::deferred)
138 {
139 auto deferred_fn = [key, compiled_ext, create_fn]() -> std::shared_ptr<T>
140 {
141 std::string path{};
142 if(!validate(key, compiled_ext, path))
143 {
144 return nullptr;
145 }
146 return create_fn(path);
147 };
148 output.set_internal_job(pool.create_job(get_job_name<T>(), deferred_fn).share());
149 return true;
150 }
151
152 std::string path{};
153 if(!validate(key, compiled_ext, path))
154 {
155 return false;
156 }
157 auto immediate_fn = [path, create_fn]() -> std::shared_ptr<T>
158 {
159 return create_fn(path);
160 };
161 output.set_internal_job(pool.schedule(get_job_name<T>(), immediate_fn).share());
162 return true;
163}
164
165} // namespace detail
166
167template<>
168auto load_from_file<gfx::texture>(tpp::thread_pool& pool, asset_handle<gfx::texture>& output,
169 const std::string& key, load_mode mode) -> bool
170{
171 return detail::schedule_load<gfx::texture>(pool, output, key, {},
172 [](const std::string& path)
173 {
174 return std::make_shared<gfx::texture>(path.c_str());
175 }, mode);
176}
177
178template<>
179auto load_from_file<gfx::shader>(tpp::thread_pool& pool, asset_handle<gfx::shader>& output,
180 const std::string& key, load_mode mode) -> bool
181{
182 return detail::schedule_load<gfx::shader>(pool, output, key,
184 [key](const std::string& path)
185 {
186 return std::make_shared<gfx::shader>(path);
187 }, mode);
188}
189
190template<>
191auto load_from_file<material>(tpp::thread_pool& pool, asset_handle<material>& output,
192 const std::string& key, load_mode mode) -> bool
193{
194 return detail::schedule_load<material>(pool, output, key, {},
195 [](const std::string& path)
196 {
197 std::shared_ptr<unravel::material> mat;
198 load_from_file_bin(path, mat);
199 return mat;
200 }, mode);
201}
202
203template<>
204auto load_from_file<mesh>(tpp::thread_pool& pool, asset_handle<mesh>& output,
205 const std::string& key, load_mode mode) -> bool
206{
207 return detail::schedule_load<mesh>(pool, output, key, {},
208 [](const std::string& path)
209 {
210 mesh::load_data data;
211 load_from_file_bin(path, data);
212
213 auto m = std::make_shared<unravel::mesh>();
214 m->load_mesh(std::move(data));
215 return m;
216 }, mode);
217}
218
219template<>
221 const std::string& key, load_mode mode) -> bool
222{
223 return detail::schedule_load<animation_clip>(pool, output, key, {},
224 [](const std::string& path)
225 {
226 auto anim = std::make_shared<animation_clip>();
227 load_from_file_bin(path, *anim);
228 return anim;
229 }, mode);
230}
231
232template<>
233auto load_from_file<prefab>(tpp::thread_pool& pool, asset_handle<prefab>& output,
234 const std::string& key, load_mode mode) -> bool
235{
236 return detail::schedule_load<prefab>(pool, output, key, {},
237 [](const std::string& path)
238 {
239 auto pfb = std::make_shared<prefab>();
240 auto stream = std::ifstream{path};
241 pfb->buffer = fs::read_stream_buffer(stream);
242 return pfb;
243 }, mode);
244}
245
246template<>
247auto load_from_file<scene_prefab>(tpp::thread_pool& pool, asset_handle<scene_prefab>& output,
248 const std::string& key, load_mode mode) -> bool
249{
250 return detail::schedule_load<scene_prefab>(pool, output, key, {},
251 [](const std::string& path)
252 {
253 auto pfb = std::make_shared<scene_prefab>();
254 auto stream = std::ifstream{path};
255 pfb->buffer = fs::read_stream_buffer(stream);
256 return pfb;
257 }, mode);
258}
259
260template<>
262 const std::string& key, load_mode mode) -> bool
263{
264 return detail::schedule_load<physics_material>(pool, output, key, {},
265 [](const std::string& path)
266 {
267 auto mat = std::make_shared<physics_material>();
268 load_from_file_bin(path, mat);
269 return mat;
270 }, mode);
271}
272
273template<>
274auto load_from_file<audio_clip>(tpp::thread_pool& pool, asset_handle<audio_clip>& output,
275 const std::string& key, load_mode mode) -> bool
276{
277 return detail::schedule_load<audio_clip>(pool, output, key, {},
278 [](const std::string& path)
279 {
280 audio::sound_data data;
281 load_from_file_bin(path, data);
282
283 auto create_job = tpp::async(tpp::main_thread::get_id(),
284 [data = std::move(data)]() mutable
285 {
286 return std::make_shared<audio_clip>(std::move(data), false);
287 });
288
289 return create_job.get();
290 }, mode);
291}
292
293template<>
294auto load_from_file<font>(tpp::thread_pool& pool, asset_handle<font>& output,
295 const std::string& key, load_mode mode) -> bool
296{
297 return detail::schedule_load<font>(pool, output, key, {},
298 [](const std::string& path)
299 {
300 auto create_job = tpp::async(tpp::main_thread::get_id(),
301 [path]()
302 {
303 return std::make_shared<font>(path.c_str(), 0, 86,
305 });
306
307 return create_job.get();
308 }, mode);
309}
310
311template<>
312auto load_from_file<script>(tpp::thread_pool& pool, asset_handle<script>& output,
313 const std::string& key, load_mode mode) -> bool
314{
315 return detail::schedule_load<script>(pool, output, key, {},
316 [](const std::string& path)
317 {
318 auto scr = std::make_shared<script>();
319 load_from_file_bin(path, scr);
320 return scr;
321 }, mode);
322}
323
324template<>
325auto load_from_file<ui_tree>(tpp::thread_pool& pool, asset_handle<ui_tree>& output,
326 const std::string& key, load_mode mode) -> bool
327{
328 return detail::schedule_load<ui_tree>(pool, output, key, {},
329 [](const std::string& path)
330 {
331 auto tree = std::make_shared<ui_tree>();
332 load_from_file(path, tree);
333 return tree;
334 }, mode);
335}
336
337template<>
338auto load_from_file<style_sheet>(tpp::thread_pool& pool, asset_handle<style_sheet>& output,
339 const std::string& key, load_mode mode) -> bool
340{
341 return detail::schedule_load<style_sheet>(pool, output, key, {},
342 [](const std::string& path)
343 {
344 auto sheet = std::make_shared<style_sheet>();
345 load_from_file(path, sheet);
346 return sheet;
347 }, mode);
348}
349
350} // namespace unravel::asset_reader
gfx::texture_format format
#define FONT_TYPE_DISTANCE_OUTLINE_DROP_SHADOW_IMAGE
#define APPLOG_WARNING(...)
Definition logging.h:19
#define APPLOG_ERROR(...)
Definition logging.h:20
auto get_all_formats() -> const std::vector< std::vector< std::string > > &
auto get_data_directory(const std::string &prefix={}) -> std::string
auto is_format(const std::string &ex) -> bool
auto get_compiled_directory(const std::string &prefix={}) -> std::string
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)
auto get_current_renderer_filename_extension() -> const std::string &
auto replace(const std::string &str, const std::string &search, const std::string &replace) -> std::string
Definition utils.cpp:28
auto schedule_load(tpp::thread_pool &pool, asset_handle< T > &output, const std::string &key, const std::string &compiled_ext, CreateFromPathFn create_fn, load_mode mode) -> bool
auto resolve_path(const std::string &key) -> fs::path
auto load_from_file< gfx::texture >(tpp::thread_pool &pool, asset_handle< gfx::texture > &output, const std::string &key, load_mode mode) -> 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< scene_prefab >(tpp::thread_pool &pool, asset_handle< scene_prefab > &output, const std::string &key, load_mode mode) -> bool
auto load_from_file(tpp::thread_pool &pool, asset_handle< T > &output, const std::string &key, load_mode mode=load_mode::immediate) -> bool
auto load_from_file< style_sheet >(tpp::thread_pool &pool, asset_handle< style_sheet > &output, const std::string &key, load_mode mode) -> bool
auto resolve_compiled_asset_path(const std::string &key, const std::string &source_extension) -> fs::path
auto load_from_file< material >(tpp::thread_pool &pool, asset_handle< material > &output, const std::string &key, load_mode mode) -> 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< gfx::shader >(tpp::thread_pool &pool, asset_handle< gfx::shader > &output, const std::string &key, load_mode mode) -> bool
auto load_from_file< mesh >(tpp::thread_pool &pool, asset_handle< mesh > &output, const std::string &key, load_mode mode) -> bool
auto load_from_file< script >(tpp::thread_pool &pool, asset_handle< script > &output, const std::string &key, load_mode mode) -> bool
auto load_from_file< ui_tree >(tpp::thread_pool &pool, asset_handle< ui_tree > &output, const std::string &key, load_mode mode) -> bool
auto load_from_file< animation_clip >(tpp::thread_pool &pool, asset_handle< animation_clip > &output, const std::string &key, load_mode mode) -> bool
auto load_from_file< audio_clip >(tpp::thread_pool &pool, asset_handle< audio_clip > &output, const std::string &key, load_mode mode) -> bool
auto load_from_file< physics_material >(tpp::thread_pool &pool, asset_handle< physics_material > &output, const std::string &key, load_mode mode) -> 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, load_mode mode) -> bool
auto load_from_file< font >(tpp::thread_pool &pool, asset_handle< font > &output, const std::string &key, load_mode mode) -> bool
auto get_job_name() -> std::string
void load_from_file_bin(const std::string &absolute_path, animation_clip &obj)
load_mode
Controls whether an asset is loaded immediately or deferred until first access.
Definition asset_flags.h:17
@ deferred
Register handle only; load triggered on first .get() call.
Thread-safe handle to an asset.
Struct used for mesh construction.
Definition mesh.h:451