chore: add abstraction for opening output files to be able to mock it

This commit is contained in:
Jan 2025-01-07 00:02:38 +01:00
parent cacccf64e1
commit e0f8b3d3ca
No known key found for this signature in database
GPG Key ID: 44B581F78FF5C57C
25 changed files with 202 additions and 68 deletions

View File

@ -3,6 +3,7 @@
#include "Gdt/GdtLookup.h" #include "Gdt/GdtLookup.h"
#include "IObjCompiler.h" #include "IObjCompiler.h"
#include "IObjLoader.h" #include "IObjLoader.h"
#include "SearchPath/OutputPathFilesystem.h"
#include <cassert> #include <cassert>
@ -67,8 +68,10 @@ namespace zone_creator
ZoneDefinitionContext zoneDefinitionContext(*context.m_definition); ZoneDefinitionContext zoneDefinitionContext(*context.m_definition);
AssetCreationContext creationContext(*zone, &creatorCollection, &ignoredAssetLookup); AssetCreationContext creationContext(*zone, &creatorCollection, &ignoredAssetLookup);
OutputPathFilesystem outDir(context.m_out_dir);
OutputPathFilesystem cacheDir(context.m_cache_dir);
objCompiler->ConfigureCreatorCollection( objCompiler->ConfigureCreatorCollection(
creatorCollection, *zone, zoneDefinitionContext, *context.m_asset_search_path, lookup, creationContext, context.m_out_dir, context.m_cache_dir); creatorCollection, *zone, zoneDefinitionContext, *context.m_asset_search_path, lookup, creationContext, outDir, cacheDir);
objLoader->ConfigureCreatorCollection(creatorCollection, *zone, *context.m_asset_search_path, lookup); objLoader->ConfigureCreatorCollection(creatorCollection, *zone, *context.m_asset_search_path, lookup);
for (const auto& assetEntry : context.m_definition->m_assets) for (const auto& assetEntry : context.m_definition->m_assets)

View File

@ -0,0 +1,18 @@
#pragma once
#include <memory>
#include <ostream>
#include <string>
class IOutputPath
{
public:
IOutputPath() = default;
virtual ~IOutputPath() = default;
IOutputPath(const IOutputPath& other) = default;
IOutputPath(IOutputPath&& other) noexcept = default;
IOutputPath& operator=(const IOutputPath& other) = default;
IOutputPath& operator=(IOutputPath&& other) noexcept = default;
virtual std::unique_ptr<std::ostream> Open(const std::string& fileName) = 0;
};

View File

@ -0,0 +1,27 @@
#include "OutputPathFilesystem.h"
#include <fstream>
namespace fs = std::filesystem;
OutputPathFilesystem::OutputPathFilesystem(const fs::path& path)
: m_path(fs::canonical(path))
{
}
std::unique_ptr<std::ostream> OutputPathFilesystem::Open(const std::string& fileName)
{
const auto fullNewPath = fs::canonical(m_path / fileName);
if (!fullNewPath.string().starts_with(m_path.string()))
return nullptr;
const auto containingDirectory = fullNewPath.parent_path();
fs::create_directories(containingDirectory);
std::ofstream stream(fullNewPath, std::ios::binary | std::ios::out);
if (!stream.is_open())
return nullptr;
return std::make_unique<std::ofstream>(std::move(stream));
}

View File

@ -0,0 +1,16 @@
#pragma once
#include "IOutputPath.h"
#include <filesystem>
class OutputPathFilesystem final : public IOutputPath
{
public:
explicit OutputPathFilesystem(const std::filesystem::path& path);
std::unique_ptr<std::ostream> Open(const std::string& fileName) override;
private:
std::filesystem::path m_path;
};

View File

@ -22,7 +22,7 @@ namespace
const ZoneDefinitionContext& zoneDefinition, const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath, ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const fs::path& outDir) IOutputPath& outDir)
{ {
auto& memory = *zone.GetMemory(); auto& memory = *zone.GetMemory();
@ -37,8 +37,8 @@ void ObjCompiler::ConfigureCreatorCollection(AssetCreatorCollection& collection,
ISearchPath& searchPath, ISearchPath& searchPath,
IGdtQueryable& gdt, IGdtQueryable& gdt,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const fs::path& outDir, IOutputPath& outDir,
const fs::path& cacheDir) const IOutputPath& cacheDir) const
{ {
ConfigurePostProcessors(collection, zone, zoneDefinition, searchPath, zoneStates, outDir); ConfigurePostProcessors(collection, zone, zoneDefinition, searchPath, zoneStates, outDir);
} }

View File

@ -13,7 +13,7 @@ namespace IW3
ISearchPath& searchPath, ISearchPath& searchPath,
IGdtQueryable& gdt, IGdtQueryable& gdt,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const std::filesystem::path& outDir, IOutputPath& outDir,
const std::filesystem::path& cacheDir) const override; IOutputPath& cacheDir) const override;
}; };
} // namespace IW3 } // namespace IW3

