Unravel Engine C++ Reference
Loading...
Searching...
No Matches
asset_manager.cpp
Go to the documentation of this file.
1#include "asset_manager.h"
3#include "impl/asset_reader.h"
5
8#include <engine/ecs/prefab.h>
11#include <engine/ui/ui_tree.h>
16
18
19#include <graphics/shader.h>
20#include <graphics/texture.h>
21
22namespace unravel
23{
24asset_manager::asset_manager(rtti::context& ctx) : pool_(*ctx.get_cached<threader>().pool)
25{
26}
27
29
31{
32 parent_ = parent;
33}
34
36{
37 APPLOG_TRACE("{}::{}", hpp::type_name_str(*this), __func__);
38
40 init_fonts();
41 {
42 auto& storage = add_storage<gfx::shader>();
43 storage.load_from_file = asset_reader::load_from_file<gfx::shader>;
44 storage.load_from_instance = asset_reader::load_from_instance<gfx::shader>;
45 }
46 {
47 auto& storage = add_storage<gfx::texture>();
48 storage.load_from_file = asset_reader::load_from_file<gfx::texture>;
49 storage.load_from_instance = asset_reader::load_from_instance<gfx::texture>;
50 }
51
52 {
53 auto& storage = add_storage<material>();
54 storage.load_from_file = asset_reader::load_from_file<material>;
55 storage.load_from_instance = asset_reader::load_from_instance<material>;
56 }
57
58 {
59 auto& storage = add_storage<mesh>();
60 storage.load_from_file = asset_reader::load_from_file<mesh>;
61 storage.load_from_instance = asset_reader::load_from_instance<mesh>;
62 }
63
64 {
65 auto& storage = add_storage<animation_clip>();
66 storage.load_from_file = asset_reader::load_from_file<animation_clip>;
67 storage.load_from_instance = asset_reader::load_from_instance<animation_clip>;
68 }
69
70 {
71 auto& storage = add_storage<prefab>();
72 storage.load_from_file = asset_reader::load_from_file<prefab>;
73 storage.load_from_instance = asset_reader::load_from_instance<prefab>;
74 }
75
76 {
77 auto& storage = add_storage<scene_prefab>();
78 storage.load_from_file = asset_reader::load_from_file<scene_prefab>;
79 storage.load_from_instance = asset_reader::load_from_instance<scene_prefab>;
80 }
81
82 {
83 auto& storage = add_storage<physics_material>();
85 storage.load_from_instance = asset_reader::load_from_instance<physics_material>;
86 }
87
88 {
89 auto& storage = add_storage<ui_tree>();
90 storage.load_from_file = asset_reader::load_from_file<ui_tree>;
91 storage.load_from_instance = asset_reader::load_from_instance<ui_tree>;
92 }
93
94 {
95 auto& storage = add_storage<style_sheet>();
96 storage.load_from_file = asset_reader::load_from_file<style_sheet>;
97 storage.load_from_instance = asset_reader::load_from_instance<style_sheet>;
98 }
99
100 {
101 auto& storage = add_storage<audio_clip>();
102 storage.load_from_file = asset_reader::load_from_file<audio_clip>;
103 storage.load_from_instance = asset_reader::load_from_instance<audio_clip>;
104 }
105
106 {
107 auto& storage = add_storage<font>();
108 storage.load_from_file = asset_reader::load_from_file<font>;
109 storage.load_from_instance = asset_reader::load_from_instance<font>;
110 }
111
112 {
113 auto& storage = add_storage<script>();
114 storage.load_from_file = asset_reader::load_from_file<script>;
115 storage.load_from_instance = asset_reader::load_from_instance<script>;
116 }
117
118 return true;
119}
120
122{
123 APPLOG_TRACE("{}::{}", hpp::type_name_str(*this), __func__);
124
125 storages_.clear();
126 databases_.clear();
127 deinit_fonts();
128
129 return true;
130}
131
133{
134 for(auto& pair : storages_)
135 {
136 auto& storage = pair.second;
137 storage->unload_all(pool_);
138 }
139
140 {
141 std::lock_guard<std::mutex> lock(db_mutex_);
142 databases_.clear();
143 }
144}
145
146void asset_manager::unload_group(const std::string& group)
147{
148 for(auto& pair : storages_)
149 {
150 auto& storage = pair.second;
151 storage->unload_group(pool_, group);
152 }
153
154 {
155 remove_database(group);
156 }
157}
158
159auto asset_manager::get_all_assets(const std::string& group) const -> std::vector<std::string>
160{
161 std::lock_guard<std::mutex> lock(db_mutex_);
162 auto protocol = fs::extract_protocol(fs::path(group));
163
164 std::vector<std::string> result;
165 for(auto& kvp : databases_)
166 {
167 if(kvp.first != protocol)
168 {
169 continue;
170 }
171 auto& db = kvp.second;
172 for(auto& kvp : db.get_database())
173 {
174 result.push_back(kvp.second.location);
175 }
176 }
177 return result;
178}
179
180auto asset_manager::get_database(const std::string& key) -> asset_database&
181{
182 auto protocol = fs::extract_protocol(fs::path(key));
183 return databases_[protocol.generic_string()];
184}
185
186void asset_manager::remove_database(const std::string& key)
187{
188 auto protocol = fs::extract_protocol(fs::path(key));
189
190 std::lock_guard<std::mutex> lock(db_mutex_);
191 databases_.erase(protocol.generic_string());
192}
193
194auto asset_manager::load_database(const std::string& protocol) -> bool
195{
196 auto assets_pack = fs::resolve_protocol(protocol + "assets.pack");
197
198 std::lock_guard<std::mutex> lock(db_mutex_);
199 auto& db = get_database(protocol);
200 return load_from_file(assets_pack.string(), db);
201}
202
203void asset_manager::save_database(const std::string& protocol, const fs::path& path)
204{
205 std::lock_guard<std::mutex> lock(db_mutex_);
206 auto& db = get_database(protocol);
207 save_to_file(path.string(), db);
208}
209
210auto asset_manager::add_asset(const std::string& key, bool override) -> hpp::uuid
211{
212 auto meta = generate_metadata(key);
213 return add_asset_info_for_key(key, meta, override);
214}
215
216auto asset_manager::add_asset_for_path(const fs::path& path, bool override) -> hpp::uuid
217{
218 auto key = fs::convert_to_protocol(path).generic_string();
219 return add_asset(key, override);
220}
221
222auto asset_manager::add_asset_info_for_path(const fs::path& path, const asset_meta& meta, bool override) -> hpp::uuid
223{
224 auto key = fs::convert_to_protocol(path).generic_string();
225 return add_asset_info_for_key(key, meta, override);
226}
227
228auto asset_manager::add_asset_info_for_key(const std::string& key, const asset_meta& meta, bool override) -> hpp::uuid
229{
230 std::lock_guard<std::mutex> lock(db_mutex_);
231 auto& db = get_database(key);
232 return db.add_asset(key, meta, override);
233}
234
235auto asset_manager::get_metadata(const hpp::uuid& uid) const -> asset_database::meta
236{
237 std::lock_guard<std::mutex> lock(db_mutex_);
238 for(auto& kvp : databases_)
239 {
240 auto& db = kvp.second;
241 const auto& meta = db.get_metadata(uid);
242 if(!meta.location.empty())
243 {
244 return meta;
245 }
246 }
247 return {};
248}
249
251{
252 const auto key = fs::convert_to_protocol(path).generic_string();
253 return get_metadata_for_key(key);
254}
255
257{
258 // `databases_` is keyed by *protocol* (e.g. "app"), not by full asset key.
259 // The asset's metadata lives inside the database for its protocol, so we
260 // need to extract the protocol from the key before doing the map lookup.
261 std::lock_guard<std::mutex> lock(db_mutex_);
262 const auto protocol = fs::extract_protocol(fs::path(key)).generic_string();
263 const auto it = databases_.find(protocol);
264 if(it == databases_.cend())
265 {
266 static const asset_database::meta empty;
267 return empty;
268 }
269 return it->second.get_metadata(key);
270}
271
272auto asset_manager::generate_metadata(const fs::path& p) const -> asset_meta
273{
274 asset_meta meta;
275 meta.type = p.extension().string();
276 auto protocol = fs::extract_protocol(p);
277 // embedded assets which must generate uid based on their name.
278 // All assets except application assets must generate uid based on their name.
279 if(meta.type.empty() || protocol != "app")
280 {
281 meta.uid = generate_uuid(p.generic_string());
282 }
283 else
284 {
285 meta.uid = generate_uuid();
286 }
287
288 return meta;
289}
290
292{
293 auto key = fs::convert_to_protocol(path).generic_string();
295}
296
298{
299 std::lock_guard<std::mutex> lock(db_mutex_);
300 auto& db = get_database(key);
301 db.remove_asset(key);
302}
303
304void asset_manager::evict_unused_assets(const std::string& group, std::chrono::steady_clock::duration max_idle)
305{
306 for(auto& [type_hash, storage] : storages_)
307 {
308 storage->evict_unused(pool_, group, max_idle);
309 }
310}
311
313{
314 for(auto& [type_hash, storage] : storages_)
315 {
316 storage->preload_all();
317 }
318}
319
320} // namespace unravel
Manages asset metadata and provides functionality for adding, removing, and querying assets.
Manages assets, including loading, unloading, and storage.
auto load_database(const std::string &protocol) -> bool
Loads an asset database from a protocol.
void preload_all_assets()
Triggers loading on all deferred handles across every registered storage. Non-blocking: starts backgr...
void save_database(const std::string &protocol, const fs::path &path)
Saves the asset database to a specified path.
asset_manager(rtti::context &ctx)
Constructs an asset manager with the given context.
auto generate_metadata(const fs::path &p) const -> asset_meta
auto get_all_assets(const std::string &group) const -> std::vector< std::string >
Gets all assets.
auto get_metadata_for_path(const fs::path &path) const -> asset_database::meta
void evict_unused_assets(const std::string &group, std::chrono::steady_clock::duration max_idle)
Evicts full-loaded assets not accessed within the given duration. Demotes them back to deferred state...
void unload_all()
Unloads all assets.
auto init(rtti::context &ctx) -> bool
Initializes the asset manager with the given context.
~asset_manager()
Destructs the asset manager.
auto add_asset(const std::string &key, bool override=false) -> hpp::uuid
Adds an asset with a specified key.
auto get_metadata(const hpp::uuid &uid) const -> asset_database::meta
Gets metadata for a resource uid.
auto deinit(rtti::context &ctx) -> bool
Deinitializes the asset manager with the given context.
void remove_asset_info_for_key(const std::string &key)
Removes asset information for a specified key.
auto get_metadata_for_key(const std::string &key) const -> asset_database::meta
auto add_asset_info_for_key(const std::string &key, const asset_meta &meta, bool override) -> hpp::uuid
Adds asset information for a specified key.
auto add_asset_info_for_path(const fs::path &path, const asset_meta &meta, bool override) -> hpp::uuid
Adds asset information for a specified path.
void remove_asset_info_for_path(const fs::path &path)
Removes asset information for a specified path.
auto add_asset_for_path(const fs::path &path, bool override=false) -> hpp::uuid
Adds an asset with a specified path.
void unload_group(const std::string &group)
Unloads all assets in a specified group.
void set_parent(asset_manager *parent)
Sets the parent asset manager.
#define APPLOG_TRACE(...)
Definition logging.h:17
path extract_protocol(const path &_path)
Given the specified path/filename, resolve the final full filename. This will be based on either the ...
path resolve_protocol(const path &_path)
Given the specified path/filename, resolve the final full filename. This will be based on either the ...
path convert_to_protocol(const path &_path)
Oposite of the resolve_protocol this function tries to convert to protocol path from an absolute one.
auto load_from_file< gfx::texture >(tpp::thread_pool &pool, asset_handle< gfx::texture > &output, const std::string &key, load_mode mode) -> bool
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< style_sheet >(tpp::thread_pool &pool, asset_handle< style_sheet > &output, const std::string &key, load_mode mode) -> bool
auto load_from_file< material >(tpp::thread_pool &pool, asset_handle< material > &output, const std::string &key, load_mode mode) -> 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 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 load_from_instance(tpp::thread_pool &pool, asset_handle< T > &output, std::shared_ptr< T > instance) -> bool
auto generate_uuid() -> hpp::uuid
Definition uuid.cpp:25
void init_fonts()
Definition font.cpp:813
void deinit_fonts()
Definition font.cpp:818
void load_from_file(const std::string &absolute_path, animation_clip &obj)
void save_to_file(const std::string &absolute_path, const animation_clip &obj)
Metadata information for an asset including its location.
Metadata for an asset, including its UUID and type.
std::string type
Type of the asset.
hpp::uuid uid
Unique identifier for the asset.