diff --git a/src/assets/AssetsLoader.cpp b/src/assets/AssetsLoader.cpp index 0fde22fc4..49ce5e04d 100644 --- a/src/assets/AssetsLoader.cpp +++ b/src/assets/AssetsLoader.cpp @@ -5,6 +5,7 @@ #include #include "coders/imageio.hpp" +#include "coders/commons.hpp" #include "constants.hpp" #include "content/Content.hpp" #include "content/ContentPack.hpp" @@ -71,20 +72,26 @@ aloader_func AssetsLoader::getLoader(AssetType tag) { void AssetsLoader::loadNext() { const aloader_entry& entry = entries.front(); logger.info() << "loading " << entry.filename << " as " << entry.alias; + + std::string error {}; try { aloader_func loader = getLoader(entry.tag); auto postfunc = loader(this, paths, entry.filename, entry.alias, entry.config); postfunc(&assets); - entries.pop(); - } 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(); - throw assetload::error(type, std::move(filename), std::move(reason)); + } catch (const parsing_error& err) { + error = err.errorLog(); + } catch (const std::runtime_error& err) { + error = err.what(); } + if (!error.empty()) { + logger.error() << error; + auto tag = entry.tag; + auto filename = entry.filename; + entries.pop(); + throw assetload::error(tag, std::move(filename), std::move(error)); + } + entries.pop(); } static void add_layouts( diff --git a/src/coders/obj.cpp b/src/coders/obj.cpp index 0eed9bf68..d7ff244aa 100644 --- a/src/coders/obj.cpp +++ b/src/coders/obj.cpp @@ -10,20 +10,21 @@ class ObjParser : BasicParser { std::vector uvs {{0, 0}}; std::vector normals {{0, 1, 0}}; + // TODO: refactor void parseFace(Mesh& mesh) { std::vector vertices; while (hasNext()) { auto c = peekInLine(); if (c == '\n') { break; - } else { + } else if (hasNext()) { uint indices[3] {}; uint i = 0; do { char next = peekInLine(); if (is_digit(next)) { indices[i] = parseSimpleInt(10); - if (peekInLine() == '/') { + if (hasNext() && peekInLine() == '/') { pos++; } } else if (next == '/') { @@ -31,13 +32,13 @@ class ObjParser : BasicParser { } else { break; } - } while (peekInLine() != '\n' && ++i < 3); + } while (hasNext() && peekInLine() != '\n' && ++i < 3); vertices.push_back(Vertex { coords[indices[0]], uvs[indices[1]], normals[indices[2]]}); } } - if (peekInLine() != '\n' && hasNext()) { + if (hasNext() && peekInLine() != '\n') { skipLine(); } if (vertices.size() >= 3) { diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index a88146bed..c9b982810 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -492,6 +492,7 @@ void ContentLoader::loadScripts(Content& content) { load_scripts(content, content.items); for (const auto& [packid, runtime] : content.getPacks()) { + auto env = runtime->getEnvironment(); const auto& pack = runtime->getInfo(); const auto& folder = pack.folder; @@ -500,9 +501,10 @@ void ContentLoader::loadScripts(Content& content) { // Load entity components io::path componentsDir = folder / "scripts/components"; - foreach_file(componentsDir, [&pack](const io::path& file) { + foreach_file(componentsDir, [&pack, env](const io::path& file) { auto name = pack.id + ":" + file.stem(); scripting::load_entity_component( + env, name, file, pack.id + ":scripts/components/" + file.name() diff --git a/src/frontend/UiDocument.cpp b/src/frontend/UiDocument.cpp index da4fec517..c1269b879 100644 --- a/src/frontend/UiDocument.cpp +++ b/src/frontend/UiDocument.cpp @@ -45,7 +45,7 @@ std::shared_ptr UiDocument::get(const std::string& id) const { if (found == map.end()) { return nullptr; } - return found->second; + return found->second.lock(); } const uidocscript& UiDocument::getScript() const { diff --git a/src/frontend/UiDocument.hpp b/src/frontend/UiDocument.hpp index 2ad00da80..8ebf7c3e6 100644 --- a/src/frontend/UiDocument.hpp +++ b/src/frontend/UiDocument.hpp @@ -19,7 +19,7 @@ struct uidocscript { bool onclose : 1; }; -using UINodesMap = std::unordered_map>; +using UINodesMap = std::unordered_map>; class UiDocument { std::string id; diff --git a/src/graphics/ui/elements/UINode.cpp b/src/graphics/ui/elements/UINode.cpp index f61e61a90..e62ff1df2 100644 --- a/src/graphics/ui/elements/UINode.cpp +++ b/src/graphics/ui/elements/UINode.cpp @@ -385,11 +385,14 @@ bool UINode::isSubnodeOf(const UINode* node) { void UINode::getIndices( const std::shared_ptr& node, - std::unordered_map>& map + std::unordered_map>& map ) { const std::string& id = node->getId(); if (!id.empty()) { - map[id] = node; + const auto& found = map.find(id); + if (found == map.end() || found->second.expired()) { + map[id] = node; + } } auto container = std::dynamic_pointer_cast(node); if (container) { diff --git a/src/graphics/ui/elements/UINode.hpp b/src/graphics/ui/elements/UINode.hpp index 011c23673..cbd43b380 100644 --- a/src/graphics/ui/elements/UINode.hpp +++ b/src/graphics/ui/elements/UINode.hpp @@ -289,7 +289,7 @@ namespace gui { /// @brief collect all nodes having id static void getIndices( const std::shared_ptr& node, - std::unordered_map>& map + std::unordered_map>& map ); static std::shared_ptr find( diff --git a/src/logic/scripting/lua/libs/libentity.cpp b/src/logic/scripting/lua/libs/libentity.cpp index 3b9730c21..5cab675a0 100644 --- a/src/logic/scripting/lua/libs/libentity.cpp +++ b/src/logic/scripting/lua/libs/libentity.cpp @@ -1,6 +1,7 @@ #include "libentity.hpp" #include "content/Content.hpp" +#include "content/ContentPack.hpp" #include "engine/Engine.hpp" #include "engine/EnginePaths.hpp" #include "objects/Entities.hpp" @@ -236,7 +237,14 @@ static int l_reload_component(lua::State* L) { } auto filename = name.substr(0, pos + 1) + "scripts/components/" + name.substr(pos + 1) + ".lua"; - scripting::load_entity_component(name, filename, filename); + auto prefix = name.substr(0, pos); + auto runtime = content->getPackRuntime(prefix); + if (runtime == nullptr) { + throw std::runtime_error("pack '" + prefix + "' content is not loaded"); + } + scripting::load_entity_component( + runtime->getEnvironment(), name, filename, filename + ); return 0; } diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 3a68917dc..15c4e85e7 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -708,12 +708,15 @@ void scripting::load_content_script( } void scripting::load_entity_component( - const std::string& name, const io::path& file, const std::string& fileName + const scriptenv& env, + const std::string& name, + const io::path& file, + const std::string& fileName ) { auto L = lua::get_main_state(); std::string src = io::read_string(file); logger.info() << "script (component) " << file.string(); - lua::loadbuffer(L, 0, src, fileName); + lua::loadbuffer(L, *env, src, fileName); lua::store_in(L, lua::CHUNKS_TABLE, name); } diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index 966450c61..298130c99 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -186,10 +186,12 @@ namespace scripting { ); /// @brief Load component script + /// @param env environment /// @param name component full name (packid:name) /// @param file component script file path /// @param fileName script file path using the engine format void load_entity_component( + const scriptenv& env, const std::string& name, const io::path& file, const std::string& fileName diff --git a/src/util/ObjectsPool.hpp b/src/util/ObjectsPool.hpp index 55238959e..075024f8e 100644 --- a/src/util/ObjectsPool.hpp +++ b/src/util/ObjectsPool.hpp @@ -33,7 +33,9 @@ namespace util { std::shared_ptr create(Args&&... args) { std::lock_guard lock(mutex); if (freeObjects.empty()) { - allocateNew(); + if (!allocateNew()) { + return std::make_shared(std::forward(args)...); + } } auto ptr = freeObjects.front(); freeObjects.pop(); @@ -49,7 +51,7 @@ namespace util { std::queue freeObjects; std::mutex mutex; - void allocateNew() { + bool allocateNew() { std::unique_ptr ptr( #if defined(_WIN32) _aligned_malloc(sizeof(T), alignof(T)) @@ -57,8 +59,12 @@ namespace util { std::aligned_alloc(alignof(T), sizeof(T)) #endif ); + if (ptr == nullptr) { + return false; + } freeObjects.push(ptr.get()); objects.push_back(std::move(ptr)); + return true; } }; }