diff --git a/engine/plugins/runtime/asset/default_asset_loader.cpp b/engine/plugins/runtime/asset/default_asset_loader.cpp index 54a54c572..0bd5fdd90 100644 --- a/engine/plugins/runtime/asset/default_asset_loader.cpp +++ b/engine/plugins/runtime/asset/default_asset_loader.cpp @@ -27,6 +27,7 @@ #include "default_asset_loader.hpp" +#include "io/yaml.hpp" #include "profiler/profiler.hpp" namespace wmoge { @@ -56,17 +57,13 @@ namespace wmoge { return StatusCode::FailedInstantiate; } - auto asset_tree = yaml_parse_file(path_on_disk); - if (asset_tree.empty()) { - WG_LOG_ERROR("failed to read parse file " << path_on_disk); - return StatusCode::FailedParse; - }; + IoContext context; + IoYamlTree asset_tree; + WG_CHECKED(asset_tree.parse_file(path_on_disk)); asset->set_name(name); - IoContext context; - - if (!asset->read_from_yaml(context, asset_tree.crootref())) { + if (!asset->read_from_tree(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/shader_asset_loader.cpp b/engine/plugins/runtime/asset/shader_asset_loader.cpp index 9cb602591..b900222cd 100644 --- a/engine/plugins/runtime/asset/shader_asset_loader.cpp +++ b/engine/plugins/runtime/asset/shader_asset_loader.cpp @@ -30,6 +30,7 @@ #include "grc/shader.hpp" #include "grc/shader_file.hpp" #include "grc/shader_manager.hpp" +#include "io/yaml.hpp" #include "profiler/profiler.hpp" #include "system/ioc_container.hpp" @@ -55,10 +56,11 @@ namespace wmoge { } ShaderFile shader_file; - if (!yaml_read_file(path_on_disk, shader_file)) { - WG_LOG_ERROR("failed to read parse shader file " << path_on_disk); - return StatusCode::FailedParse; - } + + IoContext context; + IoYamlTree tree; + WG_CHECKED(tree.parse_file(path_on_disk)); + WG_TREE_READ(context, tree, shader_file); auto* shader_manager = IocContainer::iresolve_v(); diff --git a/engine/runtime/asset/_rtti.cpp b/engine/runtime/asset/_rtti.cpp index a5407933f..fceb809d8 100644 --- a/engine/runtime/asset/_rtti.cpp +++ b/engine/runtime/asset/_rtti.cpp @@ -37,7 +37,6 @@ namespace wmoge { void rtti_asset() { 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 86df1adfe..5333bae2e 100644 --- a/engine/runtime/asset/asset.cpp +++ b/engine/runtime/asset/asset.cpp @@ -35,12 +35,12 @@ namespace wmoge { - Status yaml_read(IoContext& context, YamlConstNodeRef node, AssetId& id) { - WG_YAML_READ(context, node, id.m_name); + Status tree_read(IoContext& context, IoPropertyTree& tree, AssetId& id) { + WG_TREE_READ(context, tree, id.m_name); return WG_OK; } - Status yaml_write(IoContext& context, YamlNodeRef node, const AssetId& id) { - WG_YAML_WRITE(context, node, id.m_name); + Status tree_write(IoContext& context, IoPropertyTree& tree, const AssetId& id) { + WG_TREE_WRITE(context, tree, id.m_name); return WG_OK; } Status stream_read(IoContext& context, IoStream& stream, AssetId& id) { diff --git a/engine/runtime/asset/asset.hpp b/engine/runtime/asset/asset.hpp index 42e4cf862..c7fa5b72f 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 yaml_read(IoContext& context, YamlConstNodeRef node, AssetId& id); - friend Status yaml_write(IoContext& context, YamlNodeRef node, const AssetId& id); + friend Status tree_read(IoContext& context, IoPropertyTree& tree, AssetId& id); + friend Status tree_write(IoContext& context, IoPropertyTree& 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); diff --git a/engine/runtime/asset/asset_meta.hpp b/engine/runtime/asset/asset_meta.hpp index 727153f82..55314edfa 100644 --- a/engine/runtime/asset/asset_meta.hpp +++ b/engine/runtime/asset/asset_meta.hpp @@ -72,8 +72,6 @@ namespace wmoge { * @brief Meta information of a particular asset */ struct AssetMeta { - WG_RTTI_STRUCT(AssetMeta); - UUID uuid = UUID(); class RttiClass* rtti = nullptr; class AssetPak* pak = nullptr; @@ -82,12 +80,4 @@ namespace wmoge { Ref import_data; }; - WG_RTTI_STRUCT_BEGIN(AssetMeta) { - WG_RTTI_META_DATA(); - WG_RTTI_FIELD(uuid, {RttiOptional}); - WG_RTTI_FIELD(deps, {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_pak.hpp b/engine/runtime/asset/asset_pak.hpp index e098aab64..ec9968da1 100644 --- a/engine/runtime/asset/asset_pak.hpp +++ b/engine/runtime/asset/asset_pak.hpp @@ -32,7 +32,7 @@ #include "core/data.hpp" #include "core/status.hpp" #include "core/string_id.hpp" -#include "io/yaml.hpp" +#include "io/property_tree.hpp" #include #include diff --git a/engine/runtime/asset/asset_pak_fs.cpp b/engine/runtime/asset/asset_pak_fs.cpp index 51e09fe4c..2d0e69dfb 100644 --- a/engine/runtime/asset/asset_pak_fs.cpp +++ b/engine/runtime/asset/asset_pak_fs.cpp @@ -29,6 +29,7 @@ #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" @@ -56,10 +57,10 @@ namespace wmoge { AssetMetaFile asset_file; - if (!yaml_read_file(meta_file_path, asset_file)) { - WG_LOG_ERROR("failed to parse .asset file " << meta_file_path); - return StatusCode::FailedRead; - } + 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); diff --git a/engine/runtime/asset/asset_ref.hpp b/engine/runtime/asset/asset_ref.hpp index 8c95c4840..df6c377fb 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/yaml.hpp" #include #include @@ -66,9 +66,9 @@ namespace wmoge { }; template - Status yaml_read(IoContext& context, YamlConstNodeRef node, AssetRef& ref) { + Status tree_read(IoContext& context, IoPropertyTree& tree, AssetRef& ref) { AssetId id; - WG_YAML_READ(context, node, id); + WG_TREE_READ(context, tree, id); Ref ptr = context.get_asset_manager()->find(id).cast(); if (!ptr) { return StatusCode::NoAsset; @@ -78,12 +78,12 @@ namespace wmoge { } template - Status yaml_write(IoContext& context, YamlNodeRef node, const AssetRef& ref) { + Status tree_write(IoContext& context, IoPropertyTree& tree, const AssetRef& ref) { assert(ref); if (!ref) { return StatusCode::NoAsset; } - WG_YAML_WRITE(context, node, ref->get_id()); + WG_TREE_WRITE(context, tree, ref->get_id()); return WG_OK; } @@ -110,17 +110,17 @@ namespace wmoge { } template - Status yaml_read(IoContext& context, YamlConstNodeRef node, AssetRefWeak& ref) { + Status tree_read(IoContext& context, IoPropertyTree& tree, AssetRefWeak& ref) { AssetId id; - WG_YAML_READ(context, node, id); + WG_TREE_READ(context, tree, id); ref = AssetRefWeak(id); return WG_OK; } template - Status yaml_write(IoContext& context, YamlNodeRef node, const AssetRefWeak& ref) { + Status tree_write(IoContext& context, IoPropertyTree& tree, const AssetRefWeak& ref) { AssetId id = ref; - WG_YAML_WRITE(context, node, id); + WG_TREE_WRITE(context, tree, id); return WG_OK; } diff --git a/engine/runtime/core/buffered_vector.hpp b/engine/runtime/core/buffered_vector.hpp index ec1c2f109..d57a9432e 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/yaml.hpp" #include #include @@ -45,15 +45,6 @@ namespace wmoge { template using buffered_vector = ankerl::svector; - template - Status stream_write(IoContext& context, IoStream& stream, const buffered_vector& vector) { - WG_ARCHIVE_WRITE(context, stream, vector.size()); - for (const auto& entry : vector) { - WG_ARCHIVE_WRITE(context, stream, entry); - } - return WG_OK; - } - template Status stream_read(IoContext& context, IoStream& stream, buffered_vector& vector) { assert(vector.empty()); @@ -67,26 +58,38 @@ namespace wmoge { } template - Status yaml_write(IoContext& context, YamlNodeRef node, const buffered_vector& vector) { - WG_YAML_SEQ(node); - for (const T& value : vector) { - YamlNodeRef child = node.append_child(); - WG_YAML_WRITE(context, child, value); + Status stream_write(IoContext& context, IoStream& stream, const buffered_vector& vector) { + WG_ARCHIVE_WRITE(context, stream, vector.size()); + for (const auto& entry : vector) { + WG_ARCHIVE_WRITE(context, stream, entry); } return WG_OK; } template - Status yaml_read(IoContext& context, YamlConstNodeRef node, buffered_vector& vector) { + Status tree_read(IoContext& context, IoPropertyTree& tree, buffered_vector& vector) { assert(vector.empty()); - vector.resize(node.num_children()); + vector.resize(tree.node_num_children()); std::size_t element_id = 0; - for (auto child = node.first_child(); child.valid(); child = child.next_sibling()) { - WG_YAML_READ(context, child, vector[element_id]); + tree.node_find_first_child(); + for (; tree.node_is_valid(); tree.node_next_sibling()) { + WG_TREE_READ(context, tree, vector[element_id]); element_id += 1; } return WG_OK; } + + template + Status tree_write(IoContext& context, IoPropertyTree& tree, const buffered_vector& vector) { + WG_TREE_SEQ(tree, vector.size()); + for (const T& value : vector) { + WG_CHECKED(tree.node_append_child()); + WG_TREE_WRITE(context, tree, value); + tree.node_pop(); + } + return WG_OK; + } + #endif }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/core/data.cpp b/engine/runtime/core/data.cpp index 2656f0f08..e96473f7b 100644 --- a/engine/runtime/core/data.cpp +++ b/engine/runtime/core/data.cpp @@ -85,21 +85,21 @@ namespace wmoge { return stream.nread(static_cast(size), data->buffer()); } - Status yaml_write(IoContext& context, YamlNodeRef node, const Ref& data) { + Status tree_write(IoContext& context, IoPropertyTree& tree, const Ref& data) { if (!data) { - node << ""; + tree.node_write_value(""); return WG_OK; } std::string encoded; if (Base64::encode(data, encoded)) { - return yaml_write(context, node, encoded); + return tree_write(context, tree, encoded); } return StatusCode::FailedWrite; } - Status yaml_read(IoContext& context, YamlConstNodeRef node, Ref& data) { + Status tree_read(IoContext& context, IoPropertyTree& tree, Ref& data) { std::string encoded; - if (yaml_read(context, node, encoded)) { + if (tree_read(context, tree, encoded)) { return Base64::decode(encoded, data); } return StatusCode::FailedRead; diff --git a/engine/runtime/core/data.hpp b/engine/runtime/core/data.hpp index 638a61631..c77b30b55 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/yaml.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 yaml_write(IoContext& context, YamlNodeRef node, const Ref& data); - friend Status yaml_read(IoContext& context, YamlConstNodeRef node, Ref& data); + friend Status tree_write(IoContext& context, IoPropertyTree& tree, const Ref& data); + friend Status tree_read(IoContext& context, IoPropertyTree& 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 1307721fa..053591cb8 100644 --- a/engine/runtime/core/date_time.cpp +++ b/engine/runtime/core/date_time.cpp @@ -116,15 +116,15 @@ namespace wmoge { return t; } - Status yaml_read(IoContext& context, YamlConstNodeRef node, DateTime& value) { + Status tree_read(IoContext& context, IoPropertyTree& tree, DateTime& value) { std::string s; - WG_YAML_READ(context, node, s); + WG_TREE_READ(context, tree, s); value = DateTime(s); return WG_OK; } - Status yaml_write(IoContext& context, YamlNodeRef node, const DateTime& value) { + Status tree_write(IoContext& context, IoPropertyTree& tree, const DateTime& value) { const std::string s = value.to_string(); - WG_YAML_WRITE(context, node, s); + WG_TREE_WRITE(context, tree, s); return WG_OK; } Status stream_read(IoContext& context, IoStream& stream, DateTime& value) { diff --git a/engine/runtime/core/date_time.hpp b/engine/runtime/core/date_time.hpp index c76d7ec60..3e227c0a4 100644 --- a/engine/runtime/core/date_time.hpp +++ b/engine/runtime/core/date_time.hpp @@ -77,8 +77,8 @@ namespace wmoge { static DateTime now(); - friend Status yaml_read(IoContext& context, YamlConstNodeRef node, DateTime& value); - friend Status yaml_write(IoContext& context, YamlNodeRef node, const DateTime& value); + friend Status tree_read(IoContext& context, IoPropertyTree& tree, DateTime& value); + friend Status tree_write(IoContext& context, IoPropertyTree& 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 a3c495c33..5b0eedb0b 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/yaml.hpp" #include #include @@ -70,23 +70,25 @@ namespace wmoge { } template - Status yaml_read(IoContext& context, YamlConstNodeRef node, flat_map& map) { + Status tree_read(IoContext& context, IoPropertyTree& tree, flat_map& map) { assert(map.empty()); - map.reserve(node.num_children()); - for (auto child = node.first_child(); child.valid(); child = child.next_sibling()) { + map.reserve(tree.node_num_children()); + tree.node_find_first_child(); + for (; tree.node_is_valid(); tree.node_next_sibling()) { robin_hood::pair entry; - WG_YAML_READ(context, child, entry); + WG_TREE_READ(context, tree, entry); map.insert(std::move(entry)); } return WG_OK; } template - Status yaml_write(IoContext& context, YamlNodeRef node, const flat_map& map) { - WG_YAML_SEQ(node); + Status tree_write(IoContext& context, IoPropertyTree& tree, const flat_map& map) { + WG_TREE_SEQ(tree, map.size()); for (const auto& entry : map) { - YamlNodeRef entry_child = node.append_child(); - WG_YAML_WRITE(context, entry_child, entry); + WG_CHECKED(tree.node_append_child()); + WG_TREE_WRITE(context, tree, entry); + tree.node_pop(); } return WG_OK; } diff --git a/engine/runtime/core/mask.hpp b/engine/runtime/core/mask.hpp index 723d33d1c..226581907 100644 --- a/engine/runtime/core/mask.hpp +++ b/engine/runtime/core/mask.hpp @@ -28,8 +28,8 @@ #pragma once #include "core/buffered_vector.hpp" +#include "io/property_tree.hpp" #include "io/stream.hpp" -#include "io/yaml.hpp" #include #include @@ -107,9 +107,9 @@ namespace wmoge { } template - Status yaml_read(IoContext& context, YamlConstNodeRef node, Mask& mask) { + Status tree_read(IoContext& context, IoPropertyTree& tree, Mask& mask) { buffered_vector flags; - WG_YAML_READ(context, node, flags); + WG_TREE_READ(context, tree, flags); for (auto flag : flags) { mask.set(flag); @@ -119,14 +119,14 @@ namespace wmoge { } template - Status yaml_write(IoContext& context, YamlNodeRef node, const Mask& mask) { + Status tree_write(IoContext& context, IoPropertyTree& tree, const Mask& mask) { buffered_vector flags; mask.for_each([&](int, T flag) { flags.push_back(flag); }); - WG_YAML_WRITE(context, node, flags); + WG_TREE_WRITE(context, tree, flags); return WG_OK; } diff --git a/engine/runtime/core/object.cpp b/engine/runtime/core/object.cpp index 48ade45c7..e06e12d3b 100644 --- a/engine/runtime/core/object.cpp +++ b/engine/runtime/core/object.cpp @@ -123,11 +123,11 @@ namespace wmoge { return name; } - Status yaml_read_object(IoContext& context, YamlConstNodeRef node, Ref& object) { + Status tree_read_object(IoContext& context, IoPropertyTree& tree, Ref& object) { assert(!object); Strid class_name; - WG_YAML_READ_AS(context, node, "rtti", class_name); + WG_TREE_READ_AS(context, tree, "rtti", class_name); auto* cls = Class::class_ptr(class_name); @@ -143,13 +143,13 @@ namespace wmoge { return StatusCode::FailedInstantiate; } - return object->read_from_yaml(node); + return object->read_from_tree(tree); } - Status yaml_write_object(IoContext& context, YamlNodeRef node, const Ref& object) { + Status tree_write_object(IoContext& context, IoPropertyTree& tree, const Ref& object) { assert(object); - WG_YAML_MAP(node); - WG_YAML_WRITE_AS(context, node, "rtti", object->class_name()); - return object->write_to_yaml(node); + WG_TREE_MAP(tree); + WG_TREE_WRITE_AS(context, tree, "rtti", object->class_name()); + return object->write_to_tree(tree); } Status archive_read_object(IoContext& context, IoStream& stream, Ref& object) { diff --git a/engine/runtime/core/object.hpp b/engine/runtime/core/object.hpp index 9c63d23e0..77901bab8 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/yaml.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_yaml(const YamlConstNodeRef& node) { return StatusCode::NotImplemented; } - virtual Status write_to_yaml(YamlNodeRef node) const { return StatusCode::NotImplemented; } + 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_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 yaml_read_object(IoContext& context, YamlConstNodeRef node, Ref& object); - friend Status yaml_write_object(IoContext& context, YamlNodeRef node, const Ref& object); + 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 archive_read_object(IoContext& context, IoStream& stream, Ref& object); friend Status archive_write_object(IoContext& context, IoStream& stream, const Ref& object); @@ -127,40 +127,6 @@ namespace wmoge { return std::move(result); } - template - Status yaml_read(IoContext& context, YamlConstNodeRef node, Ref& ref, typename std::enable_if_t>* = 0) { - Ref object; - auto status = yaml_read_object(context, node, object); - if (!status) return status; - ref = object.template cast(); - return WG_OK; - } - - template - Status yaml_write(IoContext& context, YamlNodeRef node, const Ref& ref, typename std::enable_if_t>* = 0) { - Ref object = ref.template as(); - auto status = yaml_write_object(context, node, object); - if (!status) return status; - return WG_OK; - } - - template - Status stream_read(IoContext& context, IoStream& stream, Ref& ref, typename std::enable_if_t>* = 0) { - Ref object; - auto status = archive_read_object(context, stream, object); - if (!status) return status; - ref = object.template cast(); - return WG_OK; - } - - template - Status stream_write(IoContext& context, IoStream& stream, const Ref& ref, typename std::enable_if_t>* = 0) { - Ref object = ref.template as(); - auto status = archive_write_object(context, stream, object); - if (!status) return status; - return WG_OK; - } - #define WG_OBJECT(name, super) \ public: \ friend class Class; \ diff --git a/engine/runtime/core/pool_vector.hpp b/engine/runtime/core/pool_vector.hpp index 537da2cfe..8c1482746 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/yaml.hpp" +#include "io/property_tree.hpp" #include #include @@ -203,25 +203,4 @@ namespace wmoge { return m_nodes[node_idx]->items[item_idx].mem; } - template - Status yaml_read(IoContext& context, YamlConstNodeRef node, pool_vector& vec) { - vec.reserve(node.num_children()); - for (auto child = node.first_child(); child.valid(); child = child.next_sibling()) { - T element; - WG_YAML_READ(context, child, element); - vec.push_back(std::move(element)); - } - return WG_OK; - } - - template - Status yaml_write(IoContext& context, YamlNodeRef node, const pool_vector& vec) { - WG_YAML_SEQ(node); - for (const T& value : vec) { - YamlNodeRef child = node.append_child(); - WG_YAML_WRITE(context, child, value); - } - return WG_OK; - } - }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/core/sha256.cpp b/engine/runtime/core/sha256.cpp index d70393caa..f9c6c6d8b 100644 --- a/engine/runtime/core/sha256.cpp +++ b/engine/runtime/core/sha256.cpp @@ -96,15 +96,15 @@ namespace wmoge { return hash_value; } - Status yaml_read(IoContext& context, YamlConstNodeRef node, Sha256& sha) { + Status tree_read(IoContext& context, IoPropertyTree& tree, Sha256& sha) { std::string s; - WG_CHECKED(yaml_read(context, node, s)); + WG_CHECKED(tree_read(context, tree, s)); sha = Sha256(s); return WG_OK; } - Status yaml_write(IoContext& context, YamlNodeRef node, const Sha256& sha) { - return yaml_write(context, node, sha.to_string()); + Status tree_write(IoContext& context, IoPropertyTree& tree, const Sha256& sha) { + return tree_write(context, tree, sha.to_string()); } Status stream_read(IoContext& context, IoStream& stream, Sha256& sha) { return stream.nread(sizeof(sha), &sha); diff --git a/engine/runtime/core/sha256.hpp b/engine/runtime/core/sha256.hpp index edf755706..46178d595 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/yaml.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 yaml_read(IoContext& context, YamlConstNodeRef node, Sha256& sha); - Status yaml_write(IoContext& context, YamlNodeRef node, const Sha256& sha); + Status tree_read(IoContext& context, IoPropertyTree& tree, Sha256& sha); + Status tree_write(IoContext& context, IoPropertyTree& 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/typed_array.hpp b/engine/runtime/core/typed_array.hpp index 6e2af127c..e6f243075 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/yaml.hpp" +#include "io/property_tree.hpp" #include @@ -91,29 +91,4 @@ namespace wmoge { static_assert(sizeof(TypedArray) <= sizeof(void*), "Typed array must fit size of native pointer"); - template - Status yaml_read(IoContext& context, YamlConstNodeRef node, TypedArray& array) { - array.resize(node.num_children()); - std::size_t element_id = 0; - for (auto child = node.first_child(); child.valid(); child = child.next_sibling()) { - WG_YAML_READ(context, child, array[element_id]); - element_id += 1; - } - - return WG_OK; - } - - template - Status yaml_write(IoContext& context, YamlNodeRef node, const TypedArray& array) { - WG_YAML_SEQ(node); - - const std::size_t size = array.size(); - for (std::size_t i = 0; i < size; i++) { - YamlNodeRef child = node.append_child(); - WG_YAML_WRITE(context, child, array[i]); - } - - return WG_OK; - } - }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/core/typed_map.hpp b/engine/runtime/core/typed_map.hpp index 9e32dd3e0..66358d6ea 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/yaml.hpp" +#include "io/property_tree.hpp" #include #include @@ -99,29 +99,4 @@ namespace wmoge { static_assert(sizeof(TypedMap>) <= sizeof(void*), "Typed map must fit size of native pointer"); - template - Status yaml_read(IoContext& context, YamlConstNodeRef node, TypedMap& map) { - map.reserve(node.num_children()); - - for (auto child = node.first_child(); child.valid(); child = child.next_sibling()) { - std::pair entry; - WG_YAML_READ(context, child, entry); - map.insert(std::move(entry)); - } - - return WG_OK; - } - - template - Status yaml_write(IoContext& context, YamlNodeRef node, const TypedMap& map) { - WG_YAML_SEQ(node); - - for (const auto& entry : map) { - YamlNodeRef entry_child = node.append_child(); - WG_YAML_WRITE(context, entry_child, entry); - } - - return WG_OK; - } - }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/core/uuid.cpp b/engine/runtime/core/uuid.cpp index aa38bdeee..5e138c62a 100644 --- a/engine/runtime/core/uuid.cpp +++ b/engine/runtime/core/uuid.cpp @@ -46,14 +46,14 @@ namespace wmoge { return {Random::next_uint64()}; } - Status yaml_read(IoContext& context, YamlConstNodeRef node, UUID& id) { + Status tree_read(IoContext& context, IoPropertyTree& tree, UUID& id) { std::string value; - node >> value; + WG_TREE_READ(context, tree, value); id = UUID(value); return WG_OK; } - Status yaml_write(IoContext& context, YamlNodeRef node, const UUID& id) { - node << StringUtils::from_uint64(id.m_value); + Status tree_write(IoContext& context, IoPropertyTree& 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 2ec4d1b70..24d9c3c4e 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/yaml.hpp" #include #include @@ -64,8 +64,8 @@ namespace wmoge { static UUID generate(); - friend Status yaml_read(IoContext& context, YamlConstNodeRef node, UUID& id); - friend Status yaml_write(IoContext& context, YamlNodeRef node, const UUID& id); + friend Status tree_read(IoContext& context, IoPropertyTree& tree, UUID& id); + friend Status tree_write(IoContext& context, IoPropertyTree& 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 07ea77506..68da1c3ed 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/yaml.hpp" #include #include @@ -79,11 +79,11 @@ namespace wmoge { [[nodiscard]] std::string to_string() const; - friend Status yaml_read(IoContext& context, YamlConstNodeRef node, EcsArch& arch) { - return yaml_read(context, node, *((EcsArch::Bitset*) &arch)); + friend Status tree_read(IoContext& context, IoPropertyTree& tree, EcsArch& arch) { + return tree_read(context, tree, *((EcsArch::Bitset*) &arch)); } - friend Status yaml_write(IoContext& context, YamlNodeRef node, const EcsArch& arch) { - return yaml_write(context, node, *((const EcsArch::Bitset*) &arch)); + friend Status tree_write(IoContext& context, IoPropertyTree& tree, const EcsArch& arch) { + return tree_write(context, tree, *((const EcsArch::Bitset*) &arch)); } friend Status stream_read(IoContext& context, IoStream& stream, EcsArch& arch) { return stream_read(context, stream, *((EcsArch::Bitset*) &arch)); diff --git a/engine/runtime/engine.hpp b/engine/runtime/engine.hpp index b72582d6c..1be33cbe9 100644 --- a/engine/runtime/engine.hpp +++ b/engine/runtime/engine.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/yaml.hpp" #include "material/material.hpp" diff --git a/engine/runtime/gfx/gfx_sampler.cpp b/engine/runtime/gfx/gfx_sampler.cpp index 1272f3106..01584f3aa 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/yaml.hpp" +#include "io/property_tree.hpp" #include #include diff --git a/engine/runtime/grc/font.cpp b/engine/runtime/grc/font.cpp index 7ea1d5ace..c23911e58 100644 --- a/engine/runtime/grc/font.cpp +++ b/engine/runtime/grc/font.cpp @@ -37,12 +37,6 @@ namespace wmoge { - WG_IO_BEGIN(FontImportOptions) - WG_IO_FIELD(source_file) - WG_IO_FIELD(height) - WG_IO_FIELD(glyphs_in_row) - WG_IO_END(FontImportOptions) - Status Font::init(const FontDesc& desc) { m_glyphs = desc.glyphs; m_texture = desc.texture; diff --git a/engine/runtime/grc/font.hpp b/engine/runtime/grc/font.hpp index 80599f699..926ccdb00 100644 --- a/engine/runtime/grc/font.hpp +++ b/engine/runtime/grc/font.hpp @@ -41,18 +41,6 @@ namespace wmoge { - /** - * @class FontImportOptions - * @brief Options to import a font asset - */ - struct FontImportOptions { - std::string source_file; - int height = 32; - int glyphs_in_row = 16; - - WG_IO_DECLARE(FontImportOptions); - }; - /** * @brief Alignment of text for layout */ diff --git a/engine/runtime/grc/texture.cpp b/engine/runtime/grc/texture.cpp index 6b2384af6..cca0c28e0 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/yaml.hpp" +#include "io/property_tree.hpp" #include "profiler/profiler.hpp" #include "system/ioc_container.hpp" diff --git a/engine/runtime/io/property_tree.cpp b/engine/runtime/io/property_tree.cpp new file mode 100644 index 000000000..56dfb45ae --- /dev/null +++ b/engine/runtime/io/property_tree.cpp @@ -0,0 +1,95 @@ +/**********************************************************************************/ +/* 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 "property_tree.hpp" + +namespace wmoge { + + Status tree_read(IoContext& context, IoPropertyTree& tree, bool& value) { + return tree.node_read_value(value); + } + Status tree_write(IoContext& context, IoPropertyTree& tree, const bool& value) { + return tree.node_write_value(value); + } + + Status tree_read(IoContext& context, IoPropertyTree& tree, int& value) { + return tree.node_read_value(value); + } + Status tree_write(IoContext& context, IoPropertyTree& tree, const int& value) { + return tree.node_write_value(value); + } + + Status tree_read(IoContext& context, IoPropertyTree& tree, unsigned int& value) { + return tree.node_read_value(value); + } + Status tree_write(IoContext& context, IoPropertyTree& tree, const unsigned int& value) { + return tree.node_write_value(value); + } + + Status tree_read(IoContext& context, IoPropertyTree& tree, float& value) { + return tree.node_read_value(value); + } + Status tree_write(IoContext& context, IoPropertyTree& tree, const float& value) { + return tree.node_write_value(value); + } + + Status tree_read(IoContext& context, IoPropertyTree& tree, Strid& value) { + return tree.node_read_value(value); + } + Status tree_write(IoContext& context, IoPropertyTree& tree, const Strid& value) { + return tree.node_write_value(value); + } + + Status tree_read(IoContext& context, IoPropertyTree& tree, std::string& value) { + return tree.node_read_value(value); + } + Status tree_write(IoContext& context, IoPropertyTree& tree, const std::string& value) { + return tree.node_write_value(value); + } + + Status tree_read(IoContext& context, IoPropertyTree& tree, std::int16_t& value) { + return tree.node_read_value(value); + } + Status tree_write(IoContext& context, IoPropertyTree& tree, const std::int16_t& value) { + return tree.node_write_value(value); + } + + Status tree_read(IoContext& context, IoPropertyTree& tree, std::size_t& value) { + return tree.node_read_value(value); + } + Status tree_write(IoContext& context, IoPropertyTree& tree, const std::size_t& value) { + return tree.node_write_value(value); + } + + Status tree_read(IoContext& context, IoPropertyTree& tree, Status& value) { + return tree_read(context, tree, value.code()); + } + Status tree_write(IoContext& context, IoPropertyTree& tree, const Status& value) { + return tree_write(context, tree, value.code()); + } + +}// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/io/property_tree.hpp b/engine/runtime/io/property_tree.hpp new file mode 100644 index 000000000..520dac9b0 --- /dev/null +++ b/engine/runtime/io/property_tree.hpp @@ -0,0 +1,378 @@ +/**********************************************************************************/ +/* 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 "core/log.hpp" +#include "core/ref.hpp" +#include "core/status.hpp" +#include "core/string_id.hpp" +#include "io/context.hpp" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace wmoge { + + /** + * @class IoPropertyTree + * @brief Structured property serialization and de-serialization tree + */ + class IoPropertyTree { + public: + virtual ~IoPropertyTree() = default; + + virtual bool node_is_empty() = 0; + virtual bool node_has_child(const std::string_view& name) = 0; + virtual Status node_find_child(const std::string_view& name) = 0; + virtual Status node_append_child() = 0; + virtual void node_find_first_child() = 0; + virtual bool node_is_valid() = 0; + virtual void node_next_sibling() = 0; + virtual void node_pop() = 0; + virtual std::size_t node_num_children() = 0; + + virtual Status node_write_key(const std::string_view& key) = 0; + + virtual Status node_write_value(const bool& value) = 0; + virtual Status node_write_value(const int& value) = 0; + virtual Status node_write_value(const unsigned int& value) = 0; + virtual Status node_write_value(const float& value) = 0; + virtual Status node_write_value(const std::string& value) = 0; + virtual Status node_write_value(const Strid& value) = 0; + virtual Status node_write_value(const std::int16_t& value) = 0; + virtual Status node_write_value(const std::size_t& value) = 0; + + virtual Status node_read_value(bool& value) = 0; + virtual Status node_read_value(int& value) = 0; + virtual Status node_read_value(unsigned int& value) = 0; + virtual Status node_read_value(float& value) = 0; + virtual Status node_read_value(std::string& value) = 0; + virtual Status node_read_value(Strid& value) = 0; + virtual Status node_read_value(std::int16_t& value) = 0; + virtual Status node_read_value(std::size_t& value) = 0; + + 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; } + + protected: + Strid m_name; + 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, IoPropertyTree& tree, int& value); + Status tree_write(IoContext& context, IoPropertyTree& 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, IoPropertyTree& tree, float& value); + Status tree_write(IoContext& context, IoPropertyTree& 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, IoPropertyTree& tree, std::string& value); + Status tree_write(IoContext& context, IoPropertyTree& 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, IoPropertyTree& tree, std::size_t& value); + Status tree_write(IoContext& context, IoPropertyTree& 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); + +#define WG_TREE_READ(context, tree, what) \ + do { \ + if (!tree_read(context, tree, what)) { \ + WG_LOG_ERROR("failed to read tree \"" << #what << "\""); \ + return StatusCode::FailedRead; \ + } \ + } while (false) + +#define WG_TREE_READ_AS(context, tree, node_name, what) \ + do { \ + if (!tree.node_find_child(node_name)) { \ + WG_LOG_ERROR("failed to fetch child tree \"" << #what << "\""); \ + return StatusCode::FailedRead; \ + } \ + if (!tree_read(context, tree, what)) { \ + WG_LOG_ERROR("failed to read tree \"" << #what << "\""); \ + return StatusCode::FailedRead; \ + } \ + tree.node_pop(); \ + } while (false) + +#define WG_TREE_READ_AS_OPT(context, tree, node_name, what) \ + do { \ + if (tree.node_has_child(node_name)) { \ + if (!tree.node_find_child(node_name)) { \ + WG_LOG_ERROR("failed to fetch child tree \"" << #what << "\""); \ + return StatusCode::FailedRead; \ + } \ + if (!tree_read(context, tree, what)) { \ + WG_LOG_ERROR("failed to read tree \"" << #what << "\""); \ + return StatusCode::FailedRead; \ + } \ + tree.node_pop(); \ + } \ + } while (false) + +#define WG_TREE_READ_SUPER(context, tree, super, what) \ + do { \ + WG_TREE_READ(context, tree, *((super*) (&what))); \ + } while (false) + +#define WG_TREE_WRITE(context, tree, what) \ + do { \ + if (!tree_write(context, tree, what)) { \ + WG_LOG_ERROR("failed to write tree \"" << #what << "\""); \ + return StatusCode::FailedWrite; \ + } \ + } while (false) + +#define WG_TREE_WRITE_AS(context, tree, node_name, what) \ + do { \ + if (!tree.node_append_child()) { \ + WG_LOG_ERROR("failed to append child tree \"" << #what << "\""); \ + return StatusCode::FailedWrite; \ + } \ + tree.node_write_key(node_name); \ + if (!tree_write(context, tree, what)) { \ + WG_LOG_ERROR("failed to write tree \"" << #what << "\""); \ + return StatusCode::FailedWrite; \ + } \ + tree.node_pop(); \ + } while (false) + +#define WG_TREE_WRITE_SUPER(tree, super, what) \ + do { \ + WG_TREE_WRITE(tree, *((const super*) (&what))); \ + } while (false) + +#define WG_TREE_MAP(tree) tree.node_as_map() +#define WG_TREE_SEQ(tree, length) tree.node_as_list(length) + + template + Status tree_read(IoContext& context, IoPropertyTree& 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) { + WG_TREE_MAP(tree); + WG_TREE_WRITE_AS(context, tree, "key", pair.first); + WG_TREE_WRITE_AS(context, tree, "value", pair.second); + return WG_OK; + } + + template + Status tree_read(IoContext& context, IoPropertyTree& 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) { + WG_TREE_MAP(tree); + WG_TREE_WRITE_AS(context, tree, "key", pair.first); + WG_TREE_WRITE_AS(context, tree, "value", pair.second); + return WG_OK; + } + + template + Status tree_read(IoContext& context, IoPropertyTree& tree, std::array& array) { + std::size_t element_id = 0; + assert(tree.node_num_children() <= S); + tree.node_find_first_child(); + for (; tree.node_is_valid() && element_id < S; tree.node_next_sibling()) { + WG_TREE_READ(context, tree, array[element_id]); + element_id++; + } + return WG_OK; + } + template + Status tree_write(IoContext& context, IoPropertyTree& 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()); + WG_TREE_WRITE(context, tree, array[i]); + tree.node_pop(); + } + return WG_OK; + } + + template + Status tree_read(IoContext& context, IoPropertyTree& tree, std::vector& vector) { + assert(vector.empty()); + vector.resize(tree.node_num_children()); + std::size_t element_id = 0; + tree.node_find_first_child(); + for (; tree.node_is_valid(); tree.node_next_sibling()) { + WG_TREE_READ(context, tree, vector[element_id]); + element_id++; + } + return WG_OK; + } + template + Status tree_write(IoContext& context, IoPropertyTree& tree, const std::vector& vector) { + WG_TREE_SEQ(tree, vector.size()); + for (const T& value : vector) { + WG_CHECKED(tree.node_append_child()); + WG_TREE_WRITE(context, tree, value); + tree.node_pop(); + } + return WG_OK; + } + + template + Status tree_read(IoContext& context, IoPropertyTree& tree, std::unordered_set& set) { + assert(set.empty()); + set.reserve(tree.node_num_children()); + tree.node_find_first_child(); + for (; tree.node_is_valid(); tree.node_next_sibling()) { + T entry; + WG_TREE_READ(context, tree, entry); + set.insert(std::move(entry)); + } + return WG_OK; + } + template + Status tree_write(IoContext& context, IoPropertyTree& tree, const std::unordered_set& set) { + WG_TREE_SEQ(tree, set.size()); + for (const T& entry : set) { + WG_CHECKED(tree.node_append_child()); + WG_TREE_WRITE(context, tree, entry); + tree.node_pop(); + } + return WG_OK; + } + + template + Status tree_read(IoContext& context, IoPropertyTree& tree, std::unordered_map& map) { + assert(map.empty()); + map.reserve(tree.node_num_children()); + tree.node_find_first_child(); + for (; tree.node_is_valid(); tree.node_next_sibling()) { + std::pair entry; + WG_TREE_READ(context, tree, entry); + map.insert(std::move(entry)); + } + return WG_OK; + } + template + Status tree_write(IoContext& context, IoPropertyTree& tree, const std::unordered_map& map) { + WG_TREE_SEQ(tree, map.size()); + for (const auto& entry : map) { + WG_CHECKED(tree.node_append_child()); + WG_TREE_WRITE(context, tree, entry); + tree.node_pop(); + } + return WG_OK; + } + + template::value>::type> + Status tree_read(IoContext& context, IoPropertyTree& tree, T& enum_value) { + std::string s; + WG_TREE_READ(context, tree, s); + auto parsed = magic_enum::enum_cast(s); + if (!parsed.has_value()) { + return StatusCode::FailedRead; + } + enum_value = parsed.value(); + return WG_OK; + } + template::value>::type> + Status tree_write(IoContext& context, IoPropertyTree& 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) { + if (!tree.node_is_empty()) { + wrapper.emplace(); + WG_TREE_READ(context, tree, wrapper.value()); + } + return WG_OK; + } + template + Status tree_write(IoContext& context, IoPropertyTree& tree, const std::optional& wrapper) { + if (wrapper.has_value()) { + WG_TREE_WRITE(context, tree, wrapper.value()); + } + return WG_OK; + } + + template + Status tree_read(IoContext& context, IoPropertyTree& tree, std::bitset& bitset) { + std::array values; + WG_TREE_READ(context, tree, values); + for (std::size_t i = 0; i < N; i++) { + if (values[i]) { + bitset.set(i); + } + } + return WG_OK; + } + template + Status tree_write(IoContext& context, IoPropertyTree& tree, const std::bitset& bitset) { + std::array values; + values.fill(false); + for (std::size_t i = 0; i < N; i++) { + if (bitset.test(i)) { + values[i] = true; + } + } + WG_TREE_WRITE(context, tree, values); + return WG_OK; + } + +}// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/io/serialization.hpp b/engine/runtime/io/serialization.hpp index 706075364..663a60cac 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/yaml.hpp" #include @@ -46,18 +46,18 @@ namespace wmoge { struct IoTagRead; struct IoTagWrite; -#define WG_IO_DECLARE(cls) \ - friend Status yaml_read(IoContext& context, YamlConstNodeRef node, cls& value); \ - friend Status yaml_write(IoContext& context, YamlNodeRef node, const cls& value); \ - friend Status stream_read(IoContext& context, IoStream& stream, cls& value); \ +#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); \ friend Status stream_write(IoContext& context, IoStream& stream, const cls& value); #define WG_IO_IMPLEMENT(nmsp, trg, cls) \ - Status yaml_read(IoContext& context, YamlConstNodeRef node, trg& value) { \ - return nmsp##__##cls##Serializer()(context, node, value); \ + Status tree_read(IoContext& context, IoPropertyTree& tree, trg& value) { \ + return nmsp##__##cls##Serializer()(context, tree, value); \ } \ - Status yaml_write(IoContext& context, YamlNodeRef node, const trg& value) { \ - return nmsp##__##cls##Serializer()(context, node, value); \ + Status tree_write(IoContext& context, IoPropertyTree& tree, const trg& value) { \ + return nmsp##__##cls##Serializer()(context, tree, value); \ } \ Status stream_read(IoContext& context, IoStream& stream, trg& value) { \ return nmsp##__##cls##Serializer()(context, stream, value); \ @@ -68,10 +68,10 @@ namespace wmoge { #define WG_IO_SUPER(super) \ if constexpr (std::is_same_v) { \ - WG_YAML_READ_SUPER(context, stream, super, target); \ + WG_TREE_READ_SUPER(context, stream, super, target); \ } \ if constexpr (std::is_same_v) { \ - WG_YAML_WRITE_SUPER(context, stream, super, target); \ + WG_TREE_WRITE_SUPER(context, stream, super, target); \ } \ if constexpr (std::is_same_v && std::is_same_v) { \ WG_ARCHIVE_READ_SUPER(context, stream, super, target); \ @@ -84,12 +84,12 @@ namespace wmoge { template \ struct nmsp##__##cls##Serializer final { \ Status operator()(IoContext& context, Stream stream, Target target) { \ - static const char* profile_mark_yaml_read = #cls "::yaml_read"; \ - static const char* profile_mark_yaml_write = #cls "::yaml_write"; \ + static const char* profile_mark_tree_read = #cls "::tree_read"; \ + static const char* profile_mark_tree_write = #cls "::tree_write"; \ static const char* profile_mark_archive_read = #cls "::stream_read"; \ static const char* profile_mark_archive_write = #cls "::stream_write"; \ if constexpr (std::is_same_v) { \ - WG_YAML_MAP(stream); \ + WG_TREE_MAP(stream); \ } #define WG_IO_BEGIN(cls) WG_IO_BEGIN_NMSP(global, cls) @@ -97,10 +97,10 @@ namespace wmoge { #define WG_IO_PROFILE() \ const char* profile_mark_name = ""; \ if constexpr (std::is_same_v) { \ - profile_mark_name = profile_mark_yaml_read; \ + profile_mark_name = profile_mark_tree_read; \ } \ if constexpr (std::is_same_v) { \ - profile_mark_name = profile_mark_yaml_write; \ + profile_mark_name = profile_mark_tree_write; \ } \ if constexpr (std::is_same_v && std::is_same_v) { \ profile_mark_name = profile_mark_archive_read; \ @@ -114,13 +114,13 @@ namespace wmoge { if constexpr (std::is_same_v) { \ const IoFlags mask = flags; \ if (mask.get(IoFlag::ReadOptional)) { \ - WG_YAML_READ_AS_OPT(context, stream, name, target.field); \ + WG_TREE_READ_AS_OPT(context, stream, name, target.field); \ } else { \ - WG_YAML_READ_AS(context, stream, name, target.field); \ + WG_TREE_READ_AS(context, stream, name, target.field); \ } \ } \ if constexpr (std::is_same_v) { \ - WG_YAML_WRITE_AS(context, stream, name, target.field); \ + WG_TREE_WRITE_AS(context, stream, name, target.field); \ } \ if constexpr (std::is_same_v && std::is_same_v) { \ WG_ARCHIVE_READ(context, stream, target.field); \ diff --git a/engine/runtime/io/yaml.cpp b/engine/runtime/io/yaml.cpp index bc9261914..1617077d5 100644 --- a/engine/runtime/io/yaml.cpp +++ b/engine/runtime/io/yaml.cpp @@ -28,6 +28,7 @@ #include "yaml.hpp" #include "platform/file_system.hpp" +#include "profiler/profiler.hpp" #include "system/ioc_container.hpp" #include @@ -36,103 +37,170 @@ namespace wmoge { - YamlTree yaml_parse(const std::vector& data) { + Status IoYamlTree::create_tree() { + assert(m_stack.empty()); + m_tree = Tree(); + m_can_read = false; + m_can_write = true; + m_stack.push_back(m_tree.rootref()); + return WG_OK; + } + + 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()); - return std::move(ryml::parse_in_arena(str_view)); + m_tree = std::move(ryml::parse_in_arena(str_view)); + if (m_tree.empty()) { + return StatusCode::FailedParse; + } + m_can_read = true; + m_can_write = false; + m_stack.push_back(m_tree.rootref()); + return WG_OK; + } + + Status IoYamlTree::parse_file(const std::string& path) { + FileSystem* file_system = IocContainer::iresolve_v(); + std::vector data; + WG_CHECKED(file_system->read_file(path, data)); + return parse_data(data); } - YamlTree yaml_parse_file(const std::string& file_path) { - std::vector file; +#define TOP m_stack.back() +#define STR(s) ryml::csubstr(s.data(), s.length()) - if (!IocContainer::iresolve_v()->read_file(file_path, file)) { - WG_LOG_ERROR("failed to read content of file " << file_path); - return {}; + bool IoYamlTree::node_is_empty() { + return TOP.empty(); + } + bool IoYamlTree::node_has_child(const std::string_view& name) { + return TOP.has_child(STR(name)); + } + Status IoYamlTree::node_find_child(const std::string_view& name) { + assert(can_read()); + if (TOP.has_child(STR(name))) { + m_stack.push_back(TOP[STR(name)]); + return WG_OK; } + return StatusCode::Error; + } + Status IoYamlTree::node_append_child() { + assert(can_write()); + m_stack.push_back(TOP.append_child()); + return WG_OK; + } + void IoYamlTree::node_find_first_child() { + TOP = TOP.first_child(); + } + bool IoYamlTree::node_is_valid() { + return TOP.valid(); + } + void IoYamlTree::node_next_sibling() { + TOP = TOP.next_sibling(); + } + void IoYamlTree::node_pop() { + assert(m_stack.size() > 1); + m_stack.pop_back(); + } + std::size_t IoYamlTree::node_num_children() { + return TOP.num_children(); + } - return yaml_parse(file); + Status IoYamlTree::node_write_key(const std::string_view& key) { + assert(can_write()); + TOP << ryml::key(STR(key)); + return WG_OK; } - Status yaml_read(IoContext& context, YamlConstNodeRef node, bool& value) { - node >> value; + Status IoYamlTree::node_write_value(const bool& value) { + assert(can_write()); + TOP << value; return WG_OK; } - Status yaml_write(IoContext& context, YamlNodeRef node, const bool& value) { - node << value; + Status IoYamlTree::node_write_value(const int& value) { + assert(can_write()); + TOP << value; return WG_OK; } - - Status yaml_read(IoContext& context, YamlConstNodeRef node, int& value) { - node >> value; + Status IoYamlTree::node_write_value(const unsigned int& value) { + assert(can_write()); + TOP << value; return WG_OK; } - Status yaml_write(IoContext& context, YamlNodeRef node, const int& value) { - node << value; + Status IoYamlTree::node_write_value(const float& value) { + assert(can_write()); + TOP << value; return WG_OK; } - - Status yaml_read(IoContext& context, YamlConstNodeRef node, unsigned int& value) { - node >> value; + Status IoYamlTree::node_write_value(const std::string& value) { + assert(can_write()); + TOP << value; return WG_OK; } - Status yaml_write(IoContext& context, YamlNodeRef node, const unsigned int& value) { - node << value; + Status IoYamlTree::node_write_value(const Strid& value) { + assert(can_write()); + TOP << value.str(); return WG_OK; } - - Status yaml_read(IoContext& context, YamlConstNodeRef node, float& value) { - node >> value; + Status IoYamlTree::node_write_value(const std::int16_t& value) { + assert(can_write()); + TOP << value; return WG_OK; } - Status yaml_write(IoContext& context, YamlNodeRef node, const float& value) { - node << value; + Status IoYamlTree::node_write_value(const std::size_t& value) { + assert(can_write()); + TOP << value; return WG_OK; } - Status yaml_read(IoContext& context, YamlConstNodeRef node, Strid& value) { - std::string string; - node >> string; - value = SID(string); + Status IoYamlTree::node_read_value(bool& value) { + assert(can_read()); + TOP >> value; return WG_OK; } - Status yaml_write(IoContext& context, YamlNodeRef node, const Strid& value) { - node << value.str(); + Status IoYamlTree::node_read_value(int& value) { + assert(can_read()); + TOP >> value; return WG_OK; } - - Status yaml_read(IoContext& context, YamlConstNodeRef node, std::string& value) { - if (node.has_val()) { - node >> value; - } + Status IoYamlTree::node_read_value(unsigned int& value) { + assert(can_read()); + TOP >> value; return WG_OK; } - Status yaml_write(IoContext& context, YamlNodeRef node, const std::string& value) { - node << value; + Status IoYamlTree::node_read_value(float& value) { + assert(can_read()); + TOP >> value; return WG_OK; } - - Status yaml_read(IoContext& context, YamlConstNodeRef node, std::int16_t& value) { - node >> value; + Status IoYamlTree::node_read_value(std::string& value) { + assert(can_read()); + TOP >> value; return WG_OK; } - Status yaml_write(IoContext& context, YamlNodeRef node, const std::int16_t& value) { - node << value; + Status IoYamlTree::node_read_value(Strid& value) { + assert(can_read()); + std::string content; + TOP >> content; + value = Strid(content); return WG_OK; } - - Status yaml_read(IoContext& context, YamlConstNodeRef node, std::size_t& value) { - node >> value; + Status IoYamlTree::node_read_value(std::int16_t& value) { + assert(can_read()); + TOP >> value; return WG_OK; } - Status yaml_write(IoContext& context, YamlNodeRef node, const std::size_t& value) { - node << value; + Status IoYamlTree::node_read_value(std::size_t& value) { + assert(can_read()); + TOP >> value; return WG_OK; } - Status yaml_read(IoContext& context, YamlConstNodeRef node, Status& value) { - return yaml_read(context, node, value.code()); + void IoYamlTree::node_as_map() { + TOP |= ryml::MAP; } - Status yaml_write(IoContext& context, YamlNodeRef node, const Status& value) { - return yaml_write(context, node, value.code()); + void IoYamlTree::node_as_list(std::size_t) { + TOP |= ryml::SEQ; } }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/io/yaml.hpp b/engine/runtime/io/yaml.hpp index 1b660c73c..364ebc8a3 100644 --- a/engine/runtime/io/yaml.hpp +++ b/engine/runtime/io/yaml.hpp @@ -27,350 +27,72 @@ #pragma once +#include "core/array_view.hpp" #include "core/log.hpp" #include "core/ref.hpp" #include "core/status.hpp" #include "core/string_id.hpp" -#include "io/context.hpp" +#include "io/property_tree.hpp" -#include -#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include namespace wmoge { /** - * @brief Represents parsed tree of yaml document + * @class IoYamlTree + * @brief Yaml tree implementation for serialization and de-serialization */ - using YamlTree = ryml::Tree; - - /** - * @brief Reference to a node in yaml tree - */ - using YamlNodeRef = ryml::NodeRef; - - /** - * @brief Constant reference to a node in yaml tree - */ - using YamlConstNodeRef = ryml::ConstNodeRef; - - /** - * @brief Parse binary data into a tree - * - * @param data Data to parse, will not be modified - * - * @return Tree containing the data - */ - YamlTree yaml_parse(const std::vector& data); - - /** - * @brief Opens and parses file - * - * @param file_path Path to the file - * - * @return Parse tree or empty tree - */ - YamlTree yaml_parse_file(const std::string& file_path); - - Status yaml_read(IoContext& context, YamlConstNodeRef node, bool& value); - Status yaml_write(IoContext& context, YamlNodeRef node, const bool& value); - - Status yaml_read(IoContext& context, YamlConstNodeRef node, int& value); - Status yaml_write(IoContext& context, YamlNodeRef node, const int& value); - - Status yaml_read(IoContext& context, YamlConstNodeRef node, unsigned int& value); - Status yaml_write(IoContext& context, YamlNodeRef node, const unsigned int& value); - - Status yaml_read(IoContext& context, YamlConstNodeRef node, float& value); - Status yaml_write(IoContext& context, YamlNodeRef node, const float& value); - - Status yaml_read(IoContext& context, YamlConstNodeRef node, Strid& value); - Status yaml_write(IoContext& context, YamlNodeRef node, const Strid& value); - - Status yaml_read(IoContext& context, YamlConstNodeRef node, std::string& value); - Status yaml_write(IoContext& context, YamlNodeRef node, const std::string& value); - - Status yaml_read(IoContext& context, YamlConstNodeRef node, std::int16_t& value); - Status yaml_write(IoContext& context, YamlNodeRef node, const std::int16_t& value); - - Status yaml_read(IoContext& context, YamlConstNodeRef node, std::size_t& value); - Status yaml_write(IoContext& context, YamlNodeRef node, const std::size_t& value); - - Status yaml_read(IoContext& context, YamlConstNodeRef node, Status& value); - Status yaml_write(IoContext& context, YamlNodeRef node, const Status& value); - - template - Status yaml_read_tree(YamlTree& tree, T& value) { - IoContext context; - return yaml_read(context, tree.crootref(), value); - } - - template - Status yaml_read_file(const std::string& file_path, T& value) { - YamlTree tree = yaml_parse_file(file_path); - if (tree.empty()) { - return StatusCode::FailedParse; - } - return yaml_read_tree(tree, value); - } - -#define WG_YAML_READ(context, node, what) \ - do { \ - if (!yaml_read(context, node, what)) { \ - WG_LOG_ERROR("failed to read yaml \"" << #what << "\""); \ - return StatusCode::FailedRead; \ - } \ - } while (false) - -#define WG_YAML_READ_AS(context, node, node_name, what) \ - do { \ - if (!node.has_child(node_name) || !yaml_read(context, node[node_name], what)) { \ - WG_LOG_ERROR("failed to read yaml \"" << #what << "\""); \ - return StatusCode::FailedRead; \ - } \ - } while (false) - -#define WG_YAML_READ_AS_OPT(context, node, node_name, what) \ - do { \ - if (node.has_child(node_name)) { \ - if (!yaml_read(context, node[node_name], what)) { \ - WG_LOG_ERROR("failed to read yaml \"" << #what << "\""); \ - return StatusCode::FailedRead; \ - } \ - } \ - } while (false) - -#define WG_YAML_READ_SUPER(context, node, super, what) \ - do { \ - WG_YAML_READ(context, node, *((super*) (&what))); \ - } while (false) - -#define WG_YAML_WRITE(context, node, what) \ - do { \ - if (!yaml_write(context, node, what)) { \ - WG_LOG_ERROR("failed to write yaml \"" << #what << "\""); \ - return StatusCode::FailedWrite; \ - } \ - } while (false) - -#define WG_YAML_WRITE_AS(context, node, node_name, what) \ - do { \ - auto child = node.append_child(); \ - child << ryml::key(node_name); \ - if (!yaml_write(context, child, what)) { \ - WG_LOG_ERROR("failed to write yaml \"" << #what << "\""); \ - return StatusCode::FailedWrite; \ - } \ - } while (false) - -#define WG_YAML_WRITE_AS_OPT(node, node_name, condition, what) \ - do { \ - if (condition) { \ - auto child = node.append_child(); \ - child << ryml::key(node_name); \ - if (!yaml_write(context, child, what)) { \ - WG_LOG_ERROR("failed to write yaml \"" << #what << "\""); \ - return StatusCode::FailedWrite; \ - } \ - } \ - } while (false) - -#define WG_YAML_WRITE_SUPER(node, super, what) \ - do { \ - WG_YAML_WRITE(node, *((const super*) (&what))); \ - } while (false) - -#define WG_YAML_MAP(node) node |= ryml::MAP -#define WG_YAML_SEQ(node) node |= ryml::SEQ - - template - Status yaml_read(IoContext& context, YamlConstNodeRef node, std::pair& pair) { - WG_YAML_READ_AS(context, node, "key", pair.first); - WG_YAML_READ_AS(context, node, "value", pair.second); - return WG_OK; - } - template - Status yaml_write(IoContext& context, YamlNodeRef node, const std::pair& pair) { - WG_YAML_MAP(node); - - YamlNodeRef key = node.append_child(); - WG_YAML_WRITE_AS(context, key, "key", pair.first); - - YamlNodeRef value = node.append_child(); - WG_YAML_WRITE_AS(context, value, "value", pair.second); - - return WG_OK; - } - - template - Status yaml_read(IoContext& context, YamlConstNodeRef node, robin_hood::pair& pair) { - WG_YAML_READ_AS(context, node, "key", pair.first); - WG_YAML_READ_AS(context, node, "value", pair.second); - return WG_OK; - } - template - Status yaml_write(IoContext& context, YamlNodeRef node, const robin_hood::pair& pair) { - WG_YAML_MAP(node); - - YamlNodeRef key = node.append_child(); - WG_YAML_WRITE_AS(context, key, "key", pair.first); - - YamlNodeRef value = node.append_child(); - WG_YAML_WRITE_AS(context, value, "value", pair.second); - - return WG_OK; - } - - template - Status yaml_read(IoContext& context, YamlConstNodeRef node, std::array& array) { - std::size_t element_id = 0; - assert(node.num_children() <= S); - for (auto child = node.first_child(); child.valid() && element_id < S; child = child.next_sibling()) { - WG_YAML_READ(context, child, array[element_id++]); - } - return WG_OK; - } - template - Status yaml_write(IoContext& context, YamlNodeRef node, const std::array& array) { - WG_YAML_SEQ(node); - for (std::size_t i = 0; i < S; i++) { - YamlNodeRef child = node.append_child(); - WG_YAML_WRITE(context, child, array[i]); - } - return WG_OK; - } - - template - Status yaml_read(IoContext& context, YamlConstNodeRef node, std::vector& vector) { - assert(vector.empty()); - vector.resize(node.num_children()); - std::size_t element_id = 0; - for (auto child = node.first_child(); child.valid(); child = child.next_sibling()) { - WG_YAML_READ(context, child, vector[element_id]); - element_id += 1; - } - return WG_OK; - } - template - Status yaml_write(IoContext& context, YamlNodeRef node, const std::vector& vector) { - WG_YAML_SEQ(node); - for (const T& value : vector) { - YamlNodeRef child = node.append_child(); - WG_YAML_WRITE(context, child, value); - } - return WG_OK; - } - - template - Status yaml_read(IoContext& context, YamlConstNodeRef node, std::unordered_set& set) { - assert(set.empty()); - set.reserve(node.num_children()); - for (auto child = node.first_child(); child.valid(); child = child.next_sibling()) { - T entry; - WG_YAML_READ(context, child, entry); - set.insert(std::move(entry)); - } - return WG_OK; - } - template - Status yaml_write(IoContext& context, YamlNodeRef node, const std::unordered_set& set) { - WG_YAML_SEQ(node); - for (const T& value : set) { - YamlNodeRef child = node.append_child(); - WG_YAML_WRITE(context, child, value); - } - return WG_OK; - } - - template - Status yaml_read(IoContext& context, YamlConstNodeRef node, std::unordered_map& map) { - assert(map.empty()); - map.reserve(node.num_children()); - for (auto child = node.first_child(); child.valid(); child = child.next_sibling()) { - std::pair entry; - WG_YAML_READ(context, child, entry); - map.insert(std::move(entry)); - } - return WG_OK; - } - template - Status yaml_write(IoContext& context, YamlNodeRef node, const std::unordered_map& map) { - WG_YAML_SEQ(node); - for (const auto& entry : map) { - YamlNodeRef entry_child = node.append_child(); - WG_YAML_WRITE(context, entry_child, entry); - } - return WG_OK; - } - - template::value>::type> - Status yaml_read(IoContext& context, YamlConstNodeRef node, T& enum_value) { - std::string s; - WG_YAML_READ(context, node, s); - auto parsed = magic_enum::enum_cast(s); - if (!parsed.has_value()) { - return StatusCode::FailedRead; - } - enum_value = parsed.value(); - return WG_OK; - } - template::value>::type> - Status yaml_write(IoContext& context, YamlNodeRef node, const T& enum_value) { - node << std::string(magic_enum::enum_name(enum_value)); - return WG_OK; - } - - template - Status yaml_read(IoContext& context, YamlConstNodeRef node, std::optional& wrapper) { - if (!node.empty()) { - wrapper.emplace(); - WG_YAML_READ(context, node, wrapper.value()); - } - return WG_OK; - } - template - Status yaml_write(IoContext& context, YamlNodeRef node, const std::optional& wrapper) { - if (wrapper.has_value()) { - WG_YAML_WRITE(context, node, wrapper.value()); - } - return WG_OK; - } - - template - Status yaml_read(IoContext& context, YamlConstNodeRef node, std::bitset& bitset) { - std::array values; - WG_YAML_READ(context, node, values); - for (std::size_t i = 0; i < N; i++) { - if (values[i]) { - bitset.set(i); - } - } - return WG_OK; - } - template - Status yaml_write(IoContext& context, YamlNodeRef node, const std::bitset& bitset) { - std::array values; - values.fill(false); - for (std::size_t i = 0; i < N; i++) { - if (bitset.test(i)) { - values[i] = true; - } - } - WG_YAML_WRITE(context, node, values); - return WG_OK; - } + class IoYamlTree : public IoPropertyTree { + public: + IoYamlTree() = default; + ~IoYamlTree() = default; + + Status create_tree(); + Status parse_data(const array_view& data); + Status parse_file(const std::string& path); + + bool node_is_empty() override; + bool node_has_child(const std::string_view& name) override; + Status node_find_child(const std::string_view& name) override; + Status node_append_child() override; + void node_find_first_child() override; + bool node_is_valid() override; + void node_next_sibling() override; + void node_pop() override; + std::size_t node_num_children() override; + + Status node_write_key(const std::string_view& key) override; + + Status node_write_value(const bool& value) override; + Status node_write_value(const int& value) override; + Status node_write_value(const unsigned int& value) override; + Status node_write_value(const float& value) override; + Status node_write_value(const std::string& value) override; + Status node_write_value(const Strid& value) override; + Status node_write_value(const std::int16_t& value) override; + Status node_write_value(const std::size_t& value) override; + + Status node_read_value(bool& value) override; + Status node_read_value(int& value) override; + Status node_read_value(unsigned int& value) override; + Status node_read_value(float& value) override; + Status node_read_value(std::string& value) override; + Status node_read_value(Strid& value) override; + Status node_read_value(std::int16_t& value) override; + Status node_read_value(std::size_t& value) override; + + void node_as_map() override; + void node_as_list(std::size_t length) override; + + private: + using Tree = ryml::Tree; + using Node = ryml::NodeRef; + + Tree m_tree; + std::vector m_stack; + }; }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/math/aabb.hpp b/engine/runtime/math/aabb.hpp index 4c6d0a5a0..ca399bf57 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/yaml.hpp" #include "math/mat.hpp" #include "math/vec.hpp" @@ -120,16 +120,16 @@ namespace wmoge { } template - Status yaml_read(IoContext& context, YamlConstNodeRef node, TAabb& aabb) { - WG_YAML_READ_AS(context, node, "pos", aabb.pos); - WG_YAML_READ_AS(context, node, "size_half", aabb.size_half); + Status tree_read(IoContext& context, IoPropertyTree& 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 yaml_write(IoContext& context, YamlNodeRef node, const TAabb& aabb) { - WG_YAML_MAP(node); - WG_YAML_WRITE_AS(context, node, "pos", aabb.pos); - WG_YAML_WRITE_AS(context, node, "size_half", aabb.size_half); + Status tree_write(IoContext& context, IoPropertyTree& 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); return WG_OK; } template diff --git a/engine/runtime/math/quat.hpp b/engine/runtime/math/quat.hpp index a566c3545..d7dc1ff74 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/yaml.hpp" #include "math/mat.hpp" #include "math/vec.hpp" @@ -439,16 +439,16 @@ namespace wmoge { } template - Status yaml_read(IoContext& context, YamlConstNodeRef node, TQuat& quat) { - WG_YAML_READ_AS(context, node, "scalar", quat.scalar); - WG_YAML_READ_AS(context, node, "vec", quat.vec); + Status tree_read(IoContext& context, IoPropertyTree& 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 yaml_write(IoContext& context, YamlNodeRef node, const TQuat& quat) { - WG_YAML_MAP(node); - WG_YAML_WRITE_AS(context, node, "scalar", quat.scalar); - WG_YAML_WRITE_AS(context, node, "vec", quat.vec); + Status tree_write(IoContext& context, IoPropertyTree& 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); return WG_OK; } template diff --git a/engine/runtime/math/transform.hpp b/engine/runtime/math/transform.hpp index 3e67ca199..b600ea1a9 100644 --- a/engine/runtime/math/transform.hpp +++ b/engine/runtime/math/transform.hpp @@ -71,17 +71,17 @@ namespace wmoge { Math2d::translate(-m_translation); } - friend Status yaml_read(IoContext& context, YamlConstNodeRef node, Transform2d& transform) { - WG_YAML_READ_AS_OPT(context, node, "rotation", transform.m_rotation); - WG_YAML_READ_AS_OPT(context, node, "translation", transform.m_translation); - WG_YAML_READ_AS_OPT(context, node, "scale", transform.m_scale); + friend Status tree_read(IoContext& context, IoPropertyTree& 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 yaml_write(IoContext& context, YamlNodeRef node, const Transform2d& transform) { - WG_YAML_MAP(node); - WG_YAML_WRITE_AS(context, node, "rotation", transform.m_rotation); - WG_YAML_WRITE_AS(context, node, "translation", transform.m_translation); - WG_YAML_WRITE_AS(context, node, "scale", transform.m_scale); + friend Status tree_write(IoContext& context, IoPropertyTree& 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); + WG_TREE_WRITE_AS(context, tree, "scale", transform.m_scale); return WG_OK; } @@ -153,17 +153,17 @@ namespace wmoge { [[nodiscard]] const Vec3f& get_translation() const { return m_translation; } [[nodiscard]] const Vec3f& get_scale() const { return m_scale; } - friend Status yaml_read(IoContext& context, YamlConstNodeRef node, Transform3d& transform) { - WG_YAML_READ_AS_OPT(context, node, "rotation", transform.m_rotation); - WG_YAML_READ_AS_OPT(context, node, "translation", transform.m_translation); - WG_YAML_READ_AS_OPT(context, node, "scale", transform.m_scale); + friend Status tree_read(IoContext& context, IoPropertyTree& 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 yaml_write(IoContext& context, YamlNodeRef node, const Transform3d& transform) { - WG_YAML_MAP(node); - WG_YAML_WRITE_AS(context, node, "rotation", transform.m_rotation); - WG_YAML_WRITE_AS(context, node, "translation", transform.m_translation); - WG_YAML_WRITE_AS(context, node, "scale", transform.m_scale); + friend Status tree_write(IoContext& context, IoPropertyTree& 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); + WG_TREE_WRITE_AS(context, tree, "scale", transform.m_scale); return WG_OK; } @@ -224,12 +224,12 @@ namespace wmoge { [[nodiscard]] const Vec3f& get_translation() const { return m_translation; } [[nodiscard]] const Vec3f& get_scale() const { return m_scale; } - friend Status yaml_read(IoContext& context, YamlConstNodeRef node, TransformEdt& transform) { + friend Status tree_read(IoContext& context, IoPropertyTree& tree, TransformEdt& transform) { Vec3f rotation_deg; - WG_YAML_READ_AS_OPT(context, node, "rotation", rotation_deg); - WG_YAML_READ_AS_OPT(context, node, "translation", transform.m_translation); - WG_YAML_READ_AS_OPT(context, node, "scale", transform.m_scale); + WG_TREE_READ_AS_OPT(context, tree, "rotation", rotation_deg); + WG_TREE_READ_AS_OPT(context, tree, "translation", transform.m_translation); + WG_TREE_READ_AS_OPT(context, tree, "scale", transform.m_scale); transform.m_rotation.values[0] = Math::deg_to_rad(rotation_deg[0]); transform.m_rotation.values[1] = Math::deg_to_rad(rotation_deg[1]); @@ -237,17 +237,17 @@ namespace wmoge { return WG_OK; } - friend Status yaml_write(IoContext& context, YamlNodeRef node, const TransformEdt& transform) { + friend Status tree_write(IoContext& context, IoPropertyTree& tree, const TransformEdt& transform) { Vec3f rotation_deg; rotation_deg[0] = Math::rad_to_deg(transform.m_rotation.values[0]); rotation_deg[1] = Math::rad_to_deg(transform.m_rotation.values[1]); rotation_deg[2] = Math::rad_to_deg(transform.m_rotation.values[2]); - WG_YAML_MAP(node); - WG_YAML_WRITE_AS(context, node, "rotation", rotation_deg); - WG_YAML_WRITE_AS(context, node, "translation", transform.m_translation); - WG_YAML_WRITE_AS(context, node, "scale", transform.m_scale); + WG_TREE_MAP(tree); + WG_TREE_WRITE_AS(context, tree, "rotation", rotation_deg); + WG_TREE_WRITE_AS(context, tree, "translation", transform.m_translation); + WG_TREE_WRITE_AS(context, tree, "scale", transform.m_scale); return WG_OK; } diff --git a/engine/runtime/math/vec.hpp b/engine/runtime/math/vec.hpp index 1e6b03d30..b3d518070 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/yaml.hpp" #include "math_utils.hpp" #include @@ -653,9 +653,9 @@ namespace wmoge { } template - Status yaml_read(IoContext& context, YamlConstNodeRef node, TVecN& v) { + Status tree_read(IoContext& context, IoPropertyTree& tree, TVecN& v) { std::string str; - WG_YAML_READ(context, node, str); + WG_TREE_READ(context, tree, str); std::stringstream stream(str); @@ -667,7 +667,7 @@ namespace wmoge { } template - Status yaml_write(IoContext& context, YamlNodeRef node, const TVecN& v) { + Status tree_write(IoContext& context, IoPropertyTree& tree, const TVecN& v) { std::stringstream stream; for (int i = 0; i < N; i++) { @@ -675,7 +675,7 @@ namespace wmoge { if (i + 1 < N) stream << " "; } - return yaml_write(context, node, stream.str()); + return tree_write(context, tree, stream.str()); } template diff --git a/engine/runtime/pfx/pfx_component.cpp b/engine/runtime/pfx/pfx_component.cpp index 6f995c313..d6dcbce1c 100644 --- a/engine/runtime/pfx/pfx_component.cpp +++ b/engine/runtime/pfx/pfx_component.cpp @@ -34,40 +34,6 @@ namespace wmoge { - bool PfxComponent::load_from_options(const YamlConstNodeRef& node) { - node["amount"] >> m_amount; - node["active"] >> m_active; - - if (node.has_child("name")) { - // m_name = Yaml::read_sid(node["name"]); - } - - for (auto it = node["features"].first_child(); it.valid(); it = it.next_sibling()) { - Strid feature_name;// = Yaml::read_sid(it["feature"]); - Class* feature_class = Class::class_ptr(feature_name); - - if (!feature_class) { - WG_LOG_ERROR("no registered class for feature " << feature_name); - return false; - } - - Ref feature = feature_class->instantiate().cast(); - - if (!feature) { - WG_LOG_ERROR("failed to instantiate feature from cls " << feature_class->name()); - return false; - } - - if (!feature->load_from_options(it)) { - WG_LOG_ERROR("failed to load feature " << feature_name); - return false; - } - - add_feature(std::move(feature)); - } - - return true; - } void PfxComponent::add_feature(Ref feature) { assert(feature); m_features.push_back(feature); diff --git a/engine/runtime/pfx/pfx_component.hpp b/engine/runtime/pfx/pfx_component.hpp index 3738a66e1..bd44d7d39 100644 --- a/engine/runtime/pfx/pfx_component.hpp +++ b/engine/runtime/pfx/pfx_component.hpp @@ -56,7 +56,6 @@ namespace wmoge { public: ~PfxComponent() override = default; - bool load_from_options(const YamlConstNodeRef& node); void add_feature(Ref feature); void set_amount(int amount); void set_active(bool active); diff --git a/engine/runtime/pfx/pfx_feature.hpp b/engine/runtime/pfx/pfx_feature.hpp index 0db606e1f..0913237b9 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/yaml.hpp" +#include "io/property_tree.hpp" #include "pfx/pfx_storage.hpp" namespace wmoge { @@ -58,8 +58,6 @@ namespace wmoge { virtual Strid get_feature_name() const { return Strid(); }; virtual Strid get_feature_family() const { return Strid(); }; - virtual bool load_from_options(const YamlConstNodeRef& node) { return true; }; - virtual void on_added(PfxAttributes& attributes) {} virtual void on_spawn(class PfxComponentRuntime& runtime, const struct PfxSpawnParams& params) {} virtual void on_update(class PfxComponentRuntime& runtime, float dt) {} diff --git a/engine/runtime/platform/common/mount_volume_physical.cpp b/engine/runtime/platform/common/mount_volume_physical.cpp index a5a2a6297..171c24697 100644 --- a/engine/runtime/platform/common/mount_volume_physical.cpp +++ b/engine/runtime/platform/common/mount_volume_physical.cpp @@ -43,7 +43,7 @@ namespace wmoge { std::string MountVolumePhysical::resolve_physical(const std::string& path) { auto prefix = path.find(m_mapping); if (prefix != 0) { - return false; + return ""; } const std::filesystem::path remapped = m_path / path.substr(m_mapping.length()); diff --git a/engine/runtime/render/graphics_pipeline.cpp b/engine/runtime/render/graphics_pipeline.cpp index 350cfccbc..44b1789b7 100644 --- a/engine/runtime/render/graphics_pipeline.cpp +++ b/engine/runtime/render/graphics_pipeline.cpp @@ -33,43 +33,6 @@ namespace wmoge { - WG_IO_BEGIN(BloomSettings) - WG_IO_PROFILE() - WG_IO_FIELD_OPT(enable) - WG_IO_FIELD_OPT(intensity) - WG_IO_FIELD_OPT(threshold) - WG_IO_FIELD_OPT(knee) - WG_IO_FIELD_OPT(radius) - WG_IO_FIELD_OPT(uspample_weight) - WG_IO_FIELD_OPT(dirt_mask_intensity) - WG_IO_FIELD_OPT(dirt_mask) - WG_IO_END(BloomSettings) - - WG_IO_BEGIN(AutoExposureSettings) - WG_IO_PROFILE() - WG_IO_FIELD_OPT(enable) - WG_IO_FIELD_OPT(mode) - WG_IO_FIELD_OPT(histogram_log_min) - WG_IO_FIELD_OPT(histogram_log_max) - WG_IO_FIELD_OPT(speed_up) - WG_IO_FIELD_OPT(speed_down) - WG_IO_FIELD_OPT(exposure_compensation) - WG_IO_END(AutoExposureSettings) - - WG_IO_BEGIN(TonemapSettings) - WG_IO_PROFILE() - WG_IO_FIELD_OPT(mode) - WG_IO_FIELD_OPT(exposure) - WG_IO_FIELD_OPT(white_point) - WG_IO_END(TonemapSettings) - - WG_IO_BEGIN(GraphicsPipelineSettings) - WG_IO_PROFILE() - WG_IO_FIELD_OPT(bloom) - WG_IO_FIELD_OPT(auto_exposure) - WG_IO_FIELD_OPT(tonemap) - WG_IO_END(GraphicsPipelineSettings) - void GraphicsPipeline::set_scene(RenderScene* scene) { m_scene = scene; } diff --git a/engine/runtime/render/graphics_pipeline.hpp b/engine/runtime/render/graphics_pipeline.hpp index b8313a7fd..52b8a30b2 100644 --- a/engine/runtime/render/graphics_pipeline.hpp +++ b/engine/runtime/render/graphics_pipeline.hpp @@ -34,7 +34,6 @@ #include "gfx/gfx_driver.hpp" #include "gfx/gfx_texture.hpp" #include "grc/texture.hpp" -#include "io/serialization.hpp" #include "math/mat.hpp" #include "math/vec.hpp" #include "render/camera.hpp" @@ -50,17 +49,14 @@ namespace wmoge { * @brief Bloom effect settings */ struct BloomSettings { - bool enable = true; - float intensity = 1.0f; - float threshold = 1.0f; - float knee = 0.5f; - float radius = 4.0f; - float uspample_weight = 0.4f; - float dirt_mask_intensity = 3.0f; - + bool enable = true; + float intensity = 1.0f; + float threshold = 1.0f; + float knee = 0.5f; + float radius = 4.0f; + float uspample_weight = 0.4f; + float dirt_mask_intensity = 3.0f; std::optional> dirt_mask; - - WG_IO_DECLARE(BloomSettings); }; /** @@ -68,7 +64,6 @@ namespace wmoge { * @brief Automatic exposition or eye adaptation settings */ struct AutoExposureSettings { - /** @brief Mode to select algo */ enum class Mode { Adaptive = 0, @@ -82,8 +77,6 @@ namespace wmoge { float speed_up = 4.0f; float speed_down = 0.5f; float exposure_compensation = 1.0f; - - WG_IO_DECLARE(AutoExposureSettings); }; /** @@ -91,7 +84,6 @@ namespace wmoge { * @brief Final HDR image tonemapping settings for composition */ struct TonemapSettings { - /** @brief Mode to select algo */ enum class Mode { Exponential = 0, @@ -104,8 +96,6 @@ namespace wmoge { Mode mode = Mode::Exponential; float exposure = 1.0f; float white_point = 1.0f; - - WG_IO_DECLARE(TonemapSettings); }; /** @@ -116,8 +106,6 @@ namespace wmoge { BloomSettings bloom; AutoExposureSettings auto_exposure; TonemapSettings tonemap; - - WG_IO_DECLARE(GraphicsPipelineSettings); }; /** diff --git a/engine/runtime/render/model.cpp b/engine/runtime/render/model.cpp index 59ab43a2a..4c285cbe6 100644 --- a/engine/runtime/render/model.cpp +++ b/engine/runtime/render/model.cpp @@ -31,32 +31,6 @@ namespace wmoge { - WG_IO_BEGIN(ModelObj) - WG_IO_FIELD(material) - WG_IO_FIELD(mesh_idx) - WG_IO_FIELD(chunk_idx) - WG_IO_FIELD_OPT(flags) - WG_IO_FIELD_OPT(name) - WG_IO_END(ModelObj) - - WG_IO_BEGIN(ModelLod) - WG_IO_FIELD_OPT(ranges) - WG_IO_END(ModelLod) - - WG_IO_BEGIN(ModelLodSettings) - WG_IO_FIELD_OPT(area) - WG_IO_FIELD(minimum_lod) - WG_IO_FIELD(num_of_lods) - WG_IO_END(ModelLodSettings) - - WG_IO_BEGIN(ModelFile) - WG_IO_FIELD(objs) - WG_IO_FIELD(meshes) - WG_IO_FIELD_OPT(lod) - WG_IO_FIELD_OPT(lod_settings) - WG_IO_FIELD_OPT(aabb) - WG_IO_END(ModelFile) - void Model::update_aabb() { m_aabb = Aabbf(); diff --git a/engine/runtime/render/model.hpp b/engine/runtime/render/model.hpp index d0b13d3e2..7f82f1edc 100644 --- a/engine/runtime/render/model.hpp +++ b/engine/runtime/render/model.hpp @@ -59,8 +59,6 @@ namespace wmoge { std::int16_t chunk_idx = 0; ModelObjFlags flags; Strid name; - - WG_IO_DECLARE(ModelObj); }; /** @@ -69,8 +67,6 @@ namespace wmoge { */ struct ModelLod { buffered_vector ranges; - - WG_IO_DECLARE(ModelLod); }; /** @@ -81,8 +77,6 @@ namespace wmoge { buffered_vector area; std::optional minimum_lod; std::optional num_of_lods; - - WG_IO_DECLARE(ModelLodSettings); }; /** @@ -95,8 +89,6 @@ namespace wmoge { ModelLod lod; ModelLodSettings lod_settings; Aabbf aabb; - - WG_IO_DECLARE(ModelFile); }; /** diff --git a/engine/runtime/rtti/object.cpp b/engine/runtime/rtti/object.cpp index a1c07330c..207255f43 100644 --- a/engine/runtime/rtti/object.cpp +++ b/engine/runtime/rtti/object.cpp @@ -42,11 +42,11 @@ namespace wmoge { object = rtti_class->instantiate(); return rtti_class->copy(object.get(), this); } - Status RttiObject::read_from_yaml(IoContext& context, YamlConstNodeRef node) { - return get_class()->read_from_yaml(this, node, context); + Status RttiObject::read_from_tree(IoContext& context, IoPropertyTree& tree) { + return get_class()->read_from_tree(this, tree, context); } - Status RttiObject::write_to_yaml(IoContext& context, YamlNodeRef node) const { - return get_class()->write_to_yaml(this, node, context); + Status RttiObject::write_to_tree(IoContext& context, IoPropertyTree& tree) const { + return get_class()->write_to_tree(this, tree, context); } Status RttiObject::read_from_stream(IoContext& context, IoStream& stream) { return get_class()->read_from_stream(this, stream, context); @@ -88,15 +88,15 @@ namespace wmoge { static RttiClass* g_class = nullptr; return g_class; } - Status RttiObject::yaml_read_object(IoContext& context, YamlConstNodeRef node, Ref& object) { + Status RttiObject::tree_read_object(IoContext& context, IoPropertyTree& tree, Ref& object) { assert(!object); - if (node.empty()) { + if (tree.node_is_empty()) { return WG_OK; } Strid rtti_name; - WG_YAML_READ_AS(context, node, "rtti", rtti_name); + WG_TREE_READ_AS(context, tree, "rtti", rtti_name); RttiClass* rtti_class = context.get_type_storage()->find_class(rtti_name); if (!rtti_class) { @@ -110,15 +110,15 @@ namespace wmoge { return StatusCode::FailedInstantiate; } - return object->read_from_yaml(context, node); + return object->read_from_tree(context, tree); } - Status RttiObject::yaml_write_object(IoContext& context, YamlNodeRef node, const Ref& object) { + Status RttiObject::tree_write_object(IoContext& context, IoPropertyTree& tree, const Ref& object) { if (!object) { return WG_OK; } - WG_YAML_MAP(node); - WG_YAML_WRITE_AS(context, node, "rtti", object->get_class_name()); - return object->write_to_yaml(context, node); + WG_TREE_MAP(tree); + WG_TREE_WRITE_AS(context, tree, "rtti", object->get_class_name()); + return object->write_to_tree(context, tree); } Status RttiObject::archive_read_object(IoContext& context, IoStream& stream, Ref& object) { assert(!object); diff --git a/engine/runtime/rtti/object.hpp b/engine/runtime/rtti/object.hpp index f3e15d514..f82ff8aa2 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_yaml(IoContext& context, YamlConstNodeRef node); - virtual Status write_to_yaml(IoContext& context, YamlNodeRef node) const; + virtual Status read_from_tree(IoContext& context, IoPropertyTree& tree); + virtual Status write_to_tree(IoContext& context, IoPropertyTree& 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 yaml_read_object(IoContext& context, YamlConstNodeRef node, Ref& object); - static Status yaml_write_object(IoContext& context, YamlNodeRef node, const Ref& object); + 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 archive_read_object(IoContext& context, IoStream& stream, Ref& object); static Status archive_write_object(IoContext& context, IoStream& stream, const Ref& object); }; @@ -99,17 +99,17 @@ namespace wmoge { } template - Status yaml_read(IoContext& context, YamlConstNodeRef node, Ref& ref, typename std::enable_if_t>* = 0) { + Status tree_read(IoContext& context, IoPropertyTree& tree, Ref& ref, typename std::enable_if_t>* = 0) { Ref object; - WG_CHECKED(RttiObject::yaml_read_object(context, node, object)); + WG_CHECKED(RttiObject::tree_read_object(context, tree, object)); ref = object.template cast(); return WG_OK; } template - Status yaml_write(IoContext& context, YamlNodeRef node, const Ref& ref, typename std::enable_if_t>* = 0) { + Status tree_write(IoContext& context, IoPropertyTree& tree, const Ref& ref, typename std::enable_if_t>* = 0) { Ref object = ref.template as(); - WG_CHECKED(RttiObject::yaml_write_object(context, node, object)); + 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 e53489fdd..ac00b408e 100644 --- a/engine/runtime/rtti/struct.cpp +++ b/engine/runtime/rtti/struct.cpp @@ -104,8 +104,8 @@ namespace wmoge { return WG_OK; } - Status RttiStruct::read_from_yaml(void* dst, YamlConstNodeRef node, IoContext& context) const { - WG_AUTO_PROFILE_RTTI("RttiStruct::read_from_yaml"); + Status RttiStruct::read_from_tree(void* dst, IoPropertyTree& tree, IoContext& context) const { + WG_AUTO_PROFILE_RTTI("RttiStruct::read_from_tree"); assert(dst); std::uint8_t* self = reinterpret_cast(dst); for (const RttiField& field : get_fields()) { @@ -113,42 +113,43 @@ namespace wmoge { continue; } - const std::string& field_name = field.get_name().str(); - const ryml::csubstr field_name_str(field_name.data(), field_name.length()); + const std::string& field_name = field.get_name().str(); if (field.get_meta_data().is_optional()) { - if (node.has_child(field_name_str)) { - WG_CHECKED(field.get_type()->read_from_yaml(self + field.get_byte_offset(), node[field_name_str], context)); + if (tree.node_has_child(field_name)) { + WG_CHECKED(tree.node_find_child(field_name)); + WG_CHECKED(field.get_type()->read_from_tree(self + field.get_byte_offset(), tree, context)); + tree.node_pop(); } } else { - if (!node.has_child(field_name_str)) { + if (!tree.node_find_child(field_name)) { WG_LOG_ERROR("failed to read yaml " << field_name); return StatusCode::FailedRead; } - WG_CHECKED(field.get_type()->read_from_yaml(self + field.get_byte_offset(), node[field_name_str], context)); + WG_CHECKED(field.get_type()->read_from_tree(self + field.get_byte_offset(), tree, context)); + tree.node_pop(); } } return WG_OK; } - Status RttiStruct::write_to_yaml(const void* src, YamlNodeRef node, IoContext& context) const { - WG_AUTO_PROFILE_RTTI("RttiStruct::write_to_yaml"); + Status RttiStruct::write_to_tree(const void* src, IoPropertyTree& tree, IoContext& context) const { + WG_AUTO_PROFILE_RTTI("RttiStruct::write_to_tree"); assert(src); - WG_YAML_MAP(node); + WG_TREE_MAP(tree); const std::uint8_t* self = reinterpret_cast(src); for (const RttiField& field : get_fields()) { if (field.get_meta_data().is_no_save_load()) { continue; } - const std::string& field_name = field.get_name().str(); - const ryml::csubstr field_name_str(field_name.data(), field_name.length()); + const std::string& field_name = field.get_name().str(); - YamlNodeRef child = node.append_child(); - child << ryml::key(field_name_str); - - WG_CHECKED(field.get_type()->write_to_yaml(self + field.get_byte_offset(), child, context)); + WG_CHECKED(tree.node_append_child()); + WG_CHECKED(tree.node_write_key(field_name)); + WG_CHECKED(field.get_type()->write_to_tree(self + field.get_byte_offset(), tree, context)); + tree.node_pop(); } return WG_OK; } diff --git a/engine/runtime/rtti/struct.hpp b/engine/runtime/rtti/struct.hpp index 7c7bac0cf..fd67d634d 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_yaml(void* dst, YamlConstNodeRef node, IoContext& context) const override; - Status write_to_yaml(const void* src, YamlNodeRef node, IoContext& context) 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_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 9925db81b..7dd1d776d 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/yaml.hpp" #include "math/aabb.hpp" #include "math/mat.hpp" #include "math/quat.hpp" @@ -102,11 +102,11 @@ namespace wmoge { ((T*) dst)->~T(); return WG_OK; } - Status read_from_yaml(void* dst, YamlConstNodeRef node, IoContext& context) const override { - return yaml_read(context, node, *((T*) dst)); + Status read_from_tree(void* dst, IoPropertyTree& tree, IoContext& context) const override { + return tree_read(context, tree, *((T*) dst)); } - Status write_to_yaml(const void* src, YamlNodeRef node, IoContext& context) const override { - return yaml_write(context, node, *((const T*) src)); + Status write_to_tree(const void* src, IoPropertyTree& 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 { return stream_read(context, stream, *((T*) dst)); @@ -806,11 +806,11 @@ public: rtti_type* get_parent_class() const modifier { \ return get_parent_class_static(); \ } \ - friend Status yaml_read(IoContext& context, YamlConstNodeRef node, struct_type& value) { \ - return get_class_static()->read_from_yaml(&value, node, context); \ + friend Status tree_read(IoContext& context, IoPropertyTree& tree, struct_type& value) { \ + return get_class_static()->read_from_tree(&value, tree, context); \ } \ - friend Status yaml_write(IoContext& context, YamlNodeRef node, const struct_type& value) { \ - return get_class_static()->write_to_yaml(&value, node, context); \ + friend Status tree_write(IoContext& context, IoPropertyTree& 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) { \ return get_class_static()->read_from_stream(&value, stream, context); \ diff --git a/engine/runtime/rtti/type.hpp b/engine/runtime/rtti/type.hpp index f55d2ec1a..917df99ed 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/yaml.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_yaml(void* dst, YamlConstNodeRef node, IoContext& context) const { return StatusCode::NotImplemented; } - virtual Status write_to_yaml(const void* src, YamlNodeRef node, IoContext& context) 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_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_data.cpp b/engine/runtime/scene/scene_data.cpp index 1f301ee15..960213446 100644 --- a/engine/runtime/scene/scene_data.cpp +++ b/engine/runtime/scene/scene_data.cpp @@ -31,28 +31,6 @@ namespace wmoge { - WG_IO_BEGIN(SceneDataSpatial) - WG_IO_END(SceneDataSpatial) - - WG_IO_BEGIN(SceneDataCamera) - WG_IO_FIELD_OPT(name) - WG_IO_FIELD_OPT(color) - WG_IO_FIELD_OPT(fov) - WG_IO_FIELD_OPT(near) - WG_IO_FIELD_OPT(far) - WG_IO_FIELD_OPT(projection) - WG_IO_END(SceneDataCamera) - - WG_IO_BEGIN(SceneData) - WG_IO_PROFILE() - WG_IO_FIELD(name) - WG_IO_FIELD(entities) - WG_IO_FIELD(names) - WG_IO_FIELD(hier) - WG_IO_FIELD(cameras) - WG_IO_FIELD(pipeline) - WG_IO_END(SceneData) - void SceneDataCamera::fill(EcsComponentCamera& component) const { Camera& camera = component.camera; camera.set_fov(fov); diff --git a/engine/runtime/scene/scene_data.hpp b/engine/runtime/scene/scene_data.hpp index 4affa6a22..58ad1a7f6 100644 --- a/engine/runtime/scene/scene_data.hpp +++ b/engine/runtime/scene/scene_data.hpp @@ -57,8 +57,6 @@ namespace wmoge { struct SceneDataSpatial { Transform3d transform; std::optional parent; - - WG_IO_DECLARE(SceneDataSpatial); }; /** @@ -74,8 +72,6 @@ namespace wmoge { CameraProjection projection = CameraProjection::Perspective; void fill(EcsComponentCamera& component) const; - - WG_IO_DECLARE(SceneDataCamera); }; /** @brief Index used to reference entities in this struct */ @@ -96,8 +92,6 @@ namespace wmoge { SceneEntityVector hier; SceneEntityVector cameras; GraphicsPipelineSettings pipeline; - - WG_IO_DECLARE(SceneData); }; }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/scene/scene_packed.hpp b/engine/runtime/scene/scene_packed.hpp index a6410462e..dea9fdaa7 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/yaml.hpp" +#include "io/property_tree.hpp" #include "scene/scene.hpp" #include diff --git a/engine/runtime/scene/scene_prefab.hpp b/engine/runtime/scene/scene_prefab.hpp index 6f2bfd740..fa4843264 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/yaml.hpp" +#include "io/property_tree.hpp" #include