From 27a92fc3ad5dbd5ffe1017136d22e135f73fad98 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 24 May 2019 00:16:52 +0700 Subject: [PATCH] add library loading error messages --- headers/enduro2d/high/assets/atlas_asset.hpp | 1 + headers/enduro2d/high/assets/binary_asset.hpp | 1 + .../enduro2d/high/assets/flipbook_asset.hpp | 1 + headers/enduro2d/high/assets/image_asset.hpp | 1 + headers/enduro2d/high/assets/json_asset.hpp | 1 + .../enduro2d/high/assets/material_asset.hpp | 1 + headers/enduro2d/high/assets/mesh_asset.hpp | 1 + headers/enduro2d/high/assets/model_asset.hpp | 1 + headers/enduro2d/high/assets/prefab_asset.hpp | 1 + headers/enduro2d/high/assets/shader_asset.hpp | 1 + headers/enduro2d/high/assets/shape_asset.hpp | 1 + headers/enduro2d/high/assets/sprite_asset.hpp | 1 + headers/enduro2d/high/assets/text_asset.hpp | 1 + .../enduro2d/high/assets/texture_asset.hpp | 1 + headers/enduro2d/high/assets/xml_asset.hpp | 1 + headers/enduro2d/high/library.inl | 55 ++++++++++++++----- headers/enduro2d/high/world.hpp | 2 +- samples/bin/library/camera_prefab.json | 4 +- samples/bin/library/scene_prefab.json | 7 +-- sources/enduro2d/high/assets/atlas_asset.cpp | 3 + .../enduro2d/high/assets/flipbook_asset.cpp | 3 + sources/enduro2d/high/assets/prefab_asset.cpp | 5 ++ sources/enduro2d/high/assets/sprite_asset.cpp | 8 +-- sources/enduro2d/high/world.cpp | 28 +++++----- untests/sources/untests_high/asset.cpp | 4 ++ untests/sources/untests_high/library.cpp | 2 + 26 files changed, 96 insertions(+), 40 deletions(-) diff --git a/headers/enduro2d/high/assets/atlas_asset.hpp b/headers/enduro2d/high/assets/atlas_asset.hpp index 7fcef9f6..630dda75 100644 --- a/headers/enduro2d/high/assets/atlas_asset.hpp +++ b/headers/enduro2d/high/assets/atlas_asset.hpp @@ -15,6 +15,7 @@ namespace e2d { class atlas_asset final : public content_asset { public: + static const char* type_name() noexcept { return "atlas_asset"; } static load_async_result load_async(const library& library, str_view address); }; } diff --git a/headers/enduro2d/high/assets/binary_asset.hpp b/headers/enduro2d/high/assets/binary_asset.hpp index c07baf30..66931a4e 100644 --- a/headers/enduro2d/high/assets/binary_asset.hpp +++ b/headers/enduro2d/high/assets/binary_asset.hpp @@ -14,6 +14,7 @@ namespace e2d { class binary_asset final : public content_asset { public: + static const char* type_name() noexcept { return "binary_asset"; } static load_async_result load_async(const library& library, str_view address); }; } diff --git a/headers/enduro2d/high/assets/flipbook_asset.hpp b/headers/enduro2d/high/assets/flipbook_asset.hpp index 5fa11f25..cc9f0ed0 100644 --- a/headers/enduro2d/high/assets/flipbook_asset.hpp +++ b/headers/enduro2d/high/assets/flipbook_asset.hpp @@ -15,6 +15,7 @@ namespace e2d { class flipbook_asset final : public content_asset { public: + static const char* type_name() noexcept { return "flipbook_asset"; } static load_async_result load_async(const library& library, str_view address); }; } diff --git a/headers/enduro2d/high/assets/image_asset.hpp b/headers/enduro2d/high/assets/image_asset.hpp index 6ff7d661..f6195625 100644 --- a/headers/enduro2d/high/assets/image_asset.hpp +++ b/headers/enduro2d/high/assets/image_asset.hpp @@ -14,6 +14,7 @@ namespace e2d { class image_asset final : public content_asset { public: + static const char* type_name() noexcept { return "image_asset"; } static load_async_result load_async(const library& library, str_view address); }; } diff --git a/headers/enduro2d/high/assets/json_asset.hpp b/headers/enduro2d/high/assets/json_asset.hpp index a26a74d2..04192f41 100644 --- a/headers/enduro2d/high/assets/json_asset.hpp +++ b/headers/enduro2d/high/assets/json_asset.hpp @@ -15,6 +15,7 @@ namespace e2d using json_uptr = std::unique_ptr; class json_asset final : public content_asset { public: + static const char* type_name() noexcept { return "json_asset"; } static load_async_result load_async(const library& library, str_view address); }; } diff --git a/headers/enduro2d/high/assets/material_asset.hpp b/headers/enduro2d/high/assets/material_asset.hpp index 24062ac1..08e68ee1 100644 --- a/headers/enduro2d/high/assets/material_asset.hpp +++ b/headers/enduro2d/high/assets/material_asset.hpp @@ -14,6 +14,7 @@ namespace e2d { class material_asset final : public content_asset { public: + static const char* type_name() noexcept { return "material_asset"; } static load_async_result load_async(const library& library, str_view address); }; } diff --git a/headers/enduro2d/high/assets/mesh_asset.hpp b/headers/enduro2d/high/assets/mesh_asset.hpp index b1c104b5..8ae21fac 100644 --- a/headers/enduro2d/high/assets/mesh_asset.hpp +++ b/headers/enduro2d/high/assets/mesh_asset.hpp @@ -14,6 +14,7 @@ namespace e2d { class mesh_asset final : public content_asset { public: + static const char* type_name() noexcept { return "mesh_asset"; } static load_async_result load_async(const library& library, str_view address); }; } diff --git a/headers/enduro2d/high/assets/model_asset.hpp b/headers/enduro2d/high/assets/model_asset.hpp index 1239a8fc..62ca3557 100644 --- a/headers/enduro2d/high/assets/model_asset.hpp +++ b/headers/enduro2d/high/assets/model_asset.hpp @@ -15,6 +15,7 @@ namespace e2d { class model_asset final : public content_asset { public: + static const char* type_name() noexcept { return "model_asset"; } static load_async_result load_async(const library& library, str_view address); }; } diff --git a/headers/enduro2d/high/assets/prefab_asset.hpp b/headers/enduro2d/high/assets/prefab_asset.hpp index 6f5aee8f..01c6eed6 100644 --- a/headers/enduro2d/high/assets/prefab_asset.hpp +++ b/headers/enduro2d/high/assets/prefab_asset.hpp @@ -15,6 +15,7 @@ namespace e2d { class prefab_asset final : public content_asset { public: + static const char* type_name() noexcept { return "prefab_asset"; } static load_async_result load_async(const library& library, str_view address); }; } diff --git a/headers/enduro2d/high/assets/shader_asset.hpp b/headers/enduro2d/high/assets/shader_asset.hpp index 4a51647a..8d4fc8fe 100644 --- a/headers/enduro2d/high/assets/shader_asset.hpp +++ b/headers/enduro2d/high/assets/shader_asset.hpp @@ -14,6 +14,7 @@ namespace e2d { class shader_asset final : public content_asset { public: + static const char* type_name() noexcept { return "shader_asset"; } static load_async_result load_async(const library& library, str_view address); }; } diff --git a/headers/enduro2d/high/assets/shape_asset.hpp b/headers/enduro2d/high/assets/shape_asset.hpp index 2a45debf..779d7ab1 100644 --- a/headers/enduro2d/high/assets/shape_asset.hpp +++ b/headers/enduro2d/high/assets/shape_asset.hpp @@ -14,6 +14,7 @@ namespace e2d { class shape_asset final : public content_asset { public: + static const char* type_name() noexcept { return "shape_asset"; } static load_async_result load_async(const library& library, str_view address); }; } diff --git a/headers/enduro2d/high/assets/sprite_asset.hpp b/headers/enduro2d/high/assets/sprite_asset.hpp index 6a8fbd82..ac6f242f 100644 --- a/headers/enduro2d/high/assets/sprite_asset.hpp +++ b/headers/enduro2d/high/assets/sprite_asset.hpp @@ -15,6 +15,7 @@ namespace e2d { class sprite_asset final : public content_asset { public: + static const char* type_name() noexcept { return "sprite_asset"; } static load_async_result load_async(const library& library, str_view address); }; } diff --git a/headers/enduro2d/high/assets/text_asset.hpp b/headers/enduro2d/high/assets/text_asset.hpp index 353e7729..183fd7e6 100644 --- a/headers/enduro2d/high/assets/text_asset.hpp +++ b/headers/enduro2d/high/assets/text_asset.hpp @@ -14,6 +14,7 @@ namespace e2d { class text_asset final : public content_asset { public: + static const char* type_name() noexcept { return "text_asset"; } static load_async_result load_async(const library& library, str_view address); }; } diff --git a/headers/enduro2d/high/assets/texture_asset.hpp b/headers/enduro2d/high/assets/texture_asset.hpp index 452c706b..bc5253e5 100644 --- a/headers/enduro2d/high/assets/texture_asset.hpp +++ b/headers/enduro2d/high/assets/texture_asset.hpp @@ -14,6 +14,7 @@ namespace e2d { class texture_asset final : public content_asset { public: + static const char* type_name() noexcept { return "texture_asset"; } static load_async_result load_async(const library& library, str_view address); }; } diff --git a/headers/enduro2d/high/assets/xml_asset.hpp b/headers/enduro2d/high/assets/xml_asset.hpp index 73ee1488..4988303d 100644 --- a/headers/enduro2d/high/assets/xml_asset.hpp +++ b/headers/enduro2d/high/assets/xml_asset.hpp @@ -15,6 +15,7 @@ namespace e2d using xml_uptr = std::unique_ptr; class xml_asset final : public content_asset { public: + static const char* type_name() noexcept { return "xml_asset"; } static load_async_result load_async(const library& library, str_view address); }; } diff --git a/headers/enduro2d/high/library.inl b/headers/enduro2d/high/library.inl index a2733f9d..75c8a459 100644 --- a/headers/enduro2d/high/library.inl +++ b/headers/enduro2d/high/library.inl @@ -105,10 +105,31 @@ namespace e2d return new_asset; }).except([ this, + main_address, main_address_hash ](std::exception_ptr e) -> typename Asset::load_result { - std::lock_guard guard(mutex_); - remove_loading_asset_(main_address_hash); + { + std::lock_guard guard(mutex_); + remove_loading_asset_(main_address_hash); + } + try { + std::rethrow_exception(e); + } catch ( const std::exception& ee ) { + the().error("LIBRARY: Failed to load asset:\n" + "--> Asset: %0\n" + "--> Address: %1\n" + "--> Exception: %2", + Asset::type_name(), + main_address, + ee.what()); + } catch (...) { + the().error("LIBRARY: Failed to load asset:\n" + "--> Asset: %0\n" + "--> Address: %1\n" + "--> Exception: unexpected", + Asset::type_name(), + main_address); + } std::rethrow_exception(e); }); @@ -130,17 +151,25 @@ namespace e2d template < typename Asset, typename Nested > typename Nested::load_async_result library::load_asset_async(str_view address) const { return load_main_asset_async(address) - .then([ - nested_address = address::nested(address) - ](const typename Asset::load_result& main_asset){ - typename Nested::load_result nested_asset = nested_address.empty() - ? dynamic_pointer_cast(main_asset) - : main_asset->template find_nested_asset(nested_address); - if ( nested_asset ) { - return nested_asset; - } - throw asset_loading_exception(); - }); + .then([ + address = str(address), + nested_address = address::nested(address) + ](const typename Asset::load_result& main_asset){ + typename Nested::load_result nested_asset = nested_address.empty() + ? dynamic_pointer_cast(main_asset) + : main_asset->template find_nested_asset(nested_address); + if ( nested_asset ) { + return nested_asset; + } + the().error("LIBRARY: Failed to load asset:\n" + "--> Asset: %0\n" + "--> Nested: %1\n" + "--> Address: %2\n", + Asset::type_name(), + Nested::type_name(), + address); + throw asset_loading_exception(); + }); } template < typename Asset > diff --git a/headers/enduro2d/high/world.hpp b/headers/enduro2d/high/world.hpp index f7cea40b..c487a094 100644 --- a/headers/enduro2d/high/world.hpp +++ b/headers/enduro2d/high/world.hpp @@ -37,7 +37,7 @@ namespace e2d gobject_iptr instantiate(); gobject_iptr instantiate(const prefab& prefab); - void destroy_instance(const gobject_iptr& inst, bool recursive) noexcept; + void destroy_instance(const gobject_iptr& inst) noexcept; private: ecs::registry registry_; hash_map gobjects_; diff --git a/samples/bin/library/camera_prefab.json b/samples/bin/library/camera_prefab.json index d9d806c8..ae6043da 100644 --- a/samples/bin/library/camera_prefab.json +++ b/samples/bin/library/camera_prefab.json @@ -1,5 +1,7 @@ { "components" : { - "camera" : {} + "camera" : { + "background" : [1.0, 0.4, 0.0, 1.0] + } } } diff --git a/samples/bin/library/scene_prefab.json b/samples/bin/library/scene_prefab.json index e329b7dc..5cc9596d 100644 --- a/samples/bin/library/scene_prefab.json +++ b/samples/bin/library/scene_prefab.json @@ -3,12 +3,7 @@ "scene" : {} }, "children" : [{ - "prototype" : "camera_prefab.json", - "components" : { - "camera" : { - "background" : [1.0, 0.4, 0.0, 1.0] - } - } + "prototype" : "camera_prefab.json" },{ "prototype" : "gnome_prefab.json", "components" : { diff --git a/sources/enduro2d/high/assets/atlas_asset.cpp b/sources/enduro2d/high/assets/atlas_asset.cpp index c6a55bba..1b398bc9 100644 --- a/sources/enduro2d/high/assets/atlas_asset.cpp +++ b/sources/enduro2d/high/assets/atlas_asset.cpp @@ -84,16 +84,19 @@ namespace E2D_ASSERT(sprite_json.HasMember("name")); if ( !json_utils::try_parse_value(sprite_json["name"], tsprite_descs[i].name) ) { + the().error("ATLAS: Incorrect formatting of 'name' property"); return false; } E2D_ASSERT(sprite_json.HasMember("pivot")); if ( !json_utils::try_parse_value(sprite_json["pivot"], tsprite_descs[i].pivot) ) { + the().error("ATLAS: Incorrect formatting of 'pivot' property"); return false; } E2D_ASSERT(sprite_json.HasMember("texrect")); if ( !json_utils::try_parse_value(sprite_json["texrect"], tsprite_descs[i].texrect) ) { + the().error("ATLAS: Incorrect formatting of 'texrect' property"); return false; } } diff --git a/sources/enduro2d/high/assets/flipbook_asset.cpp b/sources/enduro2d/high/assets/flipbook_asset.cpp index 6676725d..9fcfc04f 100644 --- a/sources/enduro2d/high/assets/flipbook_asset.cpp +++ b/sources/enduro2d/high/assets/flipbook_asset.cpp @@ -146,18 +146,21 @@ namespace f32 fps{0.f}; if ( !json_utils::try_parse_value(sequence_json["fps"], fps) ) { + the().error("FLIPBOOK: Incorrect formatting of 'fps' property"); return stdex::make_rejected_promise>( flipbook_asset_loading_exception()); } str_hash name_hash; if ( !json_utils::try_parse_value(sequence_json["name"], name_hash) ) { + the().error("FLIPBOOK: Incorrect formatting of 'name' property"); return stdex::make_rejected_promise>( flipbook_asset_loading_exception()); } vector frames; if ( !json_utils::try_parse_value(sequence_json["frames"], frames) ) { + the().error("FLIPBOOK: Incorrect formatting of 'frames' property"); return stdex::make_rejected_promise>( flipbook_asset_loading_exception()); } diff --git a/sources/enduro2d/high/assets/prefab_asset.cpp b/sources/enduro2d/high/assets/prefab_asset.cpp index f4fdebb7..4a29b9e0 100644 --- a/sources/enduro2d/high/assets/prefab_asset.cpp +++ b/sources/enduro2d/high/assets/prefab_asset.cpp @@ -134,6 +134,11 @@ namespace auto proto_res = dependencies.find_asset( path::combine(parent_address, root["prototype"].GetString())); if ( !proto_res ) { + the().error("PREFAB: Dependency 'prototype' is not found:\n" + "--> Parent address: %0\n" + "--> Dependency address: %1", + parent_address, + root["flipbook"].GetString()); throw prefab_asset_loading_exception(); } content = proto_res->content(); diff --git a/sources/enduro2d/high/assets/sprite_asset.cpp b/sources/enduro2d/high/assets/sprite_asset.cpp index 0bd3dbdd..c943541a 100644 --- a/sources/enduro2d/high/assets/sprite_asset.cpp +++ b/sources/enduro2d/high/assets/sprite_asset.cpp @@ -61,15 +61,15 @@ namespace v2f pivot; E2D_ASSERT(root.HasMember("pivot")); if ( !json_utils::try_parse_value(root["pivot"], pivot) ) { - return stdex::make_rejected_promise( - sprite_asset_loading_exception()); + the().error("SPRITE: Incorrect formatting of 'pivot' property"); + return stdex::make_rejected_promise(sprite_asset_loading_exception()); } b2f texrect; E2D_ASSERT(root.HasMember("texrect")); if ( !json_utils::try_parse_value(root["texrect"], texrect) ) { - return stdex::make_rejected_promise( - sprite_asset_loading_exception()); + the().error("SPRITE: Incorrect formatting of 'texrect' property"); + return stdex::make_rejected_promise(sprite_asset_loading_exception()); } return texture_p.then([ diff --git a/sources/enduro2d/high/world.cpp b/sources/enduro2d/high/world.cpp index 1262c2e0..24eb59b0 100644 --- a/sources/enduro2d/high/world.cpp +++ b/sources/enduro2d/high/world.cpp @@ -13,7 +13,7 @@ namespace e2d { world::~world() noexcept { while ( !gobjects_.empty() ) { - destroy_instance(gobjects_.begin()->second, true); + destroy_instance(gobjects_.begin()->second); } } @@ -37,7 +37,7 @@ namespace e2d } inst_a.assign(inst_n); } catch (...) { - destroy_instance(inst, true); + destroy_instance(inst); throw; } @@ -56,7 +56,7 @@ namespace e2d } inst_a.assign(inst_n); } catch (...) { - destroy_instance(inst, true); + destroy_instance(inst); throw; } @@ -68,28 +68,26 @@ namespace e2d auto child_a = child->get_component(); inst_a->node()->add_child(child_a->node()); } catch (...) { - destroy_instance(child, true); + destroy_instance(child); throw; } } } catch (...) { - destroy_instance(inst, true); + destroy_instance(inst); throw; } return inst; } - void world::destroy_instance(const gobject_iptr& inst, bool recursive) noexcept { - if ( recursive ) { - node_iptr inst_n = inst && inst->get_component() - ? inst->get_component()->node() - : nullptr; - if ( inst_n ) { - inst_n->for_each_child([this](const node_iptr& child_n){ - destroy_instance(child_n->owner(), true); - }); - } + void world::destroy_instance(const gobject_iptr& inst) noexcept { + node_iptr inst_n = inst && inst->get_component() + ? inst->get_component()->node() + : nullptr; + if ( inst_n ) { + inst_n->for_each_child([this](const node_iptr& child_n){ + destroy_instance(child_n->owner()); + }); } if ( inst ) { inst->entity().remove_all_components(); diff --git a/untests/sources/untests_high/asset.cpp b/untests/sources/untests_high/asset.cpp index a3519dfe..1ca9e733 100644 --- a/untests/sources/untests_high/asset.cpp +++ b/untests/sources/untests_high/asset.cpp @@ -24,10 +24,14 @@ namespace }; class fake_nested_asset final : public content_asset { + public: + static const char* type_name() noexcept { return "fake_nested_asset"; } }; class fake_asset final : public content_asset { public: + static const char* type_name() noexcept { return "fake_asset"; } + static load_async_result load_async(const library& library, str_view address) { E2D_UNUSED(library); return address == "42" diff --git a/untests/sources/untests_high/library.cpp b/untests/sources/untests_high/library.cpp index f388f167..a4f2f678 100644 --- a/untests/sources/untests_high/library.cpp +++ b/untests/sources/untests_high/library.cpp @@ -25,6 +25,7 @@ namespace class fake_asset final : public content_asset { public: + static const char* type_name() noexcept { return "fake_asset"; } static load_async_result load_async(const library& library, str_view address) { E2D_UNUSED(library, address); return stdex::make_resolved_promise(fake_asset::create(42)); @@ -33,6 +34,7 @@ namespace class big_fake_asset final : public content_asset { public: + static const char* type_name() noexcept { return "big_fake_asset"; } static load_async_result load_async(const library& library, str_view address) { E2D_UNUSED(library, address); return the().do_in_worker_thread([](){