2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2026-02-14 19:33:02 +00:00

refactor: streamline obj compiling asset loading

This commit is contained in:
Jan Laupetin
2025-08-05 18:51:56 +02:00
parent 95a6a028ab
commit 33c09dfe61
31 changed files with 505 additions and 495 deletions

View File

@@ -371,68 +371,71 @@ namespace
};
} // namespace
IPakToCreate::IPakToCreate(std::string name)
: m_name(std::move(name))
namespace image
{
}
void IPakToCreate::AddImage(std::string imageName)
{
m_image_names.emplace_back(std::move(imageName));
}
void IPakToCreate::Build(ISearchPath& searchPath, IOutputPath& outPath)
{
const auto file = outPath.Open(std::format("{}.ipak", m_name));
if (!file)
IPakToCreate::IPakToCreate(std::string name)
: m_name(std::move(name))
{
std::cerr << std::format("Failed to open file for ipak {}\n", m_name);
return;
}
IPakWriter writer(*file, searchPath, m_image_names);
writer.Write();
void IPakToCreate::AddImage(std::string imageName)
{
m_image_names.emplace_back(std::move(imageName));
}
std::cout << std::format("Created ipak {} with {} entries\n", m_name, m_image_names.size());
}
void IPakToCreate::Build(ISearchPath& searchPath, IOutputPath& outPath)
{
const auto file = outPath.Open(std::format("{}.ipak", m_name));
if (!file)
{
std::cerr << std::format("Failed to open file for ipak {}\n", m_name);
return;
}
const std::vector<std::string>& IPakToCreate::GetImageNames() const
{
return m_image_names;
}
IPakWriter writer(*file, searchPath, m_image_names);
writer.Write();
IPakCreator::IPakCreator()
: m_kvp_creator(nullptr)
{
}
std::cout << std::format("Created ipak {} with {} entries\n", m_name, m_image_names.size());
}
void IPakCreator::Inject(ZoneAssetCreationInjection& inject)
{
m_kvp_creator = &inject.m_zone_states.GetZoneAssetCreationState<KeyValuePairsCreator>();
}
const std::vector<std::string>& IPakToCreate::GetImageNames() const
{
return m_image_names;
}
IPakToCreate* IPakCreator::GetOrAddIPak(const std::string& ipakName)
{
const auto existingIPak = m_ipak_lookup.find(ipakName);
if (existingIPak != m_ipak_lookup.end())
return existingIPak->second;
IPakCreator::IPakCreator()
: m_kvp_creator(nullptr)
{
}
auto newIPak = std::make_unique<IPakToCreate>(ipakName);
auto* result = newIPak.get();
m_ipak_lookup.emplace(ipakName, result);
m_ipaks.emplace_back(std::move(newIPak));
void IPakCreator::Inject(ZoneAssetCreationInjection& inject)
{
m_kvp_creator = &inject.m_zone_states.GetZoneAssetCreationState<key_value_pairs::Creator>();
}
assert(m_kvp_creator);
m_kvp_creator->AddKeyValuePair(CommonKeyValuePair("ipak_read", ipakName));
IPakToCreate* IPakCreator::GetOrAddIPak(const std::string& ipakName)
{
const auto existingIPak = m_ipak_lookup.find(ipakName);
if (existingIPak != m_ipak_lookup.end())
return existingIPak->second;
return result;
}
auto newIPak = std::make_unique<IPakToCreate>(ipakName);
auto* result = newIPak.get();
m_ipak_lookup.emplace(ipakName, result);
m_ipaks.emplace_back(std::move(newIPak));
void IPakCreator::Finalize(ISearchPath& searchPath, IOutputPath& outPath)
{
for (const auto& ipakToCreate : m_ipaks)
ipakToCreate->Build(searchPath, outPath);
assert(m_kvp_creator);
m_kvp_creator->AddKeyValuePair(key_value_pairs::CommonKeyValuePair("ipak_read", ipakName));
m_ipaks.clear();
m_ipak_lookup.clear();
}
return result;
}
void IPakCreator::Finalize(ISearchPath& searchPath, IOutputPath& outPath)
{
for (const auto& ipakToCreate : m_ipaks)
ipakToCreate->Build(searchPath, outPath);
m_ipaks.clear();
m_ipak_lookup.clear();
}
} // namespace image

