diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStructuredDataDefSet.cpp b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStructuredDataDefSet.cpp index 4360e57a..b6a5c8e2 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStructuredDataDefSet.cpp +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStructuredDataDefSet.cpp @@ -4,6 +4,7 @@ #include "ObjLoading.h" #include "Game/IW4/IW4.h" +#include "Parsing/StructuredDataDef/StructuredDataDefReader.h" #include "Pool/GlobalAssetPool.h" using namespace IW4; @@ -15,3 +16,35 @@ void* AssetLoaderStructuredDataDefSet::CreateEmptyAsset(const std::string& asset structuredDataDefSet->name = memory->Dup(assetName.c_str()); return structuredDataDefSet; } + +bool AssetLoaderStructuredDataDefSet::CanLoadFromRaw() const +{ + return true; +} + +bool AssetLoaderStructuredDataDefSet::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; + + auto* structuredDataDefSet = memory->Create(); + structuredDataDefSet->name = memory->Dup(assetName.c_str()); + + StructuredDataDefReader reader(*file.m_stream, assetName, [searchPath](const std::string& filename, const std::string& sourceFile) -> std::unique_ptr + { + auto foundFileToInclude = searchPath->Open(filename); + if (!foundFileToInclude.IsOpen() || !foundFileToInclude.m_stream) + return nullptr; + + return std::move(foundFileToInclude.m_stream); + }); + + const auto defs = reader.ReadStructureDataDefs(); + + // TODO Convert defs + + manager->AddAsset(ASSET_TYPE_STRUCTURED_DATA_DEF, assetName, structuredDataDefSet); + + return true; +} diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStructuredDataDefSet.h b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStructuredDataDefSet.h index 7491eb63..6155bf63 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStructuredDataDefSet.h +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStructuredDataDefSet.h @@ -10,5 +10,7 @@ namespace IW4 { 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/Parsing/StructuredDataDef/Domain/CommonStructuredDataDef.cpp b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDef.cpp new file mode 100644 index 00000000..908bc43e --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDef.cpp @@ -0,0 +1,13 @@ +#include "CommonStructuredDataDef.h" + +CommonStructuredDataDef::CommonStructuredDataDef() + : CommonStructuredDataDef(0) +{ +} + +CommonStructuredDataDef::CommonStructuredDataDef(const int version) + : m_version(version), + m_checksum(0u), + m_size(0u) +{ +} diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDef.h b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDef.h new file mode 100644 index 00000000..e688591d --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDef.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +#include "CommonStructuredDataDefEnum.h" +#include "CommonStructuredDataDefStruct.h" + +class CommonStructuredDataDef +{ +public: + std::vector> m_enums; + std::vector< std::unique_ptr> m_structs; + std::vector m_indexed_arrays; + std::vector m_enumed_arrays; + + int m_version; + size_t m_checksum; + CommonStructuredDataDefType m_root_type; + size_t m_size; + + CommonStructuredDataDef(); + explicit CommonStructuredDataDef(int version); +}; diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefEnum.cpp b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefEnum.cpp new file mode 100644 index 00000000..af2e3ea9 --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefEnum.cpp @@ -0,0 +1,20 @@ +#include "CommonStructuredDataDefEnum.h" + +CommonStructuredDataDefEnumEntry::CommonStructuredDataDefEnumEntry() + : m_value(0u) +{ +} + +CommonStructuredDataDefEnumEntry::CommonStructuredDataDefEnumEntry(std::string name, const size_t value) + : m_name(std::move(name)), + m_value(value) +{ +} + +CommonStructuredDataDefEnum::CommonStructuredDataDefEnum() += default; + +CommonStructuredDataDefEnum::CommonStructuredDataDefEnum(std::string name) + : m_name(std::move(name)) +{ +} diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefEnum.h b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefEnum.h new file mode 100644 index 00000000..03788831 --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefEnum.h @@ -0,0 +1,21 @@ +#pragma once +#include +#include + +struct CommonStructuredDataDefEnumEntry +{ + std::string m_name; + size_t m_value; + + CommonStructuredDataDefEnumEntry(); + CommonStructuredDataDefEnumEntry(std::string name, size_t value); +}; + +struct CommonStructuredDataDefEnum +{ + std::string m_name; + std::vector m_entries; + + CommonStructuredDataDefEnum(); + explicit CommonStructuredDataDefEnum(std::string name); +}; \ No newline at end of file diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefStruct.cpp b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefStruct.cpp new file mode 100644 index 00000000..93427303 --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefStruct.cpp @@ -0,0 +1,30 @@ +#include "CommonStructuredDataDefStruct.h" + +CommonStructuredDataDefStructEntry::CommonStructuredDataDefStructEntry() + : m_offset(0u) +{ +} + +CommonStructuredDataDefStructEntry::CommonStructuredDataDefStructEntry(std::string name) + : m_name(std::move(name)), + m_offset(0u) +{ +} + +CommonStructuredDataDefStructEntry::CommonStructuredDataDefStructEntry(std::string name, const CommonStructuredDataDefType type, const size_t offset) + : m_name(std::move(name)), + m_type(type), + m_offset(offset) +{ +} + +CommonStructuredDataDefStruct::CommonStructuredDataDefStruct() + : m_size(0u) +{ +} + +CommonStructuredDataDefStruct::CommonStructuredDataDefStruct(std::string name) + : m_name(std::move(name)), + m_size(0u) +{ +} diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefStruct.h b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefStruct.h new file mode 100644 index 00000000..f68b0bfd --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefStruct.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include + +#include "CommonStructuredDataDefTypes.h" + +struct CommonStructuredDataDefStructEntry +{ + std::string m_name; + CommonStructuredDataDefType m_type; + size_t m_offset; + + CommonStructuredDataDefStructEntry(); + explicit CommonStructuredDataDefStructEntry(std::string name); + CommonStructuredDataDefStructEntry(std::string name, CommonStructuredDataDefType type, size_t offset); +}; + +struct CommonStructuredDataDefStruct +{ + std::string m_name; + std::vector m_entries; + size_t m_size; + + CommonStructuredDataDefStruct(); + explicit CommonStructuredDataDefStruct(std::string name); +}; \ No newline at end of file diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefTypes.cpp b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefTypes.cpp new file mode 100644 index 00000000..ca7020d7 --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefTypes.cpp @@ -0,0 +1,41 @@ +#include "CommonStructuredDataDefTypes.h" + +CommonStructuredDataDefType::CommonStructuredDataDefType() + : m_category(CommonStructuredDataDefTypeCategory::UNKNOWN), + m_info({0}) +{ +} + +CommonStructuredDataDefType::CommonStructuredDataDefType(const CommonStructuredDataDefTypeCategory category) + : m_category(category), + m_info({0}) +{ +} + +CommonStructuredDataDefType::CommonStructuredDataDefType(const CommonStructuredDataDefTypeCategory category, const size_t extraInfo) + : m_category(category), + m_info({extraInfo}) +{ +} + +CommonStructuredDataDefIndexedArray::CommonStructuredDataDefIndexedArray() + : m_array_size(0u) +{ +} + +CommonStructuredDataDefIndexedArray::CommonStructuredDataDefIndexedArray(const CommonStructuredDataDefType type, const size_t arraySize) + : m_array_type(type), + m_array_size(arraySize) +{ +} + +CommonStructuredDataDefEnumedArray::CommonStructuredDataDefEnumedArray() + : m_enum_index(0u) +{ +} + +CommonStructuredDataDefEnumedArray::CommonStructuredDataDefEnumedArray(const CommonStructuredDataDefType type, const size_t enumIndex) + : m_array_type(type), + m_enum_index(enumIndex) +{ +} diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefTypes.h b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefTypes.h new file mode 100644 index 00000000..8f91972d --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefTypes.h @@ -0,0 +1,52 @@ +#pragma once + +#include + +enum class CommonStructuredDataDefTypeCategory +{ + UNKNOWN, + INT, + BYTE, + BOOL, + STRING, + FLOAT, + SHORT, + ENUM, + STRUCT, + INDEXED_ARRAY, + ENUM_ARRAY +}; + +union CommonStructuredDataDefTypeExtraInfo +{ + size_t string_length; + size_t type_index; +}; + +struct CommonStructuredDataDefType +{ + CommonStructuredDataDefTypeCategory m_category; + CommonStructuredDataDefTypeExtraInfo m_info; + + CommonStructuredDataDefType(); + explicit CommonStructuredDataDefType(CommonStructuredDataDefTypeCategory category); + CommonStructuredDataDefType(CommonStructuredDataDefTypeCategory category, size_t extraInfo); +}; + +struct CommonStructuredDataDefIndexedArray +{ + CommonStructuredDataDefType m_array_type; + size_t m_array_size; + + CommonStructuredDataDefIndexedArray(); + CommonStructuredDataDefIndexedArray(CommonStructuredDataDefType type, size_t arraySize); +}; + +struct CommonStructuredDataDefEnumedArray +{ + CommonStructuredDataDefType m_array_type; + size_t m_enum_index; + + CommonStructuredDataDefEnumedArray(); + CommonStructuredDataDefEnumedArray(CommonStructuredDataDefType type, size_t enumIndex); +}; \ No newline at end of file diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefDefScopeSequences.cpp b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefDefScopeSequences.cpp new file mode 100644 index 00000000..87f0fcf8 --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefDefScopeSequences.cpp @@ -0,0 +1,99 @@ +#include "StructuredDataDefDefScopeSequences.h" + +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +namespace sdd::def_scope_sequences +{ + class SequenceEnum final : public StructuredDataDefParser::sequence_t + { + static constexpr auto CAPTURE_NAME = 1; + + public: + SequenceEnum() + { + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Keyword("enum"), + create.Identifier().Capture(CAPTURE_NAME), + create.Char('{') + }); + } + + protected: + void ProcessMatch(StructuredDataDefParserState* state, SequenceResult& result) const override + { + assert(state->m_current_def); + + auto newEnum = std::make_unique(result.NextCapture(CAPTURE_NAME).IdentifierValue()); + state->m_current_enum = newEnum.get(); + state->m_current_def->m_enums.emplace_back(std::move(newEnum)); + } + }; + + class SequenceStruct final : public StructuredDataDefParser::sequence_t + { + static constexpr auto CAPTURE_NAME = 1; + + public: + SequenceStruct() + { + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Keyword("struct"), + create.Identifier().Capture(CAPTURE_NAME), + create.Char('{') + }); + } + + protected: + void ProcessMatch(StructuredDataDefParserState* state, SequenceResult& result) const override + { + assert(state->m_current_def); + + auto newStruct = std::make_unique(result.NextCapture(CAPTURE_NAME).IdentifierValue()); + state->m_current_struct = newStruct.get(); + state->m_current_def->m_structs.emplace_back(std::move(newStruct)); + } + }; + + class SequenceCloseScope final : public StructuredDataDefParser::sequence_t + { + static constexpr auto CAPTURE_NAME = 1; + + public: + SequenceCloseScope() + { + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Char('}') + }); + } + + protected: + void ProcessMatch(StructuredDataDefParserState* state, SequenceResult& result) const override + { + assert(state->m_current_enum == nullptr); + assert(state->m_current_struct == nullptr); + + state->m_current_def = nullptr; + } + }; +} + +using namespace sdd; +using namespace def_scope_sequences; + +StructuredDataDefDefScopeSequences::StructuredDataDefDefScopeSequences(std::vector>& allSequences, + std::vector& scopeSequences) + : AbstractScopeSequenceHolder(allSequences, scopeSequences) +{ +} + +void StructuredDataDefDefScopeSequences::AddSequences() const +{ + AddSequence(std::make_unique()); + AddSequence(std::make_unique()); +} diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefDefScopeSequences.h b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefDefScopeSequences.h new file mode 100644 index 00000000..97d4f71a --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefDefScopeSequences.h @@ -0,0 +1,15 @@ +#pragma once + +#include "Parsing/Sequence/AbstractScopeSequenceHolder.h" +#include "Parsing/StructuredDataDef/StructuredDataDefParser.h" + +namespace sdd +{ + class StructuredDataDefDefScopeSequences final : AbstractScopeSequenceHolder + { + public: + StructuredDataDefDefScopeSequences(std::vector>& allSequences, std::vector& scopeSequences); + + void AddSequences() const; + }; +} diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefEnumScopeSequences.cpp b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefEnumScopeSequences.cpp new file mode 100644 index 00000000..bf0e242c --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefEnumScopeSequences.cpp @@ -0,0 +1,77 @@ +#include "StructuredDataDefEnumScopeSequences.h" + +#include + +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +namespace sdd::enum_scope_sequences +{ + class SequenceEnumEntry final : public StructuredDataDefParser::sequence_t + { + static constexpr auto CAPTURE_ENTRY_VALUE = 1; + + public: + SequenceEnumEntry() + { + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.String().Capture(CAPTURE_ENTRY_VALUE), + create.Or({ + create.Char(','), + create.Char('}').NoConsume() + }) + }); + } + + protected: + void ProcessMatch(StructuredDataDefParserState* state, SequenceResult& result) const override + { + assert(state->m_current_enum); + + state->m_current_enum->m_entries.emplace_back(result.NextCapture(CAPTURE_ENTRY_VALUE).StringValue(), state->m_current_enum->m_entries.size()); + } + }; + + class SequenceCloseEnum final : public StructuredDataDefParser::sequence_t + { + public: + SequenceCloseEnum() + { + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Char('}'), + create.Optional(create.Char(';')) + }); + } + + protected: + void ProcessMatch(StructuredDataDefParserState* state, SequenceResult& result) const override + { + assert(state->m_current_enum != nullptr); + + std::sort(state->m_current_enum->m_entries.begin(), state->m_current_enum->m_entries.end(), [](const CommonStructuredDataDefEnumEntry& e1, const CommonStructuredDataDefEnumEntry& e2) + { + return e1.m_name < e2.m_name; + }); + + state->m_current_enum = nullptr; + } + }; +} + +using namespace sdd; +using namespace enum_scope_sequences; + +StructuredDataDefEnumScopeSequences::StructuredDataDefEnumScopeSequences(std::vector>& allSequences, + std::vector& scopeSequences) + : AbstractScopeSequenceHolder(allSequences, scopeSequences) +{ +} + +void StructuredDataDefEnumScopeSequences::AddSequences() const +{ + AddSequence(std::make_unique()); + AddSequence(std::make_unique()); +} diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefEnumScopeSequences.h b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefEnumScopeSequences.h new file mode 100644 index 00000000..2a8cb3b7 --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefEnumScopeSequences.h @@ -0,0 +1,15 @@ +#pragma once + +#include "Parsing/Sequence/AbstractScopeSequenceHolder.h" +#include "Parsing/StructuredDataDef/StructuredDataDefParser.h" + +namespace sdd +{ + class StructuredDataDefEnumScopeSequences final : AbstractScopeSequenceHolder + { + public: + StructuredDataDefEnumScopeSequences(std::vector>& allSequences, std::vector& scopeSequences); + + void AddSequences() const; + }; +} diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefNoScopeSequences.cpp b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefNoScopeSequences.cpp new file mode 100644 index 00000000..73c6f70e --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefNoScopeSequences.cpp @@ -0,0 +1,45 @@ +#include "StructuredDataDefNoScopeSequences.h" + +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +namespace sdd::no_scope_sequences +{ + class SequenceVersion final : public StructuredDataDefParser::sequence_t + { + static constexpr auto CAPTURE_VERSION = 1; + + public: + SequenceVersion() + { + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Keyword("version"), + create.Integer().Capture(CAPTURE_VERSION), + create.Char('{') + }); + } + + protected: + void ProcessMatch(StructuredDataDefParserState* state, SequenceResult& result) const override + { + auto newDef = std::make_unique(result.NextCapture(CAPTURE_VERSION).IntegerValue()); + state->m_current_def = newDef.get(); + state->m_defs.emplace_back(std::move(newDef)); + } + }; +} + +using namespace sdd; +using namespace no_scope_sequences; + +StructuredDataDefNoScopeSequences::StructuredDataDefNoScopeSequences(std::vector>& allSequences, + std::vector& scopeSequences) + : AbstractScopeSequenceHolder(allSequences, scopeSequences) +{ +} + +void StructuredDataDefNoScopeSequences::AddSequences() const +{ + AddSequence(std::make_unique()); +} diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefNoScopeSequences.h b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefNoScopeSequences.h new file mode 100644 index 00000000..228a680d --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefNoScopeSequences.h @@ -0,0 +1,15 @@ +#pragma once + +#include "Parsing/Sequence/AbstractScopeSequenceHolder.h" +#include "Parsing/StructuredDataDef/StructuredDataDefParser.h" + +namespace sdd +{ + class StructuredDataDefNoScopeSequences final : AbstractScopeSequenceHolder + { + public: + StructuredDataDefNoScopeSequences(std::vector>& allSequences, std::vector& scopeSequences); + + void AddSequences() const; + }; +} diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefStructScopeSequences.cpp b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefStructScopeSequences.cpp new file mode 100644 index 00000000..4af736ec --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefStructScopeSequences.cpp @@ -0,0 +1,47 @@ +#include "StructuredDataDefStructScopeSequences.h" + +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +namespace sdd::struct_scope_sequences +{ + class SequenceVersion final : public StructuredDataDefParser::sequence_t + { + static constexpr auto CAPTURE_VERSION = 1; + + public: + SequenceVersion() + { + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Keyword("version"), + create.Integer().Capture(CAPTURE_VERSION), + create.Char('{') + }); + } + + protected: + void ProcessMatch(StructuredDataDefParserState* state, SequenceResult& result) const override + { + auto newDef = std::make_unique(); + newDef->m_version = result.NextCapture(CAPTURE_VERSION).IntegerValue(); + + state->m_current_def = newDef.get(); + state->m_defs.emplace_back(std::move(newDef)); + } + }; +} + +using namespace sdd; +using namespace struct_scope_sequences; + +StructuredDataDefStructScopeSequences::StructuredDataDefStructScopeSequences(std::vector>& allSequences, + std::vector& scopeSequences) + : AbstractScopeSequenceHolder(allSequences, scopeSequences) +{ +} + +void StructuredDataDefStructScopeSequences::AddSequences() const +{ + AddSequence(std::make_unique()); +} diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefStructScopeSequences.h b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefStructScopeSequences.h new file mode 100644 index 00000000..f606ff8e --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefStructScopeSequences.h @@ -0,0 +1,15 @@ +#pragma once + +#include "Parsing/Sequence/AbstractScopeSequenceHolder.h" +#include "Parsing/StructuredDataDef/StructuredDataDefParser.h" + +namespace sdd +{ + class StructuredDataDefStructScopeSequences final : AbstractScopeSequenceHolder + { + public: + StructuredDataDefStructScopeSequences(std::vector>& allSequences, std::vector& scopeSequences); + + void AddSequences() const; + }; +} diff --git a/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefParser.cpp b/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefParser.cpp new file mode 100644 index 00000000..6a31244d --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefParser.cpp @@ -0,0 +1,54 @@ +#include "StructuredDataDefParser.h" + +#include "Sequence/StructuredDataDefDefScopeSequences.h" +#include "Sequence/StructuredDataDefEnumScopeSequences.h" +#include "Sequence/StructuredDataDefNoScopeSequences.h" +#include "Sequence/StructuredDataDefStructScopeSequences.h" + +using namespace sdd; + +StructuredDataDefParser::StructuredDataDefParser(SimpleLexer* lexer) + : AbstractParser(lexer, std::make_unique()) +{ + CreateSequenceCollections(); +} + +void StructuredDataDefParser::CreateSequenceCollections() +{ + m_all_tests.clear(); + m_no_scope_tests.clear(); + m_def_tests.clear(); + m_enum_tests.clear(); + m_struct_tests.clear(); + + const StructuredDataDefNoScopeSequences noScopeSequences(m_all_tests, m_no_scope_tests); + noScopeSequences.AddSequences(); + + const StructuredDataDefDefScopeSequences defScopeSequences(m_all_tests, m_def_tests); + defScopeSequences.AddSequences(); + + const StructuredDataDefEnumScopeSequences enumScopeSequences(m_all_tests, m_enum_tests); + enumScopeSequences.AddSequences(); + + const StructuredDataDefStructScopeSequences structScopeSequences(m_all_tests, m_struct_tests); + structScopeSequences.AddSequences(); +} + +const std::vector& StructuredDataDefParser::GetTestsForState() +{ + if (!m_state->m_current_def) + return m_no_scope_tests; + + if (m_state->m_current_enum) + return m_enum_tests; + + if (m_state->m_current_struct) + return m_struct_tests; + + return m_def_tests; +} + +std::vector> StructuredDataDefParser::GetDefs() const +{ + return std::move(m_state->m_defs); +} diff --git a/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefParser.h b/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefParser.h new file mode 100644 index 00000000..5a559321 --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefParser.h @@ -0,0 +1,29 @@ +#pragma once + +#include "Utils/ClassUtils.h" +#include "StructuredDataDefParserState.h" +#include "Domain/CommonStructuredDataDef.h" +#include "Parsing/Simple/SimpleLexer.h" +#include "Parsing/Simple/SimpleParserValue.h" +#include "Parsing/Impl/AbstractParser.h" + +namespace sdd +{ + class StructuredDataDefParser final : public AbstractParser + { + std::vector> m_all_tests; + std::vector m_no_scope_tests; + std::vector m_def_tests; + std::vector m_enum_tests; + std::vector m_struct_tests; + + void CreateSequenceCollections(); + + protected: + const std::vector& GetTestsForState() override; + + public: + explicit StructuredDataDefParser(SimpleLexer* lexer); + _NODISCARD std::vector> GetDefs() const; + }; +} diff --git a/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefParserState.cpp b/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefParserState.cpp new file mode 100644 index 00000000..5ad6ec1f --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefParserState.cpp @@ -0,0 +1,10 @@ +#include "StructuredDataDefParserState.h" + +using namespace sdd; + +StructuredDataDefParserState::StructuredDataDefParserState() + : m_current_def(nullptr), + m_current_enum(nullptr), + m_current_struct(nullptr) +{ +} diff --git a/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefParserState.h b/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefParserState.h new file mode 100644 index 00000000..ca6d3c2a --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefParserState.h @@ -0,0 +1,20 @@ +#pragma once +#include +#include + +#include "Domain/CommonStructuredDataDef.h" + +namespace sdd +{ + class StructuredDataDefParserState + { + public: + std::vector> m_defs; + + CommonStructuredDataDef* m_current_def; + CommonStructuredDataDefEnum* m_current_enum; + CommonStructuredDataDefStruct* m_current_struct; + + StructuredDataDefParserState(); + }; +} diff --git a/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefReader.cpp b/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefReader.cpp new file mode 100644 index 00000000..8c08b05f --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefReader.cpp @@ -0,0 +1,60 @@ +#include "StructuredDataDefReader.h" + +#include "StructuredDataDefParser.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" + +using namespace sdd; + +StructuredDataDefReader::StructuredDataDefReader(std::istream& stream, std::string fileName) + : StructuredDataDefReader(stream, std::move(fileName), nullptr) +{ +} + +StructuredDataDefReader::StructuredDataDefReader(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(); +} + +bool StructuredDataDefReader::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 StructuredDataDefReader::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(); +} + +std::vector> StructuredDataDefReader::ReadStructureDataDefs() +{ + SimpleLexer::Config lexerConfig; + lexerConfig.m_emit_new_line_tokens = false; + lexerConfig.m_read_strings = true; + lexerConfig.m_read_numbers = true; + const auto lexer = std::make_unique(m_stream, std::move(lexerConfig)); + + const auto parser = std::make_unique(lexer.get()); + + if (parser->Parse()) + return parser->GetDefs(); + + std::cout << "Parsing structured data def file \"" << m_file_name << "\" failed!" << std::endl; + return {}; +} diff --git a/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefReader.h b/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefReader.h new file mode 100644 index 00000000..b2411b11 --- /dev/null +++ b/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefReader.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include + +#include "Domain/CommonStructuredDataDef.h" +#include "Parsing/IParserLineStream.h" + +class StructuredDataDefReader +{ +public: + using include_callback_t = std::function(const std::string& filename, const std::string& sourceFile)>; + +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: + StructuredDataDefReader(std::istream& stream, std::string fileName); + StructuredDataDefReader(std::istream& stream, std::string fileName, include_callback_t includeCallback); + + std::vector> ReadStructureDataDefs(); +};