From f9df873382d6a487600bcd540cef710c2f45d59a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 23 Jul 2024 19:27:46 +0300 Subject: [PATCH] update assets errors handling & add 'atlases' to preload --- res/content/base/preload.json | 12 +++++++++++ res/preload.json | 28 ++++++++++++++++++------- src/assets/Assets.hpp | 36 ++++++++++++++++++++++++++++++++ src/assets/AssetsLoader.cpp | 38 +++++++++++++--------------------- src/assets/AssetsLoader.hpp | 16 ++++---------- src/engine.cpp | 10 +++++---- src/logic/EngineController.cpp | 23 ++++++++++++++++---- 7 files changed, 112 insertions(+), 51 deletions(-) diff --git a/res/content/base/preload.json b/res/content/base/preload.json index 005abdfd..1e519ca2 100644 --- a/res/content/base/preload.json +++ b/res/content/base/preload.json @@ -6,5 +6,17 @@ ], "models": [ "drop-item" + ], + "shaders": [ + "ui3d", + "entity", + "screen", + "background", + "skybox_gen" + ], + "textures": [ + "misc/moon", + "misc/sun", + "gui/crosshair" ] } diff --git a/res/preload.json b/res/preload.json index 63c2d238..92d371cf 100644 --- a/res/preload.json +++ b/res/preload.json @@ -1,13 +1,27 @@ { "shaders": [ - "ui3d", - "screen", - "background", - "skybox_gen" + "ui", + "main", + "lines" ], "textures": [ - "misc/moon", - "misc/sun", - "gui/crosshair" + "gui/menubg", + "gui/delete_icon", + "gui/no_icon", + "gui/no_world_icon", + "gui/warning", + "gui/error", + "gui/cross", + "gui/refresh" + ], + "fonts": [ + { + "name": "normal", + "path": "fonts/font" + } + ], + "atlases": [ + "blocks", + "items" ] } diff --git a/src/assets/Assets.hpp b/src/assets/Assets.hpp index 1602463b..97a31a09 100644 --- a/src/assets/Assets.hpp +++ b/src/assets/Assets.hpp @@ -14,6 +14,16 @@ class Assets; +enum class AssetType { + TEXTURE, + SHADER, + FONT, + ATLAS, + LAYOUT, + SOUND, + MODEL +}; + namespace assetload { /// @brief final work to do in the main thread using postfunc = std::function; @@ -22,6 +32,32 @@ namespace assetload { template void assets_setup(const Assets*); + + class error : public std::runtime_error { + AssetType type; + std::string filename; + std::string reason; + public: + error( + AssetType type, std::string filename, std::string reason + ) : std::runtime_error(filename + ": " + reason), + type(type), + filename(std::move(filename)), + reason(std::move(reason)) { + } + + AssetType getAssetType() const { + return type; + } + + const std::string& getFilename() const { + return filename; + } + + const std::string& getReason() const { + return reason; + } + }; } class Assets { diff --git a/src/assets/AssetsLoader.cpp b/src/assets/AssetsLoader.cpp index 955eb0b1..87ef0454 100644 --- a/src/assets/AssetsLoader.cpp +++ b/src/assets/AssetsLoader.cpp @@ -56,7 +56,7 @@ aloader_func AssetsLoader::getLoader(AssetType tag) { return found->second; } -bool AssetsLoader::loadNext() { +void AssetsLoader::loadNext() { const aloader_entry& entry = entries.front(); logger.info() << "loading " << entry.filename << " as " << entry.alias; try { @@ -64,11 +64,13 @@ bool AssetsLoader::loadNext() { auto postfunc = loader(this, paths, entry.filename, entry.alias, entry.config); postfunc(assets); entries.pop(); - return true; } catch (std::runtime_error& err) { logger.error() << err.what(); + auto type = entry.tag; + std::string filename = entry.filename; + std::string reason = err.what(); entries.pop(); - return false; + throw assetload::error(type, std::move(filename), std::move(reason)); } } @@ -154,6 +156,7 @@ void AssetsLoader::processPreloadList(AssetType tag, dynamic::List* list) { void AssetsLoader::processPreloadConfig(const fs::path& file) { auto root = files::read_json(file); + processPreloadList(AssetType::ATLAS, root->list("atlases").get()); processPreloadList(AssetType::FONT, root->list("fonts").get()); processPreloadList(AssetType::SHADER, root->list("shaders").get()); processPreloadList(AssetType::TEXTURE, root->list("textures").get()); @@ -163,6 +166,13 @@ void AssetsLoader::processPreloadConfig(const fs::path& file) { } void AssetsLoader::processPreloadConfigs(const Content* content) { + auto preloadFile = paths->getMainRoot()/fs::path("preload.json"); + if (fs::exists(preloadFile)) { + processPreloadConfig(preloadFile); + } + if (content == nullptr) { + return; + } for (auto& entry : content->getPacks()) { const auto& pack = entry.second; auto preloadFile = pack->getInfo().folder / fs::path("preload.json"); @@ -170,29 +180,11 @@ void AssetsLoader::processPreloadConfigs(const Content* content) { processPreloadConfig(preloadFile); } } - auto preloadFile = paths->getMainRoot()/fs::path("preload.json"); - if (fs::exists(preloadFile)) { - processPreloadConfig(preloadFile); - } } void AssetsLoader::addDefaults(AssetsLoader& loader, const Content* content) { - loader.add(AssetType::FONT, FONTS_FOLDER+"/font", "normal"); - loader.add(AssetType::SHADER, SHADERS_FOLDER+"/ui", "ui"); - loader.add(AssetType::SHADER, SHADERS_FOLDER+"/main", "main"); - loader.add(AssetType::SHADER, SHADERS_FOLDER+"/entity", "entity"); - loader.add(AssetType::SHADER, SHADERS_FOLDER+"/lines", "lines"); - loader.add(AssetType::TEXTURE, TEXTURES_FOLDER+"/gui/menubg", "gui/menubg"); - loader.add(AssetType::TEXTURE, TEXTURES_FOLDER+"/gui/delete_icon", "gui/delete_icon"); - loader.add(AssetType::TEXTURE, TEXTURES_FOLDER+"/gui/no_icon", "gui/no_icon"); - loader.add(AssetType::TEXTURE, TEXTURES_FOLDER+"/gui/no_world_icon", "gui/no_world_icon"); - loader.add(AssetType::TEXTURE, TEXTURES_FOLDER+"/gui/warning", "gui/warning"); - loader.add(AssetType::TEXTURE, TEXTURES_FOLDER+"/gui/error", "gui/error"); - loader.add(AssetType::TEXTURE, TEXTURES_FOLDER+"/gui/cross", "gui/cross"); - loader.add(AssetType::TEXTURE, TEXTURES_FOLDER+"/gui/refresh", "gui/refresh"); + loader.processPreloadConfigs(content); if (content) { - loader.processPreloadConfigs(content); - for (auto& entry : content->getBlockMaterials()) { auto& material = *entry.second; loader.tryAddSound(material.stepsSound); @@ -218,8 +210,6 @@ void AssetsLoader::addDefaults(AssetsLoader& loader, const Content* content) { } } } - loader.add(AssetType::ATLAS, TEXTURES_FOLDER+"/blocks", "blocks"); - loader.add(AssetType::ATLAS, TEXTURES_FOLDER+"/items", "items"); } bool AssetsLoader::loadExternalTexture( diff --git a/src/assets/AssetsLoader.hpp b/src/assets/AssetsLoader.hpp index b6a9b75d..65ab30fe 100644 --- a/src/assets/AssetsLoader.hpp +++ b/src/assets/AssetsLoader.hpp @@ -19,16 +19,6 @@ namespace dynamic { class List; } -enum class AssetType { - TEXTURE, - SHADER, - FONT, - ATLAS, - LAYOUT, - SOUND, - MODEL -}; - class ResPaths; class AssetsLoader; class Content; @@ -50,7 +40,7 @@ struct SoundCfg : AssetCfg { }; using aloader_func = std::function startTask(runnable onDone); diff --git a/src/engine.cpp b/src/engine.cpp index 741339bf..2c68370a 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -256,11 +256,13 @@ void Engine::loadAssets() { auto task = loader.startTask([=](){}); task->waitForEnd(); } else { - while (loader.hasNext()) { - if (!loader.loadNext()) { - new_assets.reset(); - throw std::runtime_error("could not to load assets"); + try { + while (loader.hasNext()) { + loader.loadNext(); } + } catch (const assetload::error& err) { + new_assets.reset(); + throw; } } assets = std::move(new_assets); diff --git a/src/logic/EngineController.cpp b/src/logic/EngineController.cpp index 4c56d8e3..bcd33668 100644 --- a/src/logic/EngineController.cpp +++ b/src/logic/EngineController.cpp @@ -84,6 +84,7 @@ static void show_content_missing( } static bool loadWorldContent(Engine* engine, const fs::path& folder) { + // TODO: combine errors handling with newWorld try { engine->loadWorldContent(folder); return true; @@ -95,10 +96,17 @@ static bool loadWorldContent(Engine* engine, const fs::path& folder) { util::str2wstr_utf8(error.getPackId()) ); return false; + } catch (const assetload::error& error) { + engine->setScreen(std::make_shared(engine)); + guiutil::alert( + engine->getGUI(), langs::get(L"Assets Load Error", L"menu")+L":\n"+ + util::str2wstr_utf8(error.what()) + ); + return false; } catch (const std::runtime_error& error) { engine->setScreen(std::make_shared(engine)); guiutil::alert( - engine->getGUI(), langs::get(L"Content Error", L"menu")+L": "+ + engine->getGUI(), langs::get(L"Content Error", L"menu")+L":\n"+ util::str2wstr_utf8(error.what()) ); return false; @@ -189,11 +197,18 @@ void EngineController::createWorld( ) ); return; - } catch (const std::runtime_error& error) { + } catch (const assetload::error& error) { guiutil::alert( engine->getGUI(), - langs::get(L"Content Error", L"menu")+ - L": "+util::str2wstr_utf8(error.what()) + langs::get(L"Assets Loading Error", L"menu")+ + L":\n"+util::str2wstr_utf8(error.what()) + ); + return; + } catch (const std::runtime_error& error) { + engine->setScreen(std::make_shared(engine)); + guiutil::alert( + engine->getGUI(), langs::get(L"Content Error", L"menu")+L":\n"+ + util::str2wstr_utf8(error.what()) ); return; }