View File

@ -22,7 +22,7 @@ namespace
const ZoneDefinitionContext& zoneDefinition, const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath, ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const fs::path& outDir) IOutputPath& outDir)
{ {
auto& memory = *zone.GetMemory(); auto& memory = *zone.GetMemory();
@ -37,8 +37,8 @@ void ObjCompiler::ConfigureCreatorCollection(AssetCreatorCollection& collection,
ISearchPath& searchPath, ISearchPath& searchPath,
IGdtQueryable& gdt, IGdtQueryable& gdt,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const fs::path& outDir, IOutputPath& outDir,
const fs::path& cacheDir) const IOutputPath& cacheDir) const
{ {
ConfigurePostProcessors(collection, zone, zoneDefinition, searchPath, zoneStates, outDir); ConfigurePostProcessors(collection, zone, zoneDefinition, searchPath, zoneStates, outDir);
} }

View File

@ -13,7 +13,7 @@ namespace IW4
ISearchPath& searchPath, ISearchPath& searchPath,
IGdtQueryable& gdt, IGdtQueryable& gdt,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const std::filesystem::path& outDir, IOutputPath& outDir,
const std::filesystem::path& cacheDir) const override; IOutputPath& cacheDir) const override;
}; };
} // namespace IW4 } // namespace IW4

View File

@ -22,7 +22,7 @@ namespace
const ZoneDefinitionContext& zoneDefinition, const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath, ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const fs::path& outDir) IOutputPath& outDir)
{ {
auto& memory = *zone.GetMemory(); auto& memory = *zone.GetMemory();
@ -37,8 +37,8 @@ void ObjCompiler::ConfigureCreatorCollection(AssetCreatorCollection& collection,
ISearchPath& searchPath, ISearchPath& searchPath,
IGdtQueryable& gdt, IGdtQueryable& gdt,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const fs::path& outDir, IOutputPath& outDir,
const fs::path& cacheDir) const IOutputPath& cacheDir) const
{ {
ConfigurePostProcessors(collection, zone, zoneDefinition, searchPath, zoneStates, outDir); ConfigurePostProcessors(collection, zone, zoneDefinition, searchPath, zoneStates, outDir);
} }

View File

@ -13,7 +13,7 @@ namespace IW5
ISearchPath& searchPath, ISearchPath& searchPath,
IGdtQueryable& gdt, IGdtQueryable& gdt,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const std::filesystem::path& outDir, IOutputPath& outDir,
const std::filesystem::path& cacheDir) const override; IOutputPath& cacheDir) const override;
}; };
} // namespace IW5 } // namespace IW5

View File

@ -22,7 +22,7 @@ namespace
const ZoneDefinitionContext& zoneDefinition, const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath, ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const fs::path& outDir) IOutputPath& outDir)
{ {
auto& memory = *zone.GetMemory(); auto& memory = *zone.GetMemory();
@ -37,8 +37,8 @@ void ObjCompiler::ConfigureCreatorCollection(AssetCreatorCollection& collection,
ISearchPath& searchPath, ISearchPath& searchPath,
IGdtQueryable& gdt, IGdtQueryable& gdt,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const fs::path& outDir, IOutputPath& outDir,
const fs::path& cacheDir) const IOutputPath& cacheDir) const
{ {
ConfigurePostProcessors(collection, zone, zoneDefinition, searchPath, zoneStates, outDir); ConfigurePostProcessors(collection, zone, zoneDefinition, searchPath, zoneStates, outDir);
} }

View File

@ -13,7 +13,7 @@ namespace T5
ISearchPath& searchPath, ISearchPath& searchPath,
IGdtQueryable& gdt, IGdtQueryable& gdt,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const std::filesystem::path& outDir, IOutputPath& outDir,
const std::filesystem::path& cacheDir) const override; IOutputPath& cacheDir) const override;
}; };
} // namespace T5 } // namespace T5

View File

@ -28,7 +28,7 @@ namespace
const ZoneDefinitionContext& zoneDefinition, const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath, ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const fs::path& outDir) IOutputPath& outDir)
{ {
auto& memory = *zone.GetMemory(); auto& memory = *zone.GetMemory();
@ -46,8 +46,8 @@ void ObjCompiler::ConfigureCreatorCollection(AssetCreatorCollection& collection,
ISearchPath& searchPath, ISearchPath& searchPath,
IGdtQueryable& gdt, IGdtQueryable& gdt,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const fs::path& outDir, IOutputPath& outDir,
const fs::path& cacheDir) const IOutputPath& cacheDir) const
{ {
ConfigureCompilers(collection, zone, zoneDefinition, searchPath, zoneStates); ConfigureCompilers(collection, zone, zoneDefinition, searchPath, zoneStates);
ConfigurePostProcessors(collection, zone, zoneDefinition, searchPath, zoneStates, outDir); ConfigurePostProcessors(collection, zone, zoneDefinition, searchPath, zoneStates, outDir);

View File

@ -13,7 +13,7 @@ namespace T6
ISearchPath& searchPath, ISearchPath& searchPath,
IGdtQueryable& gdt, IGdtQueryable& gdt,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const std::filesystem::path& outDir, IOutputPath& outDir,
const std::filesystem::path& cacheDir) const override; IOutputPath& cacheDir) const override;
}; };
} // namespace T6 } // namespace T6

View File

@ -4,14 +4,10 @@
#include "Asset/IZoneAssetCreationState.h" #include "Asset/IZoneAssetCreationState.h"
#include "Asset/ZoneDefinitionContext.h" #include "Asset/ZoneDefinitionContext.h"
#include "Gdt/IGdtQueryable.h" #include "Gdt/IGdtQueryable.h"
#include "SearchPath/IOutputPath.h"
#include "SearchPath/ISearchPath.h" #include "SearchPath/ISearchPath.h"
#include "Zone/Definition/ZoneDefinition.h"
#include "Zone/Zone.h" #include "Zone/Zone.h"
#include <cstdint>
#include <filesystem>
#include <string>
class IObjCompiler class IObjCompiler
{ {
public: public:
@ -28,8 +24,8 @@ public:
ISearchPath& searchPath, ISearchPath& searchPath,
IGdtQueryable& gdt, IGdtQueryable& gdt,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const std::filesystem::path& outDir, IOutputPath& outDir,
const std::filesystem::path& cacheDir) const = 0; IOutputPath& cacheDir) const = 0;
static const IObjCompiler* GetObjCompilerForGame(GameId game); static const IObjCompiler* GetObjCompilerForGame(GameId game);
}; };

View File

@ -379,17 +379,16 @@ void IPakToCreate::AddImage(std::string imageName)
m_image_names.emplace_back(std::move(imageName)); m_image_names.emplace_back(std::move(imageName));
} }
void IPakToCreate::Build(ISearchPath& searchPath, const std::filesystem::path& outPath) void IPakToCreate::Build(ISearchPath& searchPath, IOutputPath& outPath)
{ {
auto filePath = outPath / std::format("{}.ipak", m_name); const auto file = outPath.Open(std::format("{}.ipak", m_name));
std::ofstream file(filePath, std::ios::out | std::ios::binary); if (!file)
if (!file.is_open())
{ {
std::cerr << std::format("Failed to open file for ipak {}\n", m_name); std::cerr << std::format("Failed to open file for ipak {}\n", m_name);
return; return;
} }
IPakWriter writer(file, searchPath, m_image_names); IPakWriter writer(*file, searchPath, m_image_names);
writer.Write(); writer.Write();
std::cout << std::format("Created ipak {} with {} entries\n", m_name, m_image_names.size()); std::cout << std::format("Created ipak {} with {} entries\n", m_name, m_image_names.size());
@ -421,7 +420,7 @@ IPakToCreate* IPakCreator::GetOrAddIPak(const std::string& ipakName)
return result; return result;
} }
void IPakCreator::Finalize(ISearchPath& searchPath, const std::filesystem::path& outPath) void IPakCreator::Finalize(ISearchPath& searchPath, IOutputPath& outPath)
{ {
for (const auto& ipakToCreate : m_ipaks) for (const auto& ipakToCreate : m_ipaks)
ipakToCreate->Build(searchPath, outPath); ipakToCreate->Build(searchPath, outPath);

View File

@ -2,9 +2,9 @@
#include "Asset/IZoneAssetCreationState.h" #include "Asset/IZoneAssetCreationState.h"
#include "KeyValuePairs/KeyValuePairsCreator.h" #include "KeyValuePairs/KeyValuePairsCreator.h"
#include "SearchPath/IOutputPath.h"
#include "SearchPath/ISearchPath.h" #include "SearchPath/ISearchPath.h"
#include <filesystem>
#include <memory> #include <memory>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
@ -15,14 +15,14 @@ public:
explicit IPakToCreate(std::string name); explicit IPakToCreate(std::string name);
void AddImage(std::string imageName); void AddImage(std::string imageName);
void Build(ISearchPath& searchPath, const std::filesystem::path& outPath); void Build(ISearchPath& searchPath, IOutputPath& outPath);
private: private:
std::string m_name; std::string m_name;
std::vector<std::string> m_image_names; std::vector<std::string> m_image_names;
}; };
class IPakCreator : public IZoneAssetCreationState class IPakCreator final : public IZoneAssetCreationState
{ {
public: public:
IPakCreator(); IPakCreator();
@ -30,7 +30,7 @@ public:
void Inject(ZoneAssetCreationInjection& inject) override; void Inject(ZoneAssetCreationInjection& inject) override;
IPakToCreate* GetOrAddIPak(const std::string& ipakName); IPakToCreate* GetOrAddIPak(const std::string& ipakName);
void Finalize(ISearchPath& searchPath, const std::filesystem::path& outPath); void Finalize(ISearchPath& searchPath, IOutputPath& outPath);
private: private:
KeyValuePairsCreator* m_kvp_creator; KeyValuePairsCreator* m_kvp_creator;

View File

@ -8,7 +8,7 @@
AbstractImageIPakPostProcessor::AbstractImageIPakPostProcessor(const ZoneDefinitionContext& zoneDefinition, AbstractImageIPakPostProcessor::AbstractImageIPakPostProcessor(const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath, ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const std::filesystem::path& outDir) IOutputPath& outDir)
: m_zone_definition(zoneDefinition), : m_zone_definition(zoneDefinition),
m_search_path(searchPath), m_search_path(searchPath),
m_ipak_creator(zoneStates.GetZoneAssetCreationState<IPakCreator>()), m_ipak_creator(zoneStates.GetZoneAssetCreationState<IPakCreator>()),

View File

@ -3,8 +3,7 @@
#include "Asset/IAssetPostProcessor.h" #include "Asset/IAssetPostProcessor.h"
#include "Asset/ZoneDefinitionContext.h" #include "Asset/ZoneDefinitionContext.h"
#include "Image/IPak/IPakCreator.h" #include "Image/IPak/IPakCreator.h"
#include "SearchPath/IOutputPath.h"
#include <filesystem>
class AbstractImageIPakPostProcessor : public IAssetPostProcessor class AbstractImageIPakPostProcessor : public IAssetPostProcessor
{ {
@ -12,7 +11,7 @@ public:
AbstractImageIPakPostProcessor(const ZoneDefinitionContext& zoneDefinition, AbstractImageIPakPostProcessor(const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath, ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const std::filesystem::path& outDir); IOutputPath& outDir);
static bool AppliesToZoneDefinition(const ZoneDefinitionContext& zoneDefinition); static bool AppliesToZoneDefinition(const ZoneDefinitionContext& zoneDefinition);
@ -25,7 +24,7 @@ private:
const ZoneDefinitionContext& m_zone_definition; const ZoneDefinitionContext& m_zone_definition;
ISearchPath& m_search_path; ISearchPath& m_search_path;
IPakCreator& m_ipak_creator; IPakCreator& m_ipak_creator;
const std::filesystem::path& m_out_dir; IOutputPath& m_out_dir;
unsigned m_obj_container_index; unsigned m_obj_container_index;
IPakToCreate* m_current_ipak; IPakToCreate* m_current_ipak;
@ -41,7 +40,7 @@ public:
ImageIPakPostProcessor(const ZoneDefinitionContext& zoneDefinition, ImageIPakPostProcessor(const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath, ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const std::filesystem::path& outDir) IOutputPath& outDir)
: AbstractImageIPakPostProcessor(zoneDefinition, searchPath, zoneStates, outDir) : AbstractImageIPakPostProcessor(zoneDefinition, searchPath, zoneStates, outDir)
{ {
} }
@ -49,5 +48,5 @@ public:
[[nodiscard]] asset_type_t GetHandlingAssetType() const override [[nodiscard]] asset_type_t GetHandlingAssetType() const override
{ {
return AssetType::EnumEntry; return AssetType::EnumEntry;
}; }
}; };

View File

@ -9,7 +9,7 @@
AbstractImageIwdPostProcessor::AbstractImageIwdPostProcessor(const ZoneDefinitionContext& zoneDefinition, AbstractImageIwdPostProcessor::AbstractImageIwdPostProcessor(const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath, ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const std::filesystem::path& outDir) IOutputPath& outDir)
: m_zone_definition(zoneDefinition), : m_zone_definition(zoneDefinition),
m_search_path(searchPath), m_search_path(searchPath),
m_iwd_creator(zoneStates.GetZoneAssetCreationState<IwdCreator>()), m_iwd_creator(zoneStates.GetZoneAssetCreationState<IwdCreator>()),

View File

@ -3,8 +3,7 @@
#include "Asset/IAssetPostProcessor.h" #include "Asset/IAssetPostProcessor.h"
#include "Asset/ZoneDefinitionContext.h" #include "Asset/ZoneDefinitionContext.h"
#include "Iwd/IwdCreator.h" #include "Iwd/IwdCreator.h"
#include "SearchPath/IOutputPath.h"
#include <filesystem>
class AbstractImageIwdPostProcessor : public IAssetPostProcessor class AbstractImageIwdPostProcessor : public IAssetPostProcessor
{ {
@ -12,7 +11,7 @@ public:
AbstractImageIwdPostProcessor(const ZoneDefinitionContext& zoneDefinition, AbstractImageIwdPostProcessor(const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath, ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const std::filesystem::path& outDir); IOutputPath& outDir);
static bool AppliesToZoneDefinition(const ZoneDefinitionContext& zoneDefinition); static bool AppliesToZoneDefinition(const ZoneDefinitionContext& zoneDefinition);
@ -25,7 +24,7 @@ private:
const ZoneDefinitionContext& m_zone_definition; const ZoneDefinitionContext& m_zone_definition;
ISearchPath& m_search_path; ISearchPath& m_search_path;
IwdCreator& m_iwd_creator; IwdCreator& m_iwd_creator;
const std::filesystem::path& m_out_dir; IOutputPath& m_out_dir;
unsigned m_obj_container_index; unsigned m_obj_container_index;
IwdToCreate* m_current_iwd; IwdToCreate* m_current_iwd;
@ -41,7 +40,7 @@ public:
ImageIwdPostProcessor(const ZoneDefinitionContext& zoneDefinition, ImageIwdPostProcessor(const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath, ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates, ZoneAssetCreationStateContainer& zoneStates,
const std::filesystem::path& outDir) IOutputPath& outDir)
: AbstractImageIwdPostProcessor(zoneDefinition, searchPath, zoneStates, outDir) : AbstractImageIwdPostProcessor(zoneDefinition, searchPath, zoneStates, outDir)
{ {
} }
@ -49,5 +48,5 @@ public:
[[nodiscard]] asset_type_t GetHandlingAssetType() const override [[nodiscard]] asset_type_t GetHandlingAssetType() const override
{ {
return AssetType::EnumEntry; return AssetType::EnumEntry;
}; }
}; };

View File

@ -18,19 +18,19 @@ void IwdToCreate::AddFile(std::string filePath)
m_file_paths.emplace_back(std::move(filePath)); m_file_paths.emplace_back(std::move(filePath));
} }
void IwdToCreate::Build(ISearchPath& searchPath, const std::filesystem::path& outPath) void IwdToCreate::Build(ISearchPath& searchPath, IOutputPath& outPath)
{ {
auto filePath = outPath / std::format("{}.iwd", m_name); const auto fileName = std::format("{}.iwd", m_name);
std::ofstream file(filePath, std::ios::out | std::ios::binary); const auto file = outPath.Open(fileName);
if (!file.is_open()) if (!file)
{ {
std::cerr << std::format("Failed to open file for iwd {}\n", m_name); std::cerr << std::format("Failed to open file for iwd {}\n", m_name);
return; return;
} }
auto functions = FileToZlibWrapper::CreateFunctions32ForFile(&file); auto functions = FileToZlibWrapper::CreateFunctions32ForFile(file.get());
auto zipFile = zipOpen2(filePath.string().c_str(), APPEND_STATUS_CREATE, nullptr, &functions); const auto zipFile = zipOpen2(fileName.c_str(), APPEND_STATUS_CREATE, nullptr, &functions);
if (!zipFile) if (!zipFile)
{ {
std::cerr << std::format("Failed to open file as zip for iwd {}\n", m_name); std::cerr << std::format("Failed to open file as zip for iwd {}\n", m_name);
@ -92,7 +92,7 @@ IwdToCreate* IwdCreator::GetOrAddIwd(const std::string& iwdName)
return result; return result;
} }
void IwdCreator::Finalize(ISearchPath& searchPath, const std::filesystem::path& outPath) void IwdCreator::Finalize(ISearchPath& searchPath, IOutputPath& outPath)
{ {
std::cout << std::format("Writing {} iwd files to disk\n", m_iwds.size()); std::cout << std::format("Writing {} iwd files to disk\n", m_iwds.size());
for (const auto& iwdToCreate : m_iwds) for (const auto& iwdToCreate : m_iwds)

View File

@ -1,9 +1,9 @@
#pragma once #pragma once
#include "Asset/IZoneAssetCreationState.h" #include "Asset/IZoneAssetCreationState.h"
#include "SearchPath/IOutputPath.h"
#include "SearchPath/ISearchPath.h" #include "SearchPath/ISearchPath.h"
#include <filesystem>
#include <memory> #include <memory>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
@ -14,18 +14,18 @@ public:
explicit IwdToCreate(std::string name); explicit IwdToCreate(std::string name);
void AddFile(std::string filePath); void AddFile(std::string filePath);
void Build(ISearchPath& searchPath, const std::filesystem::path& outPath); void Build(ISearchPath& searchPath, IOutputPath& outPath);
private: private:
std::string m_name; std::string m_name;
std::vector<std::string> m_file_paths; std::vector<std::string> m_file_paths;
}; };
class IwdCreator : public IZoneAssetCreationState class IwdCreator final : public IZoneAssetCreationState
{ {
public: public:
IwdToCreate* GetOrAddIwd(const std::string& iwdName); IwdToCreate* GetOrAddIwd(const std::string& iwdName);
void Finalize(ISearchPath& searchPath, const std::filesystem::path& outPath); void Finalize(ISearchPath& searchPath, IOutputPath& outPath);
private: private:
std::unordered_map<std::string, IwdToCreate*> m_iwd_lookup; std::unordered_map<std::string, IwdToCreate*> m_iwd_lookup;

View File

@ -0,0 +1,49 @@
#include "MockOutputPath.h"
#include <sstream>
namespace
{
class MockFileWrapper final : public std::ostringstream
{
public:
MockFileWrapper(std::string name, std::vector<MockOutputFile>& files)
: m_name(std::move(name)),
m_files(files)
{
}
~MockFileWrapper() override
{
m_files.emplace_back(std::move(m_name), str());
}
private:
std::string m_name;
std::vector<MockOutputFile>& m_files;
};
} // namespace
MockOutputFile::MockOutputFile() = default;
MockOutputFile::MockOutputFile(std::string name, std::string data)
: m_name(std::move(name)),
m_data(std::move(data))
{
}
std::unique_ptr<std::ostream> MockOutputPath::Open(const std::string& fileName)
{
return std::make_unique<MockFileWrapper>(fileName, m_files);
}
const MockOutputFile* MockOutputPath::GetMockedFile(const std::string& name) const
{
for (const auto& file : m_files)
{
if (file.m_name == name)
return &file;
}
return nullptr;
}

View File

@ -0,0 +1,28 @@
#pragma once
#include "SearchPath/IOutputPath.h"
#include <sstream>
#include <string>
#include <vector>
class MockOutputFile
{
public:
std::string m_name;
std::string m_data;
MockOutputFile();
MockOutputFile(std::string name, std::string data);
};
class MockOutputPath final : public IOutputPath
{
public:
std::unique_ptr<std::ostream> Open(const std::string& fileName) override;
[[nodiscard]] const MockOutputFile* GetMockedFile(const std::string& name) const;
private:
std::vector<MockOutputFile> m_files;
};