mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-14 08:07:17 +07:00
add mod_children property to prefab asset
This commit is contained in:
@@ -27,9 +27,14 @@ namespace
|
||||
"uuid" : { "$ref": "#/common_definitions/uuid" },
|
||||
"parent" : { "$ref": "#/common_definitions/address" },
|
||||
"children" : { "$ref": "#/definitions/children" },
|
||||
"mod_children" : { "$ref": "#/definitions/mod_children" },
|
||||
"components" : { "type" : "object" }
|
||||
},
|
||||
"definitions" : {
|
||||
"children" : {
|
||||
"type" : "array",
|
||||
"items" : { "$ref": "#/definitions/child" }
|
||||
},
|
||||
"child" : {
|
||||
"type" : "object",
|
||||
"required" : [],
|
||||
@@ -38,12 +43,24 @@ namespace
|
||||
"uuid" : { "$ref": "#/common_definitions/uuid" },
|
||||
"parent" : { "$ref": "#/common_definitions/address" },
|
||||
"children" : { "$ref": "#/definitions/children" },
|
||||
"mod_children" : { "$ref": "#/definitions/mod_children" },
|
||||
"components" : { "type" : "object" }
|
||||
}
|
||||
},
|
||||
"children" : {
|
||||
"mod_children" : {
|
||||
"type" : "array",
|
||||
"items" : { "$ref": "#/definitions/child" }
|
||||
"items" : { "$ref": "#/definitions/mod_child" }
|
||||
},
|
||||
"mod_child" : {
|
||||
"type" : "object",
|
||||
"required" : [ "uuid" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"uuid" : { "$ref": "#/common_definitions/uuid" },
|
||||
"children" : { "$ref": "#/definitions/children" },
|
||||
"mod_children" : { "$ref": "#/definitions/mod_children" },
|
||||
"components" : { "type" : "object" }
|
||||
}
|
||||
}
|
||||
}
|
||||
})json";
|
||||
@@ -83,6 +100,13 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
if ( root.HasMember("mod_children") ) {
|
||||
const rapidjson::Value& mod_children_root = root["mod_children"];
|
||||
for ( rapidjson::SizeType i = 0; i < mod_children_root.Size(); ++i ) {
|
||||
collect_dependencies(parent_address, mod_children_root[i], dependencies);
|
||||
}
|
||||
}
|
||||
|
||||
if ( root.HasMember("components") ) {
|
||||
const rapidjson::Value& components_root = root["components"];
|
||||
for ( rapidjson::Value::ConstMemberIterator component_root = components_root.MemberBegin();
|
||||
@@ -123,13 +147,28 @@ namespace
|
||||
return dependencies.load_async(library);
|
||||
}
|
||||
|
||||
prefab parse_prefab(
|
||||
prefab* find_prefab_child(prefab& parent, str_view child_uuid) noexcept {
|
||||
for ( prefab& child : parent.children() ) {
|
||||
if ( child.uuid() == child_uuid ) {
|
||||
return &child;
|
||||
}
|
||||
}
|
||||
|
||||
for ( prefab& child : parent.children() ) {
|
||||
if ( prefab* sub_child = find_prefab_child(child, child_uuid) ) {
|
||||
return sub_child;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void parse_prefab_inplace(
|
||||
prefab& content,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root,
|
||||
const asset_group& dependencies)
|
||||
{
|
||||
prefab content;
|
||||
|
||||
if ( root.HasMember("uuid") ) {
|
||||
str uuid = content.uuid();
|
||||
if ( !json_utils::try_parse_value(root["uuid"], uuid) ) {
|
||||
@@ -161,13 +200,39 @@ namespace
|
||||
children.reserve(children_root.Size());
|
||||
|
||||
for ( rapidjson::SizeType i = 0; i < children_root.Size(); ++i ) {
|
||||
children.emplace_back(parse_prefab(
|
||||
parent_address, children_root[i], dependencies));
|
||||
prefab child;
|
||||
parse_prefab_inplace(
|
||||
child,
|
||||
parent_address,
|
||||
children_root[i],
|
||||
dependencies);
|
||||
children.push_back(std::move(child));
|
||||
}
|
||||
|
||||
content.set_children(std::move(children));
|
||||
}
|
||||
|
||||
if ( root.HasMember("mod_children") ) {
|
||||
const rapidjson::Value& mod_children_root = root["mod_children"];
|
||||
|
||||
for ( rapidjson::SizeType i = 0; i < mod_children_root.Size(); ++i ) {
|
||||
const rapidjson::Value& mod_child_root = mod_children_root[i];
|
||||
E2D_ASSERT(mod_child_root.HasMember("uuid") && mod_child_root["uuid"].IsString());
|
||||
prefab* child_prefab = find_prefab_child(content, mod_child_root["uuid"].GetString());
|
||||
if ( !child_prefab ) {
|
||||
the<debug>().error("PREFAB: Modifiable child is not found:\n"
|
||||
"--> Child UUID: %0",
|
||||
mod_child_root["uuid"].GetString());
|
||||
throw prefab_asset_loading_exception();
|
||||
}
|
||||
parse_prefab_inplace(
|
||||
*child_prefab,
|
||||
parent_address,
|
||||
mod_child_root,
|
||||
dependencies);
|
||||
}
|
||||
}
|
||||
|
||||
if ( root.HasMember("components") ) {
|
||||
const rapidjson::Value& components_root = root["components"];
|
||||
for ( rapidjson::Value::ConstMemberIterator component_root = components_root.MemberBegin();
|
||||
@@ -187,7 +252,15 @@ namespace
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prefab parse_prefab(
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root,
|
||||
const asset_group& dependencies)
|
||||
{
|
||||
prefab content;
|
||||
parse_prefab_inplace(content, parent_address, root, dependencies);
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,5 +8,20 @@
|
||||
"radius" : 5,
|
||||
"offset" : [4,2]
|
||||
}
|
||||
}
|
||||
},
|
||||
"children" : [{
|
||||
"uuid" : "4A93547E-4635-4C2F-9C59-3546E11B1722",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "child(1)"
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"uuid" : "58063213-9FC1-457C-B773-B826BE1BE6D7",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "child(2)"
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"parent" : "prototype.json",
|
||||
"parent" : "parent.json",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "prefab"
|
||||
@@ -12,5 +12,20 @@
|
||||
"points" : [[1,2],[2,3],[3,4]],
|
||||
"offset" : [8,4]
|
||||
}
|
||||
}
|
||||
},
|
||||
"mod_children" : [{
|
||||
"uuid" : "4A93547E-4635-4C2F-9C59-3546E11B1722",
|
||||
"components" : {
|
||||
"widget" : {
|
||||
"size" : [10,10]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"uuid" : "58063213-9FC1-457C-B773-B826BE1BE6D7",
|
||||
"components" : {
|
||||
"widget" : {
|
||||
"size" : [20,20]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
@@ -9,19 +9,6 @@ using namespace e2d;
|
||||
|
||||
namespace
|
||||
{
|
||||
class safe_starter_initializer final : private noncopyable {
|
||||
public:
|
||||
safe_starter_initializer() {
|
||||
modules::initialize<starter>(0, nullptr,
|
||||
starter::parameters(
|
||||
engine::parameters("world_untests", "enduro2d")));
|
||||
}
|
||||
|
||||
~safe_starter_initializer() noexcept {
|
||||
modules::shutdown<starter>();
|
||||
}
|
||||
};
|
||||
|
||||
class fake_node final : public node {
|
||||
protected:
|
||||
fake_node() : node() {
|
||||
@@ -61,7 +48,6 @@ namespace
|
||||
}
|
||||
|
||||
TEST_CASE("node") {
|
||||
safe_starter_initializer initializer;
|
||||
SECTION("empty_node") {
|
||||
auto n = node::create();
|
||||
REQUIRE(n);
|
||||
|
||||
136
untests/sources/untests_high/prefab.cpp
Normal file
136
untests/sources/untests_high/prefab.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2020, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include "_high.hpp"
|
||||
using namespace e2d;
|
||||
|
||||
namespace
|
||||
{
|
||||
class safe_starter_initializer final : private noncopyable {
|
||||
public:
|
||||
safe_starter_initializer() {
|
||||
modules::initialize<starter>(0, nullptr,
|
||||
starter::parameters(
|
||||
engine::parameters("prefab_untests", "enduro2d")));
|
||||
}
|
||||
|
||||
~safe_starter_initializer() noexcept {
|
||||
modules::shutdown<starter>();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("prefab"){
|
||||
safe_starter_initializer initializer;
|
||||
library& l = the<library>();
|
||||
{
|
||||
auto parent_res = l.load_asset<prefab_asset>("parent.json");
|
||||
REQUIRE(parent_res);
|
||||
REQUIRE(parent_res->content().uuid() == "73740BC4-CE9F-4A7F-A029-4AB65027A8AE");
|
||||
|
||||
REQUIRE(parent_res->content().children().size() == 2u);
|
||||
REQUIRE(parent_res->content().children()[0].uuid() == "4A93547E-4635-4C2F-9C59-3546E11B1722");
|
||||
REQUIRE(parent_res->content().children()[1].uuid() == "58063213-9FC1-457C-B773-B826BE1BE6D7");
|
||||
|
||||
auto go = the<world>().instantiate(parent_res->content());
|
||||
REQUIRE(go);
|
||||
|
||||
REQUIRE(go.component<named>());
|
||||
REQUIRE(go.component<named>()->name() == "parent");
|
||||
|
||||
REQUIRE(go.component<circle_collider>());
|
||||
REQUIRE(math::approximately(go.component<circle_collider>()->radius(), 5.f));
|
||||
REQUIRE(go.component<circle_collider>()->offset() == v2f(4.f,2.f));
|
||||
|
||||
{
|
||||
node_iptr go_node = go.component<actor>()
|
||||
? go.component<actor>()->node()
|
||||
: node_iptr();
|
||||
|
||||
REQUIRE(go_node);
|
||||
REQUIRE(go_node->owner() == go);
|
||||
REQUIRE(go_node->child_count() == 2u);
|
||||
|
||||
node_iptr child1 = go_node->child_at(0u);
|
||||
node_iptr child2 = go_node->child_at(1u);
|
||||
|
||||
REQUIRE(child1);
|
||||
REQUIRE(child2);
|
||||
|
||||
gobject child1_go = child1->owner();
|
||||
gobject child2_go = child2->owner();
|
||||
|
||||
REQUIRE(child1_go);
|
||||
REQUIRE(child2_go);
|
||||
|
||||
REQUIRE(child1_go.component<named>());
|
||||
REQUIRE(child1_go.component<named>()->name() == "child(1)");
|
||||
|
||||
REQUIRE(child2_go.component<named>());
|
||||
REQUIRE(child2_go.component<named>()->name() == "child(2)");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto prefab_res = l.load_asset<prefab_asset>("prefab.json");
|
||||
REQUIRE(prefab_res);
|
||||
REQUIRE(prefab_res->content().uuid().empty());
|
||||
|
||||
REQUIRE(prefab_res->content().children().size() == 2u);
|
||||
REQUIRE(prefab_res->content().children()[0].uuid() == "4A93547E-4635-4C2F-9C59-3546E11B1722");
|
||||
REQUIRE(prefab_res->content().children()[1].uuid() == "58063213-9FC1-457C-B773-B826BE1BE6D7");
|
||||
|
||||
auto go = the<world>().instantiate(prefab_res->content());
|
||||
REQUIRE(go);
|
||||
|
||||
REQUIRE(go.component<named>());
|
||||
REQUIRE(go.component<named>()->name() == "prefab");
|
||||
|
||||
REQUIRE(go.component<rect_collider>());
|
||||
REQUIRE(go.component<rect_collider>()->size() == v2f(1.f,2.f));
|
||||
REQUIRE(go.component<rect_collider>()->offset() == v2f(2.f,4.f));
|
||||
|
||||
REQUIRE(go.component<circle_collider>());
|
||||
REQUIRE(math::approximately(go.component<circle_collider>()->radius(), 5.f));
|
||||
REQUIRE(go.component<circle_collider>()->offset() == v2f(4.f,2.f));
|
||||
|
||||
REQUIRE(go.component<polygon_collider>());
|
||||
REQUIRE(go.component<polygon_collider>()->points() == vector<v2f>{{1,2},{2,3},{3,4}});
|
||||
REQUIRE(go.component<polygon_collider>()->offset() == v2f(8.f,4.f));
|
||||
|
||||
{
|
||||
node_iptr go_node = go.component<actor>()
|
||||
? go.component<actor>()->node()
|
||||
: node_iptr();
|
||||
|
||||
REQUIRE(go_node);
|
||||
REQUIRE(go_node->owner() == go);
|
||||
REQUIRE(go_node->child_count() == 2u);
|
||||
|
||||
node_iptr child1 = go_node->child_at(0u);
|
||||
node_iptr child2 = go_node->child_at(1u);
|
||||
|
||||
REQUIRE(child1);
|
||||
REQUIRE(child2);
|
||||
|
||||
gobject child1_go = child1->owner();
|
||||
gobject child2_go = child2->owner();
|
||||
|
||||
REQUIRE(child1_go);
|
||||
REQUIRE(child2_go);
|
||||
|
||||
REQUIRE(child1_go.component<named>());
|
||||
REQUIRE(child1_go.component<named>()->name() == "child(1)");
|
||||
|
||||
REQUIRE(child1_go.component<widget>());
|
||||
REQUIRE(child1_go.component<widget>()->size() == v2f(10.f, 10.f));
|
||||
|
||||
REQUIRE(child2_go.component<named>());
|
||||
REQUIRE(child2_go.component<named>()->name() == "child(2)");
|
||||
REQUIRE(child2_go.component<widget>()->size() == v2f(20.f, 20.f));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user