diff --git a/src/Linker/Linker.cpp b/src/Linker/Linker.cpp index ed21b47e..fbe52b00 100644 --- a/src/Linker/Linker.cpp +++ b/src/Linker/Linker.cpp @@ -58,7 +58,7 @@ class LinkerImpl final : public Linker return false; } - ZoneDefinitionInputStream zoneDefinitionInputStream(*definitionStream.m_stream, definitionFileName, m_args.m_verbose); + ZoneDefinitionInputStream zoneDefinitionInputStream(*definitionStream.m_stream, source, definitionFileName, m_args.m_verbose); zoneDefinitionInputStream.SetPreviouslySetGame(zoneDefinition.m_game); includeDefinition = zoneDefinitionInputStream.ReadDefinition(); } @@ -147,7 +147,7 @@ class LinkerImpl final : public Linker return nullptr; } - ZoneDefinitionInputStream zoneDefinitionInputStream(*definitionStream.m_stream, definitionFileName, m_args.m_verbose); + ZoneDefinitionInputStream zoneDefinitionInputStream(*definitionStream.m_stream, targetName, definitionFileName, m_args.m_verbose); zoneDefinition = zoneDefinitionInputStream.ReadDefinition(); } diff --git a/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParser.cpp b/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParser.cpp index eba6f2fb..da287d10 100644 --- a/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParser.cpp +++ b/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParser.cpp @@ -7,8 +7,8 @@ #include "Sequence/SequenceZoneDefinitionInclude.h" #include "Sequence/SequenceZoneDefinitionMetaData.h" -ZoneDefinitionParser::ZoneDefinitionParser(ZoneDefinitionLexer* lexer, const std::optional maybeGame) - : AbstractParser(lexer, std::make_unique()) +ZoneDefinitionParser::ZoneDefinitionParser(ZoneDefinitionLexer* lexer, std::string targetName, const std::optional maybeGame) + : AbstractParser(lexer, std::make_unique(std::move(targetName))) { if (maybeGame) m_state->SetGame(*maybeGame); diff --git a/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParser.h b/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParser.h index 4ffffeee..37b37242 100644 --- a/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParser.h +++ b/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParser.h @@ -15,6 +15,6 @@ protected: const std::vector& GetTestsForState() override; public: - explicit ZoneDefinitionParser(ZoneDefinitionLexer* lexer, std::optional maybeGame = std::nullopt); + ZoneDefinitionParser(ZoneDefinitionLexer* lexer, std::string targetName, std::optional maybeGame = std::nullopt); std::unique_ptr GetParsedValue(); }; diff --git a/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParserState.cpp b/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParserState.cpp index 54dffc88..beabf448 100644 --- a/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParserState.cpp +++ b/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParserState.cpp @@ -1,9 +1,10 @@ #include "ZoneDefinitionParserState.h" -ZoneDefinitionParserState::ZoneDefinitionParserState() +ZoneDefinitionParserState::ZoneDefinitionParserState(std::string targetName) : m_asset_name_resolver(nullptr), m_definition(std::make_unique()) { + m_definition->m_name = std::move(targetName); } void ZoneDefinitionParserState::SetGame(const GameId game) diff --git a/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParserState.h b/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParserState.h index 80074879..8135636e 100644 --- a/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParserState.h +++ b/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParserState.h @@ -8,7 +8,7 @@ class ZoneDefinitionParserState { public: - ZoneDefinitionParserState(); + explicit ZoneDefinitionParserState(std::string targetName); void SetGame(GameId game); diff --git a/src/ZoneCommon/Zone/Definition/ZoneDefinitionStream.cpp b/src/ZoneCommon/Zone/Definition/ZoneDefinitionStream.cpp index 72a34c8e..2ebc6cee 100644 --- a/src/ZoneCommon/Zone/Definition/ZoneDefinitionStream.cpp +++ b/src/ZoneCommon/Zone/Definition/ZoneDefinitionStream.cpp @@ -9,8 +9,9 @@ #include #include -ZoneDefinitionInputStream::ZoneDefinitionInputStream(std::istream& stream, std::string fileName, bool verbose) - : m_file_name(std::move(fileName)), +ZoneDefinitionInputStream::ZoneDefinitionInputStream(std::istream& stream, std::string targetName, std::string fileName, const bool verbose) + : m_target_name(std::move(targetName)), + m_file_name(std::move(fileName)), m_verbose(verbose), m_stream(nullptr), m_previously_set_game(std::nullopt) @@ -46,7 +47,7 @@ std::unique_ptr ZoneDefinitionInputStream::ReadDefinition() std::cout << std::format("Reading zone definition file: {}\n", m_file_name); const auto lexer = std::make_unique(m_stream); - const auto parser = std::make_unique(lexer.get(), m_previously_set_game); + const auto parser = std::make_unique(lexer.get(), m_target_name, m_previously_set_game); const auto start = std::chrono::steady_clock::now(); std::unique_ptr definition; diff --git a/src/ZoneCommon/Zone/Definition/ZoneDefinitionStream.h b/src/ZoneCommon/Zone/Definition/ZoneDefinitionStream.h index b0b26984..d4e6b6e2 100644 --- a/src/ZoneCommon/Zone/Definition/ZoneDefinitionStream.h +++ b/src/ZoneCommon/Zone/Definition/ZoneDefinitionStream.h @@ -11,7 +11,7 @@ class ZoneDefinitionInputStream { public: - ZoneDefinitionInputStream(std::istream& stream, std::string fileName, bool verbose); + ZoneDefinitionInputStream(std::istream& stream, std::string targetName, std::string fileName, bool verbose); void SetPreviouslySetGame(GameId game); std::unique_ptr ReadDefinition(); @@ -20,6 +20,7 @@ private: bool OpenBaseStream(std::istream& stream); void SetupStreamProxies(); + std::string m_target_name; std::string m_file_name; bool m_verbose; IParserLineStream* m_stream; diff --git a/test/ZoneCommonTests/Zone/Definition/ZoneDefinitionStreamTests.cpp b/test/ZoneCommonTests/Zone/Definition/ZoneDefinitionStreamTests.cpp new file mode 100644 index 00000000..15638c64 --- /dev/null +++ b/test/ZoneCommonTests/Zone/Definition/ZoneDefinitionStreamTests.cpp @@ -0,0 +1,222 @@ +#include "Game/T6/T6.h" +#include "Zone/Definition/ZoneDefinitionStream.h" + +#include +#include +#include + +namespace test::zone::definition::zone_definition_stream +{ + TEST_CASE("ZoneDefinitionInputStream: Ensure can read simple ZoneDefinition", "[zonedefinition]") + { + std::istringstream inputData(R"sampledata( +// Call Of Duty: Black Ops II +>game,T6 +>name,common_mp + +techniqueset,,trivial_9z33feqw +material,gradient_top +menu,demo_ingame +)sampledata"); + + ZoneDefinitionInputStream inputStream(inputData, "test", "test.zone", true); + + const auto result = inputStream.ReadDefinition(); + REQUIRE(result); + + REQUIRE(result->m_game == GameId::T6); + REQUIRE(result->m_name == "common_mp"); + REQUIRE(result->m_assets.size() == 3u); + + REQUIRE(result->m_assets[0].m_asset_name == "trivial_9z33feqw"); + REQUIRE(result->m_assets[0].m_asset_type == T6::ASSET_TYPE_TECHNIQUE_SET); + REQUIRE(result->m_assets[0].m_is_reference == true); + + REQUIRE(result->m_assets[1].m_asset_name == "gradient_top"); + REQUIRE(result->m_assets[1].m_asset_type == T6::ASSET_TYPE_MATERIAL); + REQUIRE(result->m_assets[1].m_is_reference == false); + + REQUIRE(result->m_assets[2].m_asset_name == "demo_ingame"); + REQUIRE(result->m_assets[2].m_asset_type == T6::ASSET_TYPE_MENU); + REQUIRE(result->m_assets[2].m_is_reference == false); + } + + TEST_CASE("ZoneDefinitionInputStream: Ensure ZoneDefinition name is target name by default", "[zonedefinition]") + { + std::istringstream inputData(R"sampledata( +// Call Of Duty: Black Ops II +>game,T6 + +material,demo_material +)sampledata"); + + ZoneDefinitionInputStream inputStream(inputData, "test", "test.zone", true); + + const auto result = inputStream.ReadDefinition(); + REQUIRE(result); + + REQUIRE(result->m_game == GameId::T6); + REQUIRE(result->m_name == "test"); + REQUIRE(result->m_assets.size() == 1u); + } + + TEST_CASE("ZoneDefinitionInputStream: Ensure can include other ZoneDefinitions", "[zonedefinition]") + { + std::istringstream inputData(R"sampledata( +// Call Of Duty: Black Ops II +>game,T6 +>name,test_mod + +include,demo_gun +include,demo_scripts +)sampledata"); + + ZoneDefinitionInputStream inputStream(inputData, "test", "test.zone", true); + + const auto result = inputStream.ReadDefinition(); + REQUIRE(result); + + REQUIRE(result->m_assets.empty()); + REQUIRE(result->m_includes.size() == 2); + + REQUIRE(result->m_includes[0] == "demo_gun"); + REQUIRE(result->m_includes[1] == "demo_scripts"); + } + + TEST_CASE("ZoneDefinitionInputStream: Ensure can include assetlists", "[zonedefinition]") + { + std::istringstream inputData(R"sampledata( +// Call Of Duty: Black Ops II +>game,T6 +>name,test_mod + +assetlist,code_post_gfx_mp +assetlist,common_mp + +material,test_material +)sampledata"); + + ZoneDefinitionInputStream inputStream(inputData, "test", "test.zone", true); + + const auto result = inputStream.ReadDefinition(); + REQUIRE(result); + + REQUIRE(result->m_assets.size() == 1); + REQUIRE(result->m_asset_lists.size() == 2); + + REQUIRE(result->m_asset_lists[0] == "code_post_gfx_mp"); + REQUIRE(result->m_asset_lists[1] == "common_mp"); + } + + TEST_CASE("ZoneDefinitionInputStream: Ensure can define other build targets", "[zonedefinition]") + { + std::istringstream inputData(R"sampledata( +// Call Of Duty: Black Ops II +>game,T6 +>name,test_mod + +build,other_mod + +material,test_material + +build,more_mods +)sampledata"); + + ZoneDefinitionInputStream inputStream(inputData, "test", "test.zone", true); + + const auto result = inputStream.ReadDefinition(); + REQUIRE(result); + + REQUIRE(result->m_assets.size() == 1); + REQUIRE(result->m_targets_to_build.size() == 2); + + REQUIRE(result->m_targets_to_build[0] == "other_mod"); + REQUIRE(result->m_targets_to_build[1] == "more_mods"); + } + + TEST_CASE("ZoneDefinitionInputStream: Ensure can ignore other zones", "[zonedefinition]") + { + std::istringstream inputData(R"sampledata( +// Call Of Duty: Black Ops II +>game,T6 +>name,test_mod + +ignore,code_post_gfx_mp +ignore,common_mp + +material,test_material +)sampledata"); + + ZoneDefinitionInputStream inputStream(inputData, "test", "test.zone", true); + + const auto result = inputStream.ReadDefinition(); + REQUIRE(result); + + REQUIRE(result->m_assets.size() == 1); + REQUIRE(result->m_ignores.size() == 2); + + REQUIRE(result->m_ignores[0] == "code_post_gfx_mp"); + REQUIRE(result->m_ignores[1] == "common_mp"); + } + + TEST_CASE("ZoneDefinitionInputStream: Ensure can read gdts", "[zonedefinition]") + { + std::istringstream inputData(R"sampledata( +// Call Of Duty: Black Ops II +>game,T6 +>name,test_mod +>gdt,crazy_gdt +>gdt,even_crazier_gdt + +material,test_material +)sampledata"); + + ZoneDefinitionInputStream inputStream(inputData, "test", "test.zone", true); + + const auto result = inputStream.ReadDefinition(); + REQUIRE(result); + + REQUIRE(result->m_assets.size() == 1); + REQUIRE(result->m_gdts.size() == 2); + + REQUIRE(result->m_gdts[0] == "crazy_gdt"); + REQUIRE(result->m_gdts[1] == "even_crazier_gdt"); + } + + TEST_CASE("ZoneDefinitionInputStream: Ensure can define meta data", "[zonedefinition]") + { + std::istringstream inputData(R"sampledata( +// Call Of Duty: Black Ops II +>game,T6 +>name,test_mod +>foo,bar + +material,test_material + +>level.ipak_read,base +>level.ipak_read,code_post_gfx +)sampledata"); + + ZoneDefinitionInputStream inputStream(inputData, "test", "test.zone", true); + + const auto result = inputStream.ReadDefinition(); + REQUIRE(result); + + REQUIRE(result->m_assets.size() == 1); + REQUIRE(result->m_properties.m_properties.size() == 3); + + auto fooResults = result->m_properties.m_properties.equal_range("foo"); + REQUIRE(fooResults.first != fooResults.second); + REQUIRE(fooResults.first->second == "bar"); + REQUIRE(++fooResults.first == fooResults.second); + + auto ipakReadResults = result->m_properties.m_properties.equal_range("level.ipak_read"); + auto iterator = ipakReadResults.first; + REQUIRE(iterator != ipakReadResults.second); + REQUIRE(iterator->second == "base"); + ++iterator; + REQUIRE(iterator->second == "code_post_gfx"); + ++iterator; + REQUIRE(iterator == ipakReadResults.second); + } +} // namespace test::zone::definition::zone_definition_stream