View File

@@ -9,32 +9,35 @@
#include <string>
#include <unordered_map>
class IPakToCreate
namespace image
{
public:
explicit IPakToCreate(std::string name);
class IPakToCreate
{
public:
explicit IPakToCreate(std::string name);
void AddImage(std::string imageName);
void Build(ISearchPath& searchPath, IOutputPath& outPath);
[[nodiscard]] const std::vector<std::string>& GetImageNames() const;
void AddImage(std::string imageName);
void Build(ISearchPath& searchPath, IOutputPath& outPath);
[[nodiscard]] const std::vector<std::string>& GetImageNames() const;
private:
std::string m_name;
std::vector<std::string> m_image_names;
};
private:
std::string m_name;
std::vector<std::string> m_image_names;
};
class IPakCreator final : public IZoneAssetCreationState
{
public:
IPakCreator();
class IPakCreator final : public IZoneAssetCreationState
{
public:
IPakCreator();
void Inject(ZoneAssetCreationInjection& inject) override;
void Inject(ZoneAssetCreationInjection& inject) override;
IPakToCreate* GetOrAddIPak(const std::string& ipakName);
void Finalize(ISearchPath& searchPath, IOutputPath& outPath);
IPakToCreate* GetOrAddIPak(const std::string& ipakName);
void Finalize(ISearchPath& searchPath, IOutputPath& outPath);
private:
KeyValuePairsCreator* m_kvp_creator;
std::unordered_map<std::string, IPakToCreate*> m_ipak_lookup;
std::vector<std::unique_ptr<IPakToCreate>> m_ipaks;
};
private:
key_value_pairs::Creator* m_kvp_creator;
std::unordered_map<std::string, IPakToCreate*> m_ipak_lookup;
std::vector<std::unique_ptr<IPakToCreate>> m_ipaks;
};
} // namespace image

View File

@@ -4,63 +4,66 @@
#include <algorithm>
AbstractImageIPakPostProcessor::AbstractImageIPakPostProcessor(const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates,
IOutputPath& outDir)
: m_zone_definition(zoneDefinition),
m_search_path(searchPath),
m_ipak_creator(zoneStates.GetZoneAssetCreationState<IPakCreator>()),
m_out_dir(outDir),
m_obj_container_index(0u),
m_current_ipak(nullptr),
m_current_ipak_start_index(0u),
m_current_ipak_end_index(0u)
namespace image
{
FindNextObjContainer();
}
bool AbstractImageIPakPostProcessor::AppliesToZoneDefinition(const ZoneDefinitionContext& zoneDefinition)
{
return std::ranges::any_of(zoneDefinition.m_zone_definition.m_obj_containers,
[](const ZoneDefinitionObjContainer& objContainer)
{
return objContainer.m_type == ZoneDefinitionObjContainerType::IPAK;
});
}
void AbstractImageIPakPostProcessor::FindNextObjContainer()
{
const auto objContainerCount = m_zone_definition.m_zone_definition.m_obj_containers.size();
while (m_obj_container_index < objContainerCount)
AbstractIPakPostProcessor::AbstractIPakPostProcessor(const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates,
IOutputPath& outDir)
: m_zone_definition(zoneDefinition),
m_search_path(searchPath),
m_ipak_creator(zoneStates.GetZoneAssetCreationState<IPakCreator>()),
m_out_dir(outDir),
m_obj_container_index(0u),
m_current_ipak(nullptr),
m_current_ipak_start_index(0u),
m_current_ipak_end_index(0u)
{
const auto& objContainer = m_zone_definition.m_zone_definition.m_obj_containers[m_obj_container_index++];
if (objContainer.m_type != ZoneDefinitionObjContainerType::IPAK)
continue;
m_current_ipak = m_ipak_creator.GetOrAddIPak(objContainer.m_name);
m_current_ipak_start_index = objContainer.m_asset_start;
m_current_ipak_end_index = objContainer.m_asset_end;
return;
FindNextObjContainer();
}
m_current_ipak = nullptr;
}
bool AbstractIPakPostProcessor::AppliesToZoneDefinition(const ZoneDefinitionContext& zoneDefinition)
{
return std::ranges::any_of(zoneDefinition.m_zone_definition.m_obj_containers,
[](const ZoneDefinitionObjContainer& objContainer)
{
return objContainer.m_type == ZoneDefinitionObjContainerType::IPAK;
});
}
void AbstractImageIPakPostProcessor::PostProcessAsset(XAssetInfoGeneric& assetInfo, AssetCreationContext& context)
{
if (assetInfo.m_name.empty() || assetInfo.m_name[0] == ',')
return;
void AbstractIPakPostProcessor::FindNextObjContainer()
{
const auto objContainerCount = m_zone_definition.m_zone_definition.m_obj_containers.size();
while (m_obj_container_index < objContainerCount)
{
const auto& objContainer = m_zone_definition.m_zone_definition.m_obj_containers[m_obj_container_index++];
while (m_current_ipak && m_zone_definition.m_asset_index_in_definition >= m_current_ipak_end_index)
FindNextObjContainer();
if (objContainer.m_type != ZoneDefinitionObjContainerType::IPAK)
continue;
if (m_current_ipak && m_zone_definition.m_asset_index_in_definition >= m_current_ipak_start_index)
m_current_ipak->AddImage(assetInfo.m_name);
}
m_current_ipak = m_ipak_creator.GetOrAddIPak(objContainer.m_name);
m_current_ipak_start_index = objContainer.m_asset_start;
m_current_ipak_end_index = objContainer.m_asset_end;
return;
}
void AbstractImageIPakPostProcessor::FinalizeZone(AssetCreationContext& context)
{
m_ipak_creator.Finalize(m_search_path, m_out_dir);
}
m_current_ipak = nullptr;
}
void AbstractIPakPostProcessor::PostProcessAsset(XAssetInfoGeneric& assetInfo, AssetCreationContext& context)
{
if (assetInfo.m_name.empty() || assetInfo.m_name[0] == ',')
return;
while (m_current_ipak && m_zone_definition.m_asset_index_in_definition >= m_current_ipak_end_index)
FindNextObjContainer();
if (m_current_ipak && m_zone_definition.m_asset_index_in_definition >= m_current_ipak_start_index)
m_current_ipak->AddImage(assetInfo.m_name);
}
void AbstractIPakPostProcessor::FinalizeZone(AssetCreationContext& context)
{
m_ipak_creator.Finalize(m_search_path, m_out_dir);
}
} // namespace image

