From d8002cbdba7e262d254c800ff8286cb8652cba7f Mon Sep 17 00:00:00 2001 From: Egor Orachyov Date: Mon, 7 Oct 2024 22:36:18 +0300 Subject: [PATCH] gh-82: use new data file request api in asset loaders --- engine/plugins/assimp/assimp_asset_loader.cpp | 26 ++--- engine/plugins/assimp/assimp_asset_loader.hpp | 1 + engine/plugins/assimp/assimp_importer.cpp | 2 +- engine/plugins/assimp/assimp_importer.hpp | 2 +- .../freetype/freetype_asset_loader.cpp | 17 ++- .../freetype/freetype_asset_loader.hpp | 1 + engine/plugins/freetype/freetype_font.cpp | 10 +- engine/plugins/freetype/freetype_font.hpp | 5 +- .../runtime/asset/default_asset_loader.cpp | 22 ++-- .../runtime/asset/default_asset_loader.hpp | 1 + .../runtime/asset/image_asset_loader.cpp | 16 ++- .../runtime/asset/image_asset_loader.hpp | 1 + .../runtime/asset/shader_asset_loader.cpp | 19 ++-- .../runtime/asset/shader_asset_loader.hpp | 1 + .../runtime/asset/texture_asset_loader.cpp | 65 +++++++---- .../runtime/asset/texture_asset_loader.hpp | 2 + .../runtime/asset/wav_asset_loader.cpp | 16 ++- .../runtime/asset/wav_asset_loader.hpp | 1 + engine/runtime/asset/asset_library.hpp | 1 + engine/runtime/asset/asset_library_fs.cpp | 14 ++- engine/runtime/asset/asset_library_fs.hpp | 1 + engine/runtime/asset/asset_loader.cpp | 10 +- engine/runtime/asset/asset_loader.hpp | 12 +- engine/runtime/asset/asset_loader_adapter.hpp | 2 + engine/runtime/asset/asset_manager.cpp | 103 ++++++++++++------ engine/runtime/asset/asset_manager.hpp | 24 ++-- engine/runtime/audio/audio_stream_wav.cpp | 20 ++-- engine/runtime/audio/audio_stream_wav.hpp | 5 +- engine/runtime/grc/image.cpp | 16 +-- engine/runtime/grc/image.hpp | 18 ++- engine/runtime/grc/shader.cpp | 4 +- engine/runtime/grc/shader_reflection.cpp | 3 + engine/runtime/grc/shader_reflection.hpp | 75 ++++++++----- engine/runtime/io/tree_yaml.cpp | 2 +- engine/runtime/io/tree_yaml.hpp | 2 +- engine/runtime/system/engine.cpp | 6 +- 36 files changed, 327 insertions(+), 199 deletions(-) diff --git a/engine/plugins/assimp/assimp_asset_loader.cpp b/engine/plugins/assimp/assimp_asset_loader.cpp index e1e7bf92c..80e8920de 100644 --- a/engine/plugins/assimp/assimp_asset_loader.cpp +++ b/engine/plugins/assimp/assimp_asset_loader.cpp @@ -44,9 +44,7 @@ namespace wmoge { - Status AssimpMeshAssetLoader::load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) { - WG_AUTO_PROFILE_ASSET("AssimpMeshAssetLoader::load_typed"); - + Status AssimpMeshAssetLoader::fill_request(AssetLoadContext& context, const AssetId& asset_id, AssetLoadRequest& request) { Ref import_data = context.asset_meta.import_data.cast(); if (!import_data) { WG_LOG_ERROR("no import data for " << asset_id); @@ -56,25 +54,25 @@ namespace wmoge { WG_LOG_ERROR("no source file " << asset_id); return StatusCode::InvalidData; } + request.add_data_file(FILE_TAG, import_data->source_files[0].file); + return WG_OK; + } - FileSystem* file_system = IocContainer::iresolve_v(); - std::string file_name = import_data->source_files[0].file; + Status AssimpMeshAssetLoader::load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) { + WG_AUTO_PROFILE_ASSET("AssimpMeshAssetLoader::load_typed"); - std::vector file_data; - if (!file_system->read_file(file_name, file_data)) { - WG_LOG_ERROR("failed to load file " << file_name); - return StatusCode::FailedRead; - } + Ref import_data = context.asset_meta.import_data.cast(); + assert(import_data); AssimpMeshImporter importer; - if (!importer.read(file_name, file_data, import_data->process)) { - WG_LOG_ERROR("failed to import file " << file_name); + if (!importer.read(asset_id.str(), result.get_data_file(FILE_TAG), import_data->process)) { + WG_LOG_ERROR("failed to import mesh " << asset_id); return StatusCode::Error; } importer.set_attribs(import_data->attributes); if (!importer.process()) { - WG_LOG_ERROR("failed to process file " << file_name); + WG_LOG_ERROR("failed to process mesh " << asset_id); return StatusCode::Error; } @@ -89,7 +87,7 @@ namespace wmoge { MeshBuilder& builder = importer.get_builder(); builder.set_mesh(asset); if (!builder.build()) { - WG_LOG_ERROR("failed to build mesh " << file_name); + WG_LOG_ERROR("failed to build mesh " << asset_id); return StatusCode::Error; } diff --git a/engine/plugins/assimp/assimp_asset_loader.hpp b/engine/plugins/assimp/assimp_asset_loader.hpp index de9fcec74..8bcbb7cff 100644 --- a/engine/plugins/assimp/assimp_asset_loader.hpp +++ b/engine/plugins/assimp/assimp_asset_loader.hpp @@ -50,6 +50,7 @@ namespace wmoge { AssimpMeshAssetLoader() = default; ~AssimpMeshAssetLoader() override = default; + Status fill_request(AssetLoadContext& context, const AssetId& asset_id, AssetLoadRequest& request) override; Status load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) override; }; diff --git a/engine/plugins/assimp/assimp_importer.cpp b/engine/plugins/assimp/assimp_importer.cpp index 27733a081..c328b8abc 100644 --- a/engine/plugins/assimp/assimp_importer.cpp +++ b/engine/plugins/assimp/assimp_importer.cpp @@ -38,7 +38,7 @@ namespace wmoge { - Status AssimpImporter::read(std::string file_name, array_view data, const AssimpProcess& flags) { + Status AssimpImporter::read(std::string file_name, array_view data, const AssimpProcess& flags) { WG_AUTO_PROFILE_ASSET("AssimpImporter::read"); if (flags.triangulate) m_options |= aiProcess_Triangulate; diff --git a/engine/plugins/assimp/assimp_importer.hpp b/engine/plugins/assimp/assimp_importer.hpp index ee31eb9ed..9a2124d19 100644 --- a/engine/plugins/assimp/assimp_importer.hpp +++ b/engine/plugins/assimp/assimp_importer.hpp @@ -47,7 +47,7 @@ namespace wmoge { public: AssimpImporter() = default; - Status read(std::string file_name, array_view data, const AssimpProcess& flags); + Status read(std::string file_name, array_view data, const AssimpProcess& flags); Status process(); [[nodiscard]] const AssimpProcess& get_flags() const { return m_flags; } diff --git a/engine/plugins/freetype/freetype_asset_loader.cpp b/engine/plugins/freetype/freetype_asset_loader.cpp index e3ac57289..1564a1092 100644 --- a/engine/plugins/freetype/freetype_asset_loader.cpp +++ b/engine/plugins/freetype/freetype_asset_loader.cpp @@ -33,24 +33,31 @@ namespace wmoge { - Status FreetypeAssetLoader::load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) { - WG_AUTO_PROFILE_ASSET("FreetypeAssetLoader::load_typed"); - + Status FreetypeAssetLoader::fill_request(AssetLoadContext& context, const AssetId& asset_id, AssetLoadRequest& request) { Ref import_data = context.asset_meta.import_data.cast(); if (!import_data) { 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 " << asset_id); + WG_LOG_ERROR("no source files for " << asset_id); return StatusCode::InvalidData; } + request.add_data_file(FILE_TAG, import_data->source_files[0].file); + return WG_OK; + } + + 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 = context.asset_meta.import_data.cast(); + assert(import_data); asset = make_ref(); asset->set_id(asset_id); FreetypeFont loader; - return loader.load(asset, import_data->source_files[0].file, import_data->height, import_data->glyphs_in_row); + return loader.load(asset, result.get_data_file(FILE_TAG), 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 97481901a..f67ac8c6e 100644 --- a/engine/plugins/freetype/freetype_asset_loader.hpp +++ b/engine/plugins/freetype/freetype_asset_loader.hpp @@ -43,6 +43,7 @@ namespace wmoge { FreetypeAssetLoader() = default; ~FreetypeAssetLoader() override = default; + Status fill_request(AssetLoadContext& context, const AssetId& asset_id, AssetLoadRequest& request) override; Status load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) override; }; diff --git a/engine/plugins/freetype/freetype_font.cpp b/engine/plugins/freetype/freetype_font.cpp index 079d42733..480a4ae6d 100644 --- a/engine/plugins/freetype/freetype_font.cpp +++ b/engine/plugins/freetype/freetype_font.cpp @@ -44,18 +44,12 @@ namespace wmoge { m_texture_manager = IocContainer::iresolve_v(); } - Status FreetypeFont::load(const Ref& font, const std::string& path, int height, int glyphs_in_row) { + Status FreetypeFont::load(const Ref& font, array_view ttf_data, int height, int glyphs_in_row) { WG_AUTO_PROFILE_ASSET("FreetypeFont::load"); static const int GLYPHS_SIZE_SHIFT = 6; static const int GLYPHS_BITMAP_OFFSET = 2; - std::vector ttf_data; - if (!m_file_system->read_file(path, ttf_data)) { - WG_LOG_ERROR("failed to load font data from asset pak " << path); - return StatusCode::FailedRead; - } - FT_Library ft_library; if (FT_Init_FreeType(&ft_library)) { WG_LOG_ERROR("failed to init free type library"); @@ -64,7 +58,7 @@ namespace wmoge { FT_Face ft_face; if (FT_New_Memory_Face(ft_library, ttf_data.data(), static_cast(ttf_data.size()), 0, &ft_face)) { - WG_LOG_ERROR("failed to parse font data for " << path); + WG_LOG_ERROR("failed to parse font data for " << font->get_name()); FT_Done_FreeType(ft_library); return StatusCode::FailedParse; } diff --git a/engine/plugins/freetype/freetype_font.hpp b/engine/plugins/freetype/freetype_font.hpp index 7a48c459d..449b3bd7f 100644 --- a/engine/plugins/freetype/freetype_font.hpp +++ b/engine/plugins/freetype/freetype_font.hpp @@ -27,6 +27,7 @@ #pragma once +#include "core/array_view.hpp" #include "core/status.hpp" #include "core/string_utils.hpp" #include "gfx/gfx_driver.hpp" @@ -50,13 +51,13 @@ namespace wmoge { * @note Uses FreeType2 library for .ttf file loading * * @param font Font to load into - * @param filepath Path to the font .ttf file in a file system + * @param ttf_data Content of the font .ttf file in a file system * @param height Font height in pixels * @param glyphs_in_row Num of glyphs in a row of a bitmap * * @return True if font loaded */ - Status load(const Ref& font, const std::string& path, int height = 40, int glyphs_in_row = 16); + Status load(const Ref& font, array_view ttf_data, int height = 40, int glyphs_in_row = 16); private: GfxDriver* m_gfx_driver; diff --git a/engine/plugins/runtime/asset/default_asset_loader.cpp b/engine/plugins/runtime/asset/default_asset_loader.cpp index 69b374d95..67af1477d 100644 --- a/engine/plugins/runtime/asset/default_asset_loader.cpp +++ b/engine/plugins/runtime/asset/default_asset_loader.cpp @@ -35,25 +35,25 @@ namespace wmoge { - Status DefaultAssetLoader::load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) { - WG_AUTO_PROFILE_ASSET("DefaultAssetLoader::load_typed"); - + Status DefaultAssetLoader::fill_request(AssetLoadContext& context, const AssetId& asset_id, AssetLoadRequest& request) { Ref import_data = context.asset_meta.import_data.cast(); if (!import_data) { 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 " << asset_id); return StatusCode::InvalidData; } + request.add_data_file(FILE_TAG, import_data->source_files[0].file); + return WG_OK; + } - 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 " << asset_id); - return StatusCode::InvalidData; - } + 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 = context.asset_meta.import_data.cast(); + assert(import_data); RttiClass* rtti = IocContainer::iresolve_v()->find_class(context.asset_meta.rtti); if (!rtti) { @@ -70,10 +70,10 @@ namespace wmoge { asset->set_id(asset_id); IoYamlTree asset_tree; - WG_CHECKED(asset_tree.parse_file(path_on_disk)); + WG_CHECKED(asset_tree.parse_data(result.get_data_file(FILE_TAG))); if (!asset->read_from_tree(context.io_context, asset_tree)) { - WG_LOG_ERROR("failed to load asset from file " << path_on_disk); + WG_LOG_ERROR("failed to load asset from file " << asset_id); return StatusCode::FailedRead; } diff --git a/engine/plugins/runtime/asset/default_asset_loader.hpp b/engine/plugins/runtime/asset/default_asset_loader.hpp index 46058a754..9197c0395 100644 --- a/engine/plugins/runtime/asset/default_asset_loader.hpp +++ b/engine/plugins/runtime/asset/default_asset_loader.hpp @@ -42,6 +42,7 @@ namespace wmoge { DefaultAssetLoader() = default; ~DefaultAssetLoader() override = default; + Status fill_request(AssetLoadContext& context, const AssetId& asset_id, AssetLoadRequest& request) override; Status load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) override; }; diff --git a/engine/plugins/runtime/asset/image_asset_loader.cpp b/engine/plugins/runtime/asset/image_asset_loader.cpp index cad9868cd..b07a24224 100644 --- a/engine/plugins/runtime/asset/image_asset_loader.cpp +++ b/engine/plugins/runtime/asset/image_asset_loader.cpp @@ -32,24 +32,30 @@ namespace wmoge { - Status ImageAssetLoader::load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) { - WG_AUTO_PROFILE_ASSET("ImageAssetLoader::load_typed"); - + Status ImageAssetLoader::fill_request(AssetLoadContext& context, const AssetId& asset_id, AssetLoadRequest& request) { Ref import_data = context.asset_meta.import_data.cast(); if (!import_data) { 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 " << asset_id); return StatusCode::InvalidData; } + request.add_data_file(FILE_TAG, import_data->source_files[0].file); + return WG_OK; + } + + 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 = context.asset_meta.import_data.cast(); + assert(import_data); asset = make_ref(); asset->set_id(asset_id); - return asset->load(import_data->source_files[0].file, import_data->channels); + return asset->load(result.get_data_file(FILE_TAG), 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 89ec36033..e8f93b54a 100644 --- a/engine/plugins/runtime/asset/image_asset_loader.hpp +++ b/engine/plugins/runtime/asset/image_asset_loader.hpp @@ -43,6 +43,7 @@ namespace wmoge { ImageAssetLoader() = default; ~ImageAssetLoader() override = default; + Status fill_request(AssetLoadContext& context, const AssetId& asset_id, AssetLoadRequest& request) override; Status load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) override; }; diff --git a/engine/plugins/runtime/asset/shader_asset_loader.cpp b/engine/plugins/runtime/asset/shader_asset_loader.cpp index bd24daa9c..03eec6cfd 100644 --- a/engine/plugins/runtime/asset/shader_asset_loader.cpp +++ b/engine/plugins/runtime/asset/shader_asset_loader.cpp @@ -36,9 +36,7 @@ namespace wmoge { - Status ShaderAssetLoader::load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) { - WG_AUTO_PROFILE_ASSET("ShaderAssetLoader::load_typed"); - + Status ShaderAssetLoader::fill_request(AssetLoadContext& context, const AssetId& asset_id, AssetLoadRequest& request) { Ref import_data = context.asset_meta.import_data.cast(); if (!import_data) { WG_LOG_ERROR("no import data to load " << asset_id); @@ -48,16 +46,19 @@ namespace wmoge { WG_LOG_ERROR("no source file " << asset_id); return StatusCode::InvalidData; } + request.add_data_file(FILE_TAG, import_data->source_files[0].file); + return WG_OK; + } - 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 " << asset_id); - return StatusCode::InvalidData; - } + 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 = context.asset_meta.import_data.cast(); + assert(import_data); ShaderFile shader_file; IoYamlTree tree; - WG_CHECKED(tree.parse_file(path_on_disk)); + WG_CHECKED(tree.parse_data(result.get_data_file(FILE_TAG))); WG_TREE_READ(context.io_context, tree, shader_file); auto* shader_manager = IocContainer::iresolve_v(); diff --git a/engine/plugins/runtime/asset/shader_asset_loader.hpp b/engine/plugins/runtime/asset/shader_asset_loader.hpp index e05de0adb..596f567f6 100644 --- a/engine/plugins/runtime/asset/shader_asset_loader.hpp +++ b/engine/plugins/runtime/asset/shader_asset_loader.hpp @@ -43,6 +43,7 @@ namespace wmoge { ShaderAssetLoader() = default; ~ShaderAssetLoader() override = default; + Status fill_request(AssetLoadContext& context, const AssetId& asset_id, AssetLoadRequest& request) override; Status load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) override; }; diff --git a/engine/plugins/runtime/asset/texture_asset_loader.cpp b/engine/plugins/runtime/asset/texture_asset_loader.cpp index 2df33fac4..1f5f27eda 100644 --- a/engine/plugins/runtime/asset/texture_asset_loader.cpp +++ b/engine/plugins/runtime/asset/texture_asset_loader.cpp @@ -39,9 +39,7 @@ namespace wmoge { - Status Texture2dAssetLoader::load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) { - WG_AUTO_PROFILE_ASSET("Texture2dAssetLoader::load_typed"); - + Status Texture2dAssetLoader::fill_request(AssetLoadContext& context, const AssetId& asset_id, AssetLoadRequest& request) { Ref import_data = context.asset_meta.import_data.cast(); if (!import_data) { WG_LOG_ERROR("no import data for " << asset_id); @@ -51,10 +49,19 @@ namespace wmoge { WG_LOG_ERROR("no source file " << asset_id); return StatusCode::InvalidData; } + request.add_data_file(FILE_TAG, import_data->source_files[0].file); + return WG_OK; + } + + 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 = context.asset_meta.import_data.cast(); + assert(import_data); Ref source_image = make_ref(); - if (!source_image->load(import_data->source_files[0].file, import_data->channels)) { + if (!source_image->load(result.get_data_file(FILE_TAG), import_data->channels)) { WG_LOG_ERROR("failed to load source image " << import_data->source_files[0].file); return StatusCode::FailedRead; } @@ -104,39 +111,57 @@ namespace wmoge { return WG_OK; } - Status TextureCubeAssetLoader::load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) { - WG_AUTO_PROFILE_ASSET("TextureCubeAssetLoader::load_typed"); + static const Strid TAG_IMG_RIGHT = SID("right"); + static const Strid TAG_IMG_LEFT = SID("left"); + static const Strid TAG_IMG_TOP = SID("top"); + static const Strid TAG_IMG_BOTTOM = SID("bottom"); + static const Strid TAG_IMG_FRONT = SID("front"); + static const Strid TAG_IMG_BACK = SID("back"); + Status TextureCubeAssetLoader::fill_request(AssetLoadContext& context, const AssetId& asset_id, AssetLoadRequest& request) { Ref import_data = context.asset_meta.import_data.cast(); if (!import_data) { 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 " << asset_id); + if (!import_data->has_soruce_files()) { + WG_LOG_ERROR("no source file " << asset_id); return StatusCode::InvalidData; } + // right, left, top, bottom, front, back + request.add_data_file(TAG_IMG_RIGHT, import_data->source_files[0].file); + request.add_data_file(TAG_IMG_LEFT, import_data->source_files[1].file); + request.add_data_file(TAG_IMG_TOP, import_data->source_files[2].file); + request.add_data_file(TAG_IMG_BOTTOM, import_data->source_files[3].file); + request.add_data_file(TAG_IMG_FRONT, import_data->source_files[4].file); + request.add_data_file(TAG_IMG_BACK, import_data->source_files[5].file); + return WG_OK; + } + + 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 = context.asset_meta.import_data.cast(); + assert(import_data); std::vector> source_images; - auto load_source = [&](const std::string& path) { + auto load_source = [&](const Strid& tag) { auto image = source_images.emplace_back(make_ref()); - if (!image->load(path, import_data->channels)) { - WG_LOG_ERROR("failed to load source image " << path); + if (!image->load(result.get_data_file(tag), import_data->channels)) { + WG_LOG_ERROR("failed to load source image " << asset_id << " tag " << tag); return false; } - image->set_id(SID(path)); + image->set_id(SID(asset_id.str() + "_" + tag.str())); return true; }; - // right, left, top, bottom, front, back - - if (!load_source(import_data->source_files[0].file) || - !load_source(import_data->source_files[1].file) || - !load_source(import_data->source_files[2].file) || - !load_source(import_data->source_files[3].file) || - !load_source(import_data->source_files[4].file) || - !load_source(import_data->source_files[5].file)) { + if (!load_source(TAG_IMG_RIGHT) || + !load_source(TAG_IMG_LEFT) || + !load_source(TAG_IMG_TOP) || + !load_source(TAG_IMG_BOTTOM) || + !load_source(TAG_IMG_FRONT) || + !load_source(TAG_IMG_BACK)) { return StatusCode::FailedRead; } diff --git a/engine/plugins/runtime/asset/texture_asset_loader.hpp b/engine/plugins/runtime/asset/texture_asset_loader.hpp index aec5a78ca..a0eb2e615 100644 --- a/engine/plugins/runtime/asset/texture_asset_loader.hpp +++ b/engine/plugins/runtime/asset/texture_asset_loader.hpp @@ -46,6 +46,7 @@ namespace wmoge { Texture2dAssetLoader() = default; ~Texture2dAssetLoader() override = default; + Status fill_request(AssetLoadContext& context, const AssetId& asset_id, AssetLoadRequest& request) override; Status load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) override; }; @@ -66,6 +67,7 @@ namespace wmoge { TextureCubeAssetLoader() = default; ~TextureCubeAssetLoader() override = default; + Status fill_request(AssetLoadContext& context, const AssetId& asset_id, AssetLoadRequest& request) override; Status load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) override; }; diff --git a/engine/plugins/runtime/asset/wav_asset_loader.cpp b/engine/plugins/runtime/asset/wav_asset_loader.cpp index fd3e1674a..3f34cdad6 100644 --- a/engine/plugins/runtime/asset/wav_asset_loader.cpp +++ b/engine/plugins/runtime/asset/wav_asset_loader.cpp @@ -32,24 +32,30 @@ namespace wmoge { - Status WavAssetLoader::load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) { - WG_AUTO_PROFILE_ASSET("WavAssetLoader::load_typed"); - + Status WavAssetLoader::fill_request(AssetLoadContext& context, const AssetId& asset_id, AssetLoadRequest& request) { Ref import_data = context.asset_meta.import_data.cast(); if (!import_data) { WG_LOG_ERROR("no import data for " << asset_id); return StatusCode::InvalidData; } - if (!import_data->has_soruce_files()) { WG_LOG_ERROR("no source file " << asset_id); return StatusCode::InvalidData; } + request.add_data_file(FILE_TAG, import_data->source_files[0].file); + return WG_OK; + } + + 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 = context.asset_meta.import_data.cast(); + assert(import_data); asset = make_ref(); asset->set_id(asset_id); - return asset->load(import_data->source_files[0].file); + return asset->load(result.get_data_file(FILE_TAG)); } }// 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 d7adff004..91bf20165 100644 --- a/engine/plugins/runtime/asset/wav_asset_loader.hpp +++ b/engine/plugins/runtime/asset/wav_asset_loader.hpp @@ -43,6 +43,7 @@ namespace wmoge { WavAssetLoader() = default; ~WavAssetLoader() override = default; + Status fill_request(AssetLoadContext& context, const AssetId& asset_id, AssetLoadRequest& request) override; Status load_typed(AssetLoadContext& context, const AssetId& asset_id, const AssetLoadResult& result, Ref& asset) override; }; diff --git a/engine/runtime/asset/asset_library.hpp b/engine/runtime/asset/asset_library.hpp index 51cabc9fe..284025f12 100644 --- a/engine/runtime/asset/asset_library.hpp +++ b/engine/runtime/asset/asset_library.hpp @@ -51,6 +51,7 @@ namespace wmoge { virtual ~AssetLibrary() = default; virtual std::string get_name() const = 0; + virtual bool has_asset(const AssetId& name) = 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; diff --git a/engine/runtime/asset/asset_library_fs.cpp b/engine/runtime/asset/asset_library_fs.cpp index b97caf180..920814f11 100644 --- a/engine/runtime/asset/asset_library_fs.cpp +++ b/engine/runtime/asset/asset_library_fs.cpp @@ -39,26 +39,32 @@ namespace wmoge { AssetLibraryFileSystem::AssetLibraryFileSystem(std::string directory, IocContainer* ioc) { + m_directory = std::move(directory); 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"; } + static std::string make_asset_meta_path(const std::string& directory, const AssetId& name, const std::string& ext) { + return directory + name.str() + ext; + } + + bool AssetLibraryFileSystem::has_asset(const AssetId& name) { + return m_file_system->exists(make_asset_meta_path(m_directory, name, m_asset_ext)); + } + 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_CHECKED(tree.parse_file(m_file_system, make_asset_meta_path(m_directory, name, m_asset_ext))); WG_TREE_READ(context, tree, meta); return WG_OK; diff --git a/engine/runtime/asset/asset_library_fs.hpp b/engine/runtime/asset/asset_library_fs.hpp index f3a297f86..f9d0f8e37 100644 --- a/engine/runtime/asset/asset_library_fs.hpp +++ b/engine/runtime/asset/asset_library_fs.hpp @@ -41,6 +41,7 @@ namespace wmoge { ~AssetLibraryFileSystem() override = default; std::string get_name() const override; + bool has_asset(const AssetId& name) 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; diff --git a/engine/runtime/asset/asset_loader.cpp b/engine/runtime/asset/asset_loader.cpp index e305c621e..7d6bda491 100644 --- a/engine/runtime/asset/asset_loader.cpp +++ b/engine/runtime/asset/asset_loader.cpp @@ -30,12 +30,16 @@ namespace wmoge { void AssetLoadRequest::add_data_file(const Strid& name) { - data_files[name] = name.str(); + data_files[name] = name; } - std::string AssetLoadRequest::get_data_file(Strid tag) const { + void AssetLoadRequest::add_data_file(const Strid& name, const std::string& path) { + data_files[name] = SID(path); + } + + Strid AssetLoadRequest::get_data_file(Strid tag) const { auto query = data_files.find(tag); - return query != data_files.end() ? query->second : std::string(); + return query != data_files.end() ? query->second : Strid(); } void AssetLoadResult::add_data_file(Strid tag, array_view data) { diff --git a/engine/runtime/asset/asset_loader.hpp b/engine/runtime/asset/asset_loader.hpp index 2bffd5ecf..9fa8b1bb9 100644 --- a/engine/runtime/asset/asset_loader.hpp +++ b/engine/runtime/asset/asset_loader.hpp @@ -42,10 +42,11 @@ namespace wmoge { * @brief Request files to load for an asset load */ struct AssetLoadRequest { - flat_map data_files; + flat_map data_files; - void add_data_file(const Strid& name); - std::string get_data_file(Strid tag) const; + void add_data_file(const Strid& name); + void add_data_file(const Strid& name, const std::string& path); + Strid get_data_file(Strid tag) const; }; /** @@ -64,8 +65,9 @@ namespace wmoge { * @brief Context passed to the loader */ struct AssetLoadContext { - IoContext io_context; - AssetMeta asset_meta; + IoContext io_context; + AssetMeta asset_meta; + AssetLibrary* asset_library = nullptr; }; /** diff --git a/engine/runtime/asset/asset_loader_adapter.hpp b/engine/runtime/asset/asset_loader_adapter.hpp index 01ff5abaf..ea3bc7670 100644 --- a/engine/runtime/asset/asset_loader_adapter.hpp +++ b/engine/runtime/asset/asset_loader_adapter.hpp @@ -40,6 +40,8 @@ namespace wmoge { public: static_assert(std::is_base_of_v, "T must be an Asset type"); + static inline const Strid FILE_TAG = SID("file"); + 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; } diff --git a/engine/runtime/asset/asset_manager.cpp b/engine/runtime/asset/asset_manager.cpp index 45dfa84d9..58e56089a 100644 --- a/engine/runtime/asset/asset_manager.cpp +++ b/engine/runtime/asset/asset_manager.cpp @@ -39,8 +39,9 @@ namespace wmoge { AssetManager::AssetManager(IocContainer* ioc) { - m_file_system = ioc->resolve_value(); - m_type_storage = ioc->resolve_value(); + m_ioc_container = 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); @@ -73,19 +74,22 @@ namespace wmoge { 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(); + // try to find asset library + std::optional asset_library = resolve_asset(name); + if (!asset_library) { + WG_LOG_ERROR("failed to resolve asset library for " << name); + return AsyncResult>::failed(); + } + // try to find resolve meta info + AssetMeta asset_meta; + if (!asset_library.value()->find_asset_meta(name, asset_meta)) { WG_LOG_ERROR("failed to find meta info for " << name); return AsyncResult>::failed(); } // try find loader - std::optional loader = find_loader(asset_meta->loader); + std::optional loader = find_loader(asset_meta.loader); if (!loader) { WG_LOG_ERROR("failed to find loader for " << name); return AsyncResult>::failed(); @@ -93,7 +97,7 @@ namespace wmoge { // get dependencies which still loading or already loaded buffered_vector deps; - for (const Strid& dep : asset_meta.value().deps) { + for (const Strid& dep : asset_meta.deps) { deps.push_back(load_async(dep).as_async()); } @@ -101,31 +105,64 @@ namespace wmoge { AsyncOp> async_op = make_async_op>(); // create task to load - Task task(name, [=, meta = std::move(asset_meta.value()), loader = loader.value()](TaskContext&) { + Task task(name, [=, meta = std::move(asset_meta), library = asset_library.value(), loader = loader.value()](TaskContext&) { Timer timer; timer.start(); - Ref asset; - AssetLoadContext context; - AssetLoadResult result; + Ref asset; + AssetLoadContext context; + AssetLoadRequest request; + AssetLoadResult result; + std::vector> data_buffers; + context.io_context.add(m_ioc_container); 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 (!loader->fill_request(context, name, request)) { + WG_LOG_ERROR("failed fill_request for " << name); + return 1; + } - if (asset->get_name().empty()) { - asset->set_id(name); + data_buffers.reserve(request.data_files.size()); + for (const auto& tag_path : request.data_files) { + AssetDataMeta data_meta; + + if (!library->find_asset_data_meta(tag_path.second, data_meta)) { + WG_LOG_ERROR("failed to find meta for " << tag_path.second); + return 1; } - std::lock_guard guard(m_mutex); - asset->set_release_callback(m_callback); - m_assets[name] = WeakRef(asset); - async_op->set_result(std::move(asset)); - return 0; + Ref& buffer = data_buffers.emplace_back(); + buffer = make_ref(data_meta.size); + + auto async_result = library->read_data(tag_path.second, {buffer->buffer(), buffer->size()}); + async_result.wait_completed(); + + if (async_result.is_failed()) { + WG_LOG_ERROR("failed to read " << tag_path.second); + return 1; + } + + result.add_data_file(tag_path.first, {buffer->buffer(), buffer->size()}); + } + + if (!loader->load(context, name, result, asset)) { + WG_LOG_ERROR("failed load for " << name); + return 1; + } + + timer.stop(); + WG_LOG_INFO("load asset " << name << ", time: " << timer.get_elapsed_sec() << " sec"); + + if (asset->get_name().empty()) { + asset->set_id(name); } - return 1; + + std::lock_guard guard(m_mutex); + asset->set_release_callback(m_callback); + m_assets[name] = WeakRef(asset); + async_op->set_result(std::move(asset)); + return 0; }); // schedule to run only if all deps are loaded @@ -134,12 +171,9 @@ namespace wmoge { // add erase of loading state here, since it is possible, that task can be aborted task_hnd.add_on_completion([this, name, async_op](AsyncStatus status, std::optional&) { std::lock_guard guard(m_mutex); - if (status == AsyncStatus::Failed) { async_op->set_failed(); - WG_LOG_ERROR("failed load asset " << name); } - m_loading.erase(name); }); @@ -183,7 +217,6 @@ namespace wmoge { } void AssetManager::add_library(std::shared_ptr library) { - std::lock_guard guard(m_mutex); m_libraries.push_back(std::move(library)); } @@ -193,16 +226,22 @@ namespace wmoge { return query != m_loaders.end() ? std::make_optional(query->second.get()) : std::nullopt; } - std::optional AssetManager::find_meta(const AssetId& asset) { - std::lock_guard guard(m_mutex); - + std::optional AssetManager::resolve_asset_meta(const AssetId& asset) { AssetMeta asset_meta; for (auto& library : m_libraries) { if (library->find_asset_meta(asset, asset_meta)) { return std::make_optional(std::move(asset_meta)); } } + return std::nullopt; + } + std::optional AssetManager::resolve_asset(const AssetId& asset) { + for (auto& library : m_libraries) { + if (library->has_asset(asset)) { + return std::make_optional(library.get()); + } + } return std::nullopt; } diff --git a/engine/runtime/asset/asset_manager.hpp b/engine/runtime/asset/asset_manager.hpp index 2bcf805f5..af73346cb 100644 --- a/engine/runtime/asset/asset_manager.hpp +++ b/engine/runtime/asset/asset_manager.hpp @@ -66,15 +66,16 @@ namespace wmoge { AssetManager(class IocContainer* ioc); ~AssetManager() = default; - 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(); + 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 resolve_asset_meta(const AssetId& asset); + std::optional resolve_asset(const AssetId& asset); + void clear(); + void load_loaders(); private: struct LoadState { @@ -89,8 +90,9 @@ namespace wmoge { flat_map> m_loaders; std::shared_ptr> m_callback; - class FileSystem* m_file_system = nullptr; - class RttiTypeStorage* m_type_storage = nullptr; + class FileSystem* m_file_system = nullptr; + class RttiTypeStorage* m_type_storage = nullptr; + class IocContainer* m_ioc_container = nullptr; mutable std::recursive_mutex m_mutex; }; diff --git a/engine/runtime/audio/audio_stream_wav.cpp b/engine/runtime/audio/audio_stream_wav.cpp index f1166494c..b44e9ec5a 100644 --- a/engine/runtime/audio/audio_stream_wav.cpp +++ b/engine/runtime/audio/audio_stream_wav.cpp @@ -27,9 +27,7 @@ #include "audio_stream_wav.hpp" -#include "platform/file_system.hpp" #include "profiler/profiler.hpp" -#include "system/ioc_container.hpp" #include @@ -37,25 +35,21 @@ namespace wmoge { - Status AudioStreamWav::load(const std::string& file_path) { + Status AudioStreamWav::load(array_view file_data) { WG_AUTO_PROFILE_ASSET("AudioStreamWav::load"); - std::vector file_data; - - if (!IocContainer::iresolve_v()->read_file(file_path, file_data)) { - WG_LOG_ERROR("field to read wav file " << file_path); - return StatusCode::FailedRead; - } + std::vector data; + data.resize(file_data.size()); + std::memcpy(data.data(), file_data.data(), file_data.size()); AudioFile file; - if (!file.loadFromMemory(file_data)) { - WG_LOG_ERROR("failed to load from memory wav file " << file_path); + if (!file.loadFromMemory(data)) { + WG_LOG_ERROR("failed to load from memory wav file " << get_name()); return StatusCode::Error; } - if (file.getNumChannels() <= 0) { - WG_LOG_ERROR("no channels in loaded wav file " << file_path); + WG_LOG_ERROR("no channels in loaded wav file " << get_name()); return StatusCode::InvalidData; } diff --git a/engine/runtime/audio/audio_stream_wav.hpp b/engine/runtime/audio/audio_stream_wav.hpp index 410897d02..50229eb9b 100644 --- a/engine/runtime/audio/audio_stream_wav.hpp +++ b/engine/runtime/audio/audio_stream_wav.hpp @@ -29,6 +29,7 @@ #include "asset/asset.hpp" #include "audio/audio_stream.hpp" +#include "core/array_view.hpp" #include "core/buffered_vector.hpp" #include "core/data.hpp" @@ -48,11 +49,11 @@ namespace wmoge { /** * @brief Loads an audio from a wav file using audio file library * - * @param file_path Path to audio file in wav format in asset directory + * @param file_data Audio file data in wav format * * @return True if loaded */ - Status load(const std::string& file_path); + Status load(array_view file_data); Ref get_channel_data(int channel) override; diff --git a/engine/runtime/grc/image.cpp b/engine/runtime/grc/image.cpp index e777ef978..abf28fd0f 100644 --- a/engine/runtime/grc/image.cpp +++ b/engine/runtime/grc/image.cpp @@ -51,23 +51,23 @@ namespace wmoge { m_pixel_size = pixel_size; m_pixel_data = make_ref(width * height * pixel_size); } - Status Image::load(const std::string& path, int channels) { + Status Image::load(FileSystem* fs, const std::string& path, int channels) { WG_AUTO_PROFILE_ASSET("Image::load"); - FileSystem* file_system = IocContainer::iresolve_v(); - std::vector pixel_data; - if (!file_system->read_file(path, pixel_data)) { - WG_LOG_ERROR("failed to load image file from fs " << path); - return StatusCode::Error; - } + WG_CHECKED(fs->read_file(path, pixel_data)); + + return load(pixel_data, channels); + } + Status Image::load(array_view pixel_data, int channels) { + WG_AUTO_PROFILE_ASSET("Image::load"); int w, h, n; channels = Math::clamp(channels, 0, 4); stbi_uc* data = stbi_load_from_memory(reinterpret_cast(pixel_data.data()), static_cast(pixel_data.size()), &w, &h, &n, channels); if (!data) { - WG_LOG_ERROR("failed to read image data " << path); + WG_LOG_ERROR("failed to read image data"); return StatusCode::FailedRead; } diff --git a/engine/runtime/grc/image.hpp b/engine/runtime/grc/image.hpp index 3ea4863f3..c3daeedc5 100644 --- a/engine/runtime/grc/image.hpp +++ b/engine/runtime/grc/image.hpp @@ -28,6 +28,7 @@ #pragma once #include "asset/asset.hpp" +#include "core/array_view.hpp" #include "core/data.hpp" #include "io/serialization.hpp" #include "math/vec.hpp" @@ -64,14 +65,25 @@ namespace wmoge { void create(int width, int height, int channels = 4, int pixel_size = 4); /** - * @brief Loads image from a file system + * @brief Loads image from a file * - * @param filepath Path to the image in a file system + * @param fs File system to read file + * @param path Path to image pixel data * @param channels Desired number of channels to load (1 to 4) * * @return True if image successfully loaded */ - Status load(const std::string& path, int channels = 0); + Status load(class FileSystem* fs, const std::string& path, int channels = 0); + + /** + * @brief Loads image from a data + * + * @param pixel_data Image pixel data loaded from file + * @param channels Desired number of channels to load (1 to 4) + * + * @return True if image successfully loaded + */ + Status load(array_view pixel_data, int channels = 0); /** * @brief Save image to file in file system using specified filepath diff --git a/engine/runtime/grc/shader.cpp b/engine/runtime/grc/shader.cpp index 2eb5a723b..4be5917dd 100644 --- a/engine/runtime/grc/shader.cpp +++ b/engine/runtime/grc/shader.cpp @@ -324,11 +324,11 @@ namespace wmoge { if (id.is_invalid()) { return std::nullopt; } - if (id.index >= m_reflection.params_info.size()) { + if (id.value >= m_reflection.params_info.size()) { return std::nullopt; } - return &m_reflection.params_info[id.index]; + return &m_reflection.params_info[id.value]; } ShaderParamId Shader::find_param_id(Strid name) { diff --git a/engine/runtime/grc/shader_reflection.cpp b/engine/runtime/grc/shader_reflection.cpp index a2d8bb744..269fc0df5 100644 --- a/engine/runtime/grc/shader_reflection.cpp +++ b/engine/runtime/grc/shader_reflection.cpp @@ -39,6 +39,7 @@ namespace wmoge { t->type = base_type; t->byte_size = ShaderBaseTypeSizes[int(base_type)]; t->is_primitive = is_primitive; + t->is_builtin = true; return t; } static Ref make(ShaderBaseType base_type, Strid name, int n_rows) { @@ -50,6 +51,7 @@ namespace wmoge { t->n_elem = n_rows * 1; t->byte_size = ShaderBaseTypeSizes[int(base_type)] * t->n_elem; t->is_primitive = true; + t->is_builtin = true; return t; } static Ref make(ShaderBaseType base_type, Strid name, int n_rows, int n_cols) { @@ -61,6 +63,7 @@ namespace wmoge { t->n_elem = n_rows * n_cols; t->byte_size = ShaderBaseTypeSizes[int(base_type)] * t->n_elem; t->is_primitive = true; + t->is_builtin = true; return t; } diff --git a/engine/runtime/grc/shader_reflection.hpp b/engine/runtime/grc/shader_reflection.hpp index ba9d6bec5..fc5d99514 100644 --- a/engine/runtime/grc/shader_reflection.hpp +++ b/engine/runtime/grc/shader_reflection.hpp @@ -32,6 +32,7 @@ #include "core/flat_set.hpp" #include "core/mask.hpp" #include "core/ref.hpp" +#include "core/simple_id.hpp" #include "core/string_id.hpp" #include "core/var.hpp" #include "gfx/gfx_defs.hpp" @@ -102,24 +103,27 @@ namespace wmoge { * @class ShaderType * @brief Recursive complex type for declaring of anything in a shader what has a type */ - struct ShaderType : public RefCnt { + struct ShaderType : public RttiObject { + WG_RTTI_CLASS(ShaderType, RttiObject); + struct Field { - Strid name; // field name - Ref type; // base element type (elem type of array) - std::int16_t offset = -1; // offset in a struct from this to next field - std::int16_t elem_count = 0; // count of elem in array (0 if array is unbound) - bool is_array = false;// is array field - Var default_value; // optional default value to set + Strid name; // field name + Ref type; // base element type (elem type of array) + std::int16_t offset = -1; // offset in a struct from this to next field + std::int16_t elem_count = 0; // count of elem in array (0 if array is unbound) + bool is_array = false;// is array field + Var default_value; // optional default value to set }; - Strid name; // type name - ShaderBaseType type = ShaderBaseType::None;// type of its base - std::int16_t n_row = -1; // num of rows for vector like types - std::int16_t n_col = -1; // num of columns for matrix like types - std::int16_t n_elem = -1; // num of elements in vec/mat type - std::int16_t byte_size = 0; // raw byte size - buffered_vector fields; // fields of a struct type - bool is_primitive = false; // is a primitive type, raw value in a memory + Strid name; // type name + ShaderBaseType type = ShaderBaseType::None;// type of its base + std::int16_t n_row = -1; // num of rows for vector like types + std::int16_t n_col = -1; // num of columns for matrix like types + std::int16_t n_elem = -1; // num of elements in vec/mat type + std::int16_t byte_size = 0; // raw byte size + std::vector fields; // fields of a struct type + bool is_primitive = false; // is a primitive type, raw value in a memory + bool is_builtin = false; // is type pre-defined in the engine (no save/load) }; /** @@ -175,6 +179,8 @@ namespace wmoge { * @brief Declared pass constants inlined as defines into source code */ struct ShaderConstant { + WG_RTTI_STRUCT(ShaderConstant); + Strid name; Var value; std::string str; @@ -185,6 +191,8 @@ namespace wmoge { * @brief Single shader module required for compilation (shader stage) */ struct ShaderSourceFile { + WG_RTTI_STRUCT(ShaderSourceFile); + Strid file; GfxShaderModule module; GfxShaderLang lang = GfxShaderLang::GlslVk450; @@ -211,6 +219,8 @@ namespace wmoge { * @brief An interface exposed bindable param */ struct ShaderBinding { + WG_RTTI_STRUCT(ShaderBinding); + Strid name; Ref type; ShaderBindingType binding = ShaderBindingType::None; @@ -234,9 +244,11 @@ namespace wmoge { * @brief Contains interface assets for a single descriptor set */ struct ShaderSpace { - Strid name; - ShaderSpaceType type = ShaderSpaceType::Default; - buffered_vector bindings; + WG_RTTI_STRUCT(ShaderSpace); + + Strid name; + ShaderSpaceType type = ShaderSpaceType::Default; + std::vector bindings; }; /** @@ -244,6 +256,8 @@ namespace wmoge { * @brief An user controlled option which affects shader permutation */ struct ShaderOption { + WG_RTTI_STRUCT(ShaderOption); + Strid name; Strid base_variant; flat_map variants; @@ -256,6 +270,8 @@ namespace wmoge { * @brief Map of options for a technique or pass */ struct ShaderOptions { + WG_RTTI_STRUCT(ShaderOptions); + static constexpr std::int16_t MAX_OPTIONS = 64; using Mask = std::bitset; @@ -356,6 +372,8 @@ namespace wmoge { * @brief Defines single pass of shader, a functional subset */ struct ShaderPassInfo { + WG_RTTI_STRUCT(ShaderPassInfo); + Strid name; PipelineState state; ShaderOptions options; @@ -369,6 +387,8 @@ namespace wmoge { * @brief Defines single technique as collection of passes for drawing */ struct ShaderTechniqueInfo { + WG_RTTI_STRUCT(ShaderTechniqueInfo); + Strid name; ShaderOptions options; buffered_vector passes; @@ -381,26 +401,17 @@ namespace wmoge { }; /** - * @class ShaderParamId * @brief Handle to a shader param */ - struct ShaderParamId { - ShaderParamId() = default; - ShaderParamId(std::int16_t index) : index(index) {} - - operator std::int16_t() const { return index; } - - [[nodiscard]] bool is_valid() const { return index != -1; } - [[nodiscard]] bool is_invalid() const { return index == -1; } - - std::int16_t index = -1; - }; + using ShaderParamId = SimpleId; /** * @class ShaderParamInfo * @brief Info about an param which can be set from shader or material */ struct ShaderParamInfo { + WG_RTTI_STRUCT(ShaderParamInfo); + Strid name; // fully qualified param name Ref type; // param base type (in case of array - element type) ShaderBindingType binding_type; // binding type where param is @@ -426,6 +437,8 @@ namespace wmoge { * @brief Buffer info for auto packing of scalar params */ struct ShaderBufferInfo { + WG_RTTI_STRUCT(ShaderBufferInfo); + Ref defaults; std::int16_t space = -1; std::int16_t binding = -1; @@ -472,6 +485,8 @@ namespace wmoge { * @brief Full reflection information of a single shader class */ struct ShaderReflection { + WG_RTTI_STRUCT(ShaderReflection); + Strid shader_name; // shader script global unique name Strid shader_extends;// shader script which we extend in this one ShaderDomain domain; // shader domain diff --git a/engine/runtime/io/tree_yaml.cpp b/engine/runtime/io/tree_yaml.cpp index 4693de05d..fec798e73 100644 --- a/engine/runtime/io/tree_yaml.cpp +++ b/engine/runtime/io/tree_yaml.cpp @@ -46,7 +46,7 @@ namespace wmoge { return WG_OK; } - Status IoYamlTree::parse_data(const array_view& data) { + Status IoYamlTree::parse_data(const array_view& data) { WG_AUTO_PROFILE_IO("IoYamlTree::parse_data"); assert(m_stack.empty()); auto str_view = ryml::csubstr(reinterpret_cast(data.data()), data.size()); diff --git a/engine/runtime/io/tree_yaml.hpp b/engine/runtime/io/tree_yaml.hpp index 228decbe1..f3b1d1973 100644 --- a/engine/runtime/io/tree_yaml.hpp +++ b/engine/runtime/io/tree_yaml.hpp @@ -51,7 +51,7 @@ namespace wmoge { ~IoYamlTree() = default; Status create_tree(); - Status parse_data(const array_view& data); + Status parse_data(const array_view& data); Status parse_file(const std::string& path); Status parse_file(class FileSystem* fs, const std::string& path); diff --git a/engine/runtime/system/engine.cpp b/engine/runtime/system/engine.cpp index 781ef9dd5..6036c33bb 100644 --- a/engine/runtime/system/engine.cpp +++ b/engine/runtime/system/engine.cpp @@ -113,9 +113,9 @@ namespace wmoge { window_info.height = m_config->get_int_or_default(SID("engine.window.height"), 720); window_info.title = m_config->get_string_or_default(SID("engine.window.title"), "wmoge"); window_info.icons[0] = make_ref(); - window_info.icons[0]->load(m_config->get_string_or_default(SID("engine.window.icon_default")), 4); + window_info.icons[0]->load(m_file_system, m_config->get_string_or_default(SID("engine.window.icon_default")), 4); window_info.icons[1] = make_ref(); - window_info.icons[1]->load(m_config->get_string_or_default(SID("engine.window.icon_small")), 4); + window_info.icons[1]->load(m_file_system, m_config->get_string_or_default(SID("engine.window.icon_small")), 4); auto window = m_window_manager->create_window(window_info); WG_LOG_INFO("init window " << window_info.id); @@ -126,7 +126,7 @@ namespace wmoge { m_shader_manager->load_compilers(); m_asset_manager->load_loaders(); - m_asset_manager->add_library(std::make_shared("./", ioc)); + m_asset_manager->add_library(std::make_shared("", ioc)); m_shader_library = ioc->resolve_value(); m_pso_cache = ioc->resolve_value();