From bba55706bf5978f6a1ee59bd41500b967428c265 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 31 Oct 2021 15:37:46 +0100 Subject: [PATCH] Add basic parsing for menu lists with only loadMenus instructions --- .../IW4/AssetLoaders/AssetLoaderMenuDef.cpp | 0 .../IW4/AssetLoaders/AssetLoaderMenuDef.h | 17 ++++ .../IW4/AssetLoaders/AssetLoaderMenuList.cpp | 46 +++++++++++ .../IW4/AssetLoaders/AssetLoaderMenuList.h | 17 ++++ src/ObjLoading/Game/IW4/ObjLoaderIW4.cpp | 3 +- .../Parsing/Menu/Domain/CommonFunctionDef.h | 9 ++ .../Parsing/Menu/Domain/CommonItemDef.h | 9 ++ .../Parsing/Menu/Domain/CommonMenuDef.h | 13 +++ .../Parsing/Menu/Domain/MenuFeatureLevel.h | 7 ++ .../Parsing/Menu/MenuFileParser.cpp | 82 +++++++++++++++++++ src/ObjLoading/Parsing/Menu/MenuFileParser.h | 30 +++++++ .../Parsing/Menu/MenuFileParserState.cpp | 7 ++ .../Parsing/Menu/MenuFileParserState.h | 29 +++++++ .../Parsing/Menu/MenuFileReader.cpp | 58 +++++++++++++ src/ObjLoading/Parsing/Menu/MenuFileReader.h | 28 +++++++ .../Menu/Sequence/SequenceCloseBlock.cpp | 67 +++++++++++++++ .../Menu/Sequence/SequenceCloseBlock.h | 14 ++++ .../Menu/Sequence/SequenceFunctionDef.cpp | 20 +++++ .../Menu/Sequence/SequenceFunctionDef.h | 12 +++ .../Parsing/Menu/Sequence/SequenceItemDef.cpp | 20 +++++ .../Parsing/Menu/Sequence/SequenceItemDef.h | 12 +++ .../Menu/Sequence/SequenceLoadMenu.cpp | 27 ++++++ .../Parsing/Menu/Sequence/SequenceLoadMenu.h | 14 ++++ .../Parsing/Menu/Sequence/SequenceMenuDef.cpp | 20 +++++ .../Parsing/Menu/Sequence/SequenceMenuDef.h | 12 +++ .../Sequence/SequenceOpenGlobalScopeBlock.cpp | 18 ++++ .../Sequence/SequenceOpenGlobalScopeBlock.h | 12 +++ 27 files changed, 602 insertions(+), 1 deletion(-) create mode 100644 src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuDef.cpp create mode 100644 src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuDef.h create mode 100644 src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.cpp create mode 100644 src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.h create mode 100644 src/ObjLoading/Parsing/Menu/Domain/CommonFunctionDef.h create mode 100644 src/ObjLoading/Parsing/Menu/Domain/CommonItemDef.h create mode 100644 src/ObjLoading/Parsing/Menu/Domain/CommonMenuDef.h create mode 100644 src/ObjLoading/Parsing/Menu/Domain/MenuFeatureLevel.h create mode 100644 src/ObjLoading/Parsing/Menu/MenuFileParser.cpp create mode 100644 src/ObjLoading/Parsing/Menu/MenuFileParser.h create mode 100644 src/ObjLoading/Parsing/Menu/MenuFileParserState.cpp create mode 100644 src/ObjLoading/Parsing/Menu/MenuFileParserState.h create mode 100644 src/ObjLoading/Parsing/Menu/MenuFileReader.cpp create mode 100644 src/ObjLoading/Parsing/Menu/MenuFileReader.h create mode 100644 src/ObjLoading/Parsing/Menu/Sequence/SequenceCloseBlock.cpp create mode 100644 src/ObjLoading/Parsing/Menu/Sequence/SequenceCloseBlock.h create mode 100644 src/ObjLoading/Parsing/Menu/Sequence/SequenceFunctionDef.cpp create mode 100644 src/ObjLoading/Parsing/Menu/Sequence/SequenceFunctionDef.h create mode 100644 src/ObjLoading/Parsing/Menu/Sequence/SequenceItemDef.cpp create mode 100644 src/ObjLoading/Parsing/Menu/Sequence/SequenceItemDef.h create mode 100644 src/ObjLoading/Parsing/Menu/Sequence/SequenceLoadMenu.cpp create mode 100644 src/ObjLoading/Parsing/Menu/Sequence/SequenceLoadMenu.h create mode 100644 src/ObjLoading/Parsing/Menu/Sequence/SequenceMenuDef.cpp create mode 100644 src/ObjLoading/Parsing/Menu/Sequence/SequenceMenuDef.h create mode 100644 src/ObjLoading/Parsing/Menu/Sequence/SequenceOpenGlobalScopeBlock.cpp create mode 100644 src/ObjLoading/Parsing/Menu/Sequence/SequenceOpenGlobalScopeBlock.h diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuDef.cpp b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuDef.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuDef.h b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuDef.h new file mode 100644 index 00000000..bc9bd3b8 --- /dev/null +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuDef.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Game/IW4/IW4.h" +#include "AssetLoading/BasicAssetLoader.h" +#include "AssetLoading/IAssetLoadingManager.h" +#include "SearchPath/ISearchPath.h" + +namespace IW4 +{ + class AssetLoaderMenuDef final : public BasicAssetLoader + { + public: + _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; + _NODISCARD bool CanLoadFromRaw() const override; + bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; + }; +} diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.cpp b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.cpp new file mode 100644 index 00000000..2c68c4d4 --- /dev/null +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.cpp @@ -0,0 +1,46 @@ +#include "AssetLoaderMenuList.h" + +#include +#include + +#include "Game/IW4/IW4.h" +#include "Parsing/Menu/MenuFileReader.h" +#include "Pool/GlobalAssetPool.h" + +using namespace IW4; + +void* AssetLoaderMenuList::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) +{ + auto* menuList = memory->Create(); + memset(menuList, 0, sizeof(MenuList)); + menuList->name = memory->Dup(assetName.c_str()); + return menuList; +} + +bool AssetLoaderMenuList::CanLoadFromRaw() const +{ + return true; +} + +bool AssetLoaderMenuList::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const +{ + const auto file = searchPath->Open(assetName); + if (!file.IsOpen()) + return false; + + MenuFileReader reader(*file.m_stream, assetName, [searchPath](const std::string& filename) -> std::unique_ptr + { + auto foundFileToInclude = searchPath->Open(filename); + if (!foundFileToInclude.IsOpen() || !foundFileToInclude.m_stream) + return nullptr; + + return std::move(foundFileToInclude.m_stream); + }); + + if(!reader.ReadMenuFile(MenuFeatureLevel::IW4)) + { + std::cout << "Could not read menu list \"" << assetName << "\"\n"; + } + + return true; +} diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.h b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.h new file mode 100644 index 00000000..7afab37f --- /dev/null +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Game/IW4/IW4.h" +#include "AssetLoading/BasicAssetLoader.h" +#include "AssetLoading/IAssetLoadingManager.h" +#include "SearchPath/ISearchPath.h" + +namespace IW4 +{ + class AssetLoaderMenuList final : public BasicAssetLoader + { + public: + _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; + _NODISCARD bool CanLoadFromRaw() const override; + bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; + }; +} diff --git a/src/ObjLoading/Game/IW4/ObjLoaderIW4.cpp b/src/ObjLoading/Game/IW4/ObjLoaderIW4.cpp index 2316912b..c71e0332 100644 --- a/src/ObjLoading/Game/IW4/ObjLoaderIW4.cpp +++ b/src/ObjLoading/Game/IW4/ObjLoaderIW4.cpp @@ -5,6 +5,7 @@ #include "ObjContainer/IPak/IPak.h" #include "ObjLoading.h" #include "AssetLoaders/AssetLoaderLocalizeEntry.h" +#include "AssetLoaders/AssetLoaderMenuList.h" #include "AssetLoaders/AssetLoaderRawFile.h" #include "AssetLoading/AssetLoadingManager.h" #include "Image/Dx9TextureLoader.h" @@ -43,7 +44,7 @@ ObjLoader::ObjLoader() REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_GFXWORLD, GfxWorld)) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_LIGHT_DEF, GfxLightDef)) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FONT, Font_s)) - REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MENULIST, MenuList)) + REGISTER_ASSET_LOADER(AssetLoaderMenuList) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MENU, menuDef_t)) REGISTER_ASSET_LOADER(AssetLoaderLocalizeEntry) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_WEAPON, WeaponCompleteDef)) diff --git a/src/ObjLoading/Parsing/Menu/Domain/CommonFunctionDef.h b/src/ObjLoading/Parsing/Menu/Domain/CommonFunctionDef.h new file mode 100644 index 00000000..40e42237 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Domain/CommonFunctionDef.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +class CommonFunctionDef +{ +public: + std::string m_name; +}; \ No newline at end of file diff --git a/src/ObjLoading/Parsing/Menu/Domain/CommonItemDef.h b/src/ObjLoading/Parsing/Menu/Domain/CommonItemDef.h new file mode 100644 index 00000000..dacff268 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Domain/CommonItemDef.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +class CommonItemDef +{ +public: + std::string m_name; +}; \ No newline at end of file diff --git a/src/ObjLoading/Parsing/Menu/Domain/CommonMenuDef.h b/src/ObjLoading/Parsing/Menu/Domain/CommonMenuDef.h new file mode 100644 index 00000000..22065bd9 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Domain/CommonMenuDef.h @@ -0,0 +1,13 @@ +#pragma once + +#include +#include + +#include "CommonItemDef.h" + +class CommonMenuDef +{ +public: + std::string m_name; + std::vector> m_items; +}; diff --git a/src/ObjLoading/Parsing/Menu/Domain/MenuFeatureLevel.h b/src/ObjLoading/Parsing/Menu/Domain/MenuFeatureLevel.h new file mode 100644 index 00000000..22249c46 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Domain/MenuFeatureLevel.h @@ -0,0 +1,7 @@ +#pragma once + +enum class MenuFeatureLevel +{ + IW4, + IW5 +}; \ No newline at end of file diff --git a/src/ObjLoading/Parsing/Menu/MenuFileParser.cpp b/src/ObjLoading/Parsing/Menu/MenuFileParser.cpp new file mode 100644 index 00000000..aa23b41e --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/MenuFileParser.cpp @@ -0,0 +1,82 @@ +#include "MenuFileParser.h" + +#include "Sequence/SequenceCloseBlock.h" +#include "Sequence/SequenceFunctionDef.h" +#include "Sequence/SequenceItemDef.h" +#include "Sequence/SequenceLoadMenu.h" +#include "Sequence/SequenceMenuDef.h" +#include "Sequence/SequenceOpenGlobalScopeBlock.h" + +MenuFileParser::MenuFileParser(SimpleLexer* lexer, const MenuFeatureLevel featureLevel) + : AbstractParser(lexer, std::make_unique(featureLevel)) +{ + CreateTestCollections(); +} + +void MenuFileParser::AddTest(std::vector& collection, std::unique_ptr test) +{ + collection.push_back(test.get()); + m_all_tests.emplace_back(std::move(test)); +} + +void MenuFileParser::CreateNoScopeTests() +{ + AddTest(m_no_scope_tests, std::make_unique()); +} + +void MenuFileParser::CreateGlobalScopeTests() +{ + AddTest(m_global_scope_tests, std::make_unique()); + AddTest(m_global_scope_tests, std::make_unique()); + AddTest(m_global_scope_tests, std::make_unique()); + AddTest(m_global_scope_tests, std::make_unique()); +} + +void MenuFileParser::CreateFunctionScopeTests() +{ + AddTest(m_function_scope_tests, std::make_unique()); +} + +void MenuFileParser::CreateMenuScopeTests() +{ + AddTest(m_menu_scope_tests, std::make_unique()); + AddTest(m_menu_scope_tests, std::make_unique()); +} + +void MenuFileParser::CreateItemScopeTests() +{ + AddTest(m_item_scope_tests, std::make_unique()); +} + +void MenuFileParser::CreateTestCollections() +{ + m_all_tests.clear(); + m_no_scope_tests.clear(); + m_global_scope_tests.clear(); + m_function_scope_tests.clear(); + m_menu_scope_tests.clear(); + m_item_scope_tests.clear(); + + CreateNoScopeTests(); + CreateGlobalScopeTests(); + CreateFunctionScopeTests(); + CreateMenuScopeTests(); + CreateItemScopeTests(); +} + +const std::vector& MenuFileParser::GetTestsForState() +{ + if (!m_state->m_in_global_scope) + return m_no_scope_tests; + + if (m_state->m_current_item) + return m_item_scope_tests; + + if (m_state->m_current_function) + return m_function_scope_tests; + + if (m_state->m_current_menu) + return m_menu_scope_tests; + + return m_global_scope_tests; +} diff --git a/src/ObjLoading/Parsing/Menu/MenuFileParser.h b/src/ObjLoading/Parsing/Menu/MenuFileParser.h new file mode 100644 index 00000000..4c1aca4c --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/MenuFileParser.h @@ -0,0 +1,30 @@ +#pragma once + +#include "MenuFileParserState.h" +#include "Parsing/Simple/SimpleLexer.h" +#include "Parsing/Simple/SimpleParserValue.h" +#include "Parsing/Impl/AbstractParser.h" + +class MenuFileParser final : public AbstractParser +{ + std::vector> m_all_tests; + std::vector m_no_scope_tests; + std::vector m_global_scope_tests; + std::vector m_function_scope_tests; + std::vector m_menu_scope_tests; + std::vector m_item_scope_tests; + + void AddTest(std::vector& collection, std::unique_ptr test); + void CreateNoScopeTests(); + void CreateGlobalScopeTests(); + void CreateFunctionScopeTests(); + void CreateMenuScopeTests(); + void CreateItemScopeTests(); + void CreateTestCollections(); + +protected: + const std::vector& GetTestsForState() override; + +public: + MenuFileParser(SimpleLexer* lexer, MenuFeatureLevel featureLevel); +}; diff --git a/src/ObjLoading/Parsing/Menu/MenuFileParserState.cpp b/src/ObjLoading/Parsing/Menu/MenuFileParserState.cpp new file mode 100644 index 00000000..df27f35c --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/MenuFileParserState.cpp @@ -0,0 +1,7 @@ +#include "MenuFileParserState.h" + +MenuFileParserState::MenuFileParserState(const MenuFeatureLevel featureLevel) + : m_feature_level(featureLevel), + m_in_global_scope(false) +{ +} diff --git a/src/ObjLoading/Parsing/Menu/MenuFileParserState.h b/src/ObjLoading/Parsing/Menu/MenuFileParserState.h new file mode 100644 index 00000000..036860ff --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/MenuFileParserState.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include +#include + +#include "Domain/CommonFunctionDef.h" +#include "Domain/CommonMenuDef.h" +#include "Domain/MenuFeatureLevel.h" + +class MenuFileParserState +{ +public: + const MenuFeatureLevel m_feature_level; + + std::vector m_menus_to_load; + std::vector> m_functions; + std::vector> m_menus; + + std::map m_functions_by_name; + std::map m_menus_by_name; + + bool m_in_global_scope; + std::unique_ptr m_current_function; + std::unique_ptr m_current_menu; + std::unique_ptr m_current_item; + + explicit MenuFileParserState(MenuFeatureLevel featureLevel); +}; diff --git a/src/ObjLoading/Parsing/Menu/MenuFileReader.cpp b/src/ObjLoading/Parsing/Menu/MenuFileReader.cpp new file mode 100644 index 00000000..6144a0c3 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/MenuFileReader.cpp @@ -0,0 +1,58 @@ +#include "MenuFileReader.h" + +#include "MenuFileParser.h" +#include "Parsing/Impl/CommentRemovingStreamProxy.h" +#include "Parsing/Impl/DefinesStreamProxy.h" +#include "Parsing/Impl/IncludingStreamProxy.h" +#include "Parsing/Impl/ParserMultiInputStream.h" +#include "Parsing/Impl/ParserSingleInputStream.h" +#include "Parsing/Simple/SimpleLexer.h" + +MenuFileReader::MenuFileReader(std::istream& stream, std::string fileName, include_callback_t includeCallback) + : m_file_name(std::move(fileName)), + m_stream(nullptr) +{ + OpenBaseStream(stream, std::move(includeCallback)); + SetupStreamProxies(); + m_stream = m_open_streams.back().get(); +} + +MenuFileReader::MenuFileReader(std::istream& stream, std::string fileName) + : m_file_name(std::move(fileName)), + m_stream(nullptr) +{ + OpenBaseStream(stream, nullptr); + SetupStreamProxies(); + m_stream = m_open_streams.back().get(); +} + +bool MenuFileReader::OpenBaseStream(std::istream& stream, include_callback_t includeCallback) +{ + if(includeCallback) + m_open_streams.emplace_back(std::make_unique(stream, m_file_name, std::move(includeCallback))); + else + m_open_streams.emplace_back(std::make_unique(stream, m_file_name)); + + return true; +} + +void MenuFileReader::SetupStreamProxies() +{ + m_open_streams.emplace_back(std::make_unique(m_open_streams.back().get())); + m_open_streams.emplace_back(std::make_unique(m_open_streams.back().get())); + m_open_streams.emplace_back(std::make_unique(m_open_streams.back().get())); + + m_stream = m_open_streams.back().get(); +} + +bool MenuFileReader::ReadMenuFile(MenuFeatureLevel featureLevel) +{ + const auto lexer = std::make_unique(m_stream, SimpleLexer::Config{false, true, false}); + const auto parser = std::make_unique(lexer.get(), featureLevel); + + if (parser->Parse()) + return true; + + std::cout << "Parsing menu file failed!" << std::endl; + return false; +} diff --git a/src/ObjLoading/Parsing/Menu/MenuFileReader.h b/src/ObjLoading/Parsing/Menu/MenuFileReader.h new file mode 100644 index 00000000..276697a2 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/MenuFileReader.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include + +#include "Domain/MenuFeatureLevel.h" +#include "Parsing/IParserLineStream.h" + +class MenuFileReader +{ +public: + using include_callback_t = std::function(const std::string& filename)>; + +private: + std::string m_file_name; + IParserLineStream* m_stream; + std::vector> m_open_streams; + + bool OpenBaseStream(std::istream& stream, include_callback_t includeCallback); + void SetupStreamProxies(); + +public: + MenuFileReader(std::istream& stream, std::string fileName); + MenuFileReader(std::istream& stream, std::string fileName, include_callback_t includeCallback); + + bool ReadMenuFile(MenuFeatureLevel featureLevel); +}; diff --git a/src/ObjLoading/Parsing/Menu/Sequence/SequenceCloseBlock.cpp b/src/ObjLoading/Parsing/Menu/Sequence/SequenceCloseBlock.cpp new file mode 100644 index 00000000..b9ed1722 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Sequence/SequenceCloseBlock.cpp @@ -0,0 +1,67 @@ +#include "SequenceCloseBlock.h" + +#include + +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +SequenceCloseBlock::SequenceCloseBlock() +{ + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Char('}').Capture(CAPTURE_TOKEN) + }); +} + +void SequenceCloseBlock::ProcessMatch(MenuFileParserState* state, SequenceResult& result) const +{ + assert(state->m_current_item || state->m_current_menu || state->m_current_function || state->m_in_global_scope); + assert(!state->m_current_item || (state->m_current_item && state->m_current_menu)); + + if(state->m_current_item && state->m_current_menu) + { + state->m_current_menu->m_items.emplace_back(std::move(state->m_current_item)); + state->m_current_item = nullptr; + } + else if(state->m_current_menu) + { + if(state->m_current_menu->m_name.empty()) + throw ParsingException(result.NextCapture(CAPTURE_TOKEN).GetPos(), "Menu must have a name"); + + const auto existingMenu = state->m_menus_by_name.find(state->m_current_menu->m_name); + if(existingMenu == state->m_menus_by_name.end()) + { + state->m_menus_by_name.emplace(std::make_pair(state->m_current_menu->m_name, state->m_current_menu.get())); + state->m_menus.emplace_back(std::move(state->m_current_menu)); + state->m_current_menu = nullptr; + } + else + { + std::ostringstream ss; + ss << "Menu with name \"" << state->m_current_menu->m_name << "\" already exists"; + throw ParsingException(result.NextCapture(CAPTURE_TOKEN).GetPos(), ss.str()); + } + } + else if(state->m_current_function) + { + const auto existingFunction = state->m_functions_by_name.find(state->m_current_function->m_name); + if (existingFunction == state->m_functions_by_name.end()) + { + state->m_functions_by_name.emplace(std::make_pair(state->m_current_function->m_name, state->m_current_function.get())); + state->m_functions.emplace_back(std::move(state->m_current_function)); + state->m_current_function = nullptr; + } + else + { + std::ostringstream ss; + ss << "Function with name \"" << state->m_current_menu->m_name << "\" already exists"; + throw ParsingException(result.NextCapture(CAPTURE_TOKEN).GetPos(), ss.str()); + } + } + else if(state->m_in_global_scope) + { + state->m_in_global_scope = false; + } + else + throw ParsingException(result.NextCapture(CAPTURE_TOKEN).GetPos(), "Invalid close block"); +} diff --git a/src/ObjLoading/Parsing/Menu/Sequence/SequenceCloseBlock.h b/src/ObjLoading/Parsing/Menu/Sequence/SequenceCloseBlock.h new file mode 100644 index 00000000..7a7c836e --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Sequence/SequenceCloseBlock.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Parsing/Menu/MenuFileParser.h" + +class SequenceCloseBlock final : public MenuFileParser::sequence_t +{ + static constexpr auto CAPTURE_TOKEN = 1; + +protected: + void ProcessMatch(MenuFileParserState* state, SequenceResult& result) const override; + +public: + SequenceCloseBlock(); +}; diff --git a/src/ObjLoading/Parsing/Menu/Sequence/SequenceFunctionDef.cpp b/src/ObjLoading/Parsing/Menu/Sequence/SequenceFunctionDef.cpp new file mode 100644 index 00000000..c6c4b393 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Sequence/SequenceFunctionDef.cpp @@ -0,0 +1,20 @@ +#include "SequenceFunctionDef.h" + +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +SequenceFunctionDef::SequenceFunctionDef() +{ + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Keyword("functionDef"), + create.Char('{'), + }); +} + +void SequenceFunctionDef::ProcessMatch(MenuFileParserState* state, SequenceResult& result) const +{ + assert(!state->m_current_menu); + + state->m_current_item = std::make_unique(); +} diff --git a/src/ObjLoading/Parsing/Menu/Sequence/SequenceFunctionDef.h b/src/ObjLoading/Parsing/Menu/Sequence/SequenceFunctionDef.h new file mode 100644 index 00000000..84603a31 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Sequence/SequenceFunctionDef.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Parsing/Menu/MenuFileParser.h" + +class SequenceFunctionDef final : public MenuFileParser::sequence_t +{ +protected: + void ProcessMatch(MenuFileParserState* state, SequenceResult& result) const override; + +public: + SequenceFunctionDef(); +}; diff --git a/src/ObjLoading/Parsing/Menu/Sequence/SequenceItemDef.cpp b/src/ObjLoading/Parsing/Menu/Sequence/SequenceItemDef.cpp new file mode 100644 index 00000000..3a4f176e --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Sequence/SequenceItemDef.cpp @@ -0,0 +1,20 @@ +#include "SequenceItemDef.h" + +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +SequenceItemDef::SequenceItemDef() +{ + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Keyword("itemDef"), + create.Char('{'), + }); +} + +void SequenceItemDef::ProcessMatch(MenuFileParserState* state, SequenceResult& result) const +{ + assert(!state->m_current_menu); + + state->m_current_item = std::make_unique(); +} diff --git a/src/ObjLoading/Parsing/Menu/Sequence/SequenceItemDef.h b/src/ObjLoading/Parsing/Menu/Sequence/SequenceItemDef.h new file mode 100644 index 00000000..ed1b8c58 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Sequence/SequenceItemDef.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Parsing/Menu/MenuFileParser.h" + +class SequenceItemDef final : public MenuFileParser::sequence_t +{ +protected: + void ProcessMatch(MenuFileParserState* state, SequenceResult& result) const override; + +public: + SequenceItemDef(); +}; diff --git a/src/ObjLoading/Parsing/Menu/Sequence/SequenceLoadMenu.cpp b/src/ObjLoading/Parsing/Menu/Sequence/SequenceLoadMenu.cpp new file mode 100644 index 00000000..77406cc4 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Sequence/SequenceLoadMenu.cpp @@ -0,0 +1,27 @@ +#include "SequenceLoadMenu.h" + +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +SequenceLoadMenu::SequenceLoadMenu() +{ + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Keyword("loadMenu"), + create.Char('{'), + create.String().Capture(CAPTURE_MENU_NAME), + create.Char('}'), + }); +} + +void SequenceLoadMenu::ProcessMatch(MenuFileParserState* state, SequenceResult& result) const +{ + assert(!state->m_current_menu); + + const auto& menuNameToken = result.NextCapture(CAPTURE_MENU_NAME); + + if (menuNameToken.StringValue().empty()) + throw ParsingException(menuNameToken.GetPos(), "Invalid menu name"); + + state->m_menus_to_load.emplace_back(menuNameToken.StringValue()); +} diff --git a/src/ObjLoading/Parsing/Menu/Sequence/SequenceLoadMenu.h b/src/ObjLoading/Parsing/Menu/Sequence/SequenceLoadMenu.h new file mode 100644 index 00000000..108a273e --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Sequence/SequenceLoadMenu.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Parsing/Menu/MenuFileParser.h" + +class SequenceLoadMenu final : public MenuFileParser::sequence_t +{ + static constexpr auto CAPTURE_MENU_NAME = 1; + +protected: + void ProcessMatch(MenuFileParserState* state, SequenceResult& result) const override; + +public: + SequenceLoadMenu(); +}; diff --git a/src/ObjLoading/Parsing/Menu/Sequence/SequenceMenuDef.cpp b/src/ObjLoading/Parsing/Menu/Sequence/SequenceMenuDef.cpp new file mode 100644 index 00000000..91a22a2a --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Sequence/SequenceMenuDef.cpp @@ -0,0 +1,20 @@ +#include "SequenceMenuDef.h" + +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +SequenceMenuDef::SequenceMenuDef() +{ + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Keyword("menuDef"), + create.Char('{'), + }); +} + +void SequenceMenuDef::ProcessMatch(MenuFileParserState* state, SequenceResult& result) const +{ + assert(!state->m_current_menu); + + state->m_current_menu = std::make_unique(); +} diff --git a/src/ObjLoading/Parsing/Menu/Sequence/SequenceMenuDef.h b/src/ObjLoading/Parsing/Menu/Sequence/SequenceMenuDef.h new file mode 100644 index 00000000..c17289ef --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Sequence/SequenceMenuDef.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Parsing/Menu/MenuFileParser.h" + +class SequenceMenuDef final : public MenuFileParser::sequence_t +{ +protected: + void ProcessMatch(MenuFileParserState* state, SequenceResult& result) const override; + +public: + SequenceMenuDef(); +}; diff --git a/src/ObjLoading/Parsing/Menu/Sequence/SequenceOpenGlobalScopeBlock.cpp b/src/ObjLoading/Parsing/Menu/Sequence/SequenceOpenGlobalScopeBlock.cpp new file mode 100644 index 00000000..458f28f6 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Sequence/SequenceOpenGlobalScopeBlock.cpp @@ -0,0 +1,18 @@ +#include "SequenceOpenGlobalScopeBlock.h" + +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +SequenceOpenGlobalScopeBlock::SequenceOpenGlobalScopeBlock() +{ + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Char('{') + }); +} + +void SequenceOpenGlobalScopeBlock::ProcessMatch(MenuFileParserState* state, SequenceResult& result) const +{ + assert(!state->m_in_global_scope); + state->m_in_global_scope = true; +} diff --git a/src/ObjLoading/Parsing/Menu/Sequence/SequenceOpenGlobalScopeBlock.h b/src/ObjLoading/Parsing/Menu/Sequence/SequenceOpenGlobalScopeBlock.h new file mode 100644 index 00000000..aab4eccf --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Sequence/SequenceOpenGlobalScopeBlock.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Parsing/Menu/MenuFileParser.h" + +class SequenceOpenGlobalScopeBlock final : public MenuFileParser::sequence_t +{ +protected: + void ProcessMatch(MenuFileParserState* state, SequenceResult& result) const override; + +public: + SequenceOpenGlobalScopeBlock(); +};