View File

@@ -5,48 +5,51 @@
#include "Image/IPak/IPakCreator.h"
#include "SearchPath/IOutputPath.h"
class AbstractImageIPakPostProcessor : public IAssetPostProcessor
namespace image
{
public:
AbstractImageIPakPostProcessor(const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates,
IOutputPath& outDir);
static bool AppliesToZoneDefinition(const ZoneDefinitionContext& zoneDefinition);
void PostProcessAsset(XAssetInfoGeneric& assetInfo, AssetCreationContext& context) override;
void FinalizeZone(AssetCreationContext& context) override;
private:
void FindNextObjContainer();
const ZoneDefinitionContext& m_zone_definition;
ISearchPath& m_search_path;
IPakCreator& m_ipak_creator;
IOutputPath& m_out_dir;
unsigned m_obj_container_index;
IPakToCreate* m_current_ipak;
unsigned m_current_ipak_start_index;
unsigned m_current_ipak_end_index;
};
template<typename AssetType> class ImageIPakPostProcessor final : public AbstractImageIPakPostProcessor
{
public:
static_assert(std::is_base_of_v<IAssetBase, AssetType>);
ImageIPakPostProcessor(const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates,
IOutputPath& outDir)
: AbstractImageIPakPostProcessor(zoneDefinition, searchPath, zoneStates, outDir)
class AbstractIPakPostProcessor : public IAssetPostProcessor
{
}
public:
AbstractIPakPostProcessor(const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates,
IOutputPath& outDir);
[[nodiscard]] asset_type_t GetHandlingAssetType() const override
static bool AppliesToZoneDefinition(const ZoneDefinitionContext& zoneDefinition);
void PostProcessAsset(XAssetInfoGeneric& assetInfo, AssetCreationContext& context) override;
void FinalizeZone(AssetCreationContext& context) override;
private:
void FindNextObjContainer();
const ZoneDefinitionContext& m_zone_definition;
ISearchPath& m_search_path;
IPakCreator& m_ipak_creator;
IOutputPath& m_out_dir;
unsigned m_obj_container_index;
IPakToCreate* m_current_ipak;
unsigned m_current_ipak_start_index;
unsigned m_current_ipak_end_index;
};
template<typename AssetType> class IPakPostProcessor final : public AbstractIPakPostProcessor
{
return AssetType::EnumEntry;
}
};
public:
static_assert(std::is_base_of_v<IAssetBase, AssetType>);
IPakPostProcessor(const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates,
IOutputPath& outDir)
: AbstractIPakPostProcessor(zoneDefinition, searchPath, zoneStates, outDir)
{
}
[[nodiscard]] asset_type_t GetHandlingAssetType() const override
{
return AssetType::EnumEntry;
}
};
} // namespace image

View File

@@ -1,67 +1,71 @@
#include "ImageIwdPostProcessor.h"
#include "Image/ImageCommon.h"
#include "Iwd/IwdCreator.h"
#include <algorithm>
#include <format>
AbstractImageIwdPostProcessor::AbstractImageIwdPostProcessor(const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates,
IOutputPath& outDir)
: m_zone_definition(zoneDefinition),
m_search_path(searchPath),
m_iwd_creator(zoneStates.GetZoneAssetCreationState<IwdCreator>()),
m_out_dir(outDir),
m_obj_container_index(0u),
m_current_iwd(nullptr),
m_current_iwd_start_index(0u),
m_current_iwd_end_index(0u)
namespace image
{
FindNextObjContainer();
}
bool AbstractImageIwdPostProcessor::AppliesToZoneDefinition(const ZoneDefinitionContext& zoneDefinition)
{
return std::ranges::any_of(zoneDefinition.m_zone_definition.m_obj_containers,
[](const ZoneDefinitionObjContainer& objContainer)
{
return objContainer.m_type == ZoneDefinitionObjContainerType::IWD;
});
}
void AbstractImageIwdPostProcessor::FindNextObjContainer()
{
const auto objContainerCount = m_zone_definition.m_zone_definition.m_obj_containers.size();
while (m_obj_container_index < objContainerCount)
AbstractIwdPostProcessor::AbstractIwdPostProcessor(const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates,
IOutputPath& outDir)
: m_zone_definition(zoneDefinition),
m_search_path(searchPath),
m_iwd_creator(zoneStates.GetZoneAssetCreationState<IwdCreator>()),
m_out_dir(outDir),
m_obj_container_index(0u),
m_current_iwd(nullptr),
m_current_iwd_start_index(0u),
m_current_iwd_end_index(0u)
{
const auto& objContainer = m_zone_definition.m_zone_definition.m_obj_containers[m_obj_container_index++];
if (objContainer.m_type != ZoneDefinitionObjContainerType::IWD)
continue;
m_current_iwd = m_iwd_creator.GetOrAddIwd(objContainer.m_name);
m_current_iwd_start_index = objContainer.m_asset_start;
m_current_iwd_end_index = objContainer.m_asset_end;
return;
FindNextObjContainer();
}
m_current_iwd = nullptr;
}
bool AbstractIwdPostProcessor::AppliesToZoneDefinition(const ZoneDefinitionContext& zoneDefinition)
{
return std::ranges::any_of(zoneDefinition.m_zone_definition.m_obj_containers,
[](const ZoneDefinitionObjContainer& objContainer)
{
return objContainer.m_type == ZoneDefinitionObjContainerType::IWD;
});
}
void AbstractImageIwdPostProcessor::PostProcessAsset(XAssetInfoGeneric& assetInfo, AssetCreationContext& context)
{
if (assetInfo.m_name.empty() || assetInfo.m_name[0] == ',')
return;
void AbstractIwdPostProcessor::FindNextObjContainer()
{
const auto objContainerCount = m_zone_definition.m_zone_definition.m_obj_containers.size();
while (m_obj_container_index < objContainerCount)
{
const auto& objContainer = m_zone_definition.m_zone_definition.m_obj_containers[m_obj_container_index++];
while (m_current_iwd && m_zone_definition.m_asset_index_in_definition >= m_current_iwd_end_index)
FindNextObjContainer();
if (objContainer.m_type != ZoneDefinitionObjContainerType::IWD)
continue;
if (m_current_iwd && m_zone_definition.m_asset_index_in_definition >= m_current_iwd_start_index)
m_current_iwd->AddFile(std::format("images/{}.iwi", assetInfo.m_name));
}
m_current_iwd = m_iwd_creator.GetOrAddIwd(objContainer.m_name);
m_current_iwd_start_index = objContainer.m_asset_start;
m_current_iwd_end_index = objContainer.m_asset_end;
return;
}
void AbstractImageIwdPostProcessor::FinalizeZone(AssetCreationContext& context)
{
m_iwd_creator.Finalize(m_search_path, m_out_dir);
}
m_current_iwd = nullptr;
}
void AbstractIwdPostProcessor::PostProcessAsset(XAssetInfoGeneric& assetInfo, AssetCreationContext& context)
{
if (assetInfo.m_name.empty() || assetInfo.m_name[0] == ',')
return;
while (m_current_iwd && m_zone_definition.m_asset_index_in_definition >= m_current_iwd_end_index)
FindNextObjContainer();
if (m_current_iwd && m_zone_definition.m_asset_index_in_definition >= m_current_iwd_start_index)
m_current_iwd->AddFile(GetFileNameForAsset(assetInfo.m_name, ".iwi"));
}
void AbstractIwdPostProcessor::FinalizeZone(AssetCreationContext& context)
{
m_iwd_creator.Finalize(m_search_path, m_out_dir);
}
} // namespace image

View File

@@ -5,48 +5,48 @@
#include "Iwd/IwdCreator.h"
#include "SearchPath/IOutputPath.h"
class AbstractImageIwdPostProcessor : public IAssetPostProcessor
namespace image
{
public:
AbstractImageIwdPostProcessor(const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates,
IOutputPath& outDir);
static bool AppliesToZoneDefinition(const ZoneDefinitionContext& zoneDefinition);
void PostProcessAsset(XAssetInfoGeneric& assetInfo, AssetCreationContext& context) override;
void FinalizeZone(AssetCreationContext& context) override;
private:
void FindNextObjContainer();
const ZoneDefinitionContext& m_zone_definition;
ISearchPath& m_search_path;
IwdCreator& m_iwd_creator;
IOutputPath& m_out_dir;
unsigned m_obj_container_index;
IwdToCreate* m_current_iwd;
unsigned m_current_iwd_start_index;
unsigned m_current_iwd_end_index;
};
template<typename AssetType> class ImageIwdPostProcessor final : public AbstractImageIwdPostProcessor
{
public:
static_assert(std::is_base_of_v<IAssetBase, AssetType>);
ImageIwdPostProcessor(const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates,
IOutputPath& outDir)
: AbstractImageIwdPostProcessor(zoneDefinition, searchPath, zoneStates, outDir)
class AbstractIwdPostProcessor : public IAssetPostProcessor
{
}
public:
AbstractIwdPostProcessor(const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates,
IOutputPath& outDir);
[[nodiscard]] asset_type_t GetHandlingAssetType() const override
static bool AppliesToZoneDefinition(const ZoneDefinitionContext& zoneDefinition);
void PostProcessAsset(XAssetInfoGeneric& assetInfo, AssetCreationContext& context) override;
void FinalizeZone(AssetCreationContext& context) override;
private:
void FindNextObjContainer();
const ZoneDefinitionContext& m_zone_definition;
ISearchPath& m_search_path;
IwdCreator& m_iwd_creator;
IOutputPath& m_out_dir;
unsigned m_obj_container_index;
IwdToCreate* m_current_iwd;
unsigned m_current_iwd_start_index;
unsigned m_current_iwd_end_index;
};
template<typename AssetType> class IwdPostProcessor final : public AbstractIwdPostProcessor
{
return AssetType::EnumEntry;
}
};
public:
static_assert(std::is_base_of_v<IAssetBase, AssetType>);
IwdPostProcessor(const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, ZoneAssetCreationStateContainer& zoneStates, IOutputPath& outDir)
: AbstractIwdPostProcessor(zoneDefinition, searchPath, zoneStates, outDir)
{
}
[[nodiscard]] asset_type_t GetHandlingAssetType() const override
{
return AssetType::EnumEntry;
}
};
} // namespace image