Index: source/graphics/MapGenerator.cpp =================================================================== --- source/graphics/MapGenerator.cpp +++ source/graphics/MapGenerator.cpp @@ -39,7 +39,9 @@ #include "scriptinterface/JSON.h" #include "simulation2/helpers/MapEdgeTiles.h" +#include #include +#include #include // TODO: Maybe this should be optimized depending on the map size. @@ -262,12 +264,28 @@ std::vector CMapGeneratorWorker::FindTemplates(const std::string& path, bool includeSubdirectories) { - return m_TemplateLoader.FindTemplates(path, includeSubdirectories, SIMULATION_TEMPLATES); + constexpr std::array templates_to_ignore { + // We want to ignore template_*.xml templates, since they should never be built in the editor + "template_", + + // Also ignore some subfolders. + "mixins/", + "special/" + }; + return m_TemplateLoader.FindTemplates(path, includeSubdirectories, SIMULATION_TEMPLATES, templates_to_ignore); } std::vector CMapGeneratorWorker::FindActorTemplates(const std::string& path, bool includeSubdirectories) { - return m_TemplateLoader.FindTemplates(path, includeSubdirectories, ACTOR_TEMPLATES); + constexpr std::array templates_to_ignore { + // We want to ignore template_*.xml templates, since they should never be built in the editor + "template_", + + // Also ignore some subfolders. + "mixins/", + "special/" + }; + return m_TemplateLoader.FindTemplates(path, includeSubdirectories, ACTOR_TEMPLATES, templates_to_ignore); } bool CMapGeneratorWorker::LoadScripts(const VfsPath& libraryName) Index: source/ps/TemplateLoader.h =================================================================== --- source/ps/TemplateLoader.h +++ source/ps/TemplateLoader.h @@ -18,6 +18,7 @@ #ifndef INCLUDED_TEMPLATELOADER #define INCLUDED_TEMPLATELOADER +#include "ps/containers/Span.h" #include "simulation2/system/ParamNode.h" #include @@ -65,13 +66,7 @@ * Returns a list of strings that could be validly passed as @c templateName to LoadTemplateFile. * (This includes "actor|foo" etc names). */ - std::vector FindTemplates(const std::string& path, bool includeSubdirectories, ETemplatesType templatesType) const; - - /** - * Returns a list of strings that could validly be passed as @c templateName to LoadTemplateFile. - * Not ignoring any special directories. - */ - std::vector FindTemplatesUnrestricted(const std::string& path, bool includeSubdirectories) const; + std::vector FindTemplates(const std::string& path, bool includeSubdirectories, ETemplatesType templatesType, const PS::span& ignoredTemplateStarts) const; private: /** Index: source/ps/TemplateLoader.cpp =================================================================== --- source/ps/TemplateLoader.cpp +++ source/ps/TemplateLoader.cpp @@ -21,6 +21,7 @@ #include "lib/utf8.h" #include "ps/CLogger.h" +#include "ps/containers/Span.h" #include "ps/Filesystem.h" #include "ps/XML/Xeromyces.h" @@ -84,39 +85,29 @@ return true; } -static Status AddToTemplates(const VfsPath& pathname, const CFileInfo& UNUSED(fileInfo), const uintptr_t cbData) +struct ListTemplatesState { - std::vector& templates = *(std::vector*)cbData; - - // Strip the .xml extension - VfsPath pathstem = pathname.ChangeExtension(L""); - // Strip the root from the path - std::string name = pathstem.string8().substr(ARRAY_SIZE(TEMPLATE_ROOT)-1); + std::vector templates; + PS::span templates_to_ignore; - // We want to ignore template_*.xml templates, since they should never be built in the editor - if (name.substr(0, 9) == "template_") - return INFO::OK; - - // Also ignore some subfolders. - if (name.substr(0, 8) == "special/" || name.substr(0, 7) == "mixins/") - return INFO::OK; + ListTemplatesState(const PS::span& templates_to_ignore) + : templates_to_ignore(templates_to_ignore), + templates() + {} +}; - templates.push_back(name); - return INFO::OK; -} - -static Status AddToTemplatesUnrestricted(const VfsPath& pathname, const CFileInfo& UNUSED(fileInfo), const uintptr_t cbData) +static Status AddToTemplates(const VfsPath& pathname, const CFileInfo& UNUSED(fileInfo), const uintptr_t cbData) { - std::vector& templates = *(std::vector*)cbData; + ListTemplatesState* s = reinterpret_cast(cbData); VfsPath pathstem = pathname.ChangeExtension(L""); std::string name = pathstem.string8().substr(ARRAY_SIZE(TEMPLATE_ROOT)-1); - // We want to ignore template_*.xml templates, since they may be incomplete. - if (name.substr(0, 9) == "template_") - return INFO::OK; + for (std::string_view template_to_ignore : s->templates_to_ignore) + if (name.substr(0, template_to_ignore.size()) == template_to_ignore) + return INFO::SKIPPED; - templates.push_back(name); + s->templates.push_back(name); return INFO::OK; } @@ -138,36 +129,25 @@ return VfsFileExists(VfsPath(TEMPLATE_ROOT) / wstring_from_utf8(baseName + ".xml")); } -std::vector CTemplateLoader::FindTemplates(const std::string& path, bool includeSubdirectories, ETemplatesType templatesType) const +std::vector CTemplateLoader::FindTemplates(const std::string& path, bool includeSubdirectories, ETemplatesType templatesType, const PS::span& ignoredTemplateStarts) const { - std::vector templates; + ListTemplatesState state(ignoredTemplateStarts); if (templatesType != SIMULATION_TEMPLATES && templatesType != ACTOR_TEMPLATES && templatesType != ALL_TEMPLATES) { LOGERROR("Undefined template type (valid: all, simulation, actor)"); - return templates; + return state.templates; } size_t flags = includeSubdirectories ? vfs::DIR_RECURSIVE : 0; if (templatesType == SIMULATION_TEMPLATES || templatesType == ALL_TEMPLATES) - WARN_IF_ERR(vfs::ForEachFile(g_VFS, VfsPath(TEMPLATE_ROOT) / path, AddToTemplates, (uintptr_t)&templates, L"*.xml", flags)); + WARN_IF_ERR(vfs::ForEachFile(g_VFS, VfsPath(TEMPLATE_ROOT) / path, AddToTemplates, (uintptr_t)&state, L"*.xml", flags)); if (templatesType == ACTOR_TEMPLATES || templatesType == ALL_TEMPLATES) - WARN_IF_ERR(vfs::ForEachFile(g_VFS, VfsPath(ACTOR_ROOT) / path, AddActorToTemplates, (uintptr_t)&templates, L"*.xml", flags)); - - return templates; -} - -std::vector CTemplateLoader::FindTemplatesUnrestricted(const std::string& path, bool includeSubdirectories) const -{ - std::vector templates; - - size_t flags = includeSubdirectories ? vfs::DIR_RECURSIVE : 0; - - WARN_IF_ERR(vfs::ForEachFile(g_VFS, VfsPath(TEMPLATE_ROOT) / path, AddToTemplatesUnrestricted, (uintptr_t)&templates, L"*.xml", flags)); + WARN_IF_ERR(vfs::ForEachFile(g_VFS, VfsPath(ACTOR_ROOT) / path, AddActorToTemplates, (uintptr_t)&state, L"*.xml", flags)); - return templates; + return state.templates; } const CParamNode& CTemplateLoader::GetTemplateFileData(const std::string& templateName) Index: source/simulation2/components/CCmpTemplateManager.cpp =================================================================== --- source/simulation2/components/CCmpTemplateManager.cpp +++ source/simulation2/components/CCmpTemplateManager.cpp @@ -28,6 +28,9 @@ #include "ps/TemplateLoader.h" #include "ps/XML/RelaxNG.h" +#include +#include + class CCmpTemplateManager final : public ICmpTemplateManager { public: @@ -214,14 +217,25 @@ std::vector CCmpTemplateManager::FindAllTemplates(bool includeActors) const { ETemplatesType templatesType = includeActors ? ALL_TEMPLATES : SIMULATION_TEMPLATES; - return m_templateLoader.FindTemplates("", true, templatesType); + constexpr std::array templates_to_ignore { + // We want to ignore template_*.xml templates, since they may be incomplete. + "template_", + + // Also ignore some subfolders. + "mixins/", + "special/" + }; + return m_templateLoader.FindTemplates("", true, templatesType, templates_to_ignore); } std::vector> CCmpTemplateManager::GetCivData() { std::vector> data; - - std::vector names = m_templateLoader.FindTemplatesUnrestricted("special/players/", false); + constexpr std::array templates_to_ignore { + // We want to ignore template_*.xml templates, since they may be incomplete. + "template_", + }; + std::vector names = m_templateLoader.FindTemplates("special/players/", false, SIMULATION_TEMPLATES, templates_to_ignore); data.reserve(names.size()); for (const std::string& name : names) {