diff --git a/engine/config/engine.cfg b/engine/config/engine.cfg index 78c0fb396..38feaee34 100644 --- a/engine/config/engine.cfg +++ b/engine/config/engine.cfg @@ -53,7 +53,7 @@ desc_pool_max_sb = 8192 desc_pool_max_sets = 2048 [render.aux] -font = "asset://fonts/consolas" +font = "assets/fonts/consolas" screen_width = 1280 screen_height = 720 @@ -65,7 +65,7 @@ expand_size = 2 enable = true [debug.console] -font = "asset://fonts/anonymous_pro" +font = "assets/fonts/anonymous_pro" color_back = "000000ee" color_line = "060606be" color_text = "efefefff" diff --git a/engine/plugins/assimp/assimp_asset_loader.cpp b/engine/plugins/assimp/assimp_asset_loader.cpp index 45e035c7e..e1e7bf92c 100644 --- a/engine/plugins/assimp/assimp_asset_loader.cpp +++ b/engine/plugins/assimp/assimp_asset_loader.cpp @@ -44,16 +44,16 @@ namespace wmoge { - Status AssimpMeshAssetLoader::load(const Strid& name, const AssetMeta& meta, Ref& asset) { - WG_AUTO_PROFILE_ASSET("AssimpMeshAssetLoader::load"); + Status AssimpMeshAssetLoader::load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) { + WG_AUTO_PROFILE_ASSET("AssimpMeshAssetLoader::load_typed"); - Ref import_data = meta.import_data.cast(); + Ref import_data = context.asset_meta.import_data.cast(); if (!import_data) { - WG_LOG_ERROR("no import data for " << name); + WG_LOG_ERROR("no import data for " << asset_id); return StatusCode::InvalidData; } if (!import_data->has_soruce_files()) { - WG_LOG_ERROR("no source file " << name); + WG_LOG_ERROR("no source file " << asset_id); return StatusCode::InvalidData; } @@ -83,19 +83,17 @@ namespace wmoge { MeshFlags flags; flags.set(MeshFlag::FromDisk); - Ref mesh = mesh_manager->create_mesh(flags); - - asset = mesh; - asset->set_name(name); + asset = mesh_manager->create_mesh(flags); + asset->set_id(asset_id); MeshBuilder& builder = importer.get_builder(); - builder.set_mesh(mesh); + builder.set_mesh(asset); if (!builder.build()) { WG_LOG_ERROR("failed to build mesh " << file_name); return StatusCode::Error; } - mesh_manager->init_mesh(mesh.get()); + mesh_manager->init_mesh(asset.get()); return WG_OK; } diff --git a/engine/plugins/assimp/assimp_asset_loader.hpp b/engine/plugins/assimp/assimp_asset_loader.hpp index c1c254ef6..de9fcec74 100644 --- a/engine/plugins/assimp/assimp_asset_loader.hpp +++ b/engine/plugins/assimp/assimp_asset_loader.hpp @@ -27,12 +27,10 @@ #pragma once -#include "asset/asset.hpp" -#include "asset/asset_loader.hpp" -#include "asset/asset_meta.hpp" -#include "asset/asset_pak.hpp" +#include "asset/asset_loader_adapter.hpp" #include "math/mat.hpp" #include "math/vec.hpp" +#include "mesh/mesh.hpp" #include #include @@ -45,14 +43,14 @@ namespace wmoge { * @class AssimpMeshAssetLoader * @brief Loader for a mesh data based on assimp library */ - class AssimpMeshAssetLoader final : public AssetLoader { + class AssimpMeshAssetLoader final : public AssetLoaderTyped { public: WG_RTTI_CLASS(AssimpMeshAssetLoader, AssetLoader); AssimpMeshAssetLoader() = default; ~AssimpMeshAssetLoader() override = default; - Status load(const Strid& name, const AssetMeta& meta, Ref& asset) override; + Status load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) override; }; WG_RTTI_CLASS_BEGIN(AssimpMeshAssetLoader) { diff --git a/engine/plugins/assimp/assimp_importer.cpp b/engine/plugins/assimp/assimp_importer.cpp index c29581d3d..27733a081 100644 --- a/engine/plugins/assimp/assimp_importer.cpp +++ b/engine/plugins/assimp/assimp_importer.cpp @@ -128,7 +128,7 @@ namespace wmoge { const GfxVertAttribs attribs = m_attribs; Ref array_mesh = make_ref(); - array_mesh->set_name(SID(get_file_name() + "." + name.str())); + array_mesh->set_id(SID(get_file_name() + "." + name.str())); array_mesh->set_aabb(aabb); for (unsigned int vert_id = 0; vert_id < num_vertices; vert_id++) { diff --git a/engine/plugins/freetype/freetype_asset_loader.cpp b/engine/plugins/freetype/freetype_asset_loader.cpp index 25bcab128..e3ac57289 100644 --- a/engine/plugins/freetype/freetype_asset_loader.cpp +++ b/engine/plugins/freetype/freetype_asset_loader.cpp @@ -27,36 +27,30 @@ #include "freetype_asset_loader.hpp" +#include "freetype_font.hpp" #include "freetype_import_data.hpp" -#include "grc/font.hpp" #include "profiler/profiler.hpp" namespace wmoge { - Status FreetypeAssetLoader::load(const Strid& name, const AssetMeta& meta, Ref& asset) { - WG_AUTO_PROFILE_ASSET("FreetypeAssetLoader::load"); + Status FreetypeAssetLoader::load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) { + WG_AUTO_PROFILE_ASSET("FreetypeAssetLoader::load_typed"); - Ref import_data = meta.import_data.cast(); + Ref import_data = context.asset_meta.import_data.cast(); if (!import_data) { - WG_LOG_ERROR("no valid import data for " << name); + WG_LOG_ERROR("no valid import data for " << asset_id); return StatusCode::InvalidData; } if (!import_data->has_soruce_files()) { - WG_LOG_ERROR("no source file " << name); + WG_LOG_ERROR("no source file " << asset_id); return StatusCode::InvalidData; } - Ref font = meta.rtti->instantiate().cast(); - if (!font) { - WG_LOG_ERROR("failed to instantiate font " << name); - return StatusCode::FailedInstantiate; - } - - asset = font; - asset->set_name(name); + asset = make_ref(); + asset->set_id(asset_id); FreetypeFont loader; - return loader.load(font, import_data->source_files[0].file, import_data->height, import_data->glyphs_in_row); + return loader.load(asset, import_data->source_files[0].file, import_data->height, import_data->glyphs_in_row); } }// namespace wmoge \ No newline at end of file diff --git a/engine/plugins/freetype/freetype_asset_loader.hpp b/engine/plugins/freetype/freetype_asset_loader.hpp index 26bdb93da..97481901a 100644 --- a/engine/plugins/freetype/freetype_asset_loader.hpp +++ b/engine/plugins/freetype/freetype_asset_loader.hpp @@ -27,8 +27,8 @@ #pragma once -#include "asset/asset_loader.hpp" -#include "freetype_font.hpp" +#include "asset/asset_loader_adapter.hpp" +#include "grc/font.hpp" namespace wmoge { @@ -36,14 +36,14 @@ namespace wmoge { * @class FreetypeAssetLoader * @brief Loader for ttf fonts through freetype2 library */ - class FreetypeAssetLoader final : public AssetLoader { + class FreetypeAssetLoader final : public AssetLoaderTyped { public: WG_RTTI_CLASS(FreetypeAssetLoader, AssetLoader); FreetypeAssetLoader() = default; ~FreetypeAssetLoader() override = default; - Status load(const Strid& name, const AssetMeta& meta, Ref& asset) override; + Status load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) override; }; WG_RTTI_CLASS_BEGIN(FreetypeAssetLoader) { diff --git a/engine/plugins/freetype/freetype_font.cpp b/engine/plugins/freetype/freetype_font.cpp index 232e1365d..079d42733 100644 --- a/engine/plugins/freetype/freetype_font.cpp +++ b/engine/plugins/freetype/freetype_font.cpp @@ -118,7 +118,7 @@ namespace wmoge { int bitmap_size = bitmap_width * bitmap_height; Ref bitmap = make_ref(); - bitmap->set_name(SID(font->get_name().str() + "_bitmap")); + bitmap->set_id(SID(font->get_name().str() + "_bitmap")); bitmap->create(bitmap_width, bitmap_height, 1, 1); auto* dst_ptr = bitmap->get_pixel_data()->buffer(); auto* src_ptr = glyphs_rendered.data(); @@ -173,7 +173,7 @@ namespace wmoge { flags.set(TextureFlag::Compressed); font_desc.texture = m_texture_manager->create_2d(flags, GfxFormat::R8, bitmap_width, bitmap_height, GfxTexSwizz::RRRRtoRGBA); - font_desc.texture->set_name(SID(font->get_name().str() + "_bitmap")); + font_desc.texture->set_id(SID(font->get_name().str() + "_bitmap")); font_desc.texture->set_sampler(m_gfx_driver->make_sampler(sampler_desc, SID(sampler_desc.to_string()))); font_desc.texture->set_compression(compression_params); font_desc.texture->set_source_images({bitmap}); diff --git a/engine/plugins/runtime/asset/default_asset_loader.cpp b/engine/plugins/runtime/asset/default_asset_loader.cpp index 0bd5fdd90..69b374d95 100644 --- a/engine/plugins/runtime/asset/default_asset_loader.cpp +++ b/engine/plugins/runtime/asset/default_asset_loader.cpp @@ -1,3 +1,4 @@ +#include "default_asset_loader.hpp" /**********************************************************************************/ /* Wmoge game engine */ /* Available at github https://github.com/EgorOrachyov/wmoge */ @@ -27,43 +28,51 @@ #include "default_asset_loader.hpp" -#include "io/yaml.hpp" +#include "io/tree_yaml.hpp" #include "profiler/profiler.hpp" +#include "rtti/type_storage.hpp" +#include "system/ioc_container.hpp" namespace wmoge { - Status DefaultAssetLoader::load(const Strid& name, const AssetMeta& meta, Ref& asset) { - WG_AUTO_PROFILE_ASSET("DefaultAssetLoader::load"); + Status DefaultAssetLoader::load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) { + WG_AUTO_PROFILE_ASSET("DefaultAssetLoader::load_typed"); - Ref import_data = meta.import_data.cast(); + Ref import_data = context.asset_meta.import_data.cast(); if (!import_data) { - WG_LOG_ERROR("no import data to load " << name); + WG_LOG_ERROR("no import data to load " << asset_id); return StatusCode::InvalidData; } + if (!import_data->has_soruce_files()) { - WG_LOG_ERROR("no source file " << name); + WG_LOG_ERROR("no source file " << asset_id); return StatusCode::InvalidData; } std::string path_on_disk = import_data->source_files[0].file; if (path_on_disk.empty()) { - WG_LOG_ERROR("no path on disk to load asset file " << name); + WG_LOG_ERROR("no path on disk to load asset file " << asset_id); return StatusCode::InvalidData; } - asset = meta.rtti->instantiate().cast(); + RttiClass* rtti = IocContainer::iresolve_v()->find_class(context.asset_meta.rtti); + if (!rtti) { + WG_LOG_ERROR("no rtti type for " << asset_id); + return StatusCode::InvalidData; + } + + asset = rtti->instantiate().cast(); if (!asset) { - WG_LOG_ERROR("failed to instantiate asset " << name); + WG_LOG_ERROR("failed to instantiate asset " << asset_id); return StatusCode::FailedInstantiate; } - IoContext context; + asset->set_id(asset_id); + IoYamlTree asset_tree; WG_CHECKED(asset_tree.parse_file(path_on_disk)); - asset->set_name(name); - - if (!asset->read_from_tree(context, asset_tree)) { + if (!asset->read_from_tree(context.io_context, asset_tree)) { WG_LOG_ERROR("failed to load asset from file " << path_on_disk); return StatusCode::FailedRead; } diff --git a/engine/plugins/runtime/asset/default_asset_loader.hpp b/engine/plugins/runtime/asset/default_asset_loader.hpp index 9973de435..46058a754 100644 --- a/engine/plugins/runtime/asset/default_asset_loader.hpp +++ b/engine/plugins/runtime/asset/default_asset_loader.hpp @@ -27,10 +27,7 @@ #pragma once -#include "asset/asset.hpp" -#include "asset/asset_loader.hpp" -#include "asset/asset_meta.hpp" -#include "asset/asset_pak.hpp" +#include "asset/asset_loader_adapter.hpp" namespace wmoge { @@ -38,14 +35,14 @@ namespace wmoge { * @class DefaultAssetLoader * @brief Loader for default single-file assets stored in yaml format */ - class DefaultAssetLoader final : public AssetLoader { + class DefaultAssetLoader final : public AssetLoaderTyped { public: WG_RTTI_CLASS(DefaultAssetLoader, AssetLoader); DefaultAssetLoader() = default; ~DefaultAssetLoader() override = default; - Status load(const Strid& name, const AssetMeta& meta, Ref& asset) override; + Status load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) override; }; WG_RTTI_CLASS_BEGIN(DefaultAssetLoader) { diff --git a/engine/plugins/runtime/asset/image_asset_loader.cpp b/engine/plugins/runtime/asset/image_asset_loader.cpp index e9169fc8d..cad9868cd 100644 --- a/engine/plugins/runtime/asset/image_asset_loader.cpp +++ b/engine/plugins/runtime/asset/image_asset_loader.cpp @@ -27,31 +27,29 @@ #include "image_asset_loader.hpp" -#include "grc/image.hpp" #include "image_import_data.hpp" #include "profiler/profiler.hpp" namespace wmoge { - Status ImageAssetLoader::load(const Strid& name, const AssetMeta& meta, Ref& asset) { - WG_AUTO_PROFILE_ASSET("ImageAssetLoader::load"); + Status ImageAssetLoader::load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) { + WG_AUTO_PROFILE_ASSET("ImageAssetLoader::load_typed"); - Ref import_data = meta.import_data.cast(); + Ref import_data = context.asset_meta.import_data.cast(); if (!import_data) { - WG_LOG_ERROR("no import data to load image " << name); + WG_LOG_ERROR("no import data to load image " << asset_id); return StatusCode::InvalidData; } + if (!import_data->has_soruce_files()) { - WG_LOG_ERROR("no source file " << name); + WG_LOG_ERROR("no source file " << asset_id); return StatusCode::InvalidData; } - Ref image = make_ref(); - - asset = image; - asset->set_name(name); + asset = make_ref(); + asset->set_id(asset_id); - return image->load(import_data->source_files[0].file, import_data->channels); + return asset->load(import_data->source_files[0].file, import_data->channels); } }// namespace wmoge \ No newline at end of file diff --git a/engine/plugins/runtime/asset/image_asset_loader.hpp b/engine/plugins/runtime/asset/image_asset_loader.hpp index 29cbc020c..89ec36033 100644 --- a/engine/plugins/runtime/asset/image_asset_loader.hpp +++ b/engine/plugins/runtime/asset/image_asset_loader.hpp @@ -27,7 +27,8 @@ #pragma once -#include "asset/asset_loader.hpp" +#include "asset/asset_loader_adapter.hpp" +#include "grc/image.hpp" namespace wmoge { @@ -35,14 +36,14 @@ namespace wmoge { * @class ImageAssetLoader * @brief Loader for images through stb image library */ - class ImageAssetLoader final : public AssetLoader { + class ImageAssetLoader final : public AssetLoaderTyped { public: WG_RTTI_CLASS(ImageAssetLoader, AssetLoader); ImageAssetLoader() = default; ~ImageAssetLoader() override = default; - Status load(const Strid& name, const AssetMeta& meta, Ref& asset) override; + Status load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) override; }; WG_RTTI_CLASS_BEGIN(ImageAssetLoader) { diff --git a/engine/plugins/runtime/asset/shader_asset_loader.cpp b/engine/plugins/runtime/asset/shader_asset_loader.cpp index b900222cd..bd24daa9c 100644 --- a/engine/plugins/runtime/asset/shader_asset_loader.cpp +++ b/engine/plugins/runtime/asset/shader_asset_loader.cpp @@ -30,48 +30,44 @@ #include "grc/shader.hpp" #include "grc/shader_file.hpp" #include "grc/shader_manager.hpp" -#include "io/yaml.hpp" +#include "io/tree_yaml.hpp" #include "profiler/profiler.hpp" #include "system/ioc_container.hpp" namespace wmoge { - Status ShaderAssetLoader::load(const Strid& name, const AssetMeta& meta, Ref& asset) { - WG_AUTO_PROFILE_ASSET("ShaderAssetLoader::load"); + Status ShaderAssetLoader::load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) { + WG_AUTO_PROFILE_ASSET("ShaderAssetLoader::load_typed"); - Ref import_data = meta.import_data.cast(); + Ref import_data = context.asset_meta.import_data.cast(); if (!import_data) { - WG_LOG_ERROR("no import data to load " << name); + WG_LOG_ERROR("no import data to load " << asset_id); return StatusCode::InvalidData; } if (!import_data->has_soruce_files()) { - WG_LOG_ERROR("no source file " << name); + WG_LOG_ERROR("no source file " << asset_id); return StatusCode::InvalidData; } std::string path_on_disk = import_data->source_files[0].file; if (path_on_disk.empty()) { - WG_LOG_ERROR("no path on disk to load asset file " << name); + WG_LOG_ERROR("no path on disk to load asset file " << asset_id); return StatusCode::InvalidData; } ShaderFile shader_file; - - IoContext context; IoYamlTree tree; WG_CHECKED(tree.parse_file(path_on_disk)); - WG_TREE_READ(context, tree, shader_file); + WG_TREE_READ(context.io_context, tree, shader_file); auto* shader_manager = IocContainer::iresolve_v(); ShaderReflection shader_reflection; WG_CHECKED(shader_manager->load_shader_reflection(shader_file, shader_reflection)); - Ref shader = make_ref(std::move(shader_reflection)); - shader_manager->add_shader(shader); - - asset = shader; - asset->set_name(name); + asset = make_ref(std::move(shader_reflection)); + asset->set_id(asset_id); + shader_manager->add_shader(asset); return WG_OK; } diff --git a/engine/plugins/runtime/asset/shader_asset_loader.hpp b/engine/plugins/runtime/asset/shader_asset_loader.hpp index 79775aed4..e05de0adb 100644 --- a/engine/plugins/runtime/asset/shader_asset_loader.hpp +++ b/engine/plugins/runtime/asset/shader_asset_loader.hpp @@ -27,10 +27,8 @@ #pragma once -#include "asset/asset.hpp" -#include "asset/asset_loader.hpp" -#include "asset/asset_meta.hpp" -#include "asset/asset_pak.hpp" +#include "asset/asset_loader_adapter.hpp" +#include "grc/shader.hpp" namespace wmoge { @@ -38,14 +36,14 @@ namespace wmoge { * @class DefaultAssetLoader * @brief Loader for shader files from a specific shader syntax files */ - class ShaderAssetLoader final : public AssetLoader { + class ShaderAssetLoader final : public AssetLoaderTyped { public: WG_RTTI_CLASS(ShaderAssetLoader, AssetLoader); ShaderAssetLoader() = default; ~ShaderAssetLoader() override = default; - Status load(const Strid& name, const AssetMeta& meta, Ref& asset) override; + Status load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) override; }; WG_RTTI_CLASS_BEGIN(ShaderAssetLoader) { diff --git a/engine/plugins/runtime/asset/texture_asset_loader.cpp b/engine/plugins/runtime/asset/texture_asset_loader.cpp index dd07af167..2df33fac4 100644 --- a/engine/plugins/runtime/asset/texture_asset_loader.cpp +++ b/engine/plugins/runtime/asset/texture_asset_loader.cpp @@ -39,16 +39,16 @@ namespace wmoge { - Status Texture2dAssetLoader::load(const Strid& name, const AssetMeta& meta, Ref& asset) { - WG_AUTO_PROFILE_ASSET("Texture2dAssetLoader::load"); + Status Texture2dAssetLoader::load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) { + WG_AUTO_PROFILE_ASSET("Texture2dAssetLoader::load_typed"); - Ref import_data = meta.import_data.cast(); + Ref import_data = context.asset_meta.import_data.cast(); if (!import_data) { - WG_LOG_ERROR("no import data for " << name); + WG_LOG_ERROR("no import data for " << asset_id); return StatusCode::InvalidData; } if (!import_data->has_soruce_files()) { - WG_LOG_ERROR("no source file " << name); + WG_LOG_ERROR("no source file " << asset_id); return StatusCode::InvalidData; } @@ -72,51 +72,48 @@ namespace wmoge { flags.set(TextureFlag::FromDisk); flags.set(TextureFlag::Compressed, import_data->compression.format != TexCompressionFormat::Unknown); - Ref texture = - texture_manager->create_2d(flags, + asset = texture_manager->create_2d(flags, import_data->format, source_image->get_width(), source_image->get_height()); - if (!texture) { - WG_LOG_ERROR("failed to instantiate texture " << name); + if (!asset) { + WG_LOG_ERROR("failed to instantiate texture " << asset_id); return StatusCode::FailedInstantiate; } - asset = texture; - asset->set_name(name); - - texture->set_source_images({source_image}); - texture->set_sampler(gfx_driver->make_sampler(import_data->sampling, SID(import_data->sampling.to_string()))); - texture->set_compression(import_data->compression); + asset->set_id(asset_id); + asset->set_source_images({source_image}); + asset->set_sampler(gfx_driver->make_sampler(import_data->sampling, SID(import_data->sampling.to_string()))); + asset->set_compression(import_data->compression); if (import_data->mipmaps) { - if (!texture->generate_mips()) { - WG_LOG_ERROR("failed to gen mip chain for " << name); + if (!asset->generate_mips()) { + WG_LOG_ERROR("failed to gen mip chain for " << asset_id); return StatusCode::Error; } } if (import_data->compression.format != TexCompressionFormat::Unknown) { - if (!texture->generate_compressed_data()) { - WG_LOG_ERROR("failed to compress data for " << name); + if (!asset->generate_compressed_data()) { + WG_LOG_ERROR("failed to compress data for " << asset_id); return StatusCode::Error; } } - texture_manager->init(texture.get()); + texture_manager->init(asset.get()); return WG_OK; } - Status TextureCubeAssetLoader::load(const Strid& name, const AssetMeta& meta, Ref& asset) { - WG_AUTO_PROFILE_ASSET("TextureCubeAssetLoader::load"); + Status TextureCubeAssetLoader::load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) { + WG_AUTO_PROFILE_ASSET("TextureCubeAssetLoader::load_typed"); - Ref import_data = meta.import_data.cast(); + Ref import_data = context.asset_meta.import_data.cast(); if (!import_data) { - WG_LOG_ERROR("no import data for " << name); + WG_LOG_ERROR("no import data for " << asset_id); return StatusCode::InvalidData; } if (import_data->source_files_size() < 6) { - WG_LOG_ERROR("not enough source files " << name); + WG_LOG_ERROR("not enough source files " << asset_id); return StatusCode::InvalidData; } @@ -128,7 +125,7 @@ namespace wmoge { WG_LOG_ERROR("failed to load source image " << path); return false; } - image->set_name(SID(path)); + image->set_id(SID(path)); return true; }; @@ -158,37 +155,34 @@ namespace wmoge { flags.set(TextureFlag::FromDisk); flags.set(TextureFlag::Compressed, import_data->compression.format != TexCompressionFormat::Unknown); - Ref texture = - texture_manager->create_cube(flags, + asset = texture_manager->create_cube(flags, import_data->format, source_images.front()->get_width(), source_images.front()->get_height()); - if (!texture) { - WG_LOG_ERROR("failed to instantiate texture " << name); + if (!asset) { + WG_LOG_ERROR("failed to instantiate texture " << asset_id); return StatusCode::Error; } - asset = texture; - asset->set_name(name); - - texture->set_source_images(source_images); - texture->set_sampler(gfx_driver->make_sampler(import_data->sampling, SID(import_data->sampling.to_string()))); - texture->set_compression(import_data->compression); + asset->set_id(asset_id); + asset->set_source_images(source_images); + asset->set_sampler(gfx_driver->make_sampler(import_data->sampling, SID(import_data->sampling.to_string()))); + asset->set_compression(import_data->compression); if (import_data->mipmaps) { - if (!texture->generate_mips()) { - WG_LOG_ERROR("failed to gen mip chain for " << name); + if (!asset->generate_mips()) { + WG_LOG_ERROR("failed to gen mip chain for " << asset_id); return StatusCode::Error; } } if (import_data->compression.format != TexCompressionFormat::Unknown) { - if (!texture->generate_compressed_data()) { - WG_LOG_ERROR("failed to compress data for " << name); + if (!asset->generate_compressed_data()) { + WG_LOG_ERROR("failed to compress data for " << asset_id); return StatusCode::Error; } } - texture_manager->init(texture.get()); + texture_manager->init(asset.get()); return WG_OK; } diff --git a/engine/plugins/runtime/asset/texture_asset_loader.hpp b/engine/plugins/runtime/asset/texture_asset_loader.hpp index 51e45a318..aec5a78ca 100644 --- a/engine/plugins/runtime/asset/texture_asset_loader.hpp +++ b/engine/plugins/runtime/asset/texture_asset_loader.hpp @@ -27,8 +27,7 @@ #pragma once -#include "asset/asset_loader.hpp" - +#include "asset/asset_loader_adapter.hpp" #include "gfx/gfx_defs.hpp" #include "gfx/gfx_sampler.hpp" #include "gfx/gfx_texture.hpp" @@ -40,14 +39,14 @@ namespace wmoge { * @class Texture2dAssetLoader * @brief Loader for 2d textures through stb image library */ - class Texture2dAssetLoader final : public AssetLoader { + class Texture2dAssetLoader final : public AssetLoaderTyped { public: WG_RTTI_CLASS(Texture2dAssetLoader, AssetLoader); Texture2dAssetLoader() = default; ~Texture2dAssetLoader() override = default; - Status load(const Strid& name, const AssetMeta& meta, Ref& asset) override; + Status load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) override; }; WG_RTTI_CLASS_BEGIN(Texture2dAssetLoader) { @@ -60,14 +59,14 @@ namespace wmoge { * @class TextureCubeAssetLoader * @brief Loader for cube-map textures through stb image library */ - class TextureCubeAssetLoader final : public AssetLoader { + class TextureCubeAssetLoader final : public AssetLoaderTyped { public: WG_RTTI_CLASS(TextureCubeAssetLoader, AssetLoader); TextureCubeAssetLoader() = default; ~TextureCubeAssetLoader() override = default; - Status load(const Strid& name, const AssetMeta& meta, Ref& asset) override; + Status load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) override; }; WG_RTTI_CLASS_BEGIN(TextureCubeAssetLoader) { diff --git a/engine/plugins/runtime/asset/wav_asset_loader.cpp b/engine/plugins/runtime/asset/wav_asset_loader.cpp index 2b6283814..fd3e1674a 100644 --- a/engine/plugins/runtime/asset/wav_asset_loader.cpp +++ b/engine/plugins/runtime/asset/wav_asset_loader.cpp @@ -28,34 +28,28 @@ #include "wav_asset_loader.hpp" #include "asset/wav_import_data.hpp" -#include "audio/audio_stream_wav.hpp" #include "profiler/profiler.hpp" namespace wmoge { - Status WavAssetLoader::load(const Strid& name, const AssetMeta& meta, Ref& asset) { - WG_AUTO_PROFILE_ASSET("WavAssetLoader::load"); + Status WavAssetLoader::load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) { + WG_AUTO_PROFILE_ASSET("WavAssetLoader::load_typed"); - Ref import_data = meta.import_data.cast(); + Ref import_data = context.asset_meta.import_data.cast(); if (!import_data) { - WG_LOG_ERROR("no import data for " << name); + WG_LOG_ERROR("no import data for " << asset_id); return StatusCode::InvalidData; } + if (!import_data->has_soruce_files()) { - WG_LOG_ERROR("no source file " << name); + WG_LOG_ERROR("no source file " << asset_id); return StatusCode::InvalidData; } - Ref audio = meta.rtti->instantiate().cast(); - if (!audio) { - WG_LOG_ERROR("failed to instantiate audio " << name); - return StatusCode::FailedInstantiate; - } - - asset = audio; - asset->set_name(name); + asset = make_ref(); + asset->set_id(asset_id); - return audio->load(import_data->source_files[0].file); + return asset->load(import_data->source_files[0].file); } }// namespace wmoge \ No newline at end of file diff --git a/engine/plugins/runtime/asset/wav_asset_loader.hpp b/engine/plugins/runtime/asset/wav_asset_loader.hpp index 5c33e78ee..d7adff004 100644 --- a/engine/plugins/runtime/asset/wav_asset_loader.hpp +++ b/engine/plugins/runtime/asset/wav_asset_loader.hpp @@ -27,7 +27,8 @@ #pragma once -#include "asset/asset_loader.hpp" +#include "asset/asset_loader_adapter.hpp" +#include "audio/audio_stream_wav.hpp" namespace wmoge { @@ -35,14 +36,14 @@ namespace wmoge { * @class WavAssetLoader * @brief Loader for wav audio sources using audio file library */ - class WavAssetLoader final : public AssetLoader { + class WavAssetLoader final : public AssetLoaderTyped { public: WG_RTTI_CLASS(WavAssetLoader, AssetLoader); WavAssetLoader() = default; ~WavAssetLoader() override = default; - Status load(const Strid& name, const AssetMeta& meta, Ref& asset) override; + Status load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) override; }; WG_RTTI_CLASS_BEGIN(WavAssetLoader) { diff --git a/engine/runtime/asset/_rtti.cpp b/engine/runtime/asset/_rtti.cpp index fceb809d8..1cad85e37 100644 --- a/engine/runtime/asset/_rtti.cpp +++ b/engine/runtime/asset/_rtti.cpp @@ -36,9 +36,9 @@ namespace wmoge { void rtti_asset() { rtti_type(); - rtti_type(); + rtti_type(); + rtti_type(); rtti_type(); - rtti_type(); rtti_type(); } diff --git a/engine/runtime/asset/asset.cpp b/engine/runtime/asset/asset.cpp index 5333bae2e..90baf27bf 100644 --- a/engine/runtime/asset/asset.cpp +++ b/engine/runtime/asset/asset.cpp @@ -35,11 +35,11 @@ namespace wmoge { - Status tree_read(IoContext& context, IoPropertyTree& tree, AssetId& id) { + Status tree_read(IoContext& context, IoTree& tree, AssetId& id) { WG_TREE_READ(context, tree, id.m_name); return WG_OK; } - Status tree_write(IoContext& context, IoPropertyTree& tree, const AssetId& id) { + Status tree_write(IoContext& context, IoTree& tree, const AssetId& id) { WG_TREE_WRITE(context, tree, id.m_name); return WG_OK; } @@ -59,42 +59,4 @@ namespace wmoge { m_name = id; } - void AssetDependencies::set_mode(CollectionMode mode, std::optional num_levels) { - assert(m_cur_depth == 0); - - if (mode == CollectionMode::OneLevel) { - m_max_depth = 1; - } - if (mode == CollectionMode::MultipleLevels) { - m_max_depth = num_levels.value_or(1); - } - if (mode == CollectionMode::FullDepth) { - m_max_depth = std::numeric_limits::max(); - } - - m_mode = mode; - } - - void AssetDependencies::add(const Ref& asset) { - if (m_cur_depth >= m_max_depth) { - return; - } - if (!asset) { - return; - } - - m_cur_depth += 1; - - m_assets.emplace(asset); - asset->collect_deps(*this); - - m_cur_depth -= 1; - } - - buffered_vector> AssetDependencies::to_vector() const { - buffered_vector> vec(m_assets.size()); - std::copy(m_assets.begin(), m_assets.end(), vec.begin()); - return vec; - } - }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/asset/asset.hpp b/engine/runtime/asset/asset.hpp index c7fa5b72f..dbf77840f 100644 --- a/engine/runtime/asset/asset.hpp +++ b/engine/runtime/asset/asset.hpp @@ -68,8 +68,8 @@ namespace wmoge { [[nodiscard]] bool is_empty() const { return m_name.empty(); } [[nodiscard]] std::size_t hash() const { return m_name.hash(); } - friend Status tree_read(IoContext& context, IoPropertyTree& tree, AssetId& id); - friend Status tree_write(IoContext& context, IoPropertyTree& tree, const AssetId& id); + friend Status tree_read(IoContext& context, IoTree& tree, AssetId& id); + friend Status tree_write(IoContext& context, IoTree& tree, const AssetId& id); friend Status stream_read(IoContext& context, IoStream& stream, AssetId& id); friend Status stream_write(IoContext& context, IoStream& stream, const AssetId& id); @@ -94,15 +94,12 @@ namespace wmoge { public: WG_RTTI_CLASS(Asset, RttiObject); - void set_name(Strid name) { m_id = AssetId(name); } void set_id(AssetId id) { m_id = id; } void set_uuid(UUID uuid) { m_uuid = uuid; } const Strid& get_name() { return m_id.sid(); } const AssetId& get_id() { return m_id; } const UUID& get_uuid() { return m_uuid; } - virtual void collect_deps(class AssetDependencies& deps) {} - private: AssetId m_id; UUID m_uuid; @@ -116,35 +113,6 @@ namespace wmoge { } WG_RTTI_END; - /** - * @class AssetDependencies - * @brief Class to collect dependencies of a particular asset (primary editor only feature) - */ - class AssetDependencies { - public: - AssetDependencies() = default; - ~AssetDependencies() = default; - - /** @brief Mode how to collect deps */ - enum class CollectionMode { - OneLevel, - MultipleLevels, - FullDepth - }; - - void set_mode(CollectionMode mode, std::optional num_levels); - void add(const Ref& asset); - - [[nodiscard]] CollectionMode get_mode() const { return m_mode; } - [[nodiscard]] buffered_vector> to_vector() const; - - private: - flat_set> m_assets; - int m_max_depth = 1; - int m_cur_depth = 0; - CollectionMode m_mode = CollectionMode::OneLevel; - }; - }// namespace wmoge namespace std { diff --git a/engine/runtime/asset/asset_import_data.hpp b/engine/runtime/asset/asset_import_data.hpp index 81c0ef211..22340726a 100644 --- a/engine/runtime/asset/asset_import_data.hpp +++ b/engine/runtime/asset/asset_import_data.hpp @@ -44,7 +44,7 @@ namespace wmoge { WG_RTTI_STRUCT(AssetSourceFile); std::string file; - std::string file_tag; + Strid file_tag; Sha256 file_hash; DateTime timestamp; }; diff --git a/engine/runtime/asset/asset_pak.hpp b/engine/runtime/asset/asset_library.hpp similarity index 79% rename from engine/runtime/asset/asset_pak.hpp rename to engine/runtime/asset/asset_library.hpp index ec9968da1..51cabc9fe 100644 --- a/engine/runtime/asset/asset_pak.hpp +++ b/engine/runtime/asset/asset_library.hpp @@ -29,10 +29,11 @@ #include "asset/asset.hpp" #include "asset/asset_meta.hpp" +#include "core/async.hpp" #include "core/data.hpp" #include "core/status.hpp" #include "core/string_id.hpp" -#include "io/property_tree.hpp" +#include "io/tree.hpp" #include #include @@ -42,21 +43,17 @@ namespace wmoge { /** - * @class AssetPak - * @brief Interface for the package of the assets on disc - * - * AssetPak abstracts access to the assets on disk. It provides ability - * to load a particular asset meta file from a asset name, and allows - * to read a raw data using path. - * - * Internally asset pack can be represented as a wrapper for a file system - * asset directory, or it can manage a compressed pak of assets on a disk. + * @class AssetLibrary + * @brief Interface for a library of assets meta information */ - class AssetPak { + class AssetLibrary { public: - virtual ~AssetPak() = default; - virtual std::string get_name() const = 0; - virtual Status get_meta(const AssetId& name, AssetMeta& meta) = 0; + virtual ~AssetLibrary() = default; + + virtual std::string get_name() const = 0; + virtual Status find_asset_meta(const AssetId& name, AssetMeta& meta) = 0; + virtual Status find_asset_data_meta(const Strid& name, AssetDataMeta& meta) = 0; + virtual Async read_data(const Strid& name, array_view data) = 0; }; }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/asset/asset_library_fs.cpp b/engine/runtime/asset/asset_library_fs.cpp new file mode 100644 index 000000000..b97caf180 --- /dev/null +++ b/engine/runtime/asset/asset_library_fs.cpp @@ -0,0 +1,96 @@ +/**********************************************************************************/ +/* Wmoge game engine */ +/* Available at github https://github.com/EgorOrachyov/wmoge */ +/**********************************************************************************/ +/* MIT License */ +/* */ +/* Copyright (c) 2023 Egor Orachyov */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining a copy */ +/* of this software and associated documentation files (the "Software"), to deal */ +/* in the Software without restriction, including without limitation the rights */ +/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell */ +/* copies of the Software, and to permit persons to whom the Software is */ +/* furnished to do so, subject to the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be included in all */ +/* copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */ +/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */ +/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */ +/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */ +/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */ +/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ +/* SOFTWARE. */ +/**********************************************************************************/ + +#include "asset_library_fs.hpp" + +#include "asset/asset_manager.hpp" +#include "core/string_utils.hpp" +#include "io/tree.hpp" +#include "io/tree_yaml.hpp" +#include "platform/file_system.hpp" +#include "profiler/profiler.hpp" +#include "rtti/type_storage.hpp" +#include "system/ioc_container.hpp" + +namespace wmoge { + + AssetLibraryFileSystem::AssetLibraryFileSystem(std::string directory, IocContainer* ioc) { + m_file_system = ioc->resolve_value(); + m_rtti_storage = ioc->resolve_value(); + m_directory = std::move(directory); + } + + std::string AssetLibraryFileSystem::get_name() const { + return "AssetLibraryFileSystem"; + } + + Status AssetLibraryFileSystem::find_asset_meta(const AssetId& name, AssetMeta& meta) { + WG_AUTO_PROFILE_ASSET("AssetLibraryFileSystem::find_asset_meta"); + + const std::string path = m_directory + name.str() + m_asset_ext; + + IoContext context; + context.add(m_file_system); + context.add(m_rtti_storage); + + IoYamlTree tree; + WG_CHECKED(tree.parse_file(m_file_system, name.str() + m_asset_ext)); + WG_TREE_READ(context, tree, meta); + + return WG_OK; + } + Status AssetLibraryFileSystem::find_asset_data_meta(const Strid& name, AssetDataMeta& meta) { + WG_AUTO_PROFILE_ASSET("AssetLibraryFileSystem::find_asset_data_meta"); + + const std::string path = m_directory + name.str(); + + WG_CHECKED(m_file_system->get_file_size(path, meta.size)); + meta.size_compressed = 0; + meta.hash = Sha256(); + meta.compression = AssetCompressionMode::None; + + return WG_OK; + } + Async AssetLibraryFileSystem::read_data(const Strid& name, array_view data) { + WG_AUTO_PROFILE_ASSET("AssetLibraryFileSystem::read_data"); + + const std::string path = m_directory + name.str(); + FileOpenModeFlags mode = {FileOpenMode::In, FileOpenMode::Binary}; + Ref file; + + if (!m_file_system->open_file(path, file, mode)) { + return Async::failed(); + } + + if (!file->nread(data.data(), data.size())) { + return Async::failed(); + } + + return Async::completed(); + } + +}// namespace wmoge diff --git a/engine/runtime/asset/asset_pak_fs.hpp b/engine/runtime/asset/asset_library_fs.hpp similarity index 77% rename from engine/runtime/asset/asset_pak_fs.hpp rename to engine/runtime/asset/asset_library_fs.hpp index 8e3f0e6ba..f3a297f86 100644 --- a/engine/runtime/asset/asset_pak_fs.hpp +++ b/engine/runtime/asset/asset_library_fs.hpp @@ -27,25 +27,29 @@ #pragma once -#include "asset/asset_pak.hpp" +#include "asset/asset_library.hpp" namespace wmoge { /** - * @class AssetPakFileSystem + * @class AssetLibraryFileSystem * @brief Assets pak based on the filesystem asset directory access */ - class AssetPakFileSystem final : public AssetPak { + class AssetLibraryFileSystem final : public AssetLibrary { public: - AssetPakFileSystem(); - ~AssetPakFileSystem() override = default; + AssetLibraryFileSystem(std::string directory, class IocContainer* ioc); + ~AssetLibraryFileSystem() override = default; std::string get_name() const override; - Status get_meta(const AssetId& name, AssetMeta& meta) override; + Status find_asset_meta(const AssetId& name, AssetMeta& meta) override; + Status find_asset_data_meta(const Strid& name, AssetDataMeta& meta) override; + Async read_data(const Strid& name, array_view data) override; private: - class FileSystem* m_file_system; - class AssetManager* m_asset_manager; + class FileSystem* m_file_system; + class RttiTypeStorage* m_rtti_storage; + std::string m_directory; + std::string m_asset_ext = ".asset"; }; }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/io/context.cpp b/engine/runtime/asset/asset_loader.cpp similarity index 75% rename from engine/runtime/io/context.cpp rename to engine/runtime/asset/asset_loader.cpp index 4f2e6f8af..e305c621e 100644 --- a/engine/runtime/io/context.cpp +++ b/engine/runtime/asset/asset_loader.cpp @@ -25,34 +25,26 @@ /* SOFTWARE. */ /**********************************************************************************/ -#include "context.hpp" - -#include "asset/asset_manager.hpp" -#include "rtti/type_storage.hpp" -#include "system/config.hpp" -#include "system/ioc_container.hpp" +#include "asset_loader.hpp" namespace wmoge { - AssetManager* wmoge::IoContext::get_asset_manager() { - if (!m_asset_manager) { - m_asset_manager = get_ioc_container()->resolve_v(); - } - return m_asset_manager; + void AssetLoadRequest::add_data_file(const Strid& name) { + data_files[name] = name.str(); + } + + std::string AssetLoadRequest::get_data_file(Strid tag) const { + auto query = data_files.find(tag); + return query != data_files.end() ? query->second : std::string(); } - RttiTypeStorage* IoContext::get_type_storage() { - if (!m_type_storage) { - m_type_storage = get_ioc_container()->resolve_v(); - } - return m_type_storage; + void AssetLoadResult::add_data_file(Strid tag, array_view data) { + data_files[tag] = data; } - IocContainer* IoContext::get_ioc_container() { - if (!m_ioc_container) { - m_ioc_container = IocContainer::instance(); - } - return m_ioc_container; + array_view AssetLoadResult::get_data_file(Strid tag) const { + auto query = data_files.find(tag); + return query != data_files.end() ? query->second : array_view(); } }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/asset/asset_loader.hpp b/engine/runtime/asset/asset_loader.hpp index e0c3c7cad..2bffd5ecf 100644 --- a/engine/runtime/asset/asset_loader.hpp +++ b/engine/runtime/asset/asset_loader.hpp @@ -28,12 +28,46 @@ #pragma once #include "asset/asset.hpp" +#include "asset/asset_library.hpp" #include "asset/asset_meta.hpp" -#include "asset/asset_pak.hpp" +#include "core/array_view.hpp" +#include "core/flat_map.hpp" +#include "io/context.hpp" #include "rtti/traits.hpp" namespace wmoge { + /** + * @class AssetLoadRequest + * @brief Request files to load for an asset load + */ + struct AssetLoadRequest { + flat_map data_files; + + void add_data_file(const Strid& name); + std::string get_data_file(Strid tag) const; + }; + + /** + * @class AssetLoadResult + * @brief Loaded files requested by an asset loader + */ + struct AssetLoadResult { + flat_map> data_files; + + void add_data_file(Strid tag, array_view data); + array_view get_data_file(Strid tag) const; + }; + + /** + * @class AssetLoadContext + * @brief Context passed to the loader + */ + struct AssetLoadContext { + IoContext io_context; + AssetMeta asset_meta; + }; + /** * @class AssetLoader * @brief Class responsible for loading or asset(s) in a specific format @@ -45,7 +79,9 @@ namespace wmoge { AssetLoader() = default; virtual ~AssetLoader() = default; - virtual Status load(const Strid& name, const AssetMeta& meta, Ref& asset) { return StatusCode::NotImplemented; } + virtual Status fill_request(AssetLoadContext& context, const AssetId& asset_id, AssetLoadRequest& request) { return StatusCode::NotImplemented; }; + virtual Status load(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) { return StatusCode::NotImplemented; } + virtual Status unload(Asset* asset) { return StatusCode::Ok; } }; WG_RTTI_CLASS_BEGIN(AssetLoader) { @@ -53,24 +89,4 @@ namespace wmoge { } WG_RTTI_END; - /** - * @class AssetUnloader - * @brief Class responsible for unloading assets(s) of a specific type - */ - class AssetUnloader : public RttiObject { - public: - WG_RTTI_CLASS(AssetUnloader, RttiObject); - - AssetUnloader() = default; - virtual ~AssetUnloader() = default; - - virtual Status unload(Asset* asset) { return StatusCode::NotImplemented; } - virtual RttiClass* get_asset_type() { return nullptr; } - }; - - WG_RTTI_CLASS_BEGIN(AssetUnloader) { - WG_RTTI_META_DATA(RttiUiHint("Interface for an asset unloader to implement custom unloading")); - } - WG_RTTI_END; - }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/asset/asset_pak_fs.cpp b/engine/runtime/asset/asset_loader_adapter.hpp similarity index 58% rename from engine/runtime/asset/asset_pak_fs.cpp rename to engine/runtime/asset/asset_loader_adapter.hpp index 2d0e69dfb..739991e01 100644 --- a/engine/runtime/asset/asset_pak_fs.cpp +++ b/engine/runtime/asset/asset_loader_adapter.hpp @@ -25,54 +25,41 @@ /* SOFTWARE. */ /**********************************************************************************/ -#include "asset_pak_fs.hpp" +#pragma once -#include "asset/asset_manager.hpp" -#include "core/string_utils.hpp" -#include "io/property_tree.hpp" -#include "io/yaml.hpp" -#include "platform/file_system.hpp" -#include "profiler/profiler.hpp" -#include "system/ioc_container.hpp" +#include "asset/asset_loader.hpp" namespace wmoge { - AssetPakFileSystem::AssetPakFileSystem() { - m_file_system = IocContainer::iresolve_v(); - } + /** + * @class AssetLoaderTyped + * @brief Adapter to implement asset loaders of a particular asset type + */ + template + class AssetLoaderTyped : public AssetLoader { + public: + static_assert(std::is_base_of_v, "T must be an Asset type"); - std::string AssetPakFileSystem::get_name() const { - return "pak_fs"; - } + virtual Status load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) { return StatusCode::NotImplemented; } + virtual Status unload_typed(T* asset) { return StatusCode::Ok; } - Status AssetPakFileSystem::get_meta(const AssetId& name, AssetMeta& meta) { - WG_AUTO_PROFILE_ASSET("AssetPakFileSystem::meta"); - - std::string meta_file_path = name.str(); - if (StringUtils::is_starts_with(meta_file_path, "asset://")) { - meta_file_path = StringUtils::find_replace_first(meta_file_path, "asset://", "assets/"); + Status fill_request(AssetLoadContext& context, const AssetId& asset_id, AssetLoadRequest& request) override { + for (const Strid& name : context.asset_meta.data) { + request.add_data_file(name); + } + return WG_OK; } - meta_file_path += AssetMetaFile::FILE_EXTENSION; - - AssetMetaFile asset_file; - - IoContext context; - IoYamlTree tree; - WG_CHECKED(tree.parse_file(meta_file_path)); - WG_TREE_READ(context, tree, asset_file); - - auto loader = IocContainer::iresolve_v()->find_loader(asset_file.loader); - auto rtti = IocContainer::iresolve_v()->find_class(asset_file.rtti); - - meta.uuid = asset_file.uuid; - meta.rtti = rtti; - meta.pak = this; - meta.loader = loader.value_or(nullptr); - meta.deps = std::move(asset_file.deps); - meta.import_data = std::move(asset_file.import_data); + Status load(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) override final { + Ref asset_typed; + WG_CHECKED(load_typed(context, asset_id, result, asset_typed)); + asset = asset_typed.as(); + return WG_OK; + } - return WG_OK; - } + Status unload(Asset* asset) override final { + return unload_typed(dynamic_cast(asset)); + } + }; -}// namespace wmoge +}// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/asset/asset_manager.cpp b/engine/runtime/asset/asset_manager.cpp index b1ffd10f6..45dfa84d9 100644 --- a/engine/runtime/asset/asset_manager.cpp +++ b/engine/runtime/asset/asset_manager.cpp @@ -27,7 +27,7 @@ #include "asset_manager.hpp" -#include "asset/asset_pak_fs.hpp" +#include "asset/asset_library_fs.hpp" #include "core/timer.hpp" #include "platform/file_system.hpp" #include "profiler/profiler.hpp" @@ -38,29 +38,21 @@ namespace wmoge { - AssetManager::AssetManager() { - m_file_system = IocContainer::iresolve_v(); - m_type_storage = IocContainer::iresolve_v(); + AssetManager::AssetManager(IocContainer* ioc) { + m_file_system = ioc->resolve_value(); + m_type_storage = ioc->resolve_value(); m_callback = std::make_shared([this](Asset* asset) { std::lock_guard guard(m_mutex); - auto& id = asset->get_id(); - auto rtti = asset->get_class_name(); - - auto unloader = find_unloader(rtti); - if (unloader) { - (*unloader)->unload(asset); - } - - auto entry = m_assets.find(id); + auto entry = m_assets.find(asset->get_id()); if (entry != m_assets.end()) { m_assets.erase(entry); } }); } - AsyncResult> AssetManager::load_async(const AssetId& name, AssetCallback callback) { + AsyncResult> AssetManager::load_async(const AssetId& name) { WG_AUTO_PROFILE_ASSET("AssetManager::load_async"); std::lock_guard guard(m_mutex); @@ -71,7 +63,6 @@ namespace wmoge { std::optional> res_opt(res); auto async_op = make_async_op>(); async_op->set_result(std::move(res)); - async_op->add_on_completion(std::move(callback)); return AsyncResult>(async_op); } @@ -79,26 +70,29 @@ namespace wmoge { auto loading = m_loading.find(name); if (loading != m_loading.end()) { auto& async_op = loading->second.async_op; - async_op->add_on_completion(std::move(callback)); return AsyncResult>(async_op); } // try to find meta info, to load from pak std::optional asset_meta = find_meta(name); - if (!asset_meta.has_value()) { // failed to load, return dummy async in error state auto async_op = make_async_op>(); async_op->set_failed(); - async_op->add_on_completion(std::move(callback)); WG_LOG_ERROR("failed to find meta info for " << name); - return AsyncResult>(async_op); + return AsyncResult>::failed(); + } + + // try find loader + std::optional loader = find_loader(asset_meta->loader); + if (!loader) { + WG_LOG_ERROR("failed to find loader for " << name); + return AsyncResult>::failed(); } // get dependencies which still loading or already loaded buffered_vector deps; - for (const Strid& dep : asset_meta.value().deps) { deps.push_back(load_async(dep).as_async()); } @@ -107,17 +101,22 @@ namespace wmoge { AsyncOp> async_op = make_async_op>(); // create task to load - Task task(name, [=, meta = std::move(asset_meta.value())](TaskContext&) { + Task task(name, [=, meta = std::move(asset_meta.value()), loader = loader.value()](TaskContext&) { Timer timer; timer.start(); - Ref asset; - if (meta.loader->load(name, meta, asset)) { + Ref asset; + AssetLoadContext context; + AssetLoadResult result; + + context.asset_meta = std::move(meta); + + if (loader->load(context, name, result, asset)) { timer.stop(); WG_LOG_INFO("load asset " << name << ", time: " << timer.get_elapsed_sec() << " sec"); if (asset->get_name().empty()) { - asset->set_name(name); + asset->set_id(name); } std::lock_guard guard(m_mutex); @@ -149,7 +148,6 @@ namespace wmoge { state.task_hnd = std::move(task_hnd); state.async_op = std::move(async_op); - state.async_op->add_on_completion(std::move(callback)); return AsyncResult>(state.async_op); } @@ -184,14 +182,9 @@ namespace wmoge { m_loaders[loader->get_class_name()] = std::move(loader); } - void AssetManager::add_unloader(Ref unloader) { - std::lock_guard guard(m_mutex); - m_unloaders[unloader->get_asset_type()->get_name()] = std::move(unloader); - } - - void AssetManager::add_pak(std::shared_ptr pak) { + void AssetManager::add_library(std::shared_ptr library) { std::lock_guard guard(m_mutex); - m_paks.push_back(std::move(pak)); + m_libraries.push_back(std::move(library)); } std::optional AssetManager::find_loader(const Strid& loader_rtti) { @@ -200,30 +193,13 @@ namespace wmoge { return query != m_loaders.end() ? std::make_optional(query->second.get()) : std::nullopt; } - std::optional AssetManager::find_unloader(const Strid& asset_rtti) { - std::lock_guard guard(m_mutex); - auto query = m_unloaders.find(asset_rtti); - return query != m_unloaders.end() ? std::make_optional(query->second.get()) : std::nullopt; - } - std::optional AssetManager::find_meta(const AssetId& asset) { std::lock_guard guard(m_mutex); AssetMeta asset_meta; - for (auto& pak : m_paks) { - if (pak->get_meta(asset, asset_meta)) { - if (asset_meta.rtti && asset_meta.loader && asset_meta.pak) { - return std::make_optional(std::move(asset_meta)); - } - if (!asset_meta.rtti) { - WG_LOG_ERROR("no class found in runtime for " << asset << " in " << pak->get_name()); - } - if (!asset_meta.loader) { - WG_LOG_ERROR("no loader found in runtime for " << asset << " in " << pak->get_name()); - } - if (!asset_meta.pak) { - WG_LOG_ERROR("no pak found in runtime for " << asset << " in " << pak->get_name()); - } + for (auto& library : m_libraries) { + if (library->find_asset_meta(asset, asset_meta)) { + return std::make_optional(std::move(asset_meta)); } } @@ -249,18 +225,6 @@ namespace wmoge { assert(loader->can_instantiate()); add_loader(loader->instantiate().cast()); } - - std::vector unloaders = m_type_storage->find_classes([](const Ref& type) { - return type->is_subtype_of(AssetUnloader::get_class_static()) && type->can_instantiate(); - }); - - for (auto& unloader : unloaders) { - assert(unloader); - assert(unloader->can_instantiate()); - add_unloader(unloader->instantiate().cast()); - } - - add_pak(std::make_shared()); } }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/asset/asset_manager.hpp b/engine/runtime/asset/asset_manager.hpp index a5939ecd9..2bcf805f5 100644 --- a/engine/runtime/asset/asset_manager.hpp +++ b/engine/runtime/asset/asset_manager.hpp @@ -28,9 +28,9 @@ #pragma once #include "asset/asset.hpp" +#include "asset/asset_library.hpp" #include "asset/asset_loader.hpp" #include "asset/asset_meta.hpp" -#include "asset/asset_pak.hpp" #include "core/async.hpp" #include "core/buffered_vector.hpp" #include "core/flat_map.hpp" @@ -44,18 +44,10 @@ #include #include #include +#include namespace wmoge { - /** - * @brief Callback function called when asset loading request is finished - * - * Use this callback function in async asset loading request. - * As argument function accepts asset being loaded. - * Function called when either asset successfully loaded or failed to load. - */ - using AssetCallback = AsyncCallback>; - /** * @class AssetManager * @brief Manages assets loading and caching in the engine @@ -71,20 +63,18 @@ namespace wmoge { */ class AssetManager { public: - AssetManager(); + AssetManager(class IocContainer* ioc); ~AssetManager() = default; - AsyncResult> load_async(const AssetId& name, AssetCallback callback = AssetCallback()); - Ref load(const AssetId& name); - Ref find(const AssetId& name); - void add_loader(Ref loader); - void add_unloader(Ref unloader); - void add_pak(std::shared_ptr pak); - std::optional find_loader(const Strid& loader_rtti); - std::optional find_unloader(const Strid& asset_rtti); - std::optional find_meta(const AssetId& asset); - void clear(); - void load_loaders(); + AsyncResult> load_async(const AssetId& name); + Ref load(const AssetId& name); + Ref find(const AssetId& name); + void add_loader(Ref loader); + void add_library(std::shared_ptr library); + std::optional find_loader(const Strid& loader_rtti); + std::optional find_meta(const AssetId& asset); + void clear(); + void load_loaders(); private: struct LoadState { @@ -93,11 +83,10 @@ namespace wmoge { TaskHnd task_hnd; }; - buffered_vector> m_paks; + std::vector> m_libraries; flat_map> m_assets; flat_map m_loading; flat_map> m_loaders; - flat_map> m_unloaders; std::shared_ptr> m_callback; class FileSystem* m_file_system = nullptr; diff --git a/engine/runtime/asset/asset_meta.hpp b/engine/runtime/asset/asset_meta.hpp index 55314edfa..f8efee669 100644 --- a/engine/runtime/asset/asset_meta.hpp +++ b/engine/runtime/asset/asset_meta.hpp @@ -30,54 +30,75 @@ #include "asset/asset.hpp" #include "asset/asset_import_data.hpp" #include "core/buffered_vector.hpp" +#include "core/date_time.hpp" +#include "core/sha256.hpp" #include "core/string_id.hpp" #include "core/uuid.hpp" #include "rtti/traits.hpp" +#include #include #include namespace wmoge { + /** @brief Asset data compression on dics */ + enum class AssetCompressionMode { + None = 0, + LZ4, + Zip + }; + /** - * @class AssetMetaFile - * @brief Structure for AssetMeta info stored as `.asset` file in file system + * @class AssetDataDesc + * @brief Describes asset associated data stored in asset system */ - struct AssetMetaFile { - WG_RTTI_STRUCT(AssetMetaFile); - - static constexpr char FILE_EXTENSION[] = ".asset"; + struct AssetDataMeta { + WG_RTTI_STRUCT(AssetDataMeta); - UUID uuid; - Strid rtti; - Strid loader; - buffered_vector deps; - std::string description; - Ref import_data; + UUID uuid; + Sha256 hash; + std::size_t size = 0; + std::size_t size_compressed = 0; + AssetCompressionMode compression = AssetCompressionMode::None; }; - WG_RTTI_STRUCT_BEGIN(AssetMetaFile) { + WG_RTTI_STRUCT_BEGIN(AssetDataMeta) { WG_RTTI_META_DATA(); WG_RTTI_FIELD(uuid, {RttiOptional}); - WG_RTTI_FIELD(rtti, {}); - WG_RTTI_FIELD(loader, {}); - WG_RTTI_FIELD(deps, {RttiOptional}); - WG_RTTI_FIELD(description, {RttiOptional}); - WG_RTTI_FIELD(import_data, {RttiOptional}); + WG_RTTI_FIELD(hash, {RttiOptional}); + WG_RTTI_FIELD(size, {RttiOptional}); + WG_RTTI_FIELD(size_compressed, {RttiOptional}); + WG_RTTI_FIELD(compression, {RttiOptional}); } WG_RTTI_END; /** * @class AssetMeta - * @brief Meta information of a particular asset + * @brief Describes asset information stored in asset system */ struct AssetMeta { - UUID uuid = UUID(); - class RttiClass* rtti = nullptr; - class AssetPak* pak = nullptr; - class AssetLoader* loader = nullptr; - buffered_vector deps; - Ref import_data; + WG_RTTI_STRUCT(AssetMeta); + + UUID uuid; + Strid rtti; + Strid loader; + std::vector deps; + std::vector data; + std::string description; + Ref import_data; }; + WG_RTTI_STRUCT_BEGIN(AssetMeta) { + WG_RTTI_META_DATA(); + WG_RTTI_FIELD(uuid, {RttiOptional}); + WG_RTTI_FIELD(rtti, {}); + WG_RTTI_FIELD(loader, {}); + WG_RTTI_FIELD(deps, {RttiOptional}); + WG_RTTI_FIELD(data, {RttiOptional}); + WG_RTTI_FIELD(description, {RttiOptional}); + WG_RTTI_FIELD(import_data, {RttiOptional}); + } + WG_RTTI_END; + }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/asset/asset_ref.hpp b/engine/runtime/asset/asset_ref.hpp index df6c377fb..e30e35a44 100644 --- a/engine/runtime/asset/asset_ref.hpp +++ b/engine/runtime/asset/asset_ref.hpp @@ -29,8 +29,8 @@ #include "asset/asset.hpp" #include "asset/asset_manager.hpp" -#include "io/property_tree.hpp" #include "io/stream.hpp" +#include "io/tree.hpp" #include #include @@ -66,10 +66,10 @@ namespace wmoge { }; template - Status tree_read(IoContext& context, IoPropertyTree& tree, AssetRef& ref) { + Status tree_read(IoContext& context, IoTree& tree, AssetRef& ref) { AssetId id; WG_TREE_READ(context, tree, id); - Ref ptr = context.get_asset_manager()->find(id).cast(); + Ref ptr = context.get()->find(id).cast(); if (!ptr) { return StatusCode::NoAsset; } @@ -78,7 +78,7 @@ namespace wmoge { } template - Status tree_write(IoContext& context, IoPropertyTree& tree, const AssetRef& ref) { + Status tree_write(IoContext& context, IoTree& tree, const AssetRef& ref) { assert(ref); if (!ref) { return StatusCode::NoAsset; @@ -91,7 +91,7 @@ namespace wmoge { Status stream_read(IoContext& context, IoStream& stream, AssetRef& ref) { AssetId id; WG_ARCHIVE_READ(context, stream, id); - Ref ptr = context.get_asset_manager()->load(id).cast(); + Ref ptr = context.get()->load(id).cast(); if (!ptr) { return StatusCode::NoAsset; } @@ -110,7 +110,7 @@ namespace wmoge { } template - Status tree_read(IoContext& context, IoPropertyTree& tree, AssetRefWeak& ref) { + Status tree_read(IoContext& context, IoTree& tree, AssetRefWeak& ref) { AssetId id; WG_TREE_READ(context, tree, id); ref = AssetRefWeak(id); @@ -118,7 +118,7 @@ namespace wmoge { } template - Status tree_write(IoContext& context, IoPropertyTree& tree, const AssetRefWeak& ref) { + Status tree_write(IoContext& context, IoTree& tree, const AssetRefWeak& ref) { AssetId id = ref; WG_TREE_WRITE(context, tree, id); return WG_OK; diff --git a/engine/runtime/core/any_storage.hpp b/engine/runtime/core/any_storage.hpp new file mode 100644 index 000000000..5630f654f --- /dev/null +++ b/engine/runtime/core/any_storage.hpp @@ -0,0 +1,63 @@ +/**********************************************************************************/ +/* Wmoge game engine */ +/* Available at github https://github.com/EgorOrachyov/wmoge */ +/**********************************************************************************/ +/* MIT License */ +/* */ +/* Copyright (c) 2023 Egor Orachyov */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining a copy */ +/* of this software and associated documentation files (the "Software"), to deal */ +/* in the Software without restriction, including without limitation the rights */ +/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell */ +/* copies of the Software, and to permit persons to whom the Software is */ +/* furnished to do so, subject to the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be included in all */ +/* copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */ +/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */ +/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */ +/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */ +/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */ +/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ +/* SOFTWARE. */ +/**********************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace wmoge { + + /** + * @class AnyStorage + * @brief Storage of elements any type tagged by the type + */ + class AnyStorage { + public: + AnyStorage() = default; + + template + void add(T element) noexcept { m_map[typeid(T)] = std::move(element); } + + template + bool has() const noexcept { return m_map.find(typeid(T)) != m_map.end(); } + + template + T get() noexcept { + assert(has()); + return std::any_cast(m_map[typeid(T)]); + } + + private: + std::unordered_map m_map; + }; + +}// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/core/async.hpp b/engine/runtime/core/async.hpp index 97cb47dc9..92ddd7aae 100644 --- a/engine/runtime/core/async.hpp +++ b/engine/runtime/core/async.hpp @@ -297,6 +297,12 @@ namespace wmoge { assert(m_state); return Async(m_state.template as()); } + + static AsyncResult failed() { + auto async_op = make_async_op(); + async_op->set_failed(); + return AsyncResult(async_op); + } }; }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/core/buffered_vector.hpp b/engine/runtime/core/buffered_vector.hpp index d57a9432e..fdf2b65bd 100644 --- a/engine/runtime/core/buffered_vector.hpp +++ b/engine/runtime/core/buffered_vector.hpp @@ -27,8 +27,8 @@ #pragma once -#include "io/property_tree.hpp" #include "io/stream.hpp" +#include "io/tree.hpp" #include #include @@ -67,7 +67,7 @@ namespace wmoge { } template - Status tree_read(IoContext& context, IoPropertyTree& tree, buffered_vector& vector) { + Status tree_read(IoContext& context, IoTree& tree, buffered_vector& vector) { assert(vector.empty()); vector.resize(tree.node_num_children()); std::size_t element_id = 0; @@ -80,7 +80,7 @@ namespace wmoge { } template - Status tree_write(IoContext& context, IoPropertyTree& tree, const buffered_vector& vector) { + Status tree_write(IoContext& context, IoTree& tree, const buffered_vector& vector) { WG_TREE_SEQ(tree, vector.size()); for (const T& value : vector) { WG_CHECKED(tree.node_append_child()); diff --git a/engine/runtime/core/data.cpp b/engine/runtime/core/data.cpp index e96473f7b..a6b29d281 100644 --- a/engine/runtime/core/data.cpp +++ b/engine/runtime/core/data.cpp @@ -85,7 +85,7 @@ namespace wmoge { return stream.nread(static_cast(size), data->buffer()); } - Status tree_write(IoContext& context, IoPropertyTree& tree, const Ref& data) { + Status tree_write(IoContext& context, IoTree& tree, const Ref& data) { if (!data) { tree.node_write_value(""); return WG_OK; @@ -97,7 +97,7 @@ namespace wmoge { } return StatusCode::FailedWrite; } - Status tree_read(IoContext& context, IoPropertyTree& tree, Ref& data) { + Status tree_read(IoContext& context, IoTree& tree, Ref& data) { std::string encoded; if (tree_read(context, tree, encoded)) { return Base64::decode(encoded, data); diff --git a/engine/runtime/core/data.hpp b/engine/runtime/core/data.hpp index c77b30b55..30cff6810 100644 --- a/engine/runtime/core/data.hpp +++ b/engine/runtime/core/data.hpp @@ -31,8 +31,8 @@ #include "core/ref.hpp" #include "core/sha256.hpp" #include "core/string_utils.hpp" -#include "io/property_tree.hpp" #include "io/stream.hpp" +#include "io/tree.hpp" #include "math/math_utils.hpp" #include @@ -76,8 +76,8 @@ namespace wmoge { friend Status stream_write(IoContext& context, IoStream& stream, const Ref& data); friend Status stream_read(IoContext& context, IoStream& stream, Ref& data); - friend Status tree_write(IoContext& context, IoPropertyTree& tree, const Ref& data); - friend Status tree_read(IoContext& context, IoPropertyTree& tree, Ref& data); + friend Status tree_write(IoContext& context, IoTree& tree, const Ref& data); + friend Status tree_read(IoContext& context, IoTree& tree, Ref& data); private: std::size_t m_size = 0; diff --git a/engine/runtime/core/date_time.cpp b/engine/runtime/core/date_time.cpp index 053591cb8..0758f6fed 100644 --- a/engine/runtime/core/date_time.cpp +++ b/engine/runtime/core/date_time.cpp @@ -32,6 +32,9 @@ namespace wmoge { + DateTime::DateTime(TimePoint tp) : m_value(tp) { + } + DateTime::DateTime(const DateTimeTm& tm) { std::tm s_tm; s_tm.tm_year = tm.year; @@ -116,13 +119,13 @@ namespace wmoge { return t; } - Status tree_read(IoContext& context, IoPropertyTree& tree, DateTime& value) { + Status tree_read(IoContext& context, IoTree& tree, DateTime& value) { std::string s; WG_TREE_READ(context, tree, s); value = DateTime(s); return WG_OK; } - Status tree_write(IoContext& context, IoPropertyTree& tree, const DateTime& value) { + Status tree_write(IoContext& context, IoTree& tree, const DateTime& value) { const std::string s = value.to_string(); WG_TREE_WRITE(context, tree, s); return WG_OK; diff --git a/engine/runtime/core/date_time.hpp b/engine/runtime/core/date_time.hpp index 3e227c0a4..e34c1e0cd 100644 --- a/engine/runtime/core/date_time.hpp +++ b/engine/runtime/core/date_time.hpp @@ -63,6 +63,7 @@ namespace wmoge { using TimePoint = Clock::time_point; DateTime() = default; + DateTime(TimePoint tp); DateTime(const DateTimeTm& tm); DateTime(const std::string& source); @@ -77,8 +78,8 @@ namespace wmoge { static DateTime now(); - friend Status tree_read(IoContext& context, IoPropertyTree& tree, DateTime& value); - friend Status tree_write(IoContext& context, IoPropertyTree& tree, const DateTime& value); + friend Status tree_read(IoContext& context, IoTree& tree, DateTime& value); + friend Status tree_write(IoContext& context, IoTree& tree, const DateTime& value); friend Status stream_read(IoContext& context, IoStream& stream, DateTime& value); friend Status stream_write(IoContext& context, IoStream& stream, const DateTime& value); diff --git a/engine/runtime/core/flat_map.hpp b/engine/runtime/core/flat_map.hpp index 5b0eedb0b..7cc7257a9 100644 --- a/engine/runtime/core/flat_map.hpp +++ b/engine/runtime/core/flat_map.hpp @@ -27,8 +27,8 @@ #pragma once -#include "io/property_tree.hpp" #include "io/stream.hpp" +#include "io/tree.hpp" #include #include @@ -70,7 +70,7 @@ namespace wmoge { } template - Status tree_read(IoContext& context, IoPropertyTree& tree, flat_map& map) { + Status tree_read(IoContext& context, IoTree& tree, flat_map& map) { assert(map.empty()); map.reserve(tree.node_num_children()); tree.node_find_first_child(); @@ -83,7 +83,7 @@ namespace wmoge { } template - Status tree_write(IoContext& context, IoPropertyTree& tree, const flat_map& map) { + Status tree_write(IoContext& context, IoTree& tree, const flat_map& map) { WG_TREE_SEQ(tree, map.size()); for (const auto& entry : map) { WG_CHECKED(tree.node_append_child()); diff --git a/engine/runtime/core/mask.hpp b/engine/runtime/core/mask.hpp index 226581907..78214a27c 100644 --- a/engine/runtime/core/mask.hpp +++ b/engine/runtime/core/mask.hpp @@ -27,10 +27,6 @@ #pragma once -#include "core/buffered_vector.hpp" -#include "io/property_tree.hpp" -#include "io/stream.hpp" - #include #include #include @@ -106,38 +102,4 @@ namespace wmoge { return stream; } - template - Status tree_read(IoContext& context, IoPropertyTree& tree, Mask& mask) { - buffered_vector flags; - WG_TREE_READ(context, tree, flags); - - for (auto flag : flags) { - mask.set(flag); - } - - return WG_OK; - } - - template - Status tree_write(IoContext& context, IoPropertyTree& tree, const Mask& mask) { - buffered_vector flags; - - mask.for_each([&](int, T flag) { - flags.push_back(flag); - }); - - WG_TREE_WRITE(context, tree, flags); - return WG_OK; - } - - template - Status stream_read(IoContext& context, IoStream& stream, Mask& mask) { - return stream.nread(sizeof(Mask), &mask); - } - - template - Status stream_write(IoContext& context, IoStream& stream, const Mask& mask) { - return stream.nwrite(sizeof(Mask), &mask); - } - }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/core/object.cpp b/engine/runtime/core/object.cpp index e06e12d3b..ff97b39cc 100644 --- a/engine/runtime/core/object.cpp +++ b/engine/runtime/core/object.cpp @@ -123,7 +123,7 @@ namespace wmoge { return name; } - Status tree_read_object(IoContext& context, IoPropertyTree& tree, Ref& object) { + Status tree_read_object(IoContext& context, IoTree& tree, Ref& object) { assert(!object); Strid class_name; @@ -145,7 +145,7 @@ namespace wmoge { return object->read_from_tree(tree); } - Status tree_write_object(IoContext& context, IoPropertyTree& tree, const Ref& object) { + Status tree_write_object(IoContext& context, IoTree& tree, const Ref& object) { assert(object); WG_TREE_MAP(tree); WG_TREE_WRITE_AS(context, tree, "rtti", object->class_name()); diff --git a/engine/runtime/core/object.hpp b/engine/runtime/core/object.hpp index 77901bab8..2f27e734e 100644 --- a/engine/runtime/core/object.hpp +++ b/engine/runtime/core/object.hpp @@ -31,8 +31,8 @@ #include "core/status.hpp" #include "core/string_id.hpp" #include "core/var.hpp" -#include "io/property_tree.hpp" #include "io/stream.hpp" +#include "io/tree.hpp" #include #include @@ -69,8 +69,8 @@ namespace wmoge { virtual Status call(const Strid& method, int argc, const Var* argv, Var& ret); virtual Status signal(const Strid& signal) { return WG_OK; } virtual Status copy_to(Object& other) const { return WG_OK; } - virtual Status read_from_tree(IoPropertyTree& tree) { return StatusCode::NotImplemented; } - virtual Status write_to_tree(IoPropertyTree& tree) const { return StatusCode::NotImplemented; } + virtual Status read_from_tree(IoTree& tree) { return StatusCode::NotImplemented; } + virtual Status write_to_tree(IoTree& tree) const { return StatusCode::NotImplemented; } virtual Status read_from_stream(IoStream& stream) { return StatusCode::NotImplemented; } virtual Status write_to_stream(IoStream& stream) const { return StatusCode::NotImplemented; } virtual Status clone(Ref& object) const; @@ -85,8 +85,8 @@ namespace wmoge { static const Strid& class_name_static(); static const Strid& super_class_name_static(); - friend Status tree_read_object(IoContext& context, IoPropertyTree& tree, Ref& object); - friend Status tree_write_object(IoContext& context, IoPropertyTree& tree, const Ref& object); + friend Status tree_read_object(IoContext& context, IoTree& tree, Ref& object); + friend Status tree_write_object(IoContext& context, IoTree& tree, const Ref& object); friend Status archive_read_object(IoContext& context, IoStream& stream, Ref& object); friend Status archive_write_object(IoContext& context, IoStream& stream, const Ref& object); diff --git a/engine/runtime/core/pool_vector.hpp b/engine/runtime/core/pool_vector.hpp index 8c1482746..6087f785e 100644 --- a/engine/runtime/core/pool_vector.hpp +++ b/engine/runtime/core/pool_vector.hpp @@ -28,7 +28,7 @@ #pragma once #include "core/buffered_vector.hpp" -#include "io/property_tree.hpp" +#include "io/tree.hpp" #include #include diff --git a/engine/runtime/core/sha256.cpp b/engine/runtime/core/sha256.cpp index f9c6c6d8b..eeaad1b9c 100644 --- a/engine/runtime/core/sha256.cpp +++ b/engine/runtime/core/sha256.cpp @@ -96,14 +96,14 @@ namespace wmoge { return hash_value; } - Status tree_read(IoContext& context, IoPropertyTree& tree, Sha256& sha) { + Status tree_read(IoContext& context, IoTree& tree, Sha256& sha) { std::string s; WG_CHECKED(tree_read(context, tree, s)); sha = Sha256(s); return WG_OK; } - Status tree_write(IoContext& context, IoPropertyTree& tree, const Sha256& sha) { + Status tree_write(IoContext& context, IoTree& tree, const Sha256& sha) { return tree_write(context, tree, sha.to_string()); } Status stream_read(IoContext& context, IoStream& stream, Sha256& sha) { diff --git a/engine/runtime/core/sha256.hpp b/engine/runtime/core/sha256.hpp index 46178d595..ccf57cb0d 100644 --- a/engine/runtime/core/sha256.hpp +++ b/engine/runtime/core/sha256.hpp @@ -27,8 +27,8 @@ #pragma once -#include "io/property_tree.hpp" #include "io/stream.hpp" +#include "io/tree.hpp" #include #include @@ -64,8 +64,8 @@ namespace wmoge { static_assert(std::is_trivially_destructible_v, "Sha256 must be trivial as ptr or int"); - Status tree_read(IoContext& context, IoPropertyTree& tree, Sha256& sha); - Status tree_write(IoContext& context, IoPropertyTree& tree, const Sha256& sha); + Status tree_read(IoContext& context, IoTree& tree, Sha256& sha); + Status tree_write(IoContext& context, IoTree& tree, const Sha256& sha); Status stream_read(IoContext& context, IoStream& stream, Sha256& sha); Status stream_write(IoContext& context, IoStream& stream, const Sha256& sha); diff --git a/engine/runtime/core/status.hpp b/engine/runtime/core/status.hpp index 6c7cb5956..632893b93 100644 --- a/engine/runtime/core/status.hpp +++ b/engine/runtime/core/status.hpp @@ -49,6 +49,7 @@ namespace wmoge { FailedLoadLibrary,// Failed to open dynamic library FailedLoadSymbol, // Failed to open dynamic symbol FailedOpenFile, // Failed to open file or stream for read/write operations + FailedFindFile, // Failed to find file or stream FailedParse, // Failed to parse structured file FailedRead, // Failed to perform reading of some data FailedWrite, // Failed to write some data diff --git a/engine/runtime/core/typed_array.hpp b/engine/runtime/core/typed_array.hpp index e6f243075..ebe9afc28 100644 --- a/engine/runtime/core/typed_array.hpp +++ b/engine/runtime/core/typed_array.hpp @@ -28,7 +28,7 @@ #pragma once #include "core/ref.hpp" -#include "io/property_tree.hpp" +#include "io/tree.hpp" #include diff --git a/engine/runtime/core/typed_map.hpp b/engine/runtime/core/typed_map.hpp index 66358d6ea..07ad4650f 100644 --- a/engine/runtime/core/typed_map.hpp +++ b/engine/runtime/core/typed_map.hpp @@ -28,7 +28,7 @@ #pragma once #include "core/ref.hpp" -#include "io/property_tree.hpp" +#include "io/tree.hpp" #include #include diff --git a/engine/runtime/core/uuid.cpp b/engine/runtime/core/uuid.cpp index 5e138c62a..51a0c2fc8 100644 --- a/engine/runtime/core/uuid.cpp +++ b/engine/runtime/core/uuid.cpp @@ -46,13 +46,13 @@ namespace wmoge { return {Random::next_uint64()}; } - Status tree_read(IoContext& context, IoPropertyTree& tree, UUID& id) { + Status tree_read(IoContext& context, IoTree& tree, UUID& id) { std::string value; WG_TREE_READ(context, tree, value); id = UUID(value); return WG_OK; } - Status tree_write(IoContext& context, IoPropertyTree& tree, const UUID& id) { + Status tree_write(IoContext& context, IoTree& tree, const UUID& id) { WG_TREE_WRITE(context, tree, StringUtils::from_uint64(id.m_value)); return WG_OK; } diff --git a/engine/runtime/core/uuid.hpp b/engine/runtime/core/uuid.hpp index 24d9c3c4e..9ee8f8b96 100644 --- a/engine/runtime/core/uuid.hpp +++ b/engine/runtime/core/uuid.hpp @@ -27,8 +27,8 @@ #pragma once -#include "io/property_tree.hpp" #include "io/stream.hpp" +#include "io/tree.hpp" #include #include @@ -64,8 +64,8 @@ namespace wmoge { static UUID generate(); - friend Status tree_read(IoContext& context, IoPropertyTree& tree, UUID& id); - friend Status tree_write(IoContext& context, IoPropertyTree& tree, const UUID& id); + friend Status tree_read(IoContext& context, IoTree& tree, UUID& id); + friend Status tree_write(IoContext& context, IoTree& tree, const UUID& id); friend Status stream_read(IoContext& context, IoStream& stream, UUID& id); friend Status stream_write(IoContext& context, IoStream& stream, const UUID& id); diff --git a/engine/runtime/ecs/ecs_core.hpp b/engine/runtime/ecs/ecs_core.hpp index 68da1c3ed..53711e0e1 100644 --- a/engine/runtime/ecs/ecs_core.hpp +++ b/engine/runtime/ecs/ecs_core.hpp @@ -27,8 +27,8 @@ #pragma once -#include "io/property_tree.hpp" #include "io/stream.hpp" +#include "io/tree.hpp" #include #include @@ -79,10 +79,10 @@ namespace wmoge { [[nodiscard]] std::string to_string() const; - friend Status tree_read(IoContext& context, IoPropertyTree& tree, EcsArch& arch) { + friend Status tree_read(IoContext& context, IoTree& tree, EcsArch& arch) { return tree_read(context, tree, *((EcsArch::Bitset*) &arch)); } - friend Status tree_write(IoContext& context, IoPropertyTree& tree, const EcsArch& arch) { + friend Status tree_write(IoContext& context, IoTree& tree, const EcsArch& arch) { return tree_write(context, tree, *((const EcsArch::Bitset*) &arch)); } friend Status stream_read(IoContext& context, IoStream& stream, EcsArch& arch) { diff --git a/engine/runtime/engine.hpp b/engine/runtime/engine.hpp index 1be33cbe9..d00b6cade 100644 --- a/engine/runtime/engine.hpp +++ b/engine/runtime/engine.hpp @@ -29,11 +29,11 @@ #include "asset/asset.hpp" #include "asset/asset_import_data.hpp" +#include "asset/asset_library.hpp" +#include "asset/asset_library_fs.hpp" #include "asset/asset_loader.hpp" #include "asset/asset_manager.hpp" #include "asset/asset_meta.hpp" -#include "asset/asset_pak.hpp" -#include "asset/asset_pak_fs.hpp" #include "asset/asset_ref.hpp" #include "audio/audio_bus.hpp" @@ -129,10 +129,10 @@ #include "io/context.hpp" #include "io/enum.hpp" #include "io/ini.hpp" -#include "io/property_tree.hpp" #include "io/serialization.hpp" #include "io/stream.hpp" #include "io/stream_file.hpp" +#include "io/tree.hpp" #include "material/material.hpp" diff --git a/engine/runtime/gfx/gfx_sampler.cpp b/engine/runtime/gfx/gfx_sampler.cpp index 01584f3aa..116314198 100644 --- a/engine/runtime/gfx/gfx_sampler.cpp +++ b/engine/runtime/gfx/gfx_sampler.cpp @@ -28,7 +28,7 @@ #include "gfx_sampler.hpp" #include "core/crc32.hpp" -#include "io/property_tree.hpp" +#include "io/tree.hpp" #include #include diff --git a/engine/runtime/grc/texture.cpp b/engine/runtime/grc/texture.cpp index cca0c28e0..5131b02f3 100644 --- a/engine/runtime/grc/texture.cpp +++ b/engine/runtime/grc/texture.cpp @@ -31,7 +31,7 @@ #include "core/data.hpp" #include "core/string_utils.hpp" #include "gfx/gfx_driver.hpp" -#include "io/property_tree.hpp" +#include "io/tree.hpp" #include "profiler/profiler.hpp" #include "system/ioc_container.hpp" diff --git a/engine/runtime/io/context.hpp b/engine/runtime/io/context.hpp index e187c551a..b2f3dd5f9 100644 --- a/engine/runtime/io/context.hpp +++ b/engine/runtime/io/context.hpp @@ -27,6 +27,8 @@ #pragma once +#include "core/any_storage.hpp" + namespace wmoge { /** @@ -37,14 +39,17 @@ namespace wmoge { public: IoContext() = default; - [[nodiscard]] class AssetManager* get_asset_manager(); - [[nodiscard]] class RttiTypeStorage* get_type_storage(); - [[nodiscard]] class IocContainer* get_ioc_container(); + template + void add(T element) { m_storage.add(std::move(element)); } + + template + T get() { return m_storage.get(); } + + template + bool has() const { return m_storage.has(); } private: - class AssetManager* m_asset_manager = nullptr; - class RttiTypeStorage* m_type_storage = nullptr; - class IocContainer* m_ioc_container = nullptr; + AnyStorage m_storage; }; }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/io/serialization.hpp b/engine/runtime/io/serialization.hpp index 663a60cac..9d4d55604 100644 --- a/engine/runtime/io/serialization.hpp +++ b/engine/runtime/io/serialization.hpp @@ -30,8 +30,8 @@ #include "core/log.hpp" #include "core/mask.hpp" #include "core/status.hpp" -#include "io/property_tree.hpp" #include "io/stream.hpp" +#include "io/tree.hpp" #include @@ -46,17 +46,17 @@ namespace wmoge { struct IoTagRead; struct IoTagWrite; -#define WG_IO_DECLARE(cls) \ - friend Status tree_read(IoContext& context, IoPropertyTree& tree, cls& value); \ - friend Status tree_write(IoContext& context, IoPropertyTree& tree, const cls& value); \ - friend Status stream_read(IoContext& context, IoStream& stream, cls& value); \ +#define WG_IO_DECLARE(cls) \ + friend Status tree_read(IoContext& context, IoTree& tree, cls& value); \ + friend Status tree_write(IoContext& context, IoTree& tree, const cls& value); \ + friend Status stream_read(IoContext& context, IoStream& stream, cls& value); \ friend Status stream_write(IoContext& context, IoStream& stream, const cls& value); #define WG_IO_IMPLEMENT(nmsp, trg, cls) \ - Status tree_read(IoContext& context, IoPropertyTree& tree, trg& value) { \ + Status tree_read(IoContext& context, IoTree& tree, trg& value) { \ return nmsp##__##cls##Serializer()(context, tree, value); \ } \ - Status tree_write(IoContext& context, IoPropertyTree& tree, const trg& value) { \ + Status tree_write(IoContext& context, IoTree& tree, const trg& value) { \ return nmsp##__##cls##Serializer()(context, tree, value); \ } \ Status stream_read(IoContext& context, IoStream& stream, trg& value) { \ diff --git a/engine/runtime/io/stream.hpp b/engine/runtime/io/stream.hpp index d114c8b0a..5e76058c7 100644 --- a/engine/runtime/io/stream.hpp +++ b/engine/runtime/io/stream.hpp @@ -28,6 +28,7 @@ #pragma once #include "core/log.hpp" +#include "core/mask.hpp" #include "core/ref.hpp" #include "core/status.hpp" #include "core/string_id.hpp" @@ -261,4 +262,14 @@ namespace wmoge { return WG_OK; } + template + Status stream_read(IoContext& context, IoStream& stream, Mask& mask) { + return stream.nread(sizeof(Mask), &mask); + } + + template + Status stream_write(IoContext& context, IoStream& stream, const Mask& mask) { + return stream.nwrite(sizeof(Mask), &mask); + } + }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/io/property_tree.cpp b/engine/runtime/io/tree.cpp similarity index 67% rename from engine/runtime/io/property_tree.cpp rename to engine/runtime/io/tree.cpp index 56dfb45ae..d31bfc510 100644 --- a/engine/runtime/io/property_tree.cpp +++ b/engine/runtime/io/tree.cpp @@ -25,70 +25,70 @@ /* SOFTWARE. */ /**********************************************************************************/ -#include "property_tree.hpp" +#include "tree.hpp" namespace wmoge { - Status tree_read(IoContext& context, IoPropertyTree& tree, bool& value) { + Status tree_read(IoContext& context, IoTree& tree, bool& value) { return tree.node_read_value(value); } - Status tree_write(IoContext& context, IoPropertyTree& tree, const bool& value) { + Status tree_write(IoContext& context, IoTree& tree, const bool& value) { return tree.node_write_value(value); } - Status tree_read(IoContext& context, IoPropertyTree& tree, int& value) { + Status tree_read(IoContext& context, IoTree& tree, int& value) { return tree.node_read_value(value); } - Status tree_write(IoContext& context, IoPropertyTree& tree, const int& value) { + Status tree_write(IoContext& context, IoTree& tree, const int& value) { return tree.node_write_value(value); } - Status tree_read(IoContext& context, IoPropertyTree& tree, unsigned int& value) { + Status tree_read(IoContext& context, IoTree& tree, unsigned int& value) { return tree.node_read_value(value); } - Status tree_write(IoContext& context, IoPropertyTree& tree, const unsigned int& value) { + Status tree_write(IoContext& context, IoTree& tree, const unsigned int& value) { return tree.node_write_value(value); } - Status tree_read(IoContext& context, IoPropertyTree& tree, float& value) { + Status tree_read(IoContext& context, IoTree& tree, float& value) { return tree.node_read_value(value); } - Status tree_write(IoContext& context, IoPropertyTree& tree, const float& value) { + Status tree_write(IoContext& context, IoTree& tree, const float& value) { return tree.node_write_value(value); } - Status tree_read(IoContext& context, IoPropertyTree& tree, Strid& value) { + Status tree_read(IoContext& context, IoTree& tree, Strid& value) { return tree.node_read_value(value); } - Status tree_write(IoContext& context, IoPropertyTree& tree, const Strid& value) { + Status tree_write(IoContext& context, IoTree& tree, const Strid& value) { return tree.node_write_value(value); } - Status tree_read(IoContext& context, IoPropertyTree& tree, std::string& value) { + Status tree_read(IoContext& context, IoTree& tree, std::string& value) { return tree.node_read_value(value); } - Status tree_write(IoContext& context, IoPropertyTree& tree, const std::string& value) { + Status tree_write(IoContext& context, IoTree& tree, const std::string& value) { return tree.node_write_value(value); } - Status tree_read(IoContext& context, IoPropertyTree& tree, std::int16_t& value) { + Status tree_read(IoContext& context, IoTree& tree, std::int16_t& value) { return tree.node_read_value(value); } - Status tree_write(IoContext& context, IoPropertyTree& tree, const std::int16_t& value) { + Status tree_write(IoContext& context, IoTree& tree, const std::int16_t& value) { return tree.node_write_value(value); } - Status tree_read(IoContext& context, IoPropertyTree& tree, std::size_t& value) { + Status tree_read(IoContext& context, IoTree& tree, std::size_t& value) { return tree.node_read_value(value); } - Status tree_write(IoContext& context, IoPropertyTree& tree, const std::size_t& value) { + Status tree_write(IoContext& context, IoTree& tree, const std::size_t& value) { return tree.node_write_value(value); } - Status tree_read(IoContext& context, IoPropertyTree& tree, Status& value) { + Status tree_read(IoContext& context, IoTree& tree, Status& value) { return tree_read(context, tree, value.code()); } - Status tree_write(IoContext& context, IoPropertyTree& tree, const Status& value) { + Status tree_write(IoContext& context, IoTree& tree, const Status& value) { return tree_write(context, tree, value.code()); } diff --git a/engine/runtime/io/property_tree.hpp b/engine/runtime/io/tree.hpp similarity index 76% rename from engine/runtime/io/property_tree.hpp rename to engine/runtime/io/tree.hpp index 520dac9b0..2c3318a79 100644 --- a/engine/runtime/io/property_tree.hpp +++ b/engine/runtime/io/tree.hpp @@ -28,6 +28,7 @@ #pragma once #include "core/log.hpp" +#include "core/mask.hpp" #include "core/ref.hpp" #include "core/status.hpp" #include "core/string_id.hpp" @@ -50,13 +51,25 @@ namespace wmoge { + /** @brief Io tree flags to control tree serialization */ + enum class IoTreeFlag { + FormatText = 0, + FormatBinary, + FormatDirect, + FormatVariant, + UserFriendly + }; + + /** @brief Io tree flags mask */ + using IoTreeFlags = Mask; + /** - * @class IoPropertyTree + * @class IoTree * @brief Structured property serialization and de-serialization tree */ - class IoPropertyTree { + class IoTree { public: - virtual ~IoPropertyTree() = default; + virtual ~IoTree() = default; virtual bool node_is_empty() = 0; virtual bool node_has_child(const std::string_view& name) = 0; @@ -91,42 +104,44 @@ namespace wmoge { virtual void node_as_map() = 0; virtual void node_as_list(std::size_t length) = 0; - [[nodiscard]] bool can_read() const { return m_can_read; } - [[nodiscard]] bool can_write() const { return m_can_write; } - [[nodiscard]] const Strid& get_name() const { return m_name; } + [[nodiscard]] bool can_read() const { return m_can_read; } + [[nodiscard]] bool can_write() const { return m_can_write; } + [[nodiscard]] const Strid& get_name() const { return m_name; } + [[nodiscard]] const IoTreeFlags& get_flags() const { return m_flags; } protected: - Strid m_name; - bool m_can_read = false; - bool m_can_write = false; + Strid m_name; + IoTreeFlags m_flags; + bool m_can_read = false; + bool m_can_write = false; }; - Status tree_read(IoContext& context, IoPropertyTree& tree, bool& value); - Status tree_write(IoContext& context, IoPropertyTree& tree, const bool& value); + Status tree_read(IoContext& context, IoTree& tree, bool& value); + Status tree_write(IoContext& context, IoTree& tree, const bool& value); - Status tree_read(IoContext& context, IoPropertyTree& tree, int& value); - Status tree_write(IoContext& context, IoPropertyTree& tree, const int& value); + Status tree_read(IoContext& context, IoTree& tree, int& value); + Status tree_write(IoContext& context, IoTree& tree, const int& value); - Status tree_read(IoContext& context, IoPropertyTree& tree, unsigned int& value); - Status tree_write(IoContext& context, IoPropertyTree& tree, const unsigned int& value); + Status tree_read(IoContext& context, IoTree& tree, unsigned int& value); + Status tree_write(IoContext& context, IoTree& tree, const unsigned int& value); - Status tree_read(IoContext& context, IoPropertyTree& tree, float& value); - Status tree_write(IoContext& context, IoPropertyTree& tree, const float& value); + Status tree_read(IoContext& context, IoTree& tree, float& value); + Status tree_write(IoContext& context, IoTree& tree, const float& value); - Status tree_read(IoContext& context, IoPropertyTree& tree, Strid& value); - Status tree_write(IoContext& context, IoPropertyTree& tree, const Strid& value); + Status tree_read(IoContext& context, IoTree& tree, Strid& value); + Status tree_write(IoContext& context, IoTree& tree, const Strid& value); - Status tree_read(IoContext& context, IoPropertyTree& tree, std::string& value); - Status tree_write(IoContext& context, IoPropertyTree& tree, const std::string& value); + Status tree_read(IoContext& context, IoTree& tree, std::string& value); + Status tree_write(IoContext& context, IoTree& tree, const std::string& value); - Status tree_read(IoContext& context, IoPropertyTree& tree, std::int16_t& value); - Status tree_write(IoContext& context, IoPropertyTree& tree, const std::int16_t& value); + Status tree_read(IoContext& context, IoTree& tree, std::int16_t& value); + Status tree_write(IoContext& context, IoTree& tree, const std::int16_t& value); - Status tree_read(IoContext& context, IoPropertyTree& tree, std::size_t& value); - Status tree_write(IoContext& context, IoPropertyTree& tree, const std::size_t& value); + Status tree_read(IoContext& context, IoTree& tree, std::size_t& value); + Status tree_write(IoContext& context, IoTree& tree, const std::size_t& value); - Status tree_read(IoContext& context, IoPropertyTree& tree, Status& value); - Status tree_write(IoContext& context, IoPropertyTree& tree, const Status& value); + Status tree_read(IoContext& context, IoTree& tree, Status& value); + Status tree_write(IoContext& context, IoTree& tree, const Status& value); #define WG_TREE_READ(context, tree, what) \ do { \ @@ -200,13 +215,13 @@ namespace wmoge { #define WG_TREE_SEQ(tree, length) tree.node_as_list(length) template - Status tree_read(IoContext& context, IoPropertyTree& tree, std::pair& pair) { + Status tree_read(IoContext& context, IoTree& tree, std::pair& pair) { WG_TREE_READ_AS(context, tree, "key", pair.first); WG_TREE_READ_AS(context, tree, "value", pair.second); return WG_OK; } template - Status tree_write(IoContext& context, IoPropertyTree& tree, const std::pair& pair) { + Status tree_write(IoContext& context, IoTree& tree, const std::pair& pair) { WG_TREE_MAP(tree); WG_TREE_WRITE_AS(context, tree, "key", pair.first); WG_TREE_WRITE_AS(context, tree, "value", pair.second); @@ -214,13 +229,13 @@ namespace wmoge { } template - Status tree_read(IoContext& context, IoPropertyTree& tree, robin_hood::pair& pair) { + Status tree_read(IoContext& context, IoTree& tree, robin_hood::pair& pair) { WG_TREE_READ_AS(context, tree, "key", pair.first); WG_TREE_READ_AS(context, tree, "value", pair.second); return WG_OK; } template - Status tree_write(IoContext& context, IoPropertyTree& tree, const robin_hood::pair& pair) { + Status tree_write(IoContext& context, IoTree& tree, const robin_hood::pair& pair) { WG_TREE_MAP(tree); WG_TREE_WRITE_AS(context, tree, "key", pair.first); WG_TREE_WRITE_AS(context, tree, "value", pair.second); @@ -228,7 +243,7 @@ namespace wmoge { } template - Status tree_read(IoContext& context, IoPropertyTree& tree, std::array& array) { + Status tree_read(IoContext& context, IoTree& tree, std::array& array) { std::size_t element_id = 0; assert(tree.node_num_children() <= S); tree.node_find_first_child(); @@ -239,7 +254,7 @@ namespace wmoge { return WG_OK; } template - Status tree_write(IoContext& context, IoPropertyTree& tree, const std::array& array) { + Status tree_write(IoContext& context, IoTree& tree, const std::array& array) { WG_TREE_SEQ(tree, S); for (std::size_t i = 0; i < S; i++) { WG_CHECKED(tree.node_append_child()); @@ -250,7 +265,7 @@ namespace wmoge { } template - Status tree_read(IoContext& context, IoPropertyTree& tree, std::vector& vector) { + Status tree_read(IoContext& context, IoTree& tree, std::vector& vector) { assert(vector.empty()); vector.resize(tree.node_num_children()); std::size_t element_id = 0; @@ -262,7 +277,7 @@ namespace wmoge { return WG_OK; } template - Status tree_write(IoContext& context, IoPropertyTree& tree, const std::vector& vector) { + Status tree_write(IoContext& context, IoTree& tree, const std::vector& vector) { WG_TREE_SEQ(tree, vector.size()); for (const T& value : vector) { WG_CHECKED(tree.node_append_child()); @@ -273,7 +288,7 @@ namespace wmoge { } template - Status tree_read(IoContext& context, IoPropertyTree& tree, std::unordered_set& set) { + Status tree_read(IoContext& context, IoTree& tree, std::unordered_set& set) { assert(set.empty()); set.reserve(tree.node_num_children()); tree.node_find_first_child(); @@ -285,7 +300,7 @@ namespace wmoge { return WG_OK; } template - Status tree_write(IoContext& context, IoPropertyTree& tree, const std::unordered_set& set) { + Status tree_write(IoContext& context, IoTree& tree, const std::unordered_set& set) { WG_TREE_SEQ(tree, set.size()); for (const T& entry : set) { WG_CHECKED(tree.node_append_child()); @@ -296,7 +311,7 @@ namespace wmoge { } template - Status tree_read(IoContext& context, IoPropertyTree& tree, std::unordered_map& map) { + Status tree_read(IoContext& context, IoTree& tree, std::unordered_map& map) { assert(map.empty()); map.reserve(tree.node_num_children()); tree.node_find_first_child(); @@ -308,7 +323,7 @@ namespace wmoge { return WG_OK; } template - Status tree_write(IoContext& context, IoPropertyTree& tree, const std::unordered_map& map) { + Status tree_write(IoContext& context, IoTree& tree, const std::unordered_map& map) { WG_TREE_SEQ(tree, map.size()); for (const auto& entry : map) { WG_CHECKED(tree.node_append_child()); @@ -319,7 +334,7 @@ namespace wmoge { } template::value>::type> - Status tree_read(IoContext& context, IoPropertyTree& tree, T& enum_value) { + Status tree_read(IoContext& context, IoTree& tree, T& enum_value) { std::string s; WG_TREE_READ(context, tree, s); auto parsed = magic_enum::enum_cast(s); @@ -330,13 +345,13 @@ namespace wmoge { return WG_OK; } template::value>::type> - Status tree_write(IoContext& context, IoPropertyTree& tree, const T& enum_value) { + Status tree_write(IoContext& context, IoTree& tree, const T& enum_value) { WG_TREE_WRITE(context, tree, std::string(magic_enum::enum_name(enum_value))); return WG_OK; } template - Status tree_read(IoContext& context, IoPropertyTree& tree, std::optional& wrapper) { + Status tree_read(IoContext& context, IoTree& tree, std::optional& wrapper) { if (!tree.node_is_empty()) { wrapper.emplace(); WG_TREE_READ(context, tree, wrapper.value()); @@ -344,7 +359,7 @@ namespace wmoge { return WG_OK; } template - Status tree_write(IoContext& context, IoPropertyTree& tree, const std::optional& wrapper) { + Status tree_write(IoContext& context, IoTree& tree, const std::optional& wrapper) { if (wrapper.has_value()) { WG_TREE_WRITE(context, tree, wrapper.value()); } @@ -352,7 +367,7 @@ namespace wmoge { } template - Status tree_read(IoContext& context, IoPropertyTree& tree, std::bitset& bitset) { + Status tree_read(IoContext& context, IoTree& tree, std::bitset& bitset) { std::array values; WG_TREE_READ(context, tree, values); for (std::size_t i = 0; i < N; i++) { @@ -363,7 +378,7 @@ namespace wmoge { return WG_OK; } template - Status tree_write(IoContext& context, IoPropertyTree& tree, const std::bitset& bitset) { + Status tree_write(IoContext& context, IoTree& tree, const std::bitset& bitset) { std::array values; values.fill(false); for (std::size_t i = 0; i < N; i++) { @@ -375,4 +390,28 @@ namespace wmoge { return WG_OK; } + template + Status tree_read(IoContext& context, IoTree& tree, Mask& mask) { + buffered_vector flags; + WG_TREE_READ(context, tree, flags); + + for (auto flag : flags) { + mask.set(flag); + } + + return WG_OK; + } + + template + Status tree_write(IoContext& context, IoTree& tree, const Mask& mask) { + buffered_vector flags; + + mask.for_each([&](int, T flag) { + flags.push_back(flag); + }); + + WG_TREE_WRITE(context, tree, flags); + return WG_OK; + } + }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/io/yaml.cpp b/engine/runtime/io/tree_yaml.cpp similarity index 96% rename from engine/runtime/io/yaml.cpp rename to engine/runtime/io/tree_yaml.cpp index 1c8853989..4693de05d 100644 --- a/engine/runtime/io/yaml.cpp +++ b/engine/runtime/io/tree_yaml.cpp @@ -25,7 +25,7 @@ /* SOFTWARE. */ /**********************************************************************************/ -#include "yaml.hpp" +#include "tree_yaml.hpp" #include "platform/file_system.hpp" #include "profiler/profiler.hpp" @@ -61,9 +61,12 @@ namespace wmoge { } Status IoYamlTree::parse_file(const std::string& path) { - FileSystem* file_system = IocContainer::iresolve_v(); + return parse_file(IocContainer::iresolve_v(), path); + } + + Status IoYamlTree::parse_file(FileSystem* fs, const std::string& path) { std::vector data; - WG_CHECKED(file_system->read_file(path, data)); + WG_CHECKED(fs->read_file(path, data)); return parse_data(data); } diff --git a/engine/runtime/io/yaml.hpp b/engine/runtime/io/tree_yaml.hpp similarity index 97% rename from engine/runtime/io/yaml.hpp rename to engine/runtime/io/tree_yaml.hpp index 364ebc8a3..228decbe1 100644 --- a/engine/runtime/io/yaml.hpp +++ b/engine/runtime/io/tree_yaml.hpp @@ -32,7 +32,7 @@ #include "core/ref.hpp" #include "core/status.hpp" #include "core/string_id.hpp" -#include "io/property_tree.hpp" +#include "io/tree.hpp" #include #include @@ -45,7 +45,7 @@ namespace wmoge { * @class IoYamlTree * @brief Yaml tree implementation for serialization and de-serialization */ - class IoYamlTree : public IoPropertyTree { + class IoYamlTree : public IoTree { public: IoYamlTree() = default; ~IoYamlTree() = default; @@ -53,6 +53,7 @@ namespace wmoge { Status create_tree(); Status parse_data(const array_view& data); Status parse_file(const std::string& path); + Status parse_file(class FileSystem* fs, const std::string& path); bool node_is_empty() override; bool node_has_child(const std::string_view& name) override; diff --git a/engine/runtime/math/aabb.hpp b/engine/runtime/math/aabb.hpp index ca399bf57..5d54269c0 100644 --- a/engine/runtime/math/aabb.hpp +++ b/engine/runtime/math/aabb.hpp @@ -27,8 +27,8 @@ #pragma once -#include "io/property_tree.hpp" #include "io/stream.hpp" +#include "io/tree.hpp" #include "math/mat.hpp" #include "math/vec.hpp" @@ -120,13 +120,13 @@ namespace wmoge { } template - Status tree_read(IoContext& context, IoPropertyTree& tree, TAabb& aabb) { + Status tree_read(IoContext& context, IoTree& tree, TAabb& aabb) { WG_TREE_READ_AS(context, tree, "pos", aabb.pos); WG_TREE_READ_AS(context, tree, "size_half", aabb.size_half); return WG_OK; } template - Status tree_write(IoContext& context, IoPropertyTree& tree, const TAabb& aabb) { + Status tree_write(IoContext& context, IoTree& tree, const TAabb& aabb) { WG_TREE_MAP(tree); WG_TREE_WRITE_AS(context, tree, "pos", aabb.pos); WG_TREE_WRITE_AS(context, tree, "size_half", aabb.size_half); diff --git a/engine/runtime/math/quat.hpp b/engine/runtime/math/quat.hpp index d7dc1ff74..672312c10 100644 --- a/engine/runtime/math/quat.hpp +++ b/engine/runtime/math/quat.hpp @@ -27,8 +27,8 @@ #pragma once -#include "io/property_tree.hpp" #include "io/stream.hpp" +#include "io/tree.hpp" #include "math/mat.hpp" #include "math/vec.hpp" @@ -439,13 +439,13 @@ namespace wmoge { } template - Status tree_read(IoContext& context, IoPropertyTree& tree, TQuat& quat) { + Status tree_read(IoContext& context, IoTree& tree, TQuat& quat) { WG_TREE_READ_AS(context, tree, "scalar", quat.scalar); WG_TREE_READ_AS(context, tree, "vec", quat.vec); return WG_OK; } template - Status tree_write(IoContext& context, IoPropertyTree& tree, const TQuat& quat) { + Status tree_write(IoContext& context, IoTree& tree, const TQuat& quat) { WG_TREE_MAP(tree); WG_TREE_WRITE_AS(context, tree, "scalar", quat.scalar); WG_TREE_WRITE_AS(context, tree, "vec", quat.vec); diff --git a/engine/runtime/math/transform.hpp b/engine/runtime/math/transform.hpp index b600ea1a9..e4b944c8f 100644 --- a/engine/runtime/math/transform.hpp +++ b/engine/runtime/math/transform.hpp @@ -71,13 +71,13 @@ namespace wmoge { Math2d::translate(-m_translation); } - friend Status tree_read(IoContext& context, IoPropertyTree& tree, Transform2d& transform) { + friend Status tree_read(IoContext& context, IoTree& tree, Transform2d& transform) { WG_TREE_READ_AS_OPT(context, tree, "rotation", transform.m_rotation); WG_TREE_READ_AS_OPT(context, tree, "translation", transform.m_translation); WG_TREE_READ_AS_OPT(context, tree, "scale", transform.m_scale); return WG_OK; } - friend Status tree_write(IoContext& context, IoPropertyTree& tree, const Transform2d& transform) { + friend Status tree_write(IoContext& context, IoTree& tree, const Transform2d& transform) { WG_TREE_MAP(tree); WG_TREE_WRITE_AS(context, tree, "rotation", transform.m_rotation); WG_TREE_WRITE_AS(context, tree, "translation", transform.m_translation); @@ -153,13 +153,13 @@ namespace wmoge { [[nodiscard]] const Vec3f& get_translation() const { return m_translation; } [[nodiscard]] const Vec3f& get_scale() const { return m_scale; } - friend Status tree_read(IoContext& context, IoPropertyTree& tree, Transform3d& transform) { + friend Status tree_read(IoContext& context, IoTree& tree, Transform3d& transform) { WG_TREE_READ_AS_OPT(context, tree, "rotation", transform.m_rotation); WG_TREE_READ_AS_OPT(context, tree, "translation", transform.m_translation); WG_TREE_READ_AS_OPT(context, tree, "scale", transform.m_scale); return WG_OK; } - friend Status tree_write(IoContext& context, IoPropertyTree& tree, const Transform3d& transform) { + friend Status tree_write(IoContext& context, IoTree& tree, const Transform3d& transform) { WG_TREE_MAP(tree); WG_TREE_WRITE_AS(context, tree, "rotation", transform.m_rotation); WG_TREE_WRITE_AS(context, tree, "translation", transform.m_translation); @@ -224,7 +224,7 @@ namespace wmoge { [[nodiscard]] const Vec3f& get_translation() const { return m_translation; } [[nodiscard]] const Vec3f& get_scale() const { return m_scale; } - friend Status tree_read(IoContext& context, IoPropertyTree& tree, TransformEdt& transform) { + friend Status tree_read(IoContext& context, IoTree& tree, TransformEdt& transform) { Vec3f rotation_deg; WG_TREE_READ_AS_OPT(context, tree, "rotation", rotation_deg); @@ -237,7 +237,7 @@ namespace wmoge { return WG_OK; } - friend Status tree_write(IoContext& context, IoPropertyTree& tree, const TransformEdt& transform) { + friend Status tree_write(IoContext& context, IoTree& tree, const TransformEdt& transform) { Vec3f rotation_deg; rotation_deg[0] = Math::rad_to_deg(transform.m_rotation.values[0]); diff --git a/engine/runtime/math/vec.hpp b/engine/runtime/math/vec.hpp index b3d518070..db604fa5d 100644 --- a/engine/runtime/math/vec.hpp +++ b/engine/runtime/math/vec.hpp @@ -27,8 +27,8 @@ #pragma once -#include "io/property_tree.hpp" #include "io/stream.hpp" +#include "io/tree.hpp" #include "math_utils.hpp" #include @@ -653,7 +653,7 @@ namespace wmoge { } template - Status tree_read(IoContext& context, IoPropertyTree& tree, TVecN& v) { + Status tree_read(IoContext& context, IoTree& tree, TVecN& v) { std::string str; WG_TREE_READ(context, tree, str); @@ -667,7 +667,7 @@ namespace wmoge { } template - Status tree_write(IoContext& context, IoPropertyTree& tree, const TVecN& v) { + Status tree_write(IoContext& context, IoTree& tree, const TVecN& v) { std::stringstream stream; for (int i = 0; i < N; i++) { diff --git a/engine/runtime/pfx/pfx_feature.hpp b/engine/runtime/pfx/pfx_feature.hpp index 0913237b9..418964330 100644 --- a/engine/runtime/pfx/pfx_feature.hpp +++ b/engine/runtime/pfx/pfx_feature.hpp @@ -32,7 +32,7 @@ #include "core/object.hpp" #include "core/ref.hpp" #include "core/string_id.hpp" -#include "io/property_tree.hpp" +#include "io/tree.hpp" #include "pfx/pfx_storage.hpp" namespace wmoge { diff --git a/engine/runtime/platform/application.cpp b/engine/runtime/platform/application.cpp index 8e16513fa..2bc9ee4a9 100644 --- a/engine/runtime/platform/application.cpp +++ b/engine/runtime/platform/application.cpp @@ -103,37 +103,37 @@ namespace wmoge { ioc->bind(); ioc->bind(); ioc->bind(); - ioc->bind(); + ioc->bind_by_ioc(); ioc->bind(); ioc->bind(); ioc->bind(); - ioc->bind_f([ioc]() { - Config* config = ioc->resolve_v(); + ioc->bind_by_factory([ioc]() { + Config* config = ioc->resolve_value(); const int num_workers = config->get_int_or_default(SID("task_manager.workers"), 4); return std::make_shared(num_workers); }); - ioc->bind_f([ioc]() { - Config* config = ioc->resolve_v(); + ioc->bind_by_factory([ioc]() { + Config* config = ioc->resolve_value(); const int num_workers = config->get_int_or_default(SID("grc.shader.compiler.workers"), 4); return std::make_shared(num_workers); }); - ioc->bind_f([ioc]() { - Config* config = ioc->resolve_v(); + ioc->bind_by_factory([ioc]() { + Config* config = ioc->resolve_value(); const bool vsync = config->get_bool_or_default(SID("gfx.vsync"), true); const bool client_api = false; return std::make_shared(vsync, client_api); }); - ioc->bind_f([ioc]() { - GlfwWindowManager* window_manager = ioc->resolve_v(); + ioc->bind_by_factory([ioc]() { + GlfwWindowManager* window_manager = ioc->resolve_value(); return window_manager->input(); }); - ioc->bind_f([ioc]() { - GlfwWindowManager* window_manager = ioc->resolve_v(); + ioc->bind_by_factory([ioc]() { + GlfwWindowManager* window_manager = ioc->resolve_value(); Ref window = window_manager->get_primary_window(); VKInitInfo init_info; @@ -146,29 +146,29 @@ namespace wmoge { return std::make_shared(std::move(init_info)); }); - ioc->bind_f([ioc]() { - return std::shared_ptr(ioc->resolve_v(), [](auto p) {}); + ioc->bind_by_factory([ioc]() { + return std::shared_ptr(ioc->resolve_value(), [](auto p) {}); }); - ioc->bind_f([]() { + ioc->bind_by_factory([]() { auto type_storage = std::make_shared(); RttiTypeStorage::provide(type_storage.get()); return type_storage; }); - ioc->bind_f([]() { + ioc->bind_by_factory([]() { auto profiler = std::make_shared(); Profiler::provide(profiler.get()); return profiler; }); - ioc->bind_f([]() { + ioc->bind_by_factory([]() { auto log = std::make_shared(); Log::provide(log.get()); return log; }); - ioc->bind_f([]() { + ioc->bind_by_factory([]() { auto engine = std::make_shared(); Engine::provide(engine.get()); return engine; @@ -196,7 +196,7 @@ namespace wmoge { } static void bind_rtti(IocContainer* ioc) { - ioc->resolve_v(); + ioc->resolve_value(); rtti_rtti(); rtti_asset(); rtti_audio(); @@ -220,7 +220,7 @@ namespace wmoge { Log* log = ioc.resolve().value(); - ioc.bind_i(std::shared_ptr(this, [](auto p) {})); + ioc.bind_by_instance(std::shared_ptr(this, [](auto p) {})); on_register(); diff --git a/engine/runtime/platform/common/mount_volume_physical.cpp b/engine/runtime/platform/common/mount_volume_physical.cpp index 171c24697..b486601fd 100644 --- a/engine/runtime/platform/common/mount_volume_physical.cpp +++ b/engine/runtime/platform/common/mount_volume_physical.cpp @@ -46,37 +46,67 @@ namespace wmoge { return ""; } - const std::filesystem::path remapped = m_path / path.substr(m_mapping.length()); + const std::filesystem::path remapped = remap_path(path); return remapped.string(); } bool MountVolumePhysical::exists(const std::string& path) { - auto prefix = path.find(m_mapping); - if (prefix != 0) { + if (!check_prefix(path)) { return false; } - const std::filesystem::path remapped = m_path / path.substr(m_mapping.length()); + const std::filesystem::path remapped = remap_path(path); return std::filesystem::exists(remapped); } bool MountVolumePhysical::exists_physical(const std::string& path) { - auto prefix = path.find(m_mapping); - if (prefix != 0) { + if (!check_prefix(path)) { return false; } - const std::filesystem::path remapped = m_path / path.substr(m_mapping.length()); + const std::filesystem::path remapped = remap_path(path); return std::filesystem::exists(remapped); } + Status MountVolumePhysical::get_file_size(const std::string& path, std::size_t& size) { + if (!check_prefix(path)) { + return StatusCode::FailedOpenFile; + } + + const std::filesystem::path remapped = remap_path(path); + if (!std::filesystem::exists(remapped)) { + return StatusCode::FailedOpenFile; + } + + size = static_cast(std::filesystem::file_size(remapped)); + return WG_OK; + } + + Status MountVolumePhysical::get_file_timespamp(const std::string& path, DateTime& timespamp) { + if (!check_prefix(path)) { + return StatusCode::FailedOpenFile; + } + + const std::filesystem::path remapped = remap_path(path); + if (!std::filesystem::exists(remapped)) { + return StatusCode::FailedOpenFile; + } + + using DateTimeClock = DateTime::Clock; + using FileClock = std::filesystem::file_time_type::clock; + + auto last_write_time = std::filesystem::last_write_time(remapped); + auto time_point = std::chrono::time_point_cast(last_write_time - FileClock::now() + DateTimeClock::now()); + timespamp = DateTime(time_point); + return WG_OK; + } + Status MountVolumePhysical::open_file(const std::string& path, Ref& file, const FileOpenModeFlags& mode) { - auto prefix = path.find(m_mapping); - if (prefix != 0) { + if (!check_prefix(path)) { return StatusCode::FailedOpenFile; } - const std::filesystem::path remapped = m_path / path.substr(m_mapping.length()); + const std::filesystem::path remapped = remap_path(path); Ref file_physical = make_ref(); if (mode.get(FileOpenMode::Out)) { @@ -91,12 +121,11 @@ namespace wmoge { } Status MountVolumePhysical::open_file_physical(const std::string& path, std::fstream& fstream, std::ios_base::openmode mode) { - auto prefix = path.find(m_mapping); - if (prefix != 0) { + if (!check_prefix(path)) { return StatusCode::FailedOpenFile; } - const std::filesystem::path remapped = m_path / path.substr(m_mapping.length()); + const std::filesystem::path remapped = remap_path(path); if (mode & std::ios_base::out) { std::filesystem::create_directories(remapped.parent_path()); @@ -115,4 +144,13 @@ namespace wmoge { return WG_OK; } + bool MountVolumePhysical::check_prefix(const std::string& path) { + auto prefix = path.find(m_mapping); + return prefix == 0; + } + + std::filesystem::path MountVolumePhysical::remap_path(const std::string& path) { + return std::move(m_path / path.substr(m_mapping.length())); + } + }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/platform/common/mount_volume_physical.hpp b/engine/runtime/platform/common/mount_volume_physical.hpp index 22bf41c7e..025602949 100644 --- a/engine/runtime/platform/common/mount_volume_physical.hpp +++ b/engine/runtime/platform/common/mount_volume_physical.hpp @@ -50,10 +50,16 @@ namespace wmoge { std::string resolve_physical(const std::string& path) override; bool exists(const std::string& path) override; bool exists_physical(const std::string& path) override; + Status get_file_size(const std::string& path, std::size_t& size) override; + Status get_file_timespamp(const std::string& path, DateTime& timespamp) override; Status open_file(const std::string& path, Ref& file, const FileOpenModeFlags& mode) override; Status open_file_physical(const std::string& path, std::fstream& fstream, std::ios_base::openmode mode) override; Status mounted() override; + private: + bool check_prefix(const std::string& path); + std::filesystem::path remap_path(const std::string& path); + private: std::filesystem::path m_path; std::string m_mapping; diff --git a/engine/runtime/platform/file_system.cpp b/engine/runtime/platform/file_system.cpp index 921be269a..3ea525338 100644 --- a/engine/runtime/platform/file_system.cpp +++ b/engine/runtime/platform/file_system.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -69,43 +70,50 @@ namespace wmoge { FileSystem::~FileSystem() = default; - std::string FileSystem::resolve_physical(const std::string& path) { - for (const MountPoint& mount_point : m_mount_points) { + template + static Result filter_mounts_and_apply(const std::deque mount_points, const std::string& path, Result default_value, Functor functor) { + for (const FileSystem::MountPoint& mount_point : mount_points) { const auto& prefix = mount_point.first; const auto& adapter = mount_point.second; if (path.find(prefix) == 0) { - return adapter->resolve_physical(path); + return functor(adapter.get()); } } - return ""; + return default_value; } - bool FileSystem::exists(const std::string& path) { - for (const MountPoint& mount_point : m_mount_points) { - const auto& prefix = mount_point.first; - const auto& adapter = mount_point.second; - - if (path.find(prefix) == 0) { - return adapter->exists(path); - } - } + std::string FileSystem::resolve_physical(const std::string& path) { + return filter_mounts_and_apply(m_mount_points, path, "", [&](MountVolume* adapter) { + return adapter->resolve_physical(path); + }); + } - return false; + bool FileSystem::exists(const std::string& path) { + return filter_mounts_and_apply(m_mount_points, path, false, [&](MountVolume* adapter) { + return adapter->exists(path); + }); } + bool FileSystem::exists_physical(const std::string& path) { - for (const MountPoint& mount_point : m_mount_points) { - const auto& prefix = mount_point.first; - const auto& adapter = mount_point.second; + return filter_mounts_and_apply(m_mount_points, path, false, [&](MountVolume* adapter) { + return adapter->exists_physical(path); + }); + } - if (path.find(prefix) == 0) { - return adapter->exists_physical(path); - } - } + Status FileSystem::get_file_size(const std::string& path, std::size_t& size) { + return filter_mounts_and_apply(m_mount_points, path, StatusCode::FailedFindFile, [&](MountVolume* adapter) { + return adapter->get_file_size(path, size); + }); + } - return false; + Status FileSystem::get_file_timespamp(const std::string& path, DateTime& timespamp) { + return filter_mounts_and_apply(m_mount_points, path, StatusCode::FailedFindFile, [&](MountVolume* adapter) { + return adapter->get_file_timespamp(path, timespamp); + }); } + Status FileSystem::read_file(const std::string& path, std::string& data) { WG_AUTO_PROFILE_PLATFORM("FileSystem::read_file"); @@ -129,6 +137,7 @@ namespace wmoge { return WG_OK; } + Status FileSystem::read_file(const std::string& path, Ref& data) { WG_AUTO_PROFILE_PLATFORM("FileSystem::read_file"); @@ -152,6 +161,7 @@ namespace wmoge { return WG_OK; } + Status FileSystem::read_file(const std::string& path, std::vector& data) { WG_AUTO_PROFILE_PLATFORM("FileSystem::read_file"); @@ -228,6 +238,7 @@ namespace wmoge { return WG_OK; } + Status FileSystem::save_file(const std::string& path, const std::vector& data) { WG_AUTO_PROFILE_PLATFORM("FileSystem::save_file"); @@ -245,6 +256,18 @@ namespace wmoge { return WG_OK; } + Status FileSystem::hash_file(const std::string& path, Sha256& file_hash) { + WG_AUTO_PROFILE_PLATFORM("FileSystem::hash_file"); + + std::vector file_data; + WG_CHECKED(read_file(path, file_data)); + + Sha256Builder sha_builder; + file_hash = sha_builder.hash(file_data.data(), file_data.size()).get(); + + return WG_OK; + } + void FileSystem::watch(const std::string& path, std::function callback) { WG_AUTO_PROFILE_PLATFORM("FileSystem::watch"); @@ -296,6 +319,7 @@ namespace wmoge { const std::filesystem::path& FileSystem::executable_path() const { return m_executable_path; } + const std::filesystem::path& FileSystem::root_path() const { return m_root_path; } diff --git a/engine/runtime/platform/file_system.hpp b/engine/runtime/platform/file_system.hpp index 44d80152c..f1a798cf7 100644 --- a/engine/runtime/platform/file_system.hpp +++ b/engine/runtime/platform/file_system.hpp @@ -28,7 +28,9 @@ #pragma once #include "core/data.hpp" +#include "core/date_time.hpp" #include "core/ref.hpp" +#include "core/sha256.hpp" #include "core/status.hpp" #include "core/string_id.hpp" #include "core/string_utf.hpp" @@ -92,6 +94,8 @@ namespace wmoge { std::string resolve_physical(const std::string& path); bool exists(const std::string& path); bool exists_physical(const std::string& path); + Status get_file_size(const std::string& path, std::size_t& size); + Status get_file_timespamp(const std::string& path, DateTime& timespamp); Status read_file(const std::string& path, std::string& data); Status read_file(const std::string& path, Ref& data); Status read_file(const std::string& path, std::vector& data); @@ -99,6 +103,7 @@ namespace wmoge { Status open_file_physical(const std::string& path, std::fstream& fstream, std::ios_base::openmode mode); Status save_file(const std::string& path, const std::string& data); Status save_file(const std::string& path, const std::vector& data); + Status hash_file(const std::string& path, Sha256& file_hash); void watch(const std::string& path, std::function callback); void add_mounting(const MountPoint& point, bool front = false); void root(const std::filesystem::path& path); diff --git a/engine/runtime/platform/mount_volume.hpp b/engine/runtime/platform/mount_volume.hpp index ef93171dc..5ad5f86ef 100644 --- a/engine/runtime/platform/mount_volume.hpp +++ b/engine/runtime/platform/mount_volume.hpp @@ -27,6 +27,7 @@ #pragma once +#include "core/date_time.hpp" #include "core/ref.hpp" #include "core/status.hpp" #include "core/string_id.hpp" @@ -48,6 +49,8 @@ namespace wmoge { virtual std::string resolve_physical(const std::string& path) { return ""; } virtual bool exists(const std::string& path) { return false; } virtual bool exists_physical(const std::string& path) { return false; } + virtual Status get_file_size(const std::string& path, std::size_t& size) { return StatusCode::NotImplemented; } + virtual Status get_file_timespamp(const std::string& path, DateTime& timespamp) { return StatusCode::NotImplemented; } virtual Status open_file(const std::string& path, Ref& file, const FileOpenModeFlags& mode) { return StatusCode::NotImplemented; } virtual Status open_file_physical(const std::string& path, std::fstream& fstream, std::ios_base::openmode mode) { return StatusCode::NotImplemented; } virtual Status mounted() { return WG_OK; } diff --git a/engine/runtime/render/aux_draw_manager.cpp b/engine/runtime/render/aux_draw_manager.cpp index 886b100a9..60d0e942c 100644 --- a/engine/runtime/render/aux_draw_manager.cpp +++ b/engine/runtime/render/aux_draw_manager.cpp @@ -465,7 +465,7 @@ namespace wmoge { Config* config = IocContainer::iresolve_v(); AssetManager* asset_manager = IocContainer::iresolve_v(); - std::string font_name = config->get_string_or_default(SID("render.aux.font"), "asset://fonts/consolas"); + std::string font_name = config->get_string_or_default(SID("render.aux.font"), "assets/fonts/consolas"); m_font = asset_manager->load(SID(font_name)).cast(); m_screen_size.values[0] = config->get_float_or_default(SID("render.aux.screen_width"), 1280.0f); diff --git a/engine/runtime/rtti/object.cpp b/engine/runtime/rtti/object.cpp index 207255f43..b306afdf9 100644 --- a/engine/runtime/rtti/object.cpp +++ b/engine/runtime/rtti/object.cpp @@ -42,10 +42,10 @@ namespace wmoge { object = rtti_class->instantiate(); return rtti_class->copy(object.get(), this); } - Status RttiObject::read_from_tree(IoContext& context, IoPropertyTree& tree) { + Status RttiObject::read_from_tree(IoContext& context, IoTree& tree) { return get_class()->read_from_tree(this, tree, context); } - Status RttiObject::write_to_tree(IoContext& context, IoPropertyTree& tree) const { + Status RttiObject::write_to_tree(IoContext& context, IoTree& tree) const { return get_class()->write_to_tree(this, tree, context); } Status RttiObject::read_from_stream(IoContext& context, IoStream& stream) { @@ -88,7 +88,7 @@ namespace wmoge { static RttiClass* g_class = nullptr; return g_class; } - Status RttiObject::tree_read_object(IoContext& context, IoPropertyTree& tree, Ref& object) { + Status RttiObject::tree_read_object(IoContext& context, IoTree& tree, Ref& object) { assert(!object); if (tree.node_is_empty()) { @@ -98,7 +98,7 @@ namespace wmoge { Strid rtti_name; WG_TREE_READ_AS(context, tree, "rtti", rtti_name); - RttiClass* rtti_class = context.get_type_storage()->find_class(rtti_name); + RttiClass* rtti_class = context.get()->find_class(rtti_name); if (!rtti_class) { WG_LOG_ERROR("no such class to read from yaml " << rtti_name); return StatusCode::NoClass; @@ -112,7 +112,7 @@ namespace wmoge { return object->read_from_tree(context, tree); } - Status RttiObject::tree_write_object(IoContext& context, IoPropertyTree& tree, const Ref& object) { + Status RttiObject::tree_write_object(IoContext& context, IoTree& tree, const Ref& object) { if (!object) { return WG_OK; } @@ -133,7 +133,7 @@ namespace wmoge { Strid rtti_name; WG_ARCHIVE_READ(context, stream, rtti_name); - RttiClass* rtti_class = context.get_type_storage()->find_class(rtti_name); + RttiClass* rtti_class = context.get()->find_class(rtti_name); if (!rtti_class) { WG_LOG_ERROR("no such class to read from stream " << rtti_name); return StatusCode::NoClass; diff --git a/engine/runtime/rtti/object.hpp b/engine/runtime/rtti/object.hpp index f82ff8aa2..96afe1c94 100644 --- a/engine/runtime/rtti/object.hpp +++ b/engine/runtime/rtti/object.hpp @@ -43,8 +43,8 @@ namespace wmoge { virtual std::string to_string() const; virtual Status clone(Ref& object) const; - virtual Status read_from_tree(IoContext& context, IoPropertyTree& tree); - virtual Status write_to_tree(IoContext& context, IoPropertyTree& tree) const; + virtual Status read_from_tree(IoContext& context, IoTree& tree); + virtual Status write_to_tree(IoContext& context, IoTree& tree) const; virtual Status read_from_stream(IoContext& context, IoStream& stream); virtual Status write_to_stream(IoContext& context, IoStream& stream) const; virtual Ref duplicate() const; @@ -57,8 +57,8 @@ namespace wmoge { static Strid get_parent_class_name_static(); static RttiClass* get_class_static(); static RttiClass* get_parent_class_static(); - static Status tree_read_object(IoContext& context, IoPropertyTree& tree, Ref& object); - static Status tree_write_object(IoContext& context, IoPropertyTree& tree, const Ref& object); + static Status tree_read_object(IoContext& context, IoTree& tree, Ref& object); + static Status tree_write_object(IoContext& context, IoTree& tree, const Ref& object); static Status archive_read_object(IoContext& context, IoStream& stream, Ref& object); static Status archive_write_object(IoContext& context, IoStream& stream, const Ref& object); }; @@ -99,7 +99,7 @@ namespace wmoge { } template - Status tree_read(IoContext& context, IoPropertyTree& tree, Ref& ref, typename std::enable_if_t>* = 0) { + Status tree_read(IoContext& context, IoTree& tree, Ref& ref, typename std::enable_if_t>* = 0) { Ref object; WG_CHECKED(RttiObject::tree_read_object(context, tree, object)); ref = object.template cast(); @@ -107,7 +107,7 @@ namespace wmoge { } template - Status tree_write(IoContext& context, IoPropertyTree& tree, const Ref& ref, typename std::enable_if_t>* = 0) { + Status tree_write(IoContext& context, IoTree& tree, const Ref& ref, typename std::enable_if_t>* = 0) { Ref object = ref.template as(); WG_CHECKED(RttiObject::tree_write_object(context, tree, object)); return WG_OK; diff --git a/engine/runtime/rtti/struct.cpp b/engine/runtime/rtti/struct.cpp index ac00b408e..a5f96b570 100644 --- a/engine/runtime/rtti/struct.cpp +++ b/engine/runtime/rtti/struct.cpp @@ -104,7 +104,7 @@ namespace wmoge { return WG_OK; } - Status RttiStruct::read_from_tree(void* dst, IoPropertyTree& tree, IoContext& context) const { + Status RttiStruct::read_from_tree(void* dst, IoTree& tree, IoContext& context) const { WG_AUTO_PROFILE_RTTI("RttiStruct::read_from_tree"); assert(dst); std::uint8_t* self = reinterpret_cast(dst); @@ -133,7 +133,7 @@ namespace wmoge { return WG_OK; } - Status RttiStruct::write_to_tree(const void* src, IoPropertyTree& tree, IoContext& context) const { + Status RttiStruct::write_to_tree(const void* src, IoTree& tree, IoContext& context) const { WG_AUTO_PROFILE_RTTI("RttiStruct::write_to_tree"); assert(src); diff --git a/engine/runtime/rtti/struct.hpp b/engine/runtime/rtti/struct.hpp index fd67d634d..b165c1755 100644 --- a/engine/runtime/rtti/struct.hpp +++ b/engine/runtime/rtti/struct.hpp @@ -108,8 +108,8 @@ namespace wmoge { [[nodiscard]] RttiStruct* get_parent() const { return m_parent; } Status copy(void* dst, const void* src) const override; - Status read_from_tree(void* dst, IoPropertyTree& tree, IoContext& context) const override; - Status write_to_tree(const void* src, IoPropertyTree& tree, IoContext& context) const override; + Status read_from_tree(void* dst, IoTree& tree, IoContext& context) const override; + Status write_to_tree(const void* src, IoTree& tree, IoContext& context) const override; Status read_from_stream(void* dst, IoStream& stream, IoContext& context) const override; Status write_to_stream(const void* src, IoStream& stream, IoContext& context) const override; Status to_string(const void* src, std::stringstream& s) const override; diff --git a/engine/runtime/rtti/traits.hpp b/engine/runtime/rtti/traits.hpp index 7dd1d776d..d9055ef49 100644 --- a/engine/runtime/rtti/traits.hpp +++ b/engine/runtime/rtti/traits.hpp @@ -37,8 +37,8 @@ #include "core/status.hpp" #include "core/uuid.hpp" #include "io/enum.hpp" -#include "io/property_tree.hpp" #include "io/stream.hpp" +#include "io/tree.hpp" #include "math/aabb.hpp" #include "math/mat.hpp" #include "math/quat.hpp" @@ -102,10 +102,10 @@ namespace wmoge { ((T*) dst)->~T(); return WG_OK; } - Status read_from_tree(void* dst, IoPropertyTree& tree, IoContext& context) const override { + Status read_from_tree(void* dst, IoTree& tree, IoContext& context) const override { return tree_read(context, tree, *((T*) dst)); } - Status write_to_tree(const void* src, IoPropertyTree& tree, IoContext& context) const override { + Status write_to_tree(const void* src, IoTree& tree, IoContext& context) const override { return tree_write(context, tree, *((const T*) src)); } Status read_from_stream(void* dst, IoStream& stream, IoContext& context) const override { @@ -806,10 +806,10 @@ public: rtti_type* get_parent_class() const modifier { \ return get_parent_class_static(); \ } \ - friend Status tree_read(IoContext& context, IoPropertyTree& tree, struct_type& value) { \ + friend Status tree_read(IoContext& context, IoTree& tree, struct_type& value) { \ return get_class_static()->read_from_tree(&value, tree, context); \ } \ - friend Status tree_write(IoContext& context, IoPropertyTree& tree, const struct_type& value) { \ + friend Status tree_write(IoContext& context, IoTree& tree, const struct_type& value) { \ return get_class_static()->write_to_tree(&value, tree, context); \ } \ friend Status stream_read(IoContext& context, IoStream& stream, struct_type& value) { \ diff --git a/engine/runtime/rtti/type.hpp b/engine/runtime/rtti/type.hpp index 917df99ed..82607d957 100644 --- a/engine/runtime/rtti/type.hpp +++ b/engine/runtime/rtti/type.hpp @@ -32,8 +32,8 @@ #include "core/status.hpp" #include "core/string_id.hpp" #include "core/string_utils.hpp" -#include "io/property_tree.hpp" #include "io/stream.hpp" +#include "io/tree.hpp" #include "rtti/meta_data.hpp" #include @@ -61,8 +61,8 @@ namespace wmoge { virtual Status consturct(void* dst) const { return StatusCode::NotImplemented; } virtual Status copy(void* dst, const void* src) const { return StatusCode::NotImplemented; } virtual Status destruct(void* dst) const { return StatusCode::NotImplemented; } - virtual Status read_from_tree(void* dst, IoPropertyTree& tree, IoContext& context) const { return StatusCode::NotImplemented; } - virtual Status write_to_tree(const void* src, IoPropertyTree& tree, IoContext& context) const { return StatusCode::NotImplemented; } + virtual Status read_from_tree(void* dst, IoTree& tree, IoContext& context) const { return StatusCode::NotImplemented; } + virtual Status write_to_tree(const void* src, IoTree& tree, IoContext& context) const { return StatusCode::NotImplemented; } virtual Status read_from_stream(void* dst, IoStream& stream, IoContext& context) const { return StatusCode::NotImplemented; } virtual Status write_to_stream(const void* src, IoStream& stream, IoContext& context) const { return StatusCode::NotImplemented; } virtual Status to_string(const void* src, std::stringstream& s) const { return StatusCode::NotImplemented; } diff --git a/engine/runtime/scene/scene.hpp b/engine/runtime/scene/scene.hpp index 46ac45fe4..e20197513 100644 --- a/engine/runtime/scene/scene.hpp +++ b/engine/runtime/scene/scene.hpp @@ -73,7 +73,7 @@ namespace wmoge { * @see SceneNode * @see SceneTree */ - class Scene final : public WeakRefCnt { + class Scene final : public RefCnt { public: Scene(Strid name = Strid()); ~Scene() override = default; diff --git a/engine/runtime/scene/scene_packed.hpp b/engine/runtime/scene/scene_packed.hpp index dea9fdaa7..60a28efdc 100644 --- a/engine/runtime/scene/scene_packed.hpp +++ b/engine/runtime/scene/scene_packed.hpp @@ -29,7 +29,7 @@ #include "asset/asset.hpp" #include "core/async.hpp" -#include "io/property_tree.hpp" +#include "io/tree.hpp" #include "scene/scene.hpp" #include diff --git a/engine/runtime/scene/scene_prefab.hpp b/engine/runtime/scene/scene_prefab.hpp index fa4843264..ceb2c2913 100644 --- a/engine/runtime/scene/scene_prefab.hpp +++ b/engine/runtime/scene/scene_prefab.hpp @@ -29,7 +29,7 @@ #include "asset/asset.hpp" #include "core/async.hpp" -#include "io/property_tree.hpp" +#include "io/tree.hpp" #include diff --git a/engine/runtime/system/console.cpp b/engine/runtime/system/console.cpp index 2e867f303..b0186d6a5 100644 --- a/engine/runtime/system/console.cpp +++ b/engine/runtime/system/console.cpp @@ -317,7 +317,7 @@ namespace wmoge { auto asset_manager = IocContainer::iresolve_v(); // m_canvas = Engine::instance()->canvas_debug(); - m_console_font = asset_manager->load(SID(config->get_string_or_default(SID("debug.console.font"), "asset://fonts/anonymous_pro"))).cast(); + m_console_font = asset_manager->load(SID(config->get_string_or_default(SID("debug.console.font"), "assets/fonts/anonymous_pro"))).cast(); m_margin_line = m_margin + m_console_font->get_string_size("> ", m_text_size).x(); config->get_color4f(SID("debug.console.color_back"), m_color_back); diff --git a/engine/runtime/system/engine.cpp b/engine/runtime/system/engine.cpp index f4f9f489b..781ef9dd5 100644 --- a/engine/runtime/system/engine.cpp +++ b/engine/runtime/system/engine.cpp @@ -27,6 +27,7 @@ #include "engine.hpp" +#include "asset/asset_library_fs.hpp" #include "asset/asset_manager.hpp" #include "audio/openal/al_engine.hpp" #include "core/callback_queue.hpp" @@ -80,16 +81,16 @@ namespace wmoge { IocContainer* ioc = IocContainer::instance(); m_class_db = ClassDB::instance(); - m_type_storage = ioc->resolve_v(); - m_time = ioc->resolve_v