diff --git a/headers/enduro2d/high/resources/prefab.hpp b/headers/enduro2d/high/resources/prefab.hpp index 336290f8..8e5b3f8e 100644 --- a/headers/enduro2d/high/resources/prefab.hpp +++ b/headers/enduro2d/high/resources/prefab.hpp @@ -27,22 +27,30 @@ namespace e2d prefab& assign(prefab&& other) noexcept; prefab& assign(const prefab& other); - prefab& set_prototype(ecs::prototype&& proto) noexcept; - prefab& set_prototype(const ecs::prototype& proto); + prefab& set_uuid(str&& uuid) noexcept; + prefab& set_uuid(const str& uuid); prefab& set_children(vector&& children) noexcept; prefab& set_children(const vector& children); + prefab& set_prototype(ecs::prototype&& prototype) noexcept; + prefab& set_prototype(const ecs::prototype& prototype); + + str& uuid() noexcept; + const str& uuid() const noexcept; + + vector& children() noexcept; + const vector& children() const noexcept; + ecs::prototype& prototype() noexcept; const ecs::prototype& prototype() const noexcept; - - const vector& children() const noexcept; private: - ecs::prototype prototype_; + str uuid_; vector children_; + ecs::prototype prototype_; }; void swap(prefab& l, prefab& r) noexcept; - bool operator==(const prefab& l, const prefab& r) noexcept; - bool operator!=(const prefab& l, const prefab& r) noexcept; + bool operator==(const prefab& l, const prefab& r) = delete; + bool operator!=(const prefab& l, const prefab& r) = delete; } diff --git a/sources/enduro2d/high/assets/prefab_asset.cpp b/sources/enduro2d/high/assets/prefab_asset.cpp index a1af71a7..7028c4b3 100644 --- a/sources/enduro2d/high/assets/prefab_asset.cpp +++ b/sources/enduro2d/high/assets/prefab_asset.cpp @@ -24,12 +24,10 @@ namespace "required" : [], "additionalProperties" : false, "properties" : { - "prototype" : { "$ref": "#/common_definitions/address" }, - "components" : { "type" : "object" }, - "children" : { - "type" : "array", - "items" : { "$ref": "#/definitions/child" } - } + "uuid" : { "$ref": "#/common_definitions/uuid" }, + "parent" : { "$ref": "#/common_definitions/address" }, + "children" : { "$ref": "#/definitions/children" }, + "components" : { "type" : "object" } }, "definitions" : { "child" : { @@ -37,13 +35,15 @@ namespace "required" : [], "additionalProperties" : false, "properties" : { - "prototype" : { "$ref": "#/common_definitions/address" }, - "components" : { "type" : "object" }, - "children" : { - "type" : "array", - "items" : { "$ref": "#/definitions/child" } - } + "uuid" : { "$ref": "#/common_definitions/uuid" }, + "parent" : { "$ref": "#/common_definitions/address" }, + "children" : { "$ref": "#/definitions/children" }, + "components" : { "type" : "object" } } + }, + "children" : { + "type" : "array", + "items" : { "$ref": "#/definitions/child" } } } })json"; @@ -71,9 +71,16 @@ namespace const rapidjson::Value& root, asset_dependencies& dependencies) { - if ( root.HasMember("prototype") ) { + if ( root.HasMember("parent") ) { dependencies.add_dependency( - path::combine(parent_address, root["prototype"].GetString())); + path::combine(parent_address, root["parent"].GetString())); + } + + if ( root.HasMember("children") ) { + const rapidjson::Value& children_root = root["children"]; + for ( rapidjson::SizeType i = 0; i < children_root.Size(); ++i ) { + collect_dependencies(parent_address, children_root[i], dependencies); + } } if ( root.HasMember("components") ) { @@ -83,7 +90,7 @@ namespace ++component_root ) { { - bool success = the().validate_json( + const bool success = the().validate_json( component_root->name.GetString(), component_root->value); if ( !success ) { @@ -94,7 +101,7 @@ namespace factory_loader<>::collect_context ctx( str(parent_address), component_root->value); - bool success = the().collect_dependencies( + const bool success = the().collect_dependencies( component_root->name.GetString(), dependencies, ctx); @@ -104,13 +111,6 @@ namespace } } } - - if ( root.HasMember("children") ) { - const rapidjson::Value& children_root = root["children"]; - for ( rapidjson::SizeType i = 0; i < children_root.Size(); ++i ) { - collect_dependencies(parent_address, children_root[i], dependencies); - } - } } stdex::promise collect_dependencies( @@ -130,38 +130,28 @@ namespace { prefab content; - if ( root.HasMember("prototype") ) { + if ( root.HasMember("uuid") ) { + str uuid = content.uuid(); + if ( !json_utils::try_parse_value(root["uuid"], uuid) ) { + the().error("PREFAB: Incorrect formatting of 'uuid' property"); + throw prefab_asset_loading_exception(); + } + content.set_uuid(std::move(uuid)); + } + + if ( root.HasMember("parent") ) { auto proto_res = dependencies.find_asset( - path::combine(parent_address, root["prototype"].GetString())); + path::combine(parent_address, root["parent"].GetString())); if ( !proto_res ) { - the().error("PREFAB: Dependency 'prototype' is not found:\n" + the().error("PREFAB: Dependency 'parent' is not found:\n" "--> Parent address: %0\n" "--> Dependency address: %1", parent_address, - root["prototype"].GetString()); + root["parent"].GetString()); throw prefab_asset_loading_exception(); } - content = proto_res->content(); - } - - if ( root.HasMember("components") ) { - const rapidjson::Value& components_root = root["components"]; - for ( rapidjson::Value::ConstMemberIterator component_root = components_root.MemberBegin(); - component_root != components_root.MemberEnd(); - ++component_root ) - { - factory_loader<>::fill_context ctx( - str(parent_address), - component_root->value, - dependencies); - bool success = the().fill_prototype( - component_root->name.GetString(), - content.prototype(), - ctx); - if ( !success ) { - throw prefab_asset_loading_exception(); - } - } + content.set_children(proto_res->content().children()); + content.set_prototype(proto_res->content().prototype()); } if ( root.HasMember("children") ) { @@ -178,6 +168,26 @@ namespace content.set_children(std::move(children)); } + if ( root.HasMember("components") ) { + const rapidjson::Value& components_root = root["components"]; + for ( rapidjson::Value::ConstMemberIterator component_root = components_root.MemberBegin(); + component_root != components_root.MemberEnd(); + ++component_root ) + { + factory_loader<>::fill_context ctx( + str(parent_address), + component_root->value, + dependencies); + const bool success = the().fill_prototype( + component_root->name.GetString(), + content.prototype(), + ctx); + if ( !success ) { + throw prefab_asset_loading_exception(); + } + } + } + return content; } } diff --git a/sources/enduro2d/high/resources/prefab.cpp b/sources/enduro2d/high/resources/prefab.cpp index 9589dae9..d17e097b 100644 --- a/sources/enduro2d/high/resources/prefab.cpp +++ b/sources/enduro2d/high/resources/prefab.cpp @@ -25,14 +25,16 @@ namespace e2d } void prefab::clear() noexcept { - prototype_.clear(); + uuid_.clear(); children_.clear(); + prototype_.clear(); } void prefab::swap(prefab& other) noexcept { using std::swap; - swap(prototype_, other.prototype_); + swap(uuid_, other.uuid_); swap(children_, other.children_); + swap(prototype_, other.prototype_); } prefab& prefab::assign(prefab&& other) noexcept { @@ -46,20 +48,21 @@ namespace e2d prefab& prefab::assign(const prefab& other) { if ( this != &other ) { prefab s; - s.prototype_ = other.prototype_; + s.uuid_ = other.uuid_; s.children_ = other.children_; + s.prototype_ = other.prototype_; swap(s); } return *this; } - prefab& prefab::set_prototype(ecs::prototype&& proto) noexcept { - prototype_ = std::move(proto); + prefab& prefab::set_uuid(str&& uuid) noexcept { + uuid_ = std::move(uuid); return *this; } - prefab& prefab::set_prototype(const ecs::prototype& proto) { - prototype_ = proto; + prefab& prefab::set_uuid(const str& uuid) { + uuid_ = uuid; return *this; } @@ -73,6 +76,32 @@ namespace e2d return *this; } + prefab& prefab::set_prototype(ecs::prototype&& prototype) noexcept { + prototype_ = std::move(prototype); + return *this; + } + + prefab& prefab::set_prototype(const ecs::prototype& prototype) { + prototype_ = prototype; + return *this; + } + + str& prefab::uuid() noexcept { + return uuid_; + } + + const str& prefab::uuid() const noexcept { + return uuid_; + } + + vector& prefab::children() noexcept { + return children_; + } + + const vector& prefab::children() const noexcept { + return children_; + } + ecs::prototype& prefab::prototype() noexcept { return prototype_; } @@ -80,10 +109,6 @@ namespace e2d const ecs::prototype& prefab::prototype() const noexcept { return prototype_; } - - const vector& prefab::children() const noexcept { - return children_; - } } namespace e2d @@ -91,13 +116,4 @@ namespace e2d void swap(prefab& l, prefab& r) noexcept { l.swap(r); } - - bool operator==(const prefab& l, const prefab& r) noexcept { - return l.prototype().empty() && l.children().empty() - && r.prototype().empty() && r.children().empty(); - } - - bool operator!=(const prefab& l, const prefab& r) noexcept { - return !(l == r); - } } diff --git a/sources/enduro2d/utils/json_utils.cpp b/sources/enduro2d/utils/json_utils.cpp index 14c960ec..6d81fe0f 100644 --- a/sources/enduro2d/utils/json_utils.cpp +++ b/sources/enduro2d/utils/json_utils.cpp @@ -197,6 +197,12 @@ namespace } }] }, + "guid" : { + "type" : "string", + "minLength" : 36, + "maxLength" : 36, + "pattern" : "^[0-9a-fA-F]{8}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{12}$" + }, "name" : { "type" : "string", "minLength" : 1 diff --git a/untests/bin/library/parent.json b/untests/bin/library/parent.json new file mode 100644 index 00000000..37baa7e8 --- /dev/null +++ b/untests/bin/library/parent.json @@ -0,0 +1,12 @@ +{ + "uuid" : "73740BC4-CE9F-4A7F-A029-4AB65027A8AE", + "components" : { + "named" : { + "name" : "parent" + }, + "circle_collider" : { + "radius" : 5, + "offset" : [4,2] + } + } +} diff --git a/untests/bin/library/prefab.json b/untests/bin/library/prefab.json index baeeaa24..12ad20a9 100644 --- a/untests/bin/library/prefab.json +++ b/untests/bin/library/prefab.json @@ -1,17 +1,13 @@ { + "parent" : "prototype.json", "components" : { - "touchable" : {}, - + "named" : { + "name" : "prefab" + }, "rect_collider" : { "size" : [1,2], "offset" : [2,4] }, - - "circle_collider" : { - "radius" : 5, - "offset" : [4,2] - }, - "polygon_collider" : { "points" : [[1,2],[2,3],[3,4]], "offset" : [8,4]