2#ifndef LIBSBX_SCENES_ASSET_REGISTRY_HPP_
3#define LIBSBX_SCENES_ASSET_REGISTRY_HPP_
5#include <unordered_map>
8#include <libsbx/utility/hashed_string.hpp>
9#include <libsbx/utility/exception.hpp>
11#include <libsbx/math/uuid.hpp>
13#include <libsbx/core/engine.hpp>
15#include <libsbx/assets/assets_module.hpp>
17#include <libsbx/graphics/graphics_module.hpp>
18#include <libsbx/graphics/images/image2d.hpp>
19#include <libsbx/graphics/images/cube_image.hpp>
21namespace sbx::scenes {
24 std::filesystem::path path;
26 std::string type{
"unknown"};
27 std::string source{
"dynamic"};
30template<
typename Handle>
36 return _by_name.contains(name);
40 if (
auto entry = _by_name.find(name); entry != _by_name.end()) {
48 if (_by_name.contains(name)) {
52 _by_name.emplace(name, handle);
53 _metadata.emplace(handle, std::move(metadata));
58 auto metadata(
const Handle& handle)
const ->
const asset_metadata& {
59 return _metadata.at(handle);
62 auto size()
const -> std::size_t {
63 return _by_name.size();
67 return _metadata.begin();
71 return _metadata.end();
75 return _metadata.begin();
79 return _metadata.end();
84 std::unordered_map<utility::hashed_string, Handle> _by_name;
85 std::unordered_map<Handle, asset_metadata> _metadata;
93 template<
typename... Args>
95 if (_images.has(name)) {
96 return _images.get(name);
99 auto& gfx = core::engine::get_module<graphics::graphics_module>();
101 const auto handle = gfx.add_resource<
graphics::image2d>(path, std::forward<Args>(args)...);
103 _images.insert(name, handle,
asset_metadata{path, name.str(),
"image",
"disk"});
109 return _images.has(name);
113 return _images.get(name);
117 return _images.metadata(handle);
124 template<
typename... Args>
126 if (_cube_images.has(name)) {
127 return _cube_images.get(name);
130 auto& gfx = core::engine::get_module<graphics::graphics_module>();
134 _cube_images.insert(name, handle,
asset_metadata{path, name.str(),
"cube_image",
"disk"});
140 return _cube_images.has(name);
144 return _cube_images.get(name);
148 return _cube_images.metadata(handle);
155 template<
typename Mesh,
typename... Args>
157 if (_meshes.has(name)) {
158 return _meshes.get(name);
161 auto& assets_module = core::engine::get_module<assets::assets_module>();
163 const auto id = assets_module.add_asset<Mesh>(std::forward<Args>(args)...);
165 _meshes.insert(name,
id,
asset_metadata{
"", name.str(),
"mesh",
"generated"});
170 template<
typename Mesh,
typename Path,
typename... Args>
171 requires (std::is_constructible_v<std::filesystem::path, Path>)
173 if (_meshes.has(name)) {
174 return _meshes.get(name);
177 auto& assets_module = core::engine::get_module<assets::assets_module>();
179 const auto id = assets_module.add_asset<Mesh>(path, std::forward<Args>(args)...);
181 _meshes.insert(name,
id,
asset_metadata{path, name.str(),
"mesh",
"disk"});
187 return _meshes.has(name);
191 return _meshes.get(name);
195 return _meshes.metadata(handle);
202 template<
typename Animation,
typename... Args>
204 if (_animations.has(name)) {
205 return _animations.get(name);
208 auto& assets_module = core::engine::get_module<assets::assets_module>();
210 const auto id = assets_module.add_asset<Animation>(std::forward<Args>(args)...);
212 _animations.insert(name,
id,
asset_metadata{
"", name.str(),
"animation",
"generated"});
218 return _animations.has(name);
222 return _animations.get(name);
229 template<
typename Material,
typename... Args>
231 auto& assets_module = core::engine::get_module<assets::assets_module>();
233 if (_materials.has(name)) {
234 return assets_module.get_asset<Material>(_materials.get(name));
237 const auto id = assets_module.add_asset<Material>(std::forward<Args>(args)...);
239 _materials.insert(name,
id,
asset_metadata{
"", name.str(),
"material",
"dynamic"});
241 return assets_module.get_asset<Material>(
id);
245 return _materials.has(name);
249 return _materials.get(name);
253 return _materials.metadata(handle);
260 auto rebase_paths(std::string_view old_uri, std::string_view new_uri) ->
void {
261 _rebase_table(_images, old_uri, new_uri);
262 _rebase_table(_cube_images, old_uri, new_uri);
263 _rebase_table(_meshes, old_uri, new_uri);
264 _rebase_table(_animations, old_uri, new_uri);
265 _rebase_table(_materials, old_uri, new_uri);
268 auto clear_paths_under(std::string_view uri) ->
void {
269 _clear_table_paths_under(_images, uri);
270 _clear_table_paths_under(_cube_images, uri);
271 _clear_table_paths_under(_meshes, uri);
272 _clear_table_paths_under(_animations, uri);
273 _clear_table_paths_under(_materials, uri);
278 template<
typename Table>
279 static auto _rebase_table(Table& table, std::string_view old_uri, std::string_view new_uri) ->
void {
280 for (
auto& [handle, metadata] : table) {
281 static_cast<void>(handle);
283 if (metadata.path.empty()) {
287 const auto current = metadata.path.generic_string();
289 if (!_uri_starts_with(current, old_uri)) {
293 auto rebuilt = std::string{new_uri};
294 rebuilt.append(current, old_uri.size(), std::string::npos);
296 metadata.path = std::filesystem::path{rebuilt};
300 template<
typename Table>
301 static auto _clear_table_paths_under(Table& table, std::string_view uri) ->
void {
302 for (
auto& [handle, metadata] : table) {
303 static_cast<void>(handle);
305 if (metadata.path.empty()) {
309 const auto current = metadata.path.generic_string();
311 if (!_uri_starts_with(current, uri)) {
315 metadata.path.clear();
319 static auto _uri_starts_with(std::string_view path, std::string_view prefix) ->
bool {
320 if (path.size() < prefix.size()) {
324 if (path.substr(0, prefix.size()) != prefix) {
328 if (path.size() == prefix.size()) {
332 return path[prefix.size()] ==
'/';
Definition: cube_image.hpp:21
Definition: image2d.hpp:53
Definition: resource_storage.hpp:18
Definition: asset_registry.hpp:89
Definition: asset_registry.hpp:31
Definition: hashed_string.hpp:17
Definition: exception.hpp:18