diff --git a/src/assets/AssetsLoader.cpp b/src/assets/AssetsLoader.cpp index a4aef1c4..c03ebf4b 100644 --- a/src/assets/AssetsLoader.cpp +++ b/src/assets/AssetsLoader.cpp @@ -42,7 +42,7 @@ bool AssetsLoader::loadNext() { return false; } aloader_func loader = found->second; - bool status = loader(assets, paths, entry.filename, entry.alias, entry.config); + bool status = loader(*this, assets, paths, entry.filename, entry.alias, entry.config); entries.pop(); return status; } diff --git a/src/assets/AssetsLoader.h b/src/assets/AssetsLoader.h index 7e0e63a5..de401846 100644 --- a/src/assets/AssetsLoader.h +++ b/src/assets/AssetsLoader.h @@ -15,9 +15,10 @@ const short ASSET_LAYOUT = 5; class ResPaths; class Assets; +class AssetsLoader; class Content; -using aloader_func = std::function)>; +using aloader_func = std::function)>; struct aloader_entry { int tag; @@ -40,6 +41,7 @@ public: const std::string alias, std::shared_ptr settings=nullptr ); + bool hasNext() const; bool loadNext(); diff --git a/src/assets/assetload_funcs.cpp b/src/assets/assetload_funcs.cpp index 2348c915..eeff84e0 100644 --- a/src/assets/assetload_funcs.cpp +++ b/src/assets/assetload_funcs.cpp @@ -3,6 +3,7 @@ #include #include #include "Assets.h" +#include "AssetsLoader.h" #include "../files/files.h" #include "../files/engine_paths.h" #include "../coders/png.h" @@ -18,11 +19,13 @@ namespace fs = std::filesystem; -bool assetload::texture(Assets* assets, - const ResPaths* paths, - const std::string filename, - const std::string name, - std::shared_ptr +bool assetload::texture( + AssetsLoader&, + Assets* assets, + const ResPaths* paths, + const std::string filename, + const std::string name, + std::shared_ptr ) { std::unique_ptr texture( png::load_texture(paths->find(filename).u8string()) @@ -35,11 +38,13 @@ bool assetload::texture(Assets* assets, return true; } -bool assetload::shader(Assets* assets, - const ResPaths* paths, - const std::string filename, - const std::string name, - std::shared_ptr +bool assetload::shader( + AssetsLoader&, + Assets* assets, + const ResPaths* paths, + const std::string filename, + const std::string name, + std::shared_ptr ) { fs::path vertexFile = paths->find(filename+".glslv"); fs::path fragmentFile = paths->find(filename+".glslf"); @@ -80,11 +85,13 @@ static bool appendAtlas(AtlasBuilder& atlas, const fs::path& file) { return true; } -bool assetload::atlas(Assets* assets, - const ResPaths* paths, - const std::string directory, - const std::string name, - std::shared_ptr +bool assetload::atlas( + AssetsLoader&, + Assets* assets, + const ResPaths* paths, + const std::string directory, + const std::string name, + std::shared_ptr ) { AtlasBuilder builder; for (const auto& file : paths->listdir(directory)) { @@ -98,11 +105,13 @@ bool assetload::atlas(Assets* assets, return true; } -bool assetload::font(Assets* assets, - const ResPaths* paths, - const std::string filename, - const std::string name, - std::shared_ptr +bool assetload::font( + AssetsLoader&, + Assets* assets, + const ResPaths* paths, + const std::string filename, + const std::string name, + std::shared_ptr ) { std::vector> pages; for (size_t i = 0; i <= 4; i++) { @@ -123,6 +132,7 @@ bool assetload::font(Assets* assets, } bool assetload::layout( + AssetsLoader& loader, Assets* assets, const ResPaths* paths, const std::string file, @@ -131,7 +141,7 @@ bool assetload::layout( ) { try { LayoutCfg* cfg = reinterpret_cast(config.get()); - auto document = UiDocument::read(cfg->env, name, file); + auto document = UiDocument::read(loader, cfg->env, name, file); assets->store(document.release(), name); return true; } catch (const parsing_error& err) { @@ -141,7 +151,6 @@ bool assetload::layout( } } - bool assetload::animation(Assets* assets, const ResPaths* paths, const std::string directory, diff --git a/src/assets/assetload_funcs.h b/src/assets/assetload_funcs.h index 745cadc5..a9ef5d26 100644 --- a/src/assets/assetload_funcs.h +++ b/src/assets/assetload_funcs.h @@ -6,39 +6,45 @@ class ResPaths; class Assets; +class AssetsLoader; class Atlas; namespace assetload { bool texture( - Assets* assets, + AssetsLoader&, + Assets*, const ResPaths* paths, const std::string filename, const std::string name, std::shared_ptr settings ); bool shader( - Assets* assets, + AssetsLoader&, + Assets*, const ResPaths* paths, const std::string filename, const std::string name, std::shared_ptr settings ); bool atlas( - Assets* assets, + AssetsLoader&, + Assets*, const ResPaths* paths, const std::string directory, const std::string name, std::shared_ptr settings ); bool font( - Assets* assets, + AssetsLoader&, + Assets*, const ResPaths* paths, const std::string filename, const std::string name, std::shared_ptr settings ); bool layout( - Assets* assets, + AssetsLoader&, + Assets*, const ResPaths* paths, const std::string file, const std::string name, @@ -46,7 +52,7 @@ namespace assetload { ); bool animation( - Assets* assets, + Assets*, const ResPaths* paths, const std::string directory, const std::string name, diff --git a/src/frontend/InventoryView.cpp b/src/frontend/InventoryView.cpp index c25bce9a..cc8902a7 100644 --- a/src/frontend/InventoryView.cpp +++ b/src/frontend/InventoryView.cpp @@ -424,28 +424,11 @@ static void readSlotsGrid(InventoryView* view, gui::UiXmlReader& reader, xml::xm } } -std::shared_ptr InventoryView::readXML( - const std::string& src, - const std::string& file, - const scripting::Environment& env -) { - auto view = std::make_shared(); - - gui::UiXmlReader reader(env); - createReaders(reader); - - auto document = xml::parse(file, src); - auto root = document->getRoot(); - if (root->getTag() != "inventory") { - throw std::runtime_error("'inventory' element expected"); - } - return std::dynamic_pointer_cast(reader.readXML(file, root)); -} - void InventoryView::createReaders(gui::UiXmlReader& reader) { reader.add("inventory", [=](gui::UiXmlReader& reader, xml::xmlelement element) { auto view = std::make_shared(); - reader.readUINode(reader, element, *view, true); + reader.addIgnore("slots-grid"); + reader.readUINode(reader, element, *view); for (auto& sub : element->getElements()) { if (sub->getTag() == "slot") { diff --git a/src/frontend/InventoryView.h b/src/frontend/InventoryView.h index 1267942c..7a8238ae 100644 --- a/src/frontend/InventoryView.h +++ b/src/frontend/InventoryView.h @@ -117,12 +117,6 @@ public: std::shared_ptr getInventory() const; - static std::shared_ptr readXML( - const std::string& src, - const std::string& file, - const scripting::Environment& env - ); - static void createReaders(gui::UiXmlReader& reader); static const int SLOT_INTERVAL = 4; diff --git a/src/frontend/UiDocument.cpp b/src/frontend/UiDocument.cpp index 78cda915..b47d8363 100644 --- a/src/frontend/UiDocument.cpp +++ b/src/frontend/UiDocument.cpp @@ -51,12 +51,12 @@ void UiDocument::collect(uinodes_map& map, std::shared_ptr node) { } } -std::unique_ptr UiDocument::read(int penv, std::string namesp, fs::path file) { +std::unique_ptr UiDocument::read(AssetsLoader& loader, int penv, std::string namesp, fs::path file) { const std::string text = files::read_string(file); auto xmldoc = xml::parse(file.u8string(), text); auto env = scripting::create_environment(penv); - gui::UiXmlReader reader(*env); + gui::UiXmlReader reader(*env, loader); InventoryView::createReaders(reader); auto view = reader.readXML( file.u8string(), xmldoc->getRoot() diff --git a/src/frontend/UiDocument.h b/src/frontend/UiDocument.h index 588cc73d..7668a414 100644 --- a/src/frontend/UiDocument.h +++ b/src/frontend/UiDocument.h @@ -24,6 +24,8 @@ struct uidocscript { using uinodes_map = std::unordered_map>; +class AssetsLoader; + class UiDocument { std::string id; uidocscript script; @@ -46,7 +48,7 @@ public: /* Collect map of all uinodes having identifiers */ static void collect(uinodes_map& map, std::shared_ptr node); - static std::unique_ptr read(int env, std::string namesp, fs::path file); + static std::unique_ptr read(AssetsLoader& loader, int env, std::string namesp, fs::path file); }; #endif // FRONTEND_UI_DOCUMENT_H_ diff --git a/src/frontend/gui/controls.h b/src/frontend/gui/controls.h index 93969e17..df6208fc 100644 --- a/src/frontend/gui/controls.h +++ b/src/frontend/gui/controls.h @@ -49,7 +49,7 @@ namespace gui { protected: std::string texture; public: - Image(std::string texture, glm::vec2 size); + Image(std::string texture, glm::vec2 size=glm::vec2(32,32)); virtual void draw(const GfxContext* pctx, Assets* assets) override; }; diff --git a/src/frontend/gui/gui_xml.cpp b/src/frontend/gui/gui_xml.cpp index 6400e82c..ee2753e8 100644 --- a/src/frontend/gui/gui_xml.cpp +++ b/src/frontend/gui/gui_xml.cpp @@ -6,6 +6,7 @@ #include "panels.h" #include "controls.h" +#include "../../assets/AssetsLoader.h" #include "../locale/langs.h" #include "../../logic/scripting/scripting.h" #include "../../util/stringutil.h" @@ -41,7 +42,7 @@ static void _readUINode(xml::xmlelement element, UINode& node) { } -static void _readContainer(UiXmlReader& reader, xml::xmlelement element, Container& container, bool ignoreUnknown) { +static void _readContainer(UiXmlReader& reader, xml::xmlelement element, Container& container) { _readUINode(element, container); if (element->has("scrollable")) { @@ -50,15 +51,15 @@ static void _readContainer(UiXmlReader& reader, xml::xmlelement element, Contain for (auto& sub : element->getElements()) { if (sub->isText()) continue; - if (ignoreUnknown && !reader.hasReader(sub->getTag())) { - continue; + auto subnode = reader.readUINode(sub); + if (subnode) { + container.add(subnode); } - container.add(reader.readUINode(sub)); } } -void UiXmlReader::readUINode(UiXmlReader& reader, xml::xmlelement element, Container& container, bool ignoreUnknown) { - _readContainer(reader, element, container, ignoreUnknown); +void UiXmlReader::readUINode(UiXmlReader& reader, xml::xmlelement element, Container& container) { + _readContainer(reader, element, container); } void UiXmlReader::readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& node) { @@ -86,7 +87,10 @@ static void _readPanel(UiXmlReader& reader, xml::xmlelement element, Panel& pane for (auto& sub : element->getElements()) { if (sub->isText()) continue; - panel.add(reader.readUINode(sub)); + auto subnode = reader.readUINode(sub); + if (subnode) { + panel.add(subnode); + } } } @@ -113,7 +117,7 @@ static std::shared_ptr readLabel(UiXmlReader& reader, xml::xmlelement el static std::shared_ptr readContainer(UiXmlReader& reader, xml::xmlelement element) { auto container = std::make_shared(glm::vec2(), glm::vec2()); - _readContainer(reader, element, *container, false); + _readContainer(reader, element, *container); return container; } @@ -156,7 +160,18 @@ static std::shared_ptr readTextBox(UiXmlReader& reader, xml::xmlelement return textbox; } -UiXmlReader::UiXmlReader(const scripting::Environment& env) : env(env) { +static std::shared_ptr readImage(UiXmlReader& reader, xml::xmlelement element) { + std::string src = element->attr("src", "").getText(); + auto image = std::make_shared(src); + _readUINode(element, *image); + reader.getAssetsLoader().add(ASSET_TEXTURE, "textures/"+src+".png", src, nullptr); + return image; +} + +UiXmlReader::UiXmlReader(const scripting::Environment& env, AssetsLoader& assetsLoader) +: env(env), assetsLoader(assetsLoader) +{ + add("image", readImage); add("label", readLabel); add("button", readButton); add("textbox", readTextBox); @@ -171,11 +186,18 @@ bool UiXmlReader::hasReader(const std::string& tag) const { return readers.find(tag) != readers.end(); } +void UiXmlReader::addIgnore(const std::string& tag) { + ignored.insert(tag); +} + std::shared_ptr UiXmlReader::readUINode(xml::xmlelement element) { const std::string& tag = element->getTag(); auto found = readers.find(tag); if (found == readers.end()) { + if (ignored.find(tag) != ignored.end()) { + return nullptr; + } throw std::runtime_error("unsupported element '"+tag+"'"); } return found->second(*this, element); @@ -206,3 +228,7 @@ const std::string& UiXmlReader::getFilename() const { const scripting::Environment& UiXmlReader::getEnvironment() const { return env; } + +AssetsLoader& UiXmlReader::getAssetsLoader() { + return assetsLoader; +} diff --git a/src/frontend/gui/gui_xml.h b/src/frontend/gui/gui_xml.h index 47a0ca3d..1bbf6153 100644 --- a/src/frontend/gui/gui_xml.h +++ b/src/frontend/gui/gui_xml.h @@ -2,6 +2,7 @@ #define FRONTEND_GUI_GUI_XML_H_ #include +#include #include #include "GUI.h" @@ -11,6 +12,8 @@ namespace scripting { class Environment; } +class AssetsLoader; + namespace gui { class UiXmlReader; @@ -18,13 +21,17 @@ namespace gui { class UiXmlReader { std::unordered_map readers; + std::unordered_set ignored; std::string filename; const scripting::Environment& env; + AssetsLoader& assetsLoader; + public: - UiXmlReader(const scripting::Environment& env); + UiXmlReader(const scripting::Environment& env, AssetsLoader& assetsLoader); void add(const std::string& tag, uinode_reader reader); bool hasReader(const std::string& tag) const; + void addIgnore(const std::string& tag); std::shared_ptr readUINode(xml::xmlelement element); @@ -37,8 +44,7 @@ namespace gui { void readUINode( UiXmlReader& reader, xml::xmlelement element, - Container& container, - bool ignoreUnknown=false + Container& container ); std::shared_ptr readXML( @@ -53,6 +59,8 @@ namespace gui { const scripting::Environment& getEnvironment() const; const std::string& getFilename() const; + + AssetsLoader& getAssetsLoader(); }; }