refactor: decouple zone loader and LoadingStep/LoadingProcessors

This commit is contained in:
Jan Laupetin committed 2026-10-22 20:01:06 +02:00
1 parent 594bf41eaf
commit 3eca9b2606
28 files changed
+205 -173

No files matched your search

+10
View File
@@ -6,3 +6,13 @@ void ZoneMemory::AddBlock(std::unique_ptr<XBlock> block)
{
m_blocks.emplace_back(std::move(block));
}
size_t ZoneMemory::GetBlockCount() const
{
return m_blocks.size();
}
XBlock* ZoneMemory::GetBlock(const size_t index) const
{
return m_blocks.at(index).get();
}
+5 -2
View File
@@ -8,10 +8,13 @@
class ZoneMemory : public MemoryManager
{
std::vector<std::unique_ptr<XBlock>> m_blocks;
public:
ZoneMemory();
void AddBlock(std::unique_ptr<XBlock> block);
[[nodiscard]] size_t GetBlockCount() const;
[[nodiscard]] XBlock* GetBlock(size_t index) const;
private:
std::vector<std::unique_ptr<XBlock>> m_blocks;
};
@@ -35,19 +35,19 @@ namespace fs = std::filesystem;
namespace
{
void SetupBlock(ZoneLoader& zoneLoader)
void SetupBlock(ZoneMemory& zoneMemory)
{
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VERTEX, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_INDEX, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneMemory.AddBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneMemory.AddBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneMemory.AddBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneMemory.AddBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VERTEX, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_INDEX, XBlockType::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF
}
@@ -185,7 +185,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
// File is supported. Now setup all required steps for loading this file.
auto zoneLoader = std::make_unique<ZoneLoader>(std::move(zone));
SetupBlock(*zoneLoader);
SetupBlock(zonePtr->Memory());
// Skip the initial header that we peeked at before
zoneLoader->AddLoadingStep(step::CreateStepSkipBytes(sizeof(ZoneHeader)));
@@ -199,7 +199,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
{
// Start of the XFile struct
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneSizes());
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks(zonePtr));
// Start of the zone content
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
@@ -210,7 +210,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK,
zonePtr->Memory(),
zonePtr,
std::move(progressCallback)));
}
else
@@ -138,18 +138,18 @@ namespace
return std::nullopt;
}
void SetupBlock(ZoneLoader& zoneLoader)
void SetupBlock(ZoneMemory& zoneMemory)
{
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_CALLBACK, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_VERTEX, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_INDEX, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneMemory.AddBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneMemory.AddBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_CALLBACK, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_VERTEX, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_INDEX, XBlockType::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF
}
@@ -192,7 +192,7 @@ namespace
}
}
void AddAuthHeaderSteps(const ZoneLoaderInspectionResultIW4& inspectResult, ZoneLoader& zoneLoader, const std::string& fileName)
void AddAuthHeaderSteps(const ZoneLoaderInspectionResultIW4& inspectResult, ZoneReader& zoneReader, const std::string& fileName)
{
// Unsigned zones do not have an auth header
if (!inspectResult.m_generic_result.m_is_signed)
@@ -201,38 +201,38 @@ namespace
// If file is signed setup a RSA instance.
auto rsa = SetupRsa(inspectResult.m_generic_result.m_is_official, inspectResult.m_generic_result.m_variant_id);
zoneLoader.AddLoadingStep(step::CreateStepVerifyMagic(ZoneConstants::MAGIC_AUTH_HEADER));
zoneLoader.AddLoadingStep(step::CreateStepSkipBytes(4)); // Skip reserved
zoneReader.AddLoadingStep(step::CreateStepVerifyMagic(ZoneConstants::MAGIC_AUTH_HEADER));
zoneReader.AddLoadingStep(step::CreateStepSkipBytes(4)); // Skip reserved
auto subHeaderHash = step::CreateStepLoadHash(sizeof(DB_AuthHash::bytes), 1);
auto* subHeaderHashPtr = subHeaderHash.get();
zoneLoader.AddLoadingStep(std::move(subHeaderHash));
zoneReader.AddLoadingStep(std::move(subHeaderHash));
auto subHeaderHashSignature = step::CreateStepLoadSignature(sizeof(DB_AuthSignature::bytes));
auto* subHeaderHashSignaturePtr = subHeaderHashSignature.get();
zoneLoader.AddLoadingStep(std::move(subHeaderHashSignature));
zoneReader.AddLoadingStep(std::move(subHeaderHashSignature));
zoneLoader.AddLoadingStep(step::CreateStepVerifySignature(std::move(rsa), subHeaderHashSignaturePtr, subHeaderHashPtr));
zoneReader.AddLoadingStep(step::CreateStepVerifySignature(std::move(rsa), subHeaderHashSignaturePtr, subHeaderHashPtr));
auto subHeaderCapture = processor::CreateProcessorCaptureData(sizeof(DB_AuthSubHeader));
auto* subHeaderCapturePtr = subHeaderCapture.get();
zoneLoader.AddLoadingStep(step::CreateStepAddProcessor(std::move(subHeaderCapture)));
zoneReader.AddLoadingStep(step::CreateStepAddProcessor(std::move(subHeaderCapture)));
zoneLoader.AddLoadingStep(step::CreateStepVerifyFileName(fileName, sizeof(DB_AuthSubHeader::fastfileName)));
zoneLoader.AddLoadingStep(step::CreateStepSkipBytes(4)); // Skip reserved
zoneReader.AddLoadingStep(step::CreateStepVerifyFileName(fileName, sizeof(DB_AuthSubHeader::fastfileName)));
zoneReader.AddLoadingStep(step::CreateStepSkipBytes(4)); // Skip reserved
auto masterBlockHashes =
step::CreateStepLoadHash(sizeof(DB_AuthHash::bytes), static_cast<unsigned>(std::extent_v<decltype(DB_AuthSubHeader::masterBlockHashes)>));
auto* masterBlockHashesPtr = masterBlockHashes.get();
zoneLoader.AddLoadingStep(std::move(masterBlockHashes));
zoneReader.AddLoadingStep(std::move(masterBlockHashes));
zoneLoader.AddLoadingStep(step::CreateStepVerifyHash(cryptography::CreateSha256(), 0, subHeaderHashPtr, subHeaderCapturePtr));
zoneLoader.AddLoadingStep(step::CreateStepRemoveProcessor(subHeaderCapturePtr));
zoneReader.AddLoadingStep(step::CreateStepVerifyHash(cryptography::CreateSha256(), 0, subHeaderHashPtr, subHeaderCapturePtr));
zoneReader.AddLoadingStep(step::CreateStepRemoveProcessor(subHeaderCapturePtr));
// Skip the rest of the first chunk
zoneLoader.AddLoadingStep(step::CreateStepSkipBytes(ZoneConstants::AUTHED_CHUNK_SIZE - sizeof(DB_AuthHeader)));
zoneReader.AddLoadingStep(step::CreateStepSkipBytes(ZoneConstants::AUTHED_CHUNK_SIZE - sizeof(DB_AuthHeader)));
zoneLoader.AddLoadingStep(step::CreateStepAddProcessor(
zoneReader.AddLoadingStep(step::CreateStepAddProcessor(
processor::CreateProcessorAuthedBlocks(ZoneConstants::AUTHED_CHUNK_COUNT_PER_GROUP,
ZoneConstants::AUTHED_CHUNK_SIZE,
static_cast<unsigned>(std::extent_v<decltype(DB_AuthSubHeader::masterBlockHashes)>),
@@ -266,7 +266,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
// File is supported. Now setup all required steps for loading this file.
auto zoneLoader = std::make_unique<ZoneLoader>(std::move(zone));
SetupBlock(*zoneLoader);
SetupBlock(zonePtr->Memory());
// Skip the initial header that we peeked at before
zoneLoader->AddLoadingStep(step::CreateStepSkipBytes(sizeof(ZoneHeader)));
@@ -296,7 +296,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
{
// Start of the XFile struct
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneSizes());
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks(zonePtr));
// Start of the zone content
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
@@ -307,7 +307,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK,
zonePtr->Memory(),
zonePtr,
std::move(progressCallback)));
}
else
@@ -32,19 +32,19 @@ using namespace IW5;
namespace
{
void SetupBlock(ZoneLoader& zoneLoader)
void SetupBlock(ZoneMemory& zoneMemory)
{
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_SCRIPT, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneMemory.AddBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneMemory.AddBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(XFILE_BLOCK_SCRIPT, XBlockType::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF
}
@@ -170,7 +170,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
// File is supported. Now setup all required steps for loading this file.
auto zoneLoader = std::make_unique<ZoneLoader>(std::move(zone));
SetupBlock(*zoneLoader);
SetupBlock(zonePtr->Memory());
// Skip the initial header that we peeked at before
zoneLoader->AddLoadingStep(step::CreateStepSkipBytes(sizeof(ZoneHeader)));
@@ -188,7 +188,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
// Start of the XFile struct
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneSizes());
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks(zonePtr));
// Start of the zone content
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
@@ -199,7 +199,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK,
zonePtr->Memory(),
zonePtr,
std::move(progressCallback)));
return zoneLoader;
@@ -21,15 +21,15 @@ namespace
static_assert(REMAINING_FILE_HEADER_SIZE == sizeof(uint32_t) * 4u);
void SetupBlock(ZoneLoader& zoneLoader)
void SetupBlock(ZoneMemory& zoneMemory)
{
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
zoneLoader.AddXBlock(XBLOCK_DEF(QOS::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneLoader.AddXBlock(XBLOCK_DEF(QOS::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(QOS::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(QOS::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(QOS::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(QOS::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneMemory.AddBlock(XBLOCK_DEF(QOS::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneMemory.AddBlock(XBLOCK_DEF(QOS::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(QOS::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(QOS::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF
}
@@ -66,7 +66,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
zone->m_language = GameLanguage::LANGUAGE_NONE;
auto zoneLoader = std::make_unique<ZoneLoader>(std::move(zone));
SetupBlock(*zoneLoader);
SetupBlock(zonePtr->Memory());
// Skip the initial header that we peeked at before
zoneLoader->AddLoadingStep(step::CreateStepSkipBytes(sizeof(ZoneHeaderQos)));
@@ -74,7 +74,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
// Maybe external data size?
zoneLoader->AddLoadingStep(step::CreateStepSkipBytes(4));
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks(zonePtr));
zoneLoader->AddLoadingStep(step::CreateStepAddProcessor(processor::CreateProcessorInflate(ZoneConstants::AUTHED_CHUNK_SIZE)));
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
[zonePtr](ZoneInputStream& stream)
@@ -84,7 +84,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK,
zonePtr->Memory(),
zonePtr,
std::move(progressCallback)));
return zoneLoader;
+11 -11
View File
@@ -20,17 +20,17 @@ using namespace T4;
namespace
{
void SetupBlock(ZoneLoader& zoneLoader)
void SetupBlock(ZoneMemory& zoneMemory)
{
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
zoneLoader.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneLoader.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_LARGE_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(T4::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneMemory.AddBlock(XBLOCK_DEF(T4::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneMemory.AddBlock(XBLOCK_DEF(T4::XFILE_BLOCK_LARGE_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneMemory.AddBlock(XBLOCK_DEF(T4::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneMemory.AddBlock(XBLOCK_DEF(T4::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(T4::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(T4::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF
}
@@ -71,14 +71,14 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
// File is supported. Now setup all required steps for loading this file.
auto zoneLoader = std::make_unique<ZoneLoader>(std::move(zone));
SetupBlock(*zoneLoader);
SetupBlock(zonePtr->Memory());
// Skip the initial header that we peeked at before
zoneLoader->AddLoadingStep(step::CreateStepSkipBytes(sizeof(ZoneHeader)));
zoneLoader->AddLoadingStep(step::CreateStepAddProcessor(processor::CreateProcessorInflate(ZoneConstants::AUTHED_CHUNK_SIZE)));
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneSizes());
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks(zonePtr));
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
[zonePtr](ZoneInputStream& stream)
{
@@ -87,7 +87,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK,
zonePtr->Memory(),
zonePtr,
std::move(progressCallback)));
return zoneLoader;
+11 -11
View File
@@ -20,17 +20,17 @@ using namespace T5;
namespace
{
void SetupBlock(ZoneLoader& zoneLoader)
void SetupBlock(ZoneMemory& zoneMemory)
{
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(T5::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneMemory.AddBlock(XBLOCK_DEF(T5::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneMemory.AddBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneMemory.AddBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneMemory.AddBlock(XBLOCK_DEF(T5::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF
}
@@ -73,7 +73,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
// File is supported. Now setup all required steps for loading this file.
auto zoneLoader = std::make_unique<ZoneLoader>(std::move(zone));
SetupBlock(*zoneLoader);
SetupBlock(zonePtr->Memory());
// Skip the initial header that we peeked at before
zoneLoader->AddLoadingStep(step::CreateStepSkipBytes(sizeof(ZoneHeader)));
@@ -82,7 +82,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
// Start of the XFile struct
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneSizes());
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks(zonePtr));
// Start of the zone content
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
@@ -93,7 +93,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK,
zonePtr->Memory(),
zonePtr,
std::move(progressCallback)));
return zoneLoader;
+12 -12
View File
@@ -201,18 +201,18 @@ namespace
return GameLanguage::LANGUAGE_NONE;
}
void SetupBlock(ZoneLoader& zoneLoader)
void SetupBlock(ZoneMemory& zoneMemory)
{
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_VIRTUAL, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_PHYSICAL, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_VIRTUAL, XBlockType::BLOCK_TYPE_DELAY));
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_PHYSICAL, XBlockType::BLOCK_TYPE_DELAY));
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_STREAMER_RESERVE, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(T6::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneMemory.AddBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_VIRTUAL, XBlockType::BLOCK_TYPE_RUNTIME));
zoneMemory.AddBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_PHYSICAL, XBlockType::BLOCK_TYPE_RUNTIME));
zoneMemory.AddBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_VIRTUAL, XBlockType::BLOCK_TYPE_DELAY));
zoneMemory.AddBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_PHYSICAL, XBlockType::BLOCK_TYPE_DELAY));
zoneMemory.AddBlock(XBLOCK_DEF(T6::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(T6::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneMemory.AddBlock(XBLOCK_DEF(T6::XFILE_BLOCK_STREAMER_RESERVE, XBlockType::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF
}
@@ -321,7 +321,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
// File is supported. Now setup all required steps for loading this file.
auto zoneLoader = std::make_unique<ZoneLoader>(std::move(zone));
SetupBlock(*zoneLoader);
SetupBlock(zonePtr->Memory());
// Skip the initial header that we peeked at before
zoneLoader->AddLoadingStep(step::CreateStepSkipBytes(sizeof(ZoneHeader)));
@@ -339,7 +339,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
{
// Start of the XFile struct
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneSizes());
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks(zonePtr));
// Start of the zone content
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
@@ -350,7 +350,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK,
zonePtr->Memory(),
zonePtr,
std::move(progressCallback)));
if (inspectResult->m_generic_result.m_is_signed)
+2 -2
View File
@@ -3,7 +3,7 @@
#include "ILoadingStream.h"
#include "Loading/ZoneLoader.h"
class ZoneLoader;
class ZoneReader;
class ILoadingStep
{
@@ -15,5 +15,5 @@ public:
ILoadingStep& operator=(const ILoadingStep& other) = default;
ILoadingStep& operator=(ILoadingStep&& other) noexcept = default;
virtual void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) = 0;
virtual void PerformStep(ZoneReader& zoneReader, ILoadingStream& stream) = 0;
};
@@ -12,11 +12,11 @@ namespace
{
}
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override
void PerformStep(ZoneReader& zoneReader, ILoadingStream& stream) override
{
assert(m_stream_processor != nullptr);
zoneLoader.AddStreamProcessor(std::move(m_stream_processor));
zoneReader.AddStreamProcessor(std::move(m_stream_processor));
m_stream_processor = nullptr;
}
@@ -9,9 +9,15 @@ namespace
class StepAllocXBlocks final : public ILoadingStep
{
public:
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override
explicit StepAllocXBlocks(Zone* zone)
: m_zone(zone)
{
const auto blockCount = static_cast<unsigned>(zoneLoader.m_blocks.size());
}
void PerformStep(ZoneReader& zoneReader, ILoadingStream& stream) override
{
const auto& zoneMemory = m_zone->Memory();
const auto blockCount = static_cast<unsigned>(zoneMemory.GetBlockCount());
std::vector<xblock_size_t> blockSizes(blockCount);
stream.Load(blockSizes.data(), sizeof(xblock_size_t) * blockCount);
@@ -29,16 +35,19 @@ namespace
for (unsigned int block = 0; block < blockCount; block++)
{
zoneLoader.m_blocks[block]->Alloc(blockSizes[block]);
zoneMemory.GetBlock(block)->Alloc(blockSizes[block]);
}
}
private:
Zone* m_zone;
};
} // namespace
namespace step
{
std::unique_ptr<ILoadingStep> CreateStepAllocXBlocks()
std::unique_ptr<ILoadingStep> CreateStepAllocXBlocks(Zone* zone)
{
return std::make_unique<StepAllocXBlocks>();
return std::make_unique<StepAllocXBlocks>(zone);
}
} // namespace step
@@ -6,5 +6,5 @@
namespace step
{
std::unique_ptr<ILoadingStep> CreateStepAllocXBlocks();
std::unique_ptr<ILoadingStep> CreateStepAllocXBlocks(Zone* zone);
}
@@ -13,7 +13,7 @@ namespace
{
}
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override
void PerformStep(ZoneReader& zoneReader, ILoadingStream& stream) override
{
uint8_t tempBuffer[0x1000];
auto dumpedBytes = 0uz;
@@ -16,7 +16,7 @@ namespace
{
}
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override
void PerformStep(ZoneReader& zoneReader, ILoadingStream& stream) override
{
if (stream.Load(m_hashes.get(), m_hash_size * m_hash_count) != m_hash_size * m_hash_count)
throw UnexpectedEndOfFileException();
@@ -15,7 +15,7 @@ namespace
{
}
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override
void PerformStep(ZoneReader& zoneReader, ILoadingStream& stream) override
{
if (stream.Load(m_signature.get(), m_signature_size) != m_signature_size)
throw UnexpectedEndOfFileException();
@@ -11,21 +11,28 @@ namespace
const unsigned pointerBitCount,
const unsigned offsetBlockBitCount,
const block_t insertBlock,
MemoryManager& memory,
Zone* zone,
std::optional<std::unique_ptr<ProgressCallback>> progressCallback)
: m_entry_point_factory(std::move(entryPointFactory)),
m_pointer_bit_count(pointerBitCount),
m_offset_block_bit_count(offsetBlockBitCount),
m_insert_block(insertBlock),
m_memory(memory),
m_zone(zone),
m_progress_callback(std::move(progressCallback))
{
}
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override
void PerformStep(ZoneReader& zoneReader, ILoadingStream& stream) override
{
const auto& zoneMemory = m_zone->Memory();
const auto blockCount = zoneMemory.GetBlockCount();
m_blocks = std::vector<XBlock*>();
m_blocks.reserve(blockCount);
for (size_t i = 0; i < blockCount; ++i)
m_blocks.emplace_back(zoneMemory.GetBlock(i));
const auto inputStream = ZoneInputStream::Create(
m_pointer_bit_count, m_offset_block_bit_count, zoneLoader.m_blocks, m_insert_block, stream, m_memory, std::move(m_progress_callback));
m_pointer_bit_count, m_offset_block_bit_count, m_blocks, m_insert_block, stream, m_zone->Memory(), std::move(m_progress_callback));
const auto entryPoint = m_entry_point_factory(*inputStream);
assert(entryPoint);
@@ -38,7 +45,8 @@ namespace
unsigned m_pointer_bit_count;
unsigned m_offset_block_bit_count;
block_t m_insert_block;
MemoryManager& m_memory;
Zone* m_zone;
std::vector<XBlock*> m_blocks;
std::optional<std::unique_ptr<ProgressCallback>> m_progress_callback;
};
} // namespace
@@ -49,10 +57,10 @@ namespace step
const unsigned pointerBitCount,
const unsigned offsetBlockBitCount,
const block_t insertBlock,
MemoryManager& memory,
Zone* zone,
std::optional<std::unique_ptr<ProgressCallback>> progressCallback)
{
return std::make_unique<StepLoadZoneContent>(
std::move(entryPointFactory), pointerBitCount, offsetBlockBitCount, insertBlock, memory, std::move(progressCallback));
std::move(entryPointFactory), pointerBitCount, offsetBlockBitCount, insertBlock, zone, std::move(progressCallback));
}
} // namespace step
@@ -13,6 +13,6 @@ namespace step
unsigned pointerBitCount,
unsigned offsetBlockBitCount,
block_t insertBlock,
MemoryManager& memory,
Zone* zone,
std::optional<std::unique_ptr<ProgressCallback>> progressCallback);
}
@@ -11,7 +11,7 @@ namespace
{
}
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override
void PerformStep(ZoneReader& zoneReader, ILoadingStream& stream) override
{
stream.Load(&m_size, sizeof(m_size));
stream.Load(&m_external_size, sizeof(m_external_size));
@@ -12,11 +12,11 @@ namespace
{
}
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override
void PerformStep(ZoneReader& zoneReader, ILoadingStream& stream) override
{
assert(m_stream_processor != nullptr);
zoneLoader.RemoveStreamProcessor(m_stream_processor);
zoneReader.RemoveStreamProcessor(m_stream_processor);
}
private:
@@ -10,7 +10,7 @@ namespace
{
}
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override
void PerformStep(ZoneReader& zoneReader, ILoadingStream& stream) override
{
uint8_t tempBuffer[128];
auto skippedBytes = 0uz;
@@ -11,9 +11,8 @@ namespace
class StepSkipZoneImageHeaders final : public ILoadingStep
{
public:
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override
void PerformStep(ZoneReader& zoneReader, ILoadingStream& stream) override
{
// Xbox fastfiles have additional header data before the auth header:
// - 4 bytes: language flags bitmask
// - 4 bytes: image count
@@ -17,7 +17,7 @@ namespace
m_expected_file_name.erase(m_file_name_buffer_size - 1);
}
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override
void PerformStep(ZoneReader& zoneReader, ILoadingStream& stream) override
{
std::stringstream originalFilenameStream;
unsigned bufferOffset = 0;
@@ -21,7 +21,7 @@ namespace
{
}
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override
void PerformStep(ZoneReader& zoneReader, ILoadingStream& stream) override
{
const uint8_t* dataToHash = nullptr;
size_t dataToHashSize = 0;
@@ -15,7 +15,7 @@ namespace
{
}
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override
void PerformStep(ZoneReader& zoneReader, ILoadingStream& stream) override
{
char currentCharacter;
@@ -18,7 +18,7 @@ namespace
{
}
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override
void PerformStep(ZoneReader& zoneReader, ILoadingStream& stream) override
{
assert(m_algorithm != nullptr);
assert(m_signature_provider != nullptr);
+35 -37
View File
@@ -7,54 +7,24 @@
#include <algorithm>
#include <cassert>
#include <format>
#include <iostream>
ZoneLoader::ZoneLoader(std::unique_ptr<Zone> zone)
: m_processor_chain_dirty(false),
m_zone(std::move(zone))
ZoneReader::ZoneReader()
: m_processor_chain_dirty(false)
{
}
ILoadingStream* ZoneLoader::BuildLoadingChain(ILoadingStream* rootStream)
{
auto* currentStream = rootStream;
for (const auto& processor : m_processors)
{
processor->SetBaseStream(currentStream);
currentStream = processor.get();
}
m_processor_chain_dirty = false;
return currentStream;
}
void ZoneLoader::AddXBlock(std::unique_ptr<XBlock> block)
{
m_blocks.push_back(block.get());
std::ranges::sort(m_blocks,
[](const XBlock* b1, const XBlock* b2) -> bool
{
return b1->m_index < b2->m_index;
});
m_zone->Memory().AddBlock(std::move(block));
}
void ZoneLoader::AddLoadingStep(std::unique_ptr<ILoadingStep> step)
void ZoneReader::AddLoadingStep(std::unique_ptr<ILoadingStep> step)
{
m_steps.emplace_back(std::move(step));
}
void ZoneLoader::AddStreamProcessor(std::unique_ptr<StreamProcessor> streamProcessor)
void ZoneReader::AddStreamProcessor(std::unique_ptr<StreamProcessor> streamProcessor)
{
m_processors.push_back(std::move(streamProcessor));
m_processor_chain_dirty = true;
}
void ZoneLoader::RemoveStreamProcessor(const StreamProcessor* streamProcessor)
void ZoneReader::RemoveStreamProcessor(const StreamProcessor* streamProcessor)
{
for (auto i = m_processors.begin(); i < m_processors.end(); ++i)
{
@@ -67,7 +37,7 @@ void ZoneLoader::RemoveStreamProcessor(const StreamProcessor* streamProcessor)
}
}
std::unique_ptr<Zone> ZoneLoader::LoadZone(std::istream& stream)
bool ZoneReader::Run(std::istream& stream)
{
LoadingFileStream fileStream(stream);
auto* endStream = BuildLoadingChain(&fileStream);
@@ -90,9 +60,37 @@ std::unique_ptr<Zone> ZoneLoader::LoadZone(std::istream& stream)
{
con::error("Loading fastfile failed: {}", e.DetailedMessage());
return nullptr;
return false;
}
return true;
}
ILoadingStream* ZoneReader::BuildLoadingChain(ILoadingStream* rootStream)
{
auto* currentStream = rootStream;
for (const auto& processor : m_processors)
{
processor->SetBaseStream(currentStream);
currentStream = processor.get();
}
m_processor_chain_dirty = false;
return currentStream;
}
ZoneLoader::ZoneLoader(std::unique_ptr<Zone> zone)
: m_zone(std::move(zone))
{
}
std::unique_ptr<Zone> ZoneLoader::LoadZone(std::istream& stream)
{
if (!Run(stream))
return nullptr;
m_zone->Register();
return std::move(m_zone);
+13 -8
View File
@@ -2,7 +2,6 @@
#include "ILoadingStep.h"
#include "StreamProcessor.h"
#include "Zone/XBlock.h"
#include "Zone/Zone.h"
#include <istream>
@@ -11,28 +10,34 @@
class ILoadingStep;
class ZoneLoader
class ZoneReader
{
public:
explicit ZoneLoader(std::unique_ptr<Zone> zone);
ZoneReader();
void AddXBlock(std::unique_ptr<XBlock> block);
void AddLoadingStep(std::unique_ptr<ILoadingStep> step);
void AddStreamProcessor(std::unique_ptr<StreamProcessor> streamProcessor);
void RemoveStreamProcessor(const StreamProcessor* streamProcessor);
std::unique_ptr<Zone> LoadZone(std::istream& stream);
bool Run(std::istream& stream);
std::vector<XBlock*> m_blocks;
private:
protected:
ILoadingStream* BuildLoadingChain(ILoadingStream* rootStream);
std::vector<std::unique_ptr<ILoadingStep>> m_steps;
std::vector<std::unique_ptr<StreamProcessor>> m_processors;
bool m_processor_chain_dirty;
};
class ZoneLoader : public ZoneReader
{
public:
explicit ZoneLoader(std::unique_ptr<Zone> zone);
std::unique_ptr<Zone> LoadZone(std::istream& stream);
private:
std::unique_ptr<Zone> m_zone;
};