mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-21 00:25:44 +00:00
Merge branch 'Laupetin:main' into main
This commit is contained in:
commit
80da882b4d
@ -3,6 +3,7 @@ include "tools/scripts/including.lua"
|
||||
include "tools/scripts/linking.lua"
|
||||
include "tools/scripts/options.lua"
|
||||
include "tools/scripts/platform.lua"
|
||||
include "tools/scripts/version.lua"
|
||||
|
||||
-- ==================
|
||||
-- Workspace
|
||||
@ -64,6 +65,13 @@ workspace "OpenAssetTools"
|
||||
"_CRT_SECURE_NO_WARNINGS"
|
||||
}
|
||||
|
||||
-- Write the current version to a header
|
||||
-- This is better than adding it as macro here since changing a global macro would cause a full rebuild
|
||||
WriteVersionHeader()
|
||||
includedirs {
|
||||
GetVersionHeaderFolder()
|
||||
}
|
||||
|
||||
filter "options:debug-structureddatadef"
|
||||
defines { "STRUCTUREDDATADEF_DEBUG" }
|
||||
filter {}
|
||||
|
@ -616,9 +616,13 @@ public:
|
||||
|
||||
bool Start(const int argc, const char** argv) override
|
||||
{
|
||||
if (!m_args.ParseArgs(argc, argv))
|
||||
auto shouldContinue = true;
|
||||
if (!m_args.ParseArgs(argc, argv, shouldContinue))
|
||||
return false;
|
||||
|
||||
if (!shouldContinue)
|
||||
return true;
|
||||
|
||||
if (!m_search_paths.BuildProjectIndependentSearchPaths())
|
||||
return false;
|
||||
|
||||
|
@ -1,11 +1,13 @@
|
||||
#include "LinkerArgs.h"
|
||||
|
||||
#include "GitVersion.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "ObjWriting.h"
|
||||
#include "Utils/Arguments/UsageInformation.h"
|
||||
#include "Utils/FileUtils.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
#include <type_traits>
|
||||
|
||||
@ -19,6 +21,12 @@ const CommandLineOption* const OPTION_HELP =
|
||||
.WithDescription("Displays usage information.")
|
||||
.Build();
|
||||
|
||||
const CommandLineOption* const OPTION_VERSION =
|
||||
CommandLineOption::Builder::Create()
|
||||
.WithLongName("version")
|
||||
.WithDescription("Prints the application version.")
|
||||
.Build();
|
||||
|
||||
const CommandLineOption* const OPTION_VERBOSE =
|
||||
CommandLineOption::Builder::Create()
|
||||
.WithShortName("v")
|
||||
@ -88,6 +96,7 @@ const CommandLineOption* const OPTION_MENU_NO_OPTIMIZATION =
|
||||
|
||||
const CommandLineOption* const COMMAND_LINE_OPTIONS[]{
|
||||
OPTION_HELP,
|
||||
OPTION_VERSION,
|
||||
OPTION_VERBOSE,
|
||||
OPTION_BASE_FOLDER,
|
||||
OPTION_OUTPUT_FOLDER,
|
||||
@ -100,7 +109,7 @@ const CommandLineOption* const COMMAND_LINE_OPTIONS[]{
|
||||
};
|
||||
|
||||
LinkerArgs::LinkerArgs()
|
||||
: m_argument_parser(COMMAND_LINE_OPTIONS, std::extent<decltype(COMMAND_LINE_OPTIONS)>::value),
|
||||
: m_argument_parser(COMMAND_LINE_OPTIONS, std::extent_v<decltype(COMMAND_LINE_OPTIONS)>),
|
||||
m_base_pattern(R"(\?base\?)"),
|
||||
m_game_pattern(R"(\?game\?)"),
|
||||
m_project_pattern(R"(\?project\?)"),
|
||||
@ -125,6 +134,11 @@ void LinkerArgs::PrintUsage()
|
||||
usage.Print();
|
||||
}
|
||||
|
||||
void LinkerArgs::PrintVersion()
|
||||
{
|
||||
std::cout << "OpenAssetTools Linker " << std::string(GIT_VERSION) << "\n";
|
||||
}
|
||||
|
||||
void LinkerArgs::SetVerbose(const bool isVerbose)
|
||||
{
|
||||
m_verbose = isVerbose;
|
||||
@ -198,8 +212,9 @@ std::set<std::string> LinkerArgs::GetSearchPathsForProject(const std::set<std::s
|
||||
return out;
|
||||
}
|
||||
|
||||
bool LinkerArgs::ParseArgs(const int argc, const char** argv)
|
||||
bool LinkerArgs::ParseArgs(const int argc, const char** argv, bool& shouldContinue)
|
||||
{
|
||||
shouldContinue = true;
|
||||
if (!m_argument_parser.ParseArguments(argc - 1, &argv[1]))
|
||||
{
|
||||
PrintUsage();
|
||||
@ -210,7 +225,16 @@ bool LinkerArgs::ParseArgs(const int argc, const char** argv)
|
||||
if (m_argument_parser.IsOptionSpecified(OPTION_HELP))
|
||||
{
|
||||
PrintUsage();
|
||||
return false;
|
||||
shouldContinue = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if the user wants to see the version
|
||||
if (m_argument_parser.IsOptionSpecified(OPTION_VERSION))
|
||||
{
|
||||
PrintVersion();
|
||||
shouldContinue = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
m_project_specifiers_to_build = m_argument_parser.GetArguments();
|
||||
|
@ -31,6 +31,7 @@ private:
|
||||
* \brief Prints a command line usage help text for the Linker tool to stdout.
|
||||
*/
|
||||
static void PrintUsage();
|
||||
static void PrintVersion();
|
||||
|
||||
void SetVerbose(bool isVerbose);
|
||||
|
||||
@ -56,7 +57,7 @@ public:
|
||||
bool m_verbose;
|
||||
|
||||
LinkerArgs();
|
||||
bool ParseArgs(int argc, const char** argv);
|
||||
bool ParseArgs(int argc, const char** argv, bool& shouldContinue);
|
||||
|
||||
/**
|
||||
* \brief Converts the output path specified by command line arguments to a path applies for the specified project.
|
||||
|
@ -14,6 +14,27 @@ bool CsvInputStream::NextRow(std::vector<std::string>& out) const
|
||||
if (!out.empty())
|
||||
out.clear();
|
||||
|
||||
return EmitNextRow(
|
||||
[&out](std::string value)
|
||||
{
|
||||
out.emplace_back(std::move(value));
|
||||
});
|
||||
}
|
||||
|
||||
bool CsvInputStream::NextRow(std::vector<const char*>& out, MemoryManager& memory) const
|
||||
{
|
||||
if (!out.empty())
|
||||
out.clear();
|
||||
|
||||
return EmitNextRow(
|
||||
[&out, &memory](const std::string& value)
|
||||
{
|
||||
out.emplace_back(memory.Dup(value.c_str()));
|
||||
});
|
||||
}
|
||||
|
||||
bool CsvInputStream::EmitNextRow(const std::function<void(std::string)>& cb) const
|
||||
{
|
||||
auto c = m_stream.get();
|
||||
const auto isEof = c == EOF;
|
||||
std::ostringstream col;
|
||||
@ -21,7 +42,7 @@ bool CsvInputStream::NextRow(std::vector<std::string>& out) const
|
||||
{
|
||||
if (c == CSV_SEPARATOR)
|
||||
{
|
||||
out.emplace_back(col.str());
|
||||
cb(col.str());
|
||||
col.clear();
|
||||
col.str(std::string());
|
||||
}
|
||||
@ -46,7 +67,7 @@ bool CsvInputStream::NextRow(std::vector<std::string>& out) const
|
||||
|
||||
if (!isEof)
|
||||
{
|
||||
out.emplace_back(col.str());
|
||||
cb(col.str());
|
||||
}
|
||||
|
||||
return !isEof;
|
||||
|
@ -1,28 +1,36 @@
|
||||
#pragma once
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class CsvInputStream
|
||||
{
|
||||
std::istream& m_stream;
|
||||
|
||||
public:
|
||||
explicit CsvInputStream(std::istream& stream);
|
||||
|
||||
bool NextRow(std::vector<std::string>& out) const;
|
||||
bool NextRow(std::vector<const char*>& out, MemoryManager& memory) const;
|
||||
|
||||
private:
|
||||
bool EmitNextRow(const std::function<void(std::string)>& cb) const;
|
||||
|
||||
std::istream& m_stream;
|
||||
};
|
||||
|
||||
class CsvOutputStream
|
||||
{
|
||||
std::ostream& m_stream;
|
||||
unsigned m_column_count;
|
||||
unsigned m_current_column;
|
||||
bool m_first_row;
|
||||
|
||||
public:
|
||||
explicit CsvOutputStream(std::ostream& stream);
|
||||
|
||||
void WriteColumn(const std::string& value);
|
||||
void NextRow();
|
||||
|
||||
private:
|
||||
std::ostream& m_stream;
|
||||
unsigned m_column_count;
|
||||
unsigned m_current_column;
|
||||
bool m_first_row;
|
||||
};
|
||||
|
@ -0,0 +1,36 @@
|
||||
#include "AssetLoaderLocalizeEntry.h"
|
||||
|
||||
#include "Localize/LocalizeCommonAssetLoader.h"
|
||||
|
||||
using namespace IW3;
|
||||
|
||||
XAssetInfoGeneric* AssetLoaderLocalizeEntry::LoadFromGlobalAssetPools(const std::string& assetName) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* AssetLoaderLocalizeEntry::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool AssetLoaderLocalizeEntry::CanLoadFromRaw() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetLoaderLocalizeEntry::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
const LocalizeCommonAssetLoader commonLoader(
|
||||
[memory, manager](const CommonLocalizeEntry& entry)
|
||||
{
|
||||
auto* localizeEntry = memory->Create<LocalizeEntry>();
|
||||
localizeEntry->name = memory->Dup(entry.m_key.c_str());
|
||||
localizeEntry->value = memory->Dup(entry.m_value.c_str());
|
||||
|
||||
manager->AddAsset(ASSET_TYPE_LOCALIZE_ENTRY, entry.m_key, localizeEntry);
|
||||
});
|
||||
|
||||
return commonLoader.LoadLocalizeAsset(assetName, searchPath, manager, zone);
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "AssetLoading/IAssetLoadingManager.h"
|
||||
#include "Game/IW3/IW3.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW3
|
||||
{
|
||||
class AssetLoaderLocalizeEntry final : public BasicAssetLoader<ASSET_TYPE_LOCALIZE_ENTRY, LocalizeEntry>
|
||||
{
|
||||
public:
|
||||
_NODISCARD XAssetInfoGeneric* LoadFromGlobalAssetPools(const std::string& assetName) const override;
|
||||
_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;
|
||||
};
|
||||
} // namespace IW3
|
@ -0,0 +1,39 @@
|
||||
#include "AssetLoaderStringTable.h"
|
||||
|
||||
#include "Csv/CsvStream.h"
|
||||
#include "Game/IW3/CommonIW3.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
#include "StringTable/StringTableLoader.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW3;
|
||||
|
||||
void* AssetLoaderStringTable::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* stringTable = memory->Create<StringTable>();
|
||||
memset(stringTable, 0, sizeof(StringTable));
|
||||
stringTable->name = memory->Dup(assetName.c_str());
|
||||
return stringTable;
|
||||
}
|
||||
|
||||
bool AssetLoaderStringTable::CanLoadFromRaw() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetLoaderStringTable::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;
|
||||
|
||||
string_table::StringTableLoaderV1<StringTable> loader;
|
||||
auto* stringTable = loader.LoadFromStream(assetName, *memory, *file.m_stream);
|
||||
|
||||
manager->AddAsset(ASSET_TYPE_STRINGTABLE, assetName, stringTable);
|
||||
|
||||
return true;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW3/IW3.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW3
|
||||
{
|
||||
class AssetLoaderStringTable final : public BasicAssetLoader<ASSET_TYPE_STRINGTABLE, StringTable>
|
||||
{
|
||||
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;
|
||||
};
|
||||
} // namespace IW3
|
@ -1,6 +1,7 @@
|
||||
#include "ObjLoaderIW3.h"
|
||||
|
||||
#include "AssetLoaders/AssetLoaderGfxImage.h"
|
||||
#include "AssetLoaders/AssetLoaderLocalizeEntry.h"
|
||||
#include "AssetLoaders/AssetLoaderRawFile.h"
|
||||
#include "AssetLoading/AssetLoadingManager.h"
|
||||
#include "Game/IW3/GameAssetPoolIW3.h"
|
||||
@ -43,7 +44,7 @@ ObjLoader::ObjLoader()
|
||||
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FONT, Font_s))
|
||||
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MENULIST, MenuList))
|
||||
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MENU, menuDef_t))
|
||||
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_LOCALIZE_ENTRY, LocalizeEntry))
|
||||
REGISTER_ASSET_LOADER(AssetLoaderLocalizeEntry)
|
||||
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_WEAPON, WeaponDef))
|
||||
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SNDDRIVER_GLOBALS, SndDriverGlobals))
|
||||
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FX, FxEffectDef))
|
||||
|
@ -22,7 +22,7 @@ bool AssetLoaderLocalizeEntry::CanLoadFromRaw() const
|
||||
bool AssetLoaderLocalizeEntry::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
LocalizeCommonAssetLoader commonLoader(
|
||||
const LocalizeCommonAssetLoader commonLoader(
|
||||
[memory, manager](const CommonLocalizeEntry& entry)
|
||||
{
|
||||
auto* localizeEntry = memory->Create<LocalizeEntry>();
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
#include "StringTable/StringTableLoader.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
@ -30,49 +31,8 @@ bool AssetLoaderStringTable::LoadFromRaw(
|
||||
if (!file.IsOpen())
|
||||
return false;
|
||||
|
||||
auto* stringTable = memory->Create<StringTable>();
|
||||
stringTable->name = memory->Dup(assetName.c_str());
|
||||
|
||||
std::vector<std::vector<std::string>> csvLines;
|
||||
std::vector<std::string> currentLine;
|
||||
auto maxCols = 0u;
|
||||
const CsvInputStream csv(*file.m_stream);
|
||||
|
||||
while (csv.NextRow(currentLine))
|
||||
{
|
||||
if (currentLine.size() > maxCols)
|
||||
maxCols = currentLine.size();
|
||||
csvLines.emplace_back(std::move(currentLine));
|
||||
currentLine = std::vector<std::string>();
|
||||
}
|
||||
|
||||
stringTable->columnCount = static_cast<int>(maxCols);
|
||||
stringTable->rowCount = static_cast<int>(csvLines.size());
|
||||
const auto cellCount = static_cast<unsigned>(stringTable->rowCount) * static_cast<unsigned>(stringTable->columnCount);
|
||||
|
||||
if (cellCount)
|
||||
{
|
||||
stringTable->values = static_cast<StringTableCell*>(memory->Alloc(sizeof(StringTableCell) * cellCount));
|
||||
|
||||
for (auto row = 0u; row < csvLines.size(); row++)
|
||||
{
|
||||
const auto& rowValues = csvLines[row];
|
||||
for (auto col = 0u; col < maxCols; col++)
|
||||
{
|
||||
auto& cell = stringTable->values[row * maxCols + col];
|
||||
if (col >= rowValues.size() || rowValues[col].empty())
|
||||
cell.string = "";
|
||||
else
|
||||
cell.string = memory->Dup(rowValues[col].c_str());
|
||||
|
||||
cell.hash = Common::StringTable_HashString(cell.string);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stringTable->values = nullptr;
|
||||
}
|
||||
string_table::StringTableLoaderV2<StringTable, Common::StringTable_HashString> loader;
|
||||
auto* stringTable = loader.LoadFromStream(assetName, *memory, *file.m_stream);
|
||||
|
||||
manager->AddAsset(ASSET_TYPE_STRINGTABLE, assetName, stringTable);
|
||||
|
||||
|
@ -22,7 +22,7 @@ bool AssetLoaderLocalizeEntry::CanLoadFromRaw() const
|
||||
bool AssetLoaderLocalizeEntry::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
LocalizeCommonAssetLoader commonLoader(
|
||||
const LocalizeCommonAssetLoader commonLoader(
|
||||
[memory, manager](const CommonLocalizeEntry& entry)
|
||||
{
|
||||
auto* localizeEntry = memory->Create<LocalizeEntry>();
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
#include "StringTable/StringTableLoader.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
@ -30,49 +31,8 @@ bool AssetLoaderStringTable::LoadFromRaw(
|
||||
if (!file.IsOpen())
|
||||
return false;
|
||||
|
||||
auto* stringTable = memory->Create<StringTable>();
|
||||
stringTable->name = memory->Dup(assetName.c_str());
|
||||
|
||||
std::vector<std::vector<std::string>> csvLines;
|
||||
std::vector<std::string> currentLine;
|
||||
auto maxCols = 0u;
|
||||
const CsvInputStream csv(*file.m_stream);
|
||||
|
||||
while (csv.NextRow(currentLine))
|
||||
{
|
||||
if (currentLine.size() > maxCols)
|
||||
maxCols = currentLine.size();
|
||||
csvLines.emplace_back(std::move(currentLine));
|
||||
currentLine = std::vector<std::string>();
|
||||
}
|
||||
|
||||
stringTable->columnCount = static_cast<int>(maxCols);
|
||||
stringTable->rowCount = static_cast<int>(csvLines.size());
|
||||
const auto cellCount = static_cast<unsigned>(stringTable->rowCount) * static_cast<unsigned>(stringTable->columnCount);
|
||||
|
||||
if (cellCount)
|
||||
{
|
||||
stringTable->values = static_cast<StringTableCell*>(memory->Alloc(sizeof(StringTableCell) * cellCount));
|
||||
|
||||
for (auto row = 0u; row < csvLines.size(); row++)
|
||||
{
|
||||
const auto& rowValues = csvLines[row];
|
||||
for (auto col = 0u; col < maxCols; col++)
|
||||
{
|
||||
auto& cell = stringTable->values[row * maxCols + col];
|
||||
if (col >= rowValues.size() || rowValues[col].empty())
|
||||
cell.string = "";
|
||||
else
|
||||
cell.string = memory->Dup(rowValues[col].c_str());
|
||||
|
||||
cell.hash = Common::StringTable_HashString(cell.string);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stringTable->values = nullptr;
|
||||
}
|
||||
string_table::StringTableLoaderV2<StringTable, Common::StringTable_HashString> loader;
|
||||
auto* stringTable = loader.LoadFromStream(assetName, *memory, *file.m_stream);
|
||||
|
||||
manager->AddAsset(ASSET_TYPE_STRINGTABLE, assetName, stringTable);
|
||||
|
||||
|
@ -22,7 +22,7 @@ bool AssetLoaderLocalizeEntry::CanLoadFromRaw() const
|
||||
bool AssetLoaderLocalizeEntry::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
LocalizeCommonAssetLoader commonLoader(
|
||||
const LocalizeCommonAssetLoader commonLoader(
|
||||
[memory, manager](const CommonLocalizeEntry& entry)
|
||||
{
|
||||
auto* localizeEntry = memory->Create<LocalizeEntry>();
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "Game/T5/CommonT5.h"
|
||||
#include "Game/T5/T5.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
#include "StringTable/StringTableLoader.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
@ -29,65 +30,8 @@ bool AssetLoaderStringTable::LoadFromRaw(
|
||||
if (!file.IsOpen())
|
||||
return false;
|
||||
|
||||
auto* stringTable = memory->Create<StringTable>();
|
||||
stringTable->name = memory->Dup(assetName.c_str());
|
||||
|
||||
std::vector<std::vector<std::string>> csvLines;
|
||||
std::vector<std::string> currentLine;
|
||||
auto maxCols = 0u;
|
||||
const CsvInputStream csv(*file.m_stream);
|
||||
|
||||
while (csv.NextRow(currentLine))
|
||||
{
|
||||
if (currentLine.size() > maxCols)
|
||||
maxCols = currentLine.size();
|
||||
csvLines.emplace_back(std::move(currentLine));
|
||||
currentLine = std::vector<std::string>();
|
||||
}
|
||||
|
||||
stringTable->columnCount = static_cast<int>(maxCols);
|
||||
stringTable->rowCount = static_cast<int>(csvLines.size());
|
||||
const auto cellCount = static_cast<unsigned>(stringTable->rowCount) * static_cast<unsigned>(stringTable->columnCount);
|
||||
|
||||
if (cellCount)
|
||||
{
|
||||
stringTable->values = static_cast<StringTableCell*>(memory->Alloc(sizeof(StringTableCell) * cellCount));
|
||||
stringTable->cellIndex = static_cast<int16_t*>(memory->Alloc(sizeof(int16_t) * cellCount));
|
||||
|
||||
for (auto c = 0u; c < cellCount; c++)
|
||||
stringTable->cellIndex[c] = static_cast<int16_t>(c);
|
||||
|
||||
for (auto row = 0u; row < csvLines.size(); row++)
|
||||
{
|
||||
const auto& rowValues = csvLines[row];
|
||||
for (auto col = 0u; col < maxCols; col++)
|
||||
{
|
||||
auto& cell = stringTable->values[row * maxCols + col];
|
||||
if (col >= rowValues.size() || rowValues[col].empty())
|
||||
cell.string = "";
|
||||
else
|
||||
cell.string = memory->Dup(rowValues[col].c_str());
|
||||
|
||||
cell.hash = Common::Com_HashString(cell.string);
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(&stringTable->cellIndex[0],
|
||||
&stringTable->cellIndex[cellCount - 1],
|
||||
[stringTable, maxCols](const int16_t a, const int16_t b)
|
||||
{
|
||||
auto compareResult = stringTable->values[a].hash - stringTable->values[b].hash;
|
||||
if (compareResult == 0)
|
||||
compareResult = a % maxCols - b % maxCols;
|
||||
return compareResult < 0;
|
||||
});
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
stringTable->values = nullptr;
|
||||
stringTable->cellIndex = nullptr;
|
||||
}
|
||||
string_table::StringTableLoaderV3<StringTable, Common::Com_HashString> loader;
|
||||
auto* stringTable = loader.LoadFromStream(assetName, *memory, *file.m_stream);
|
||||
|
||||
manager->AddAsset(ASSET_TYPE_STRINGTABLE, assetName, stringTable);
|
||||
|
||||
|
@ -22,7 +22,7 @@ bool AssetLoaderLocalizeEntry::CanLoadFromRaw() const
|
||||
bool AssetLoaderLocalizeEntry::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
LocalizeCommonAssetLoader commonLoader(
|
||||
const LocalizeCommonAssetLoader commonLoader(
|
||||
[memory, manager](const CommonLocalizeEntry& entry)
|
||||
{
|
||||
auto* localizeEntry = memory->Create<LocalizeEntry>();
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "Game/T6/CommonT6.h"
|
||||
#include "Game/T6/T6.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
#include "StringTable/StringTableLoader.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
@ -29,65 +30,8 @@ bool AssetLoaderStringTable::LoadFromRaw(
|
||||
if (!file.IsOpen())
|
||||
return false;
|
||||
|
||||
auto* stringTable = memory->Create<StringTable>();
|
||||
stringTable->name = memory->Dup(assetName.c_str());
|
||||
|
||||
std::vector<std::vector<std::string>> csvLines;
|
||||
std::vector<std::string> currentLine;
|
||||
auto maxCols = 0u;
|
||||
const CsvInputStream csv(*file.m_stream);
|
||||
|
||||
while (csv.NextRow(currentLine))
|
||||
{
|
||||
if (currentLine.size() > maxCols)
|
||||
maxCols = currentLine.size();
|
||||
csvLines.emplace_back(std::move(currentLine));
|
||||
currentLine = std::vector<std::string>();
|
||||
}
|
||||
|
||||
stringTable->columnCount = static_cast<int>(maxCols);
|
||||
stringTable->rowCount = static_cast<int>(csvLines.size());
|
||||
const auto cellCount = static_cast<unsigned>(stringTable->rowCount) * static_cast<unsigned>(stringTable->columnCount);
|
||||
|
||||
if (cellCount)
|
||||
{
|
||||
stringTable->values = static_cast<StringTableCell*>(memory->Alloc(sizeof(StringTableCell) * cellCount));
|
||||
stringTable->cellIndex = static_cast<int16_t*>(memory->Alloc(sizeof(int16_t) * cellCount));
|
||||
|
||||
for (auto c = 0u; c < cellCount; c++)
|
||||
stringTable->cellIndex[c] = static_cast<int16_t>(c);
|
||||
|
||||
for (auto row = 0u; row < csvLines.size(); row++)
|
||||
{
|
||||
const auto& rowValues = csvLines[row];
|
||||
for (auto col = 0u; col < maxCols; col++)
|
||||
{
|
||||
auto& cell = stringTable->values[row * maxCols + col];
|
||||
if (col >= rowValues.size() || rowValues[col].empty())
|
||||
cell.string = "";
|
||||
else
|
||||
cell.string = memory->Dup(rowValues[col].c_str());
|
||||
|
||||
cell.hash = Common::Com_HashString(cell.string);
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(&stringTable->cellIndex[0],
|
||||
&stringTable->cellIndex[cellCount - 1],
|
||||
[stringTable, maxCols](const int16_t a, const int16_t b)
|
||||
{
|
||||
auto compareResult = stringTable->values[a].hash - stringTable->values[b].hash;
|
||||
if (compareResult == 0)
|
||||
compareResult = a % maxCols - b % maxCols;
|
||||
return compareResult < 0;
|
||||
});
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
stringTable->values = nullptr;
|
||||
stringTable->cellIndex = nullptr;
|
||||
}
|
||||
string_table::StringTableLoaderV3<StringTable, Common::Com_HashString> loader;
|
||||
auto* stringTable = loader.LoadFromStream(assetName, *memory, *file.m_stream);
|
||||
|
||||
manager->AddAsset(ASSET_TYPE_STRINGTABLE, assetName, stringTable);
|
||||
|
||||
|
147
src/ObjLoading/StringTable/StringTableLoader.h
Normal file
147
src/ObjLoading/StringTable/StringTableLoader.h
Normal file
@ -0,0 +1,147 @@
|
||||
#pragma once
|
||||
|
||||
#include "Csv/CsvStream.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <istream>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace string_table
|
||||
{
|
||||
template<typename StringTableType, typename CellType> class AbstractStringTableLoader
|
||||
{
|
||||
protected:
|
||||
AbstractStringTableLoader() = default;
|
||||
virtual ~AbstractStringTableLoader() = default;
|
||||
AbstractStringTableLoader(const AbstractStringTableLoader& other) = default;
|
||||
AbstractStringTableLoader(AbstractStringTableLoader&& other) noexcept = default;
|
||||
AbstractStringTableLoader& operator=(const AbstractStringTableLoader& other) = default;
|
||||
AbstractStringTableLoader& operator=(AbstractStringTableLoader&& other) noexcept = default;
|
||||
|
||||
virtual void SetCellContent(CellType& cell, const char* content) = 0;
|
||||
|
||||
virtual void PostProcessStringTable(StringTableType* stringTable, const unsigned cellCount, MemoryManager& memory) {}
|
||||
|
||||
public:
|
||||
StringTableType* LoadFromStream(const std::string& assetName, MemoryManager& memory, std::istream& stream)
|
||||
{
|
||||
auto* stringTable = memory.Create<StringTableType>();
|
||||
stringTable->name = memory.Dup(assetName.c_str());
|
||||
|
||||
std::vector<std::vector<std::string>> csvLines;
|
||||
std::vector<std::string> currentLine;
|
||||
auto maxCols = 0u;
|
||||
const CsvInputStream csv(stream);
|
||||
|
||||
while (csv.NextRow(currentLine))
|
||||
{
|
||||
if (currentLine.size() > maxCols)
|
||||
maxCols = currentLine.size();
|
||||
csvLines.emplace_back(std::move(currentLine));
|
||||
currentLine = std::vector<std::string>();
|
||||
}
|
||||
|
||||
stringTable->columnCount = static_cast<int>(maxCols);
|
||||
stringTable->rowCount = static_cast<int>(csvLines.size());
|
||||
const auto cellCount = static_cast<unsigned>(stringTable->rowCount) * static_cast<unsigned>(stringTable->columnCount);
|
||||
|
||||
if (cellCount)
|
||||
{
|
||||
stringTable->values = static_cast<CellType*>(memory.Alloc(sizeof(CellType) * cellCount));
|
||||
|
||||
for (auto row = 0u; row < csvLines.size(); row++)
|
||||
{
|
||||
const auto& rowValues = csvLines[row];
|
||||
for (auto col = 0u; col < maxCols; col++)
|
||||
{
|
||||
auto& cell = stringTable->values[row * maxCols + col];
|
||||
if (col >= rowValues.size() || rowValues[col].empty())
|
||||
SetCellContent(cell, "");
|
||||
else
|
||||
SetCellContent(cell, memory.Dup(rowValues[col].c_str()));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stringTable->values = nullptr;
|
||||
}
|
||||
|
||||
PostProcessStringTable(stringTable, cellCount, memory);
|
||||
|
||||
return stringTable;
|
||||
}
|
||||
};
|
||||
|
||||
// =================================
|
||||
// V1: IW3
|
||||
// - Cells are const char*
|
||||
// =================================
|
||||
template<typename StringTableType> class StringTableLoaderV1 final : public AbstractStringTableLoader<StringTableType, const char*>
|
||||
{
|
||||
protected:
|
||||
void SetCellContent(const char*& cell, const char* content) override
|
||||
{
|
||||
cell = content;
|
||||
}
|
||||
};
|
||||
|
||||
// =================================
|
||||
// V2: IW4, IW5
|
||||
// - Cells are a struct and have a hash
|
||||
// =================================
|
||||
template<typename StringTableType, int (*HashFunc)(const char*)>
|
||||
class StringTableLoaderV2 final : public AbstractStringTableLoader<StringTableType, std::remove_pointer_t<decltype(StringTableType::values)>>
|
||||
{
|
||||
using CellType_t = decltype(*StringTableType::values);
|
||||
|
||||
protected:
|
||||
void SetCellContent(CellType_t& cell, const char* content) override
|
||||
{
|
||||
cell.string = content;
|
||||
cell.hash = HashFunc(content);
|
||||
}
|
||||
};
|
||||
|
||||
// =================================
|
||||
// V3: T5, T6
|
||||
// - Cells are a struct and have a hash
|
||||
// - StringTable has an index array for binary search
|
||||
// =================================
|
||||
template<typename StringTableType, int (*HashFunc)(const char*)>
|
||||
class StringTableLoaderV3 final : public AbstractStringTableLoader<StringTableType, std::remove_pointer_t<decltype(StringTableType::values)>>
|
||||
{
|
||||
using CellType_t = decltype(*StringTableType::values);
|
||||
|
||||
protected:
|
||||
void SetCellContent(CellType_t& cell, const char* content) override
|
||||
{
|
||||
cell.string = content;
|
||||
cell.hash = HashFunc(content);
|
||||
}
|
||||
|
||||
void PostProcessStringTable(StringTableType* stringTable, const unsigned cellCount, MemoryManager& memory) override
|
||||
{
|
||||
if (!cellCount)
|
||||
{
|
||||
stringTable->cellIndex = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
stringTable->cellIndex = static_cast<int16_t*>(memory.Alloc(sizeof(int16_t) * cellCount));
|
||||
for (auto i = 0u; i < cellCount; i++)
|
||||
stringTable->cellIndex[i] = i;
|
||||
|
||||
std::sort(&stringTable->cellIndex[0],
|
||||
&stringTable->cellIndex[cellCount - 1],
|
||||
[stringTable](const int16_t a, const int16_t b)
|
||||
{
|
||||
auto compareResult = stringTable->values[a].hash - stringTable->values[b].hash;
|
||||
if (compareResult == 0)
|
||||
compareResult = (a % stringTable->columnCount) - (b % stringTable->columnCount);
|
||||
return compareResult < 0;
|
||||
});
|
||||
}
|
||||
};
|
||||
} // namespace string_table
|
@ -45,9 +45,13 @@ public:
|
||||
|
||||
int Run(const int argc, const char** argv)
|
||||
{
|
||||
if (!m_args.Parse(argc, argv))
|
||||
auto shouldContinue = true;
|
||||
if (!m_args.ParseArgs(argc, argv, shouldContinue))
|
||||
return 1;
|
||||
|
||||
if (!shouldContinue)
|
||||
return 0;
|
||||
|
||||
if (!m_args.m_build_log_file.empty())
|
||||
{
|
||||
fs::path p = fs::path(m_args.m_build_log_file).parent_path();
|
||||
|
@ -1,11 +1,18 @@
|
||||
#include "RawTemplaterArguments.h"
|
||||
|
||||
#include "GitVersion.h"
|
||||
#include "Utils/Arguments/CommandLineOption.h"
|
||||
#include "Utils/Arguments/UsageInformation.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <type_traits>
|
||||
|
||||
const CommandLineOption* const OPTION_HELP =
|
||||
CommandLineOption::Builder::Create().WithShortName("?").WithLongName("help").WithDescription("Displays usage information.").Build();
|
||||
|
||||
const CommandLineOption* const OPTION_VERSION =
|
||||
CommandLineOption::Builder::Create().WithLongName("version").WithDescription("Prints the application version.").Build();
|
||||
|
||||
const CommandLineOption* const OPTION_VERBOSE =
|
||||
CommandLineOption::Builder::Create().WithShortName("v").WithLongName("verbose").WithDescription("Outputs a lot more and more detailed messages.").Build();
|
||||
|
||||
@ -30,7 +37,14 @@ const CommandLineOption* const OPTION_DEFINE = CommandLineOption::Builder::Creat
|
||||
.Reusable()
|
||||
.Build();
|
||||
|
||||
const CommandLineOption* const COMMAND_LINE_OPTIONS[]{OPTION_HELP, OPTION_VERBOSE, OPTION_OUTPUT_FOLDER, OPTION_BUILD_LOG, OPTION_DEFINE};
|
||||
const CommandLineOption* const COMMAND_LINE_OPTIONS[]{
|
||||
OPTION_HELP,
|
||||
OPTION_VERSION,
|
||||
OPTION_VERBOSE,
|
||||
OPTION_OUTPUT_FOLDER,
|
||||
OPTION_BUILD_LOG,
|
||||
OPTION_DEFINE,
|
||||
};
|
||||
|
||||
RawTemplaterArguments::RawTemplaterArguments()
|
||||
: m_argument_parser(COMMAND_LINE_OPTIONS, std::extent_v<decltype(COMMAND_LINE_OPTIONS)>),
|
||||
@ -50,8 +64,14 @@ void RawTemplaterArguments::PrintUsage()
|
||||
usage.Print();
|
||||
}
|
||||
|
||||
bool RawTemplaterArguments::Parse(const int argc, const char** argv)
|
||||
void RawTemplaterArguments::PrintVersion()
|
||||
{
|
||||
std::cout << "OpenAssetTools RawTemplater " << std::string(GIT_VERSION) << "\n";
|
||||
}
|
||||
|
||||
bool RawTemplaterArguments::ParseArgs(const int argc, const char** argv, bool& shouldContinue)
|
||||
{
|
||||
shouldContinue = true;
|
||||
if (!m_argument_parser.ParseArguments(argc - 1, &argv[1]))
|
||||
{
|
||||
PrintUsage();
|
||||
@ -62,7 +82,16 @@ bool RawTemplaterArguments::Parse(const int argc, const char** argv)
|
||||
if (m_argument_parser.IsOptionSpecified(OPTION_HELP))
|
||||
{
|
||||
PrintUsage();
|
||||
return false;
|
||||
shouldContinue = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if the user wants to see the version
|
||||
if (m_argument_parser.IsOptionSpecified(OPTION_VERSION))
|
||||
{
|
||||
PrintVersion();
|
||||
shouldContinue = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
m_input_files = m_argument_parser.GetArguments();
|
||||
|
@ -14,6 +14,7 @@ class RawTemplaterArguments
|
||||
* \brief Prints a command line usage help text for the RawTemplater tool to stdout.
|
||||
*/
|
||||
static void PrintUsage();
|
||||
static void PrintVersion();
|
||||
|
||||
public:
|
||||
bool m_verbose;
|
||||
@ -27,5 +28,5 @@ public:
|
||||
|
||||
RawTemplaterArguments();
|
||||
|
||||
bool Parse(int argc, const char** argv);
|
||||
bool ParseArgs(int argc, const char** argv, bool& shouldContinue);
|
||||
};
|
||||
|
@ -429,9 +429,13 @@ public:
|
||||
*/
|
||||
bool Start(const int argc, const char** argv)
|
||||
{
|
||||
if (!m_args.ParseArgs(argc, argv))
|
||||
auto shouldContinue = true;
|
||||
if (!m_args.ParseArgs(argc, argv, shouldContinue))
|
||||
return false;
|
||||
|
||||
if (!shouldContinue)
|
||||
return true;
|
||||
|
||||
if (!BuildSearchPaths())
|
||||
return false;
|
||||
|
||||
|
@ -1,10 +1,12 @@
|
||||
#include "UnlinkerArgs.h"
|
||||
|
||||
#include "GitVersion.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "ObjWriting.h"
|
||||
#include "Utils/Arguments/UsageInformation.h"
|
||||
#include "Utils/FileUtils.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
#include <type_traits>
|
||||
|
||||
@ -16,6 +18,12 @@ const CommandLineOption* const OPTION_HELP =
|
||||
.WithDescription("Displays usage information.")
|
||||
.Build();
|
||||
|
||||
const CommandLineOption* const OPTION_VERSION =
|
||||
CommandLineOption::Builder::Create()
|
||||
.WithLongName("version")
|
||||
.WithDescription("Prints the application version.")
|
||||
.Build();
|
||||
|
||||
const CommandLineOption* const OPTION_VERBOSE =
|
||||
CommandLineOption::Builder::Create()
|
||||
.WithShortName("v")
|
||||
@ -113,6 +121,7 @@ const CommandLineOption* const OPTION_LEGACY_MENUS =
|
||||
|
||||
const CommandLineOption* const COMMAND_LINE_OPTIONS[]{
|
||||
OPTION_HELP,
|
||||
OPTION_VERSION,
|
||||
OPTION_VERBOSE,
|
||||
OPTION_MINIMAL_ZONE_FILE,
|
||||
OPTION_LOAD,
|
||||
@ -155,6 +164,11 @@ void UnlinkerArgs::PrintUsage()
|
||||
usage.Print();
|
||||
}
|
||||
|
||||
void UnlinkerArgs::PrintVersion()
|
||||
{
|
||||
std::cout << "OpenAssetTools Unlinker " << std::string(GIT_VERSION) << "\n";
|
||||
}
|
||||
|
||||
void UnlinkerArgs::SetVerbose(const bool isVerbose)
|
||||
{
|
||||
m_verbose = isVerbose;
|
||||
@ -237,8 +251,9 @@ void UnlinkerArgs::ParseCommaSeparatedAssetTypeString(const std::string& input)
|
||||
AddSpecifiedAssetType(std::string(lowerInput, currentPos, lowerInput.size() - currentPos));
|
||||
}
|
||||
|
||||
bool UnlinkerArgs::ParseArgs(const int argc, const char** argv)
|
||||
bool UnlinkerArgs::ParseArgs(const int argc, const char** argv, bool& shouldContinue)
|
||||
{
|
||||
shouldContinue = true;
|
||||
if (!m_argument_parser.ParseArguments(argc - 1, &argv[1]))
|
||||
{
|
||||
PrintUsage();
|
||||
@ -249,7 +264,16 @@ bool UnlinkerArgs::ParseArgs(const int argc, const char** argv)
|
||||
if (m_argument_parser.IsOptionSpecified(OPTION_HELP))
|
||||
{
|
||||
PrintUsage();
|
||||
return false;
|
||||
shouldContinue = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if the user wants to see the version
|
||||
if (m_argument_parser.IsOptionSpecified(OPTION_VERSION))
|
||||
{
|
||||
PrintVersion();
|
||||
shouldContinue = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
m_zones_to_unlink = m_argument_parser.GetArguments();
|
||||
|
@ -21,6 +21,7 @@ private:
|
||||
* \brief Prints a command line usage help text for the Unlinker tool to stdout.
|
||||
*/
|
||||
static void PrintUsage();
|
||||
static void PrintVersion();
|
||||
|
||||
void SetVerbose(bool isVerbose);
|
||||
bool SetImageDumpingMode();
|
||||
@ -60,7 +61,7 @@ public:
|
||||
bool m_verbose;
|
||||
|
||||
UnlinkerArgs();
|
||||
bool ParseArgs(int argc, const char** argv);
|
||||
bool ParseArgs(int argc, const char** argv, bool& shouldContinue);
|
||||
|
||||
/**
|
||||
* \brief Converts the output path specified by command line arguments to a path applies for the specified zone.
|
||||
|
@ -203,6 +203,8 @@ function ZoneCode:outputForAssets(assetList)
|
||||
buildoutputs {
|
||||
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_load_db.cpp",
|
||||
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_load_db.h",
|
||||
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_mark_db.cpp",
|
||||
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_mark_db.h",
|
||||
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_write_db.cpp",
|
||||
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_write_db.h",
|
||||
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_struct_test.cpp",
|
||||
@ -231,6 +233,8 @@ function ZoneCode:allLoadFiles()
|
||||
local assetNameLower = string.lower(assetName)
|
||||
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_load_db.cpp")
|
||||
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_load_db.h")
|
||||
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_mark_db.cpp")
|
||||
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_mark_db.h")
|
||||
end
|
||||
end
|
||||
|
||||
@ -302,6 +306,7 @@ function ZoneCode:project()
|
||||
.. ' -c "' .. path.join(path.getabsolute(ProjectFolder()), 'ZoneCode/Game/%{file.basename}/%{file.basename}_Commands.txt') .. '"'
|
||||
.. ' -o "%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets"'
|
||||
.. ' -g "*" ZoneLoad'
|
||||
.. ' -g "*" ZoneMark'
|
||||
.. ' -g "*" ZoneWrite'
|
||||
.. ' -g "*" AssetStructTests'
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ StructureInformation::StructureInformation(DefinitionWithMembers* definition)
|
||||
: m_definition(definition),
|
||||
m_asset_enum_entry(nullptr),
|
||||
m_is_leaf(false),
|
||||
m_requires_marking(false),
|
||||
m_non_embedded_reference_exists(false),
|
||||
m_single_pointer_reference_exists(false),
|
||||
m_array_pointer_reference_exists(false),
|
||||
|
@ -19,6 +19,7 @@ public:
|
||||
std::vector<std::unique_ptr<MemberInformation>> m_ordered_members;
|
||||
|
||||
bool m_is_leaf;
|
||||
bool m_requires_marking;
|
||||
|
||||
bool m_non_embedded_reference_exists;
|
||||
bool m_single_pointer_reference_exists;
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "Domain/Computations/StructureComputations.h"
|
||||
#include "Templates/AssetStructTestsTemplate.h"
|
||||
#include "Templates/ZoneLoadTemplate.h"
|
||||
#include "Templates/ZoneMarkTemplate.h"
|
||||
#include "Templates/ZoneWriteTemplate.h"
|
||||
|
||||
#include <filesystem>
|
||||
@ -20,6 +21,7 @@ CodeGenerator::CodeGenerator(const ZoneCodeGeneratorArguments* args)
|
||||
void CodeGenerator::SetupTemplates()
|
||||
{
|
||||
m_template_mapping["zoneload"] = std::make_unique<ZoneLoadTemplate>();
|
||||
m_template_mapping["zonemark"] = std::make_unique<ZoneMarkTemplate>();
|
||||
m_template_mapping["zonewrite"] = std::make_unique<ZoneWriteTemplate>();
|
||||
m_template_mapping["assetstructtests"] = std::make_unique<AssetStructTestsTemplate>();
|
||||
}
|
||||
|
@ -27,6 +27,13 @@ class ZoneLoadTemplate::Internal final : BaseTemplate
|
||||
return str.str();
|
||||
}
|
||||
|
||||
static std::string MarkerClassName(StructureInformation* asset)
|
||||
{
|
||||
std::ostringstream str;
|
||||
str << "Marker_" << asset->m_definition->m_name;
|
||||
return str.str();
|
||||
}
|
||||
|
||||
static std::string VariableDecl(const DataDefinition* def)
|
||||
{
|
||||
std::ostringstream str;
|
||||
@ -155,7 +162,7 @@ class ZoneLoadTemplate::Internal final : BaseTemplate
|
||||
if (info && StructureComputations(info).IsAsset())
|
||||
{
|
||||
LINE(LoaderClassName(info) << " loader(m_zone, m_stream);")
|
||||
LINE("AddDependency(loader.Load(" << MakeTypePtrVarName(def) << "));")
|
||||
LINE("loader.Load(" << MakeTypePtrVarName(def) << ");")
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -249,32 +256,6 @@ class ZoneLoadTemplate::Internal final : BaseTemplate
|
||||
LINE("}")
|
||||
}
|
||||
|
||||
void LoadMember_ScriptString(StructureInformation* info,
|
||||
MemberInformation* member,
|
||||
const DeclarationModifierComputations& modifier,
|
||||
const MemberLoadType loadType) const
|
||||
{
|
||||
if (loadType == MemberLoadType::ARRAY_POINTER)
|
||||
{
|
||||
LINE("varScriptString = " << MakeMemberAccess(info, member, modifier) << ";")
|
||||
LINE("LoadScriptStringArray(true, " << MakeEvaluation(modifier.GetArrayPointerCountEvaluation()) << ");")
|
||||
}
|
||||
else if (loadType == MemberLoadType::EMBEDDED_ARRAY)
|
||||
{
|
||||
LINE("varScriptString = " << MakeMemberAccess(info, member, modifier) << ";")
|
||||
LINE("LoadScriptStringArray(false, " << MakeArrayCount(dynamic_cast<ArrayDeclarationModifier*>(modifier.GetDeclarationModifier())) << ");")
|
||||
}
|
||||
else if (loadType == MemberLoadType::EMBEDDED)
|
||||
{
|
||||
LINE(MakeMemberAccess(info, member, modifier) << " = UseScriptString(" << MakeMemberAccess(info, member, modifier) << ");")
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
LINE("#error unsupported loadType " << static_cast<int>(loadType) << " for scripstring")
|
||||
}
|
||||
}
|
||||
|
||||
void LoadMember_Asset(StructureInformation* info,
|
||||
MemberInformation* member,
|
||||
const DeclarationModifierComputations& modifier,
|
||||
@ -283,7 +264,7 @@ class ZoneLoadTemplate::Internal final : BaseTemplate
|
||||
if (loadType == MemberLoadType::SINGLE_POINTER)
|
||||
{
|
||||
LINE(LoaderClassName(member->m_type) << " loader(m_zone, m_stream);")
|
||||
LINE("AddDependency(loader.Load(&" << MakeMemberAccess(info, member, modifier) << "));")
|
||||
LINE("loader.Load(&" << MakeMemberAccess(info, member, modifier) << ");")
|
||||
}
|
||||
else if (loadType == MemberLoadType::POINTER_ARRAY)
|
||||
{
|
||||
@ -483,10 +464,6 @@ class ZoneLoadTemplate::Internal final : BaseTemplate
|
||||
{
|
||||
LoadMember_String(info, member, modifier, loadType);
|
||||
}
|
||||
else if (member->m_is_script_string)
|
||||
{
|
||||
LoadMember_ScriptString(info, member, modifier, loadType);
|
||||
}
|
||||
else if (member->m_type && StructureComputations(member->m_type).IsAsset())
|
||||
{
|
||||
LoadMember_Asset(info, member, modifier, loadType);
|
||||
@ -671,12 +648,6 @@ class ZoneLoadTemplate::Internal final : BaseTemplate
|
||||
|
||||
LINE(MakeMemberAccess(info, member, modifier) << " = m_stream->ConvertOffsetToPointer(" << MakeMemberAccess(info, member, modifier) << ");")
|
||||
|
||||
if (member->m_is_script_string && loadType == MemberLoadType::ARRAY_POINTER)
|
||||
{
|
||||
LINE("MarkScriptStringArrayAsUsed(" << MakeMemberAccess(info, member, modifier) << ", "
|
||||
<< MakeEvaluation(modifier.GetArrayPointerCountEvaluation()) << ");")
|
||||
}
|
||||
|
||||
m_intendation--;
|
||||
LINE("}")
|
||||
}
|
||||
@ -894,7 +865,7 @@ class ZoneLoadTemplate::Internal final : BaseTemplate
|
||||
if (computations.ShouldIgnore())
|
||||
return;
|
||||
|
||||
if (member->m_is_string || member->m_is_script_string || computations.ContainsNonEmbeddedReference() || member->m_type && !member->m_type->m_is_leaf
|
||||
if (member->m_is_string || computations.ContainsNonEmbeddedReference() || member->m_type && !member->m_type->m_is_leaf
|
||||
|| computations.IsAfterPartialLoad())
|
||||
{
|
||||
if (info->m_definition->GetType() == DataDefinitionType::UNION)
|
||||
@ -1099,7 +1070,12 @@ class ZoneLoadTemplate::Internal final : BaseTemplate
|
||||
m_intendation++;
|
||||
|
||||
LINE("assert(pAsset != nullptr);")
|
||||
LINE("m_asset_info = reinterpret_cast<XAssetInfo<" << info->m_definition->GetFullName() << ">*>(LinkAsset(GetAssetName(*pAsset), *pAsset));")
|
||||
LINE("")
|
||||
LINE(MarkerClassName(m_env.m_asset) << " marker(m_zone);")
|
||||
LINE("marker.Mark(*pAsset);")
|
||||
LINE("")
|
||||
LINE("m_asset_info = reinterpret_cast<XAssetInfo<"
|
||||
<< info->m_definition->GetFullName() << ">*>(LinkAsset(GetAssetName(*pAsset), *pAsset, marker.GetUsedScriptStrings(), marker.GetDependencies()));")
|
||||
LINE("*pAsset = m_asset_info->Asset();")
|
||||
|
||||
m_intendation--;
|
||||
@ -1272,6 +1248,7 @@ public:
|
||||
LINE("// ====================================================================")
|
||||
LINE("")
|
||||
LINE("#include \"" << Lower(m_env.m_asset->m_definition->m_name) << "_load_db.h\"")
|
||||
LINE("#include \"" << Lower(m_env.m_asset->m_definition->m_name) << "_mark_db.h\"")
|
||||
LINE("#include <cassert>")
|
||||
LINE("")
|
||||
|
||||
|
@ -0,0 +1,823 @@
|
||||
#include "ZoneMarkTemplate.h"
|
||||
|
||||
#include "Domain/Computations/MemberComputations.h"
|
||||
#include "Domain/Computations/StructureComputations.h"
|
||||
#include "Internal/BaseTemplate.h"
|
||||
#include "Utils/StringUtils.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
class ZoneMarkTemplate::Internal final : BaseTemplate
|
||||
{
|
||||
enum class MemberLoadType
|
||||
{
|
||||
ARRAY_POINTER,
|
||||
DYNAMIC_ARRAY,
|
||||
EMBEDDED,
|
||||
EMBEDDED_ARRAY,
|
||||
POINTER_ARRAY,
|
||||
SINGLE_POINTER
|
||||
};
|
||||
|
||||
static std::string MarkerClassName(StructureInformation* asset)
|
||||
{
|
||||
std::ostringstream str;
|
||||
str << "Marker_" << asset->m_definition->m_name;
|
||||
return str.str();
|
||||
}
|
||||
|
||||
static std::string VariableDecl(const DataDefinition* def)
|
||||
{
|
||||
std::ostringstream str;
|
||||
str << def->GetFullName() << "* var" << MakeSafeTypeName(def) << ";";
|
||||
return str.str();
|
||||
}
|
||||
|
||||
static std::string PointerVariableDecl(const DataDefinition* def)
|
||||
{
|
||||
std::ostringstream str;
|
||||
str << def->GetFullName() << "** var" << MakeSafeTypeName(def) << "Ptr;";
|
||||
return str.str();
|
||||
}
|
||||
|
||||
void PrintHeaderPtrArrayMarkMethodDeclaration(const DataDefinition* def) const
|
||||
{
|
||||
LINE("void MarkPtrArray_" << MakeSafeTypeName(def) << "(size_t count);")
|
||||
}
|
||||
|
||||
void PrintHeaderArrayMarkMethodDeclaration(const DataDefinition* def) const
|
||||
{
|
||||
LINE("void MarkArray_" << MakeSafeTypeName(def) << "(size_t count);")
|
||||
}
|
||||
|
||||
void PrintHeaderMarkMethodDeclaration(const StructureInformation* info) const
|
||||
{
|
||||
LINE("void Mark_" << MakeSafeTypeName(info->m_definition) << "();")
|
||||
}
|
||||
|
||||
void PrintHeaderGetAssetInfoMethodDeclaration(const StructureInformation* info) const
|
||||
{
|
||||
LINE("XAssetInfo<" << info->m_definition->GetFullName() << ">* GetAssetInfo(" << info->m_definition->GetFullName() << "* pAsset) const;")
|
||||
}
|
||||
|
||||
void PrintHeaderGetNameMethodDeclaration(const StructureInformation* info) const
|
||||
{
|
||||
LINE("static std::string GetAssetName(" << info->m_definition->GetFullName() << "* pAsset);")
|
||||
}
|
||||
|
||||
void PrintHeaderConstructor() const
|
||||
{
|
||||
LINE(MarkerClassName(m_env.m_asset) << "(Zone* zone);")
|
||||
}
|
||||
|
||||
void PrintHeaderMainMarkMethodDeclaration(const StructureInformation* info) const
|
||||
{
|
||||
LINE("void Mark(" << info->m_definition->GetFullName() << "* pAsset);")
|
||||
}
|
||||
|
||||
void PrintVariableInitialization(const DataDefinition* def) const
|
||||
{
|
||||
LINE("var" << def->m_name << " = nullptr;")
|
||||
}
|
||||
|
||||
void PrintPointerVariableInitialization(const DataDefinition* def) const
|
||||
{
|
||||
LINE("var" << def->m_name << "Ptr = nullptr;")
|
||||
}
|
||||
|
||||
void PrintConstructorMethod()
|
||||
{
|
||||
LINE(MarkerClassName(m_env.m_asset) << "::" << MarkerClassName(m_env.m_asset) << "(Zone* zone)")
|
||||
|
||||
m_intendation++;
|
||||
LINE(": AssetMarker(" << m_env.m_asset->m_asset_enum_entry->m_name << ", zone)")
|
||||
m_intendation--;
|
||||
|
||||
LINE("{")
|
||||
m_intendation++;
|
||||
|
||||
PrintVariableInitialization(m_env.m_asset->m_definition);
|
||||
PrintPointerVariableInitialization(m_env.m_asset->m_definition);
|
||||
LINE("")
|
||||
|
||||
for (const auto* type : m_env.m_used_types)
|
||||
{
|
||||
if (type->m_info && !type->m_info->m_definition->m_anonymous && !type->m_info->m_is_leaf && !StructureComputations(type->m_info).IsAsset())
|
||||
{
|
||||
PrintVariableInitialization(type->m_type);
|
||||
}
|
||||
}
|
||||
for (const auto* type : m_env.m_used_types)
|
||||
{
|
||||
if (type->m_info && type->m_pointer_array_reference_exists && !type->m_is_context_asset)
|
||||
{
|
||||
PrintPointerVariableInitialization(type->m_type);
|
||||
}
|
||||
}
|
||||
|
||||
m_intendation--;
|
||||
LINE("}")
|
||||
}
|
||||
|
||||
void PrintMarkPtrArrayMethod_Loading(const DataDefinition* def, const StructureInformation* info) const
|
||||
{
|
||||
if (info && !info->m_is_leaf)
|
||||
{
|
||||
LINE(MakeTypeVarName(info->m_definition) << " = *" << MakeTypePtrVarName(def) << ";")
|
||||
LINE("Mark_" << MakeSafeTypeName(def) << "();")
|
||||
}
|
||||
}
|
||||
|
||||
void PrintMarkPtrArrayMethod_PointerCheck(const DataDefinition* def, StructureInformation* info, const bool reusable)
|
||||
{
|
||||
LINE("if (*" << MakeTypePtrVarName(def) << ")")
|
||||
LINE("{")
|
||||
m_intendation++;
|
||||
|
||||
if (info && StructureComputations(info).IsAsset())
|
||||
{
|
||||
LINE("AddDependency(" << MarkerClassName(info) << "(m_zone).GetAssetInfo(*" << MakeTypePtrVarName(def) << "));")
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintMarkPtrArrayMethod_Loading(def, info);
|
||||
}
|
||||
|
||||
m_intendation--;
|
||||
LINE("}")
|
||||
}
|
||||
|
||||
void PrintMarkPtrArrayMethod(const DataDefinition* def, StructureInformation* info, const bool reusable)
|
||||
{
|
||||
LINE("void " << MarkerClassName(m_env.m_asset) << "::MarkPtrArray_" << MakeSafeTypeName(def) << "(const size_t count)")
|
||||
LINE("{")
|
||||
m_intendation++;
|
||||
|
||||
LINE("assert(" << MakeTypePtrVarName(def) << " != nullptr);")
|
||||
LINE("")
|
||||
|
||||
LINE(def->GetFullName() << "** var = " << MakeTypePtrVarName(def) << ";")
|
||||
LINE("for(size_t index = 0; index < count; index++)")
|
||||
LINE("{")
|
||||
m_intendation++;
|
||||
|
||||
LINE(MakeTypePtrVarName(def) << " = var;")
|
||||
PrintMarkPtrArrayMethod_PointerCheck(def, info, reusable);
|
||||
LINE("")
|
||||
LINE("var++;")
|
||||
|
||||
m_intendation--;
|
||||
LINE("}")
|
||||
m_intendation--;
|
||||
LINE("}")
|
||||
}
|
||||
|
||||
void PrintMarkArrayMethod(const DataDefinition* def, const StructureInformation* info)
|
||||
{
|
||||
LINE("void " << MarkerClassName(m_env.m_asset) << "::MarkArray_" << MakeSafeTypeName(def) << "(const size_t count)")
|
||||
LINE("{")
|
||||
m_intendation++;
|
||||
|
||||
LINE("assert(" << MakeTypeVarName(def) << " != nullptr);")
|
||||
LINE("")
|
||||
|
||||
LINE(def->GetFullName() << "* var = " << MakeTypeVarName(def) << ";")
|
||||
LINE("for(size_t index = 0; index < count; index++)")
|
||||
LINE("{")
|
||||
m_intendation++;
|
||||
|
||||
LINE(MakeTypeVarName(info->m_definition) << " = var;")
|
||||
LINE("Mark_" << info->m_definition->m_name << "();")
|
||||
LINE("var++;")
|
||||
|
||||
m_intendation--;
|
||||
LINE("}")
|
||||
|
||||
m_intendation--;
|
||||
LINE("}")
|
||||
}
|
||||
|
||||
void MarkMember_ScriptString(StructureInformation* info,
|
||||
MemberInformation* member,
|
||||
const DeclarationModifierComputations& modifier,
|
||||
const MemberLoadType loadType) const
|
||||
{
|
||||
if (loadType == MemberLoadType::ARRAY_POINTER)
|
||||
{
|
||||
LINE("MarkArray_ScriptString(" << MakeMemberAccess(info, member, modifier) << ", " << MakeEvaluation(modifier.GetArrayPointerCountEvaluation())
|
||||
<< ");")
|
||||
}
|
||||
else if (loadType == MemberLoadType::EMBEDDED_ARRAY)
|
||||
{
|
||||
LINE("MarkArray_ScriptString(" << MakeMemberAccess(info, member, modifier) << ", "
|
||||
<< MakeArrayCount(dynamic_cast<ArrayDeclarationModifier*>(modifier.GetDeclarationModifier())) << ");")
|
||||
}
|
||||
else if (loadType == MemberLoadType::EMBEDDED)
|
||||
{
|
||||
LINE("Mark_ScriptString(" << MakeMemberAccess(info, member, modifier) << ");")
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
LINE("#error unsupported loadType " << static_cast<int>(loadType) << " for scriptstring")
|
||||
}
|
||||
}
|
||||
|
||||
void MarkMember_Asset(StructureInformation* info,
|
||||
MemberInformation* member,
|
||||
const DeclarationModifierComputations& modifier,
|
||||
const MemberLoadType loadType) const
|
||||
{
|
||||
if (loadType == MemberLoadType::SINGLE_POINTER)
|
||||
{
|
||||
LINE("AddDependency(" << MarkerClassName(member->m_type) << "(m_zone).GetAssetInfo(" << MakeMemberAccess(info, member, modifier) << "));")
|
||||
}
|
||||
else if (loadType == MemberLoadType::POINTER_ARRAY)
|
||||
{
|
||||
MarkMember_PointerArray(info, member, modifier);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
LINE("#error unsupported loadType " << static_cast<int>(loadType) << " for asset")
|
||||
}
|
||||
}
|
||||
|
||||
void MarkMember_ArrayPointer(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier) const
|
||||
{
|
||||
LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type) << " = " << MakeMemberAccess(info, member, modifier) << ";")
|
||||
LINE("MarkArray_" << MakeSafeTypeName(member->m_member->m_type_declaration->m_type) << "(" << MakeEvaluation(modifier.GetArrayPointerCountEvaluation())
|
||||
<< ");")
|
||||
}
|
||||
|
||||
void MarkMember_PointerArray(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier) const
|
||||
{
|
||||
LINE(MakeTypePtrVarName(member->m_member->m_type_declaration->m_type) << " = " << MakeMemberAccess(info, member, modifier) << ";")
|
||||
if (modifier.IsArray())
|
||||
{
|
||||
LINE("MarkPtrArray_" << MakeSafeTypeName(member->m_member->m_type_declaration->m_type) << "(" << modifier.GetArraySize() << ");")
|
||||
}
|
||||
else
|
||||
{
|
||||
LINE("MarkPtrArray_" << MakeSafeTypeName(member->m_member->m_type_declaration->m_type) << "("
|
||||
<< MakeEvaluation(modifier.GetPointerArrayCountEvaluation()) << ");")
|
||||
}
|
||||
}
|
||||
|
||||
void MarkMember_EmbeddedArray(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier) const
|
||||
{
|
||||
const MemberComputations computations(member);
|
||||
std::string arraySizeStr;
|
||||
|
||||
if (modifier.HasDynamicArrayCount())
|
||||
arraySizeStr = MakeEvaluation(modifier.GetDynamicArrayCountEvaluation());
|
||||
else
|
||||
arraySizeStr = std::to_string(modifier.GetArraySize());
|
||||
|
||||
LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type) << " = " << MakeMemberAccess(info, member, modifier) << ";")
|
||||
LINE("MarkArray_" << MakeSafeTypeName(member->m_member->m_type_declaration->m_type) << "(" << arraySizeStr << ");")
|
||||
}
|
||||
|
||||
void MarkMember_DynamicArray(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier) const
|
||||
{
|
||||
LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type) << " = " << MakeMemberAccess(info, member, modifier) << ";")
|
||||
LINE("MarkArray_" << MakeSafeTypeName(member->m_member->m_type_declaration->m_type) << "(" << MakeEvaluation(modifier.GetDynamicArraySizeEvaluation())
|
||||
<< ");")
|
||||
}
|
||||
|
||||
void MarkMember_Embedded(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier) const
|
||||
{
|
||||
LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type) << " = &" << MakeMemberAccess(info, member, modifier) << ";")
|
||||
LINE("Mark_" << MakeSafeTypeName(member->m_member->m_type_declaration->m_type) << "();")
|
||||
}
|
||||
|
||||
void MarkMember_SinglePointer(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier) const
|
||||
{
|
||||
LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type) << " = " << MakeMemberAccess(info, member, modifier) << ";")
|
||||
LINE("Mark_" << MakeSafeTypeName(member->m_type->m_definition) << "();")
|
||||
}
|
||||
|
||||
void MarkMember_TypeCheck(StructureInformation* info,
|
||||
MemberInformation* member,
|
||||
const DeclarationModifierComputations& modifier,
|
||||
const MemberLoadType loadType) const
|
||||
{
|
||||
if (member->m_is_script_string)
|
||||
{
|
||||
MarkMember_ScriptString(info, member, modifier, loadType);
|
||||
}
|
||||
else if (member->m_type && StructureComputations(member->m_type).IsAsset())
|
||||
{
|
||||
MarkMember_Asset(info, member, modifier, loadType);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (loadType)
|
||||
{
|
||||
case MemberLoadType::ARRAY_POINTER:
|
||||
MarkMember_ArrayPointer(info, member, modifier);
|
||||
break;
|
||||
|
||||
case MemberLoadType::SINGLE_POINTER:
|
||||
MarkMember_SinglePointer(info, member, modifier);
|
||||
break;
|
||||
|
||||
case MemberLoadType::EMBEDDED:
|
||||
MarkMember_Embedded(info, member, modifier);
|
||||
break;
|
||||
|
||||
case MemberLoadType::POINTER_ARRAY:
|
||||
MarkMember_PointerArray(info, member, modifier);
|
||||
break;
|
||||
|
||||
case MemberLoadType::DYNAMIC_ARRAY:
|
||||
MarkMember_DynamicArray(info, member, modifier);
|
||||
break;
|
||||
|
||||
case MemberLoadType::EMBEDDED_ARRAY:
|
||||
MarkMember_EmbeddedArray(info, member, modifier);
|
||||
break;
|
||||
|
||||
default:
|
||||
LINE("// t=" << static_cast<int>(loadType))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool MarkMember_ShouldMakePointerCheck(StructureInformation* info,
|
||||
MemberInformation* member,
|
||||
const DeclarationModifierComputations& modifier,
|
||||
MemberLoadType loadType)
|
||||
{
|
||||
if (loadType != MemberLoadType::ARRAY_POINTER && loadType != MemberLoadType::POINTER_ARRAY && loadType != MemberLoadType::SINGLE_POINTER)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (loadType == MemberLoadType::POINTER_ARRAY)
|
||||
{
|
||||
return !modifier.IsArray();
|
||||
}
|
||||
|
||||
if (member->m_is_string)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MarkMember_PointerCheck(StructureInformation* info,
|
||||
MemberInformation* member,
|
||||
const DeclarationModifierComputations& modifier,
|
||||
const MemberLoadType loadType)
|
||||
{
|
||||
if (MarkMember_ShouldMakePointerCheck(info, member, modifier, loadType))
|
||||
{
|
||||
LINE("if (" << MakeMemberAccess(info, member, modifier) << ")")
|
||||
LINE("{")
|
||||
m_intendation++;
|
||||
|
||||
MarkMember_TypeCheck(info, member, modifier, loadType);
|
||||
|
||||
m_intendation--;
|
||||
LINE("}")
|
||||
}
|
||||
else
|
||||
{
|
||||
MarkMember_TypeCheck(info, member, modifier, loadType);
|
||||
}
|
||||
}
|
||||
|
||||
void MarkMember_ReferenceArray(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier)
|
||||
{
|
||||
auto first = true;
|
||||
for (const auto& entry : modifier.GetArrayEntries())
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LINE("")
|
||||
}
|
||||
|
||||
MarkMember_Reference(info, member, entry);
|
||||
}
|
||||
}
|
||||
|
||||
void MarkMember_Reference(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier)
|
||||
{
|
||||
if (modifier.IsDynamicArray())
|
||||
{
|
||||
MarkMember_PointerCheck(info, member, modifier, MemberLoadType::DYNAMIC_ARRAY);
|
||||
}
|
||||
else if (modifier.IsSinglePointer())
|
||||
{
|
||||
MarkMember_PointerCheck(info, member, modifier, MemberLoadType::SINGLE_POINTER);
|
||||
}
|
||||
else if (modifier.IsArrayPointer())
|
||||
{
|
||||
MarkMember_PointerCheck(info, member, modifier, MemberLoadType::ARRAY_POINTER);
|
||||
}
|
||||
else if (modifier.IsPointerArray())
|
||||
{
|
||||
MarkMember_PointerCheck(info, member, modifier, MemberLoadType::POINTER_ARRAY);
|
||||
}
|
||||
else if (modifier.IsArray() && modifier.GetNextDeclarationModifier() == nullptr)
|
||||
{
|
||||
MarkMember_PointerCheck(info, member, modifier, MemberLoadType::EMBEDDED_ARRAY);
|
||||
}
|
||||
else if (modifier.GetDeclarationModifier() == nullptr)
|
||||
{
|
||||
MarkMember_PointerCheck(info, member, modifier, MemberLoadType::EMBEDDED);
|
||||
}
|
||||
else if (modifier.IsArray())
|
||||
{
|
||||
MarkMember_ReferenceArray(info, member, modifier);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
LINE("#error MarkMemberReference failed @ " << member->m_member->m_name)
|
||||
}
|
||||
}
|
||||
|
||||
void MarkMember_Condition_Struct(StructureInformation* info, MemberInformation* member)
|
||||
{
|
||||
LINE("")
|
||||
if (member->m_condition)
|
||||
{
|
||||
LINE("if (" << MakeEvaluation(member->m_condition.get()) << ")")
|
||||
LINE("{")
|
||||
m_intendation++;
|
||||
|
||||
MarkMember_Reference(info, member, DeclarationModifierComputations(member));
|
||||
|
||||
m_intendation--;
|
||||
LINE("}")
|
||||
}
|
||||
else
|
||||
{
|
||||
MarkMember_Reference(info, member, DeclarationModifierComputations(member));
|
||||
}
|
||||
}
|
||||
|
||||
void MarkMember_Condition_Union(StructureInformation* info, MemberInformation* member)
|
||||
{
|
||||
const MemberComputations computations(member);
|
||||
|
||||
if (computations.IsFirstMember())
|
||||
{
|
||||
LINE("")
|
||||
if (member->m_condition)
|
||||
{
|
||||
LINE("if (" << MakeEvaluation(member->m_condition.get()) << ")")
|
||||
LINE("{")
|
||||
m_intendation++;
|
||||
|
||||
MarkMember_Reference(info, member, DeclarationModifierComputations(member));
|
||||
|
||||
m_intendation--;
|
||||
LINE("}")
|
||||
}
|
||||
else
|
||||
{
|
||||
MarkMember_Reference(info, member, DeclarationModifierComputations(member));
|
||||
}
|
||||
}
|
||||
else if (computations.IsLastMember())
|
||||
{
|
||||
if (member->m_condition)
|
||||
{
|
||||
LINE("else if (" << MakeEvaluation(member->m_condition.get()) << ")")
|
||||
LINE("{")
|
||||
m_intendation++;
|
||||
|
||||
MarkMember_Reference(info, member, DeclarationModifierComputations(member));
|
||||
|
||||
m_intendation--;
|
||||
LINE("}")
|
||||
}
|
||||
else
|
||||
{
|
||||
LINE("else")
|
||||
LINE("{")
|
||||
m_intendation++;
|
||||
|
||||
MarkMember_Reference(info, member, DeclarationModifierComputations(member));
|
||||
|
||||
m_intendation--;
|
||||
LINE("}")
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (member->m_condition)
|
||||
{
|
||||
LINE("else if (" << MakeEvaluation(member->m_condition.get()) << ")")
|
||||
LINE("{")
|
||||
m_intendation++;
|
||||
|
||||
MarkMember_Reference(info, member, DeclarationModifierComputations(member));
|
||||
|
||||
m_intendation--;
|
||||
LINE("}")
|
||||
}
|
||||
else
|
||||
{
|
||||
LINE("#error Middle member of union must have condition (" << member->m_member->m_name << ")")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrintMarkMemberIfNeedsTreatment(StructureInformation* info, MemberInformation* member)
|
||||
{
|
||||
const MemberComputations computations(member);
|
||||
if (computations.ShouldIgnore() || computations.IsInRuntimeBlock())
|
||||
return;
|
||||
|
||||
if (member->m_is_script_string || member->m_type && (member->m_type->m_requires_marking || StructureComputations(member->m_type).IsAsset()))
|
||||
{
|
||||
if (info->m_definition->GetType() == DataDefinitionType::UNION)
|
||||
MarkMember_Condition_Union(info, member);
|
||||
else
|
||||
MarkMember_Condition_Struct(info, member);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintMarkMethod(StructureInformation* info)
|
||||
{
|
||||
const StructureComputations computations(info);
|
||||
LINE("void " << MarkerClassName(m_env.m_asset) << "::Mark_" << info->m_definition->m_name << "()")
|
||||
LINE("{")
|
||||
m_intendation++;
|
||||
|
||||
LINE("assert(" << MakeTypeVarName(info->m_definition) << " != nullptr);")
|
||||
|
||||
for (const auto& member : info->m_ordered_members)
|
||||
{
|
||||
PrintMarkMemberIfNeedsTreatment(info, member.get());
|
||||
}
|
||||
|
||||
m_intendation--;
|
||||
LINE("}")
|
||||
}
|
||||
|
||||
void PrintGetNameMethod()
|
||||
{
|
||||
LINE("std::string " << MarkerClassName(m_env.m_asset) << "::GetAssetName(" << m_env.m_asset->m_definition->GetFullName() << "* pAsset)")
|
||||
LINE("{")
|
||||
m_intendation++;
|
||||
|
||||
if (!m_env.m_asset->m_name_chain.empty())
|
||||
{
|
||||
LINE_START("return pAsset")
|
||||
|
||||
auto first = true;
|
||||
for (auto* member : m_env.m_asset->m_name_chain)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
LINE_MIDDLE("->" << member->m_member->m_name)
|
||||
}
|
||||
else
|
||||
{
|
||||
LINE_MIDDLE("." << member->m_member->m_name)
|
||||
}
|
||||
}
|
||||
LINE_END(";")
|
||||
}
|
||||
else
|
||||
{
|
||||
LINE("return \"" << m_env.m_asset->m_definition->m_name << "\";")
|
||||
}
|
||||
|
||||
m_intendation--;
|
||||
LINE("}")
|
||||
}
|
||||
|
||||
void PrintGetAssetInfoMethod()
|
||||
{
|
||||
LINE("XAssetInfo<" << m_env.m_asset->m_definition->GetFullName() << ">* " << MarkerClassName(m_env.m_asset) << "::GetAssetInfo("
|
||||
<< m_env.m_asset->m_definition->GetFullName() << "* pAsset) const")
|
||||
LINE("{")
|
||||
m_intendation++;
|
||||
|
||||
LINE("return reinterpret_cast<XAssetInfo<" << m_env.m_asset->m_definition->GetFullName() << ">*>(GetAssetInfoByName(GetAssetName(pAsset)));")
|
||||
|
||||
m_intendation--;
|
||||
LINE("}")
|
||||
}
|
||||
|
||||
void PrintMainMarkMethod()
|
||||
{
|
||||
LINE("void " << MarkerClassName(m_env.m_asset) << "::Mark(" << m_env.m_asset->m_definition->GetFullName() << "* pAsset)")
|
||||
LINE("{")
|
||||
m_intendation++;
|
||||
|
||||
LINE("assert(pAsset != nullptr);")
|
||||
LINE("")
|
||||
LINE(MakeTypeVarName(m_env.m_asset->m_definition) << " = pAsset;")
|
||||
LINE("Mark_" << MakeSafeTypeName(m_env.m_asset->m_definition) << "();")
|
||||
|
||||
m_intendation--;
|
||||
LINE("}")
|
||||
}
|
||||
|
||||
public:
|
||||
Internal(std::ostream& stream, RenderingContext* context)
|
||||
: BaseTemplate(stream, context)
|
||||
{
|
||||
}
|
||||
|
||||
void Header()
|
||||
{
|
||||
LINE("// ====================================================================")
|
||||
LINE("// This file has been generated by ZoneCodeGenerator.")
|
||||
LINE("// Do not modify. ")
|
||||
LINE("// Any changes will be discarded when regenerating.")
|
||||
LINE("// ====================================================================")
|
||||
LINE("")
|
||||
LINE("#pragma once")
|
||||
LINE("")
|
||||
LINE("#include \"Loading/AssetMarker.h\"")
|
||||
LINE("#include \"Game/" << m_env.m_game << "/" << m_env.m_game << ".h\"")
|
||||
LINE("#include <string>")
|
||||
LINE("")
|
||||
LINE("namespace " << m_env.m_game)
|
||||
LINE("{")
|
||||
m_intendation++;
|
||||
LINE("class " << MarkerClassName(m_env.m_asset) << " final : public AssetMarker")
|
||||
LINE("{")
|
||||
m_intendation++;
|
||||
|
||||
LINE(VariableDecl(m_env.m_asset->m_definition))
|
||||
LINE(PointerVariableDecl(m_env.m_asset->m_definition))
|
||||
LINE("")
|
||||
|
||||
m_intendation--;
|
||||
LINE("public:")
|
||||
m_intendation++;
|
||||
|
||||
// Variable Declarations: type varType;
|
||||
for (auto* type : m_env.m_used_types)
|
||||
{
|
||||
if (type->m_info && !type->m_info->m_definition->m_anonymous && !type->m_info->m_is_leaf && !StructureComputations(type->m_info).IsAsset())
|
||||
{
|
||||
LINE(VariableDecl(type->m_type))
|
||||
}
|
||||
}
|
||||
for (auto* type : m_env.m_used_types)
|
||||
{
|
||||
if (type->m_pointer_array_reference_exists && !type->m_is_context_asset)
|
||||
{
|
||||
LINE(PointerVariableDecl(type->m_type))
|
||||
}
|
||||
}
|
||||
|
||||
LINE("")
|
||||
|
||||
// Method Declarations
|
||||
for (auto* type : m_env.m_used_types)
|
||||
{
|
||||
if (type->m_pointer_array_reference_exists && type->m_info->m_requires_marking)
|
||||
{
|
||||
PrintHeaderPtrArrayMarkMethodDeclaration(type->m_type);
|
||||
}
|
||||
}
|
||||
for (auto* type : m_env.m_used_types)
|
||||
{
|
||||
if (type->m_array_reference_exists && type->m_info && !type->m_info->m_is_leaf && type->m_info->m_requires_marking
|
||||
&& type->m_non_runtime_reference_exists)
|
||||
{
|
||||
PrintHeaderArrayMarkMethodDeclaration(type->m_type);
|
||||
}
|
||||
}
|
||||
for (const auto* type : m_env.m_used_structures)
|
||||
{
|
||||
if (type->m_non_runtime_reference_exists && !type->m_info->m_is_leaf && type->m_info->m_requires_marking
|
||||
&& !StructureComputations(type->m_info).IsAsset())
|
||||
{
|
||||
PrintHeaderMarkMethodDeclaration(type->m_info);
|
||||
}
|
||||
}
|
||||
PrintHeaderMarkMethodDeclaration(m_env.m_asset);
|
||||
LINE("")
|
||||
PrintHeaderGetNameMethodDeclaration(m_env.m_asset);
|
||||
PrintHeaderGetAssetInfoMethodDeclaration(m_env.m_asset);
|
||||
LINE("")
|
||||
PrintHeaderConstructor();
|
||||
PrintHeaderMainMarkMethodDeclaration(m_env.m_asset);
|
||||
|
||||
m_intendation--;
|
||||
LINE("};")
|
||||
m_intendation--;
|
||||
LINE("}")
|
||||
}
|
||||
|
||||
void Source()
|
||||
{
|
||||
LINE("// ====================================================================")
|
||||
LINE("// This file has been generated by ZoneCodeGenerator.")
|
||||
LINE("// Do not modify. ")
|
||||
LINE("// Any changes will be discarded when regenerating.")
|
||||
LINE("// ====================================================================")
|
||||
LINE("")
|
||||
LINE("#include \"" << Lower(m_env.m_asset->m_definition->m_name) << "_mark_db.h\"")
|
||||
LINE("#include <cassert>")
|
||||
LINE("")
|
||||
|
||||
if (!m_env.m_referenced_assets.empty())
|
||||
{
|
||||
LINE("// Referenced Assets:")
|
||||
for (const auto* type : m_env.m_referenced_assets)
|
||||
{
|
||||
LINE("#include \"../" << Lower(type->m_type->m_name) << "/" << Lower(type->m_type->m_name) << "_mark_db.h\"")
|
||||
}
|
||||
LINE("")
|
||||
}
|
||||
LINE("using namespace " << m_env.m_game << ";")
|
||||
LINE("")
|
||||
PrintConstructorMethod();
|
||||
|
||||
for (const auto* type : m_env.m_used_types)
|
||||
{
|
||||
if (type->m_pointer_array_reference_exists && type->m_info->m_requires_marking)
|
||||
{
|
||||
LINE("")
|
||||
PrintMarkPtrArrayMethod(type->m_type, type->m_info, type->m_pointer_array_reference_is_reusable);
|
||||
}
|
||||
}
|
||||
for (const auto* type : m_env.m_used_types)
|
||||
{
|
||||
if (type->m_array_reference_exists && type->m_info && !type->m_info->m_is_leaf && type->m_info->m_requires_marking
|
||||
&& type->m_non_runtime_reference_exists)
|
||||
{
|
||||
LINE("")
|
||||
PrintMarkArrayMethod(type->m_type, type->m_info);
|
||||
}
|
||||
}
|
||||
for (const auto* type : m_env.m_used_structures)
|
||||
{
|
||||
if (type->m_non_runtime_reference_exists && !type->m_info->m_is_leaf && type->m_info->m_requires_marking
|
||||
&& !StructureComputations(type->m_info).IsAsset())
|
||||
{
|
||||
LINE("")
|
||||
PrintMarkMethod(type->m_info);
|
||||
}
|
||||
}
|
||||
LINE("")
|
||||
PrintMarkMethod(m_env.m_asset);
|
||||
LINE("")
|
||||
PrintMainMarkMethod();
|
||||
LINE("")
|
||||
PrintGetNameMethod();
|
||||
PrintGetAssetInfoMethod();
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<CodeTemplateFile> ZoneMarkTemplate::GetFilesToRender(RenderingContext* context)
|
||||
{
|
||||
std::vector<CodeTemplateFile> files;
|
||||
|
||||
auto assetName = context->m_asset->m_definition->m_name;
|
||||
utils::MakeStringLowerCase(assetName);
|
||||
|
||||
{
|
||||
std::ostringstream str;
|
||||
str << assetName << '/' << assetName << "_mark_db.h";
|
||||
files.emplace_back(str.str(), TAG_HEADER);
|
||||
}
|
||||
|
||||
{
|
||||
std::ostringstream str;
|
||||
str << assetName << '/' << assetName << "_mark_db.cpp";
|
||||
files.emplace_back(str.str(), TAG_SOURCE);
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
void ZoneMarkTemplate::RenderFile(std::ostream& stream, const int fileTag, RenderingContext* context)
|
||||
{
|
||||
Internal internal(stream, context);
|
||||
|
||||
if (fileTag == TAG_HEADER)
|
||||
{
|
||||
internal.Header();
|
||||
}
|
||||
else if (fileTag == TAG_SOURCE)
|
||||
{
|
||||
internal.Source();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Unknown tag for ZoneMarkTemplate: " << fileTag << "\n";
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "Generating/ICodeTemplate.h"
|
||||
|
||||
class ZoneMarkTemplate final : public ICodeTemplate
|
||||
{
|
||||
static constexpr int TAG_HEADER = 1;
|
||||
static constexpr int TAG_SOURCE = 2;
|
||||
|
||||
class Internal;
|
||||
|
||||
public:
|
||||
std::vector<CodeTemplateFile> GetFilesToRender(RenderingContext* context) override;
|
||||
void RenderFile(std::ostream& stream, int fileTag, RenderingContext* context) override;
|
||||
};
|
@ -8,6 +8,7 @@
|
||||
#include "Parsing/Impl/ParserFilesystemStream.h"
|
||||
#include "Parsing/PostProcessing/CalculateSizeAndAlignPostProcessor.h"
|
||||
#include "Parsing/PostProcessing/LeafsPostProcessor.h"
|
||||
#include "Parsing/PostProcessing/MarkingRequiredPostProcessor.h"
|
||||
#include "Parsing/PostProcessing/MemberLeafsPostProcessor.h"
|
||||
#include "Parsing/PostProcessing/UnionsPostProcessor.h"
|
||||
#include "Parsing/PostProcessing/UsagesPostProcessor.h"
|
||||
@ -58,6 +59,7 @@ void CommandsFileReader::SetupPostProcessors()
|
||||
m_post_processors.emplace_back(std::make_unique<CalculateSizeAndAlignPostProcessor>());
|
||||
m_post_processors.emplace_back(std::make_unique<UsagesPostProcessor>());
|
||||
m_post_processors.emplace_back(std::make_unique<LeafsPostProcessor>());
|
||||
m_post_processors.emplace_back(std::make_unique<MarkingRequiredPostProcessor>());
|
||||
m_post_processors.emplace_back(std::make_unique<MemberLeafsPostProcessor>());
|
||||
m_post_processors.emplace_back(std::make_unique<UnionsPostProcessor>());
|
||||
}
|
||||
|
@ -0,0 +1,76 @@
|
||||
#include "MarkingRequiredPostProcessor.h"
|
||||
|
||||
#include "Domain/Computations/MemberComputations.h"
|
||||
#include "Domain/Computations/StructureComputations.h"
|
||||
#include "Domain/Definition/PointerDeclarationModifier.h"
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
bool MarkingRequiredPostProcessor::CalculateRequiresMarking(std::unordered_set<const void*>& visitedStructures, StructureInformation* info)
|
||||
{
|
||||
if (visitedStructures.find(info) != visitedStructures.end())
|
||||
return info->m_requires_marking;
|
||||
|
||||
visitedStructures.emplace(info);
|
||||
|
||||
if (info->m_asset_enum_entry)
|
||||
{
|
||||
info->m_requires_marking = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const auto& member : info->m_ordered_members)
|
||||
{
|
||||
// If there is a condition to this member, and it always evaluates to false: Skip this member
|
||||
if (member->m_condition && member->m_condition->IsStatic() && member->m_condition->EvaluateNumeric() == 0)
|
||||
continue;
|
||||
|
||||
// Skip if it has a pointer evaluation that always resolves to 0
|
||||
auto skip = false;
|
||||
for (const auto& modifier : member->m_member->m_type_declaration->m_declaration_modifiers)
|
||||
{
|
||||
if (modifier->GetType() == DeclarationModifierType::POINTER)
|
||||
{
|
||||
const auto* pointer = dynamic_cast<PointerDeclarationModifier*>(modifier.get());
|
||||
const auto* countEvaluation = pointer->GetCountEvaluation();
|
||||
|
||||
if (countEvaluation->IsStatic() && countEvaluation->EvaluateNumeric() == 0)
|
||||
{
|
||||
skip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (skip)
|
||||
continue;
|
||||
|
||||
// Any ScriptStrings or Strings need to be processed.
|
||||
if (member->m_is_script_string || member->m_type && member->m_type->m_asset_enum_entry)
|
||||
{
|
||||
info->m_requires_marking = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (member->m_type != nullptr && member->m_type != info && CalculateRequiresMarking(visitedStructures, member->m_type))
|
||||
{
|
||||
info->m_requires_marking = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
info->m_requires_marking = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MarkingRequiredPostProcessor::PostProcess(IDataRepository* repository)
|
||||
{
|
||||
const auto& allInfos = repository->GetAllStructureInformation();
|
||||
|
||||
std::unordered_set<const void*> visitedStructures;
|
||||
for (const auto& info : allInfos)
|
||||
{
|
||||
CalculateRequiresMarking(visitedStructures, info);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "IPostProcessor.h"
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
class MarkingRequiredPostProcessor final : public IPostProcessor
|
||||
{
|
||||
static bool CalculateRequiresMarking(std::unordered_set<const void*>& visitedStructures, StructureInformation* info);
|
||||
|
||||
public:
|
||||
bool PostProcess(IDataRepository* repository) override;
|
||||
};
|
@ -64,9 +64,13 @@ public:
|
||||
|
||||
int Run(const int argc, const char** argv)
|
||||
{
|
||||
if (!m_args.Parse(argc, argv))
|
||||
auto shouldContinue = true;
|
||||
if (!m_args.ParseArgs(argc, argv, shouldContinue))
|
||||
return 1;
|
||||
|
||||
if (!shouldContinue)
|
||||
return 0;
|
||||
|
||||
if (!ReadHeaderData() || !ReadCommandsData())
|
||||
return 1;
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "ZoneCodeGeneratorArguments.h"
|
||||
|
||||
#include "GitVersion.h"
|
||||
#include "Utils/Arguments/CommandLineOption.h"
|
||||
#include "Utils/Arguments/UsageInformation.h"
|
||||
|
||||
@ -9,6 +10,9 @@
|
||||
const CommandLineOption* const OPTION_HELP =
|
||||
CommandLineOption::Builder::Create().WithShortName("?").WithLongName("help").WithDescription("Displays usage information.").Build();
|
||||
|
||||
const CommandLineOption* const OPTION_VERSION =
|
||||
CommandLineOption::Builder::Create().WithLongName("version").WithDescription("Prints the application version.").Build();
|
||||
|
||||
const CommandLineOption* const OPTION_VERBOSE =
|
||||
CommandLineOption::Builder::Create().WithShortName("v").WithLongName("verbose").WithDescription("Outputs a lot more and more detailed messages.").Build();
|
||||
|
||||
@ -70,7 +74,15 @@ const CommandLineOption* const OPTION_GENERATE =
|
||||
.Build();
|
||||
|
||||
const CommandLineOption* const COMMAND_LINE_OPTIONS[]{
|
||||
OPTION_HELP, OPTION_VERBOSE, OPTION_HEADER, OPTION_COMMANDS_FILE, OPTION_OUTPUT_FOLDER, OPTION_PRINT, OPTION_GENERATE};
|
||||
OPTION_HELP,
|
||||
OPTION_VERSION,
|
||||
OPTION_VERBOSE,
|
||||
OPTION_HEADER,
|
||||
OPTION_COMMANDS_FILE,
|
||||
OPTION_OUTPUT_FOLDER,
|
||||
OPTION_PRINT,
|
||||
OPTION_GENERATE,
|
||||
};
|
||||
|
||||
ZoneCodeGeneratorArguments::GenerationTask::GenerationTask()
|
||||
: m_all_assets(false)
|
||||
@ -91,7 +103,7 @@ ZoneCodeGeneratorArguments::GenerationTask::GenerationTask(std::string assetName
|
||||
}
|
||||
|
||||
ZoneCodeGeneratorArguments::ZoneCodeGeneratorArguments()
|
||||
: m_argument_parser(COMMAND_LINE_OPTIONS, std::extent<decltype(COMMAND_LINE_OPTIONS)>::value),
|
||||
: m_argument_parser(COMMAND_LINE_OPTIONS, std::extent_v<decltype(COMMAND_LINE_OPTIONS)>),
|
||||
m_task_flags(0)
|
||||
{
|
||||
m_verbose = false;
|
||||
@ -109,8 +121,14 @@ void ZoneCodeGeneratorArguments::PrintUsage()
|
||||
usage.Print();
|
||||
}
|
||||
|
||||
bool ZoneCodeGeneratorArguments::Parse(const int argc, const char** argv)
|
||||
void ZoneCodeGeneratorArguments::PrintVersion()
|
||||
{
|
||||
std::cout << "OpenAssetTools ZoneCodeGenerator " << std::string(GIT_VERSION) << "\n";
|
||||
}
|
||||
|
||||
bool ZoneCodeGeneratorArguments::ParseArgs(const int argc, const char** argv, bool& shouldContinue)
|
||||
{
|
||||
shouldContinue = true;
|
||||
if (!m_argument_parser.ParseArguments(argc - 1, &argv[1]))
|
||||
{
|
||||
PrintUsage();
|
||||
@ -121,7 +139,16 @@ bool ZoneCodeGeneratorArguments::Parse(const int argc, const char** argv)
|
||||
if (m_argument_parser.IsOptionSpecified(OPTION_HELP))
|
||||
{
|
||||
PrintUsage();
|
||||
return false;
|
||||
shouldContinue = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if the user wants to see the version
|
||||
if (m_argument_parser.IsOptionSpecified(OPTION_VERSION))
|
||||
{
|
||||
PrintVersion();
|
||||
shouldContinue = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// -v; --verbose
|
||||
|
@ -13,6 +13,7 @@ class ZoneCodeGeneratorArguments
|
||||
* \brief Prints a command line usage help text for the Unlinker tool to stdout.
|
||||
*/
|
||||
static void PrintUsage();
|
||||
static void PrintVersion();
|
||||
|
||||
public:
|
||||
static constexpr unsigned FLAG_TASK_GENERATE = 1 << 0;
|
||||
@ -40,8 +41,7 @@ public:
|
||||
std::vector<GenerationTask> m_generation_tasks;
|
||||
|
||||
ZoneCodeGeneratorArguments();
|
||||
|
||||
bool Parse(int argc, const char** argv);
|
||||
bool ParseArgs(int argc, const char** argv, bool& shouldContinue);
|
||||
|
||||
_NODISCARD bool ShouldGenerate() const;
|
||||
_NODISCARD bool ShouldPrint() const;
|
||||
|
@ -10,73 +10,10 @@ AssetLoader::AssetLoader(const asset_type_t assetType, Zone* zone, IZoneInputStr
|
||||
{
|
||||
}
|
||||
|
||||
void AssetLoader::AddDependency(XAssetInfoGeneric* assetInfo)
|
||||
XAssetInfoGeneric*
|
||||
AssetLoader::LinkAsset(std::string name, void* asset, std::vector<scr_string_t> scriptStrings, std::vector<XAssetInfoGeneric*> dependencies) const
|
||||
{
|
||||
if (assetInfo == nullptr)
|
||||
return;
|
||||
|
||||
const auto existingEntry = std::find(m_dependencies.begin(), m_dependencies.end(), assetInfo);
|
||||
if (existingEntry != m_dependencies.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_dependencies.push_back(assetInfo);
|
||||
}
|
||||
|
||||
scr_string_t AssetLoader::UseScriptString(const scr_string_t scrString)
|
||||
{
|
||||
assert(scrString < m_zone->m_script_strings.Count());
|
||||
|
||||
if (scrString >= m_zone->m_script_strings.Count())
|
||||
return 0u;
|
||||
|
||||
m_used_script_strings.emplace(scrString);
|
||||
return scrString;
|
||||
}
|
||||
|
||||
void AssetLoader::LoadScriptStringArray(const bool atStreamStart, const size_t count)
|
||||
{
|
||||
assert(varScriptString != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
m_stream->Load<scr_string_t>(varScriptString, count);
|
||||
|
||||
auto* ptr = varScriptString;
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
*ptr = UseScriptString(*ptr);
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
void AssetLoader::MarkScriptStringArrayAsUsed(const scr_string_t* scrStringArray, const size_t count)
|
||||
{
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
const auto scrString = scrStringArray[index];
|
||||
if (scrString >= m_zone->m_script_strings.Count())
|
||||
continue;
|
||||
|
||||
m_used_script_strings.emplace(scrString);
|
||||
}
|
||||
}
|
||||
|
||||
XAssetInfoGeneric* AssetLoader::LinkAsset(std::string name, void* asset)
|
||||
{
|
||||
std::vector<scr_string_t> usedScriptStrings;
|
||||
if (!m_used_script_strings.empty())
|
||||
{
|
||||
for (auto scrString : m_used_script_strings)
|
||||
{
|
||||
usedScriptStrings.push_back(scrString);
|
||||
}
|
||||
|
||||
std::sort(usedScriptStrings.begin(), usedScriptStrings.end());
|
||||
m_used_script_strings.clear();
|
||||
}
|
||||
|
||||
return m_zone->m_pools->AddAsset(m_asset_type, std::move(name), asset, std::move(m_dependencies), std::move(usedScriptStrings));
|
||||
return m_zone->m_pools->AddAsset(m_asset_type, std::move(name), asset, std::move(dependencies), std::move(scriptStrings));
|
||||
}
|
||||
|
||||
XAssetInfoGeneric* AssetLoader::GetAssetInfo(std::string name) const
|
||||
|
@ -11,21 +11,12 @@ class AssetLoader : public ContentLoaderBase
|
||||
{
|
||||
asset_type_t m_asset_type;
|
||||
|
||||
std::vector<XAssetInfoGeneric*> m_dependencies;
|
||||
std::unordered_set<scr_string_t> m_used_script_strings;
|
||||
|
||||
protected:
|
||||
scr_string_t* varScriptString;
|
||||
|
||||
AssetLoader(asset_type_t assetType, Zone* zone, IZoneInputStream* stream);
|
||||
|
||||
void AddDependency(XAssetInfoGeneric* assetInfo);
|
||||
XAssetInfoGeneric* LinkAsset(std::string name, void* asset, std::vector<scr_string_t> scriptStrings, std::vector<XAssetInfoGeneric*> dependencies) const;
|
||||
|
||||
scr_string_t UseScriptString(scr_string_t scrString);
|
||||
void LoadScriptStringArray(bool atStreamStart, size_t count);
|
||||
void MarkScriptStringArrayAsUsed(const scr_string_t* scrStringArray, size_t count);
|
||||
|
||||
XAssetInfoGeneric* LinkAsset(std::string name, void* asset);
|
||||
|
||||
XAssetInfoGeneric* GetAssetInfo(std::string name) const;
|
||||
_NODISCARD XAssetInfoGeneric* GetAssetInfo(std::string name) const;
|
||||
};
|
||||
|
73
src/ZoneLoading/Loading/AssetMarker.cpp
Normal file
73
src/ZoneLoading/Loading/AssetMarker.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include "AssetMarker.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
AssetMarker::AssetMarker(const asset_type_t assetType, Zone* zone)
|
||||
: m_asset_type(assetType),
|
||||
m_zone(zone)
|
||||
{
|
||||
}
|
||||
|
||||
void AssetMarker::AddDependency(XAssetInfoGeneric* assetInfo)
|
||||
{
|
||||
if (assetInfo == nullptr)
|
||||
return;
|
||||
|
||||
const auto existingEntry = m_dependencies.find(assetInfo);
|
||||
if (existingEntry != m_dependencies.end())
|
||||
return;
|
||||
|
||||
m_dependencies.emplace(assetInfo);
|
||||
}
|
||||
|
||||
void AssetMarker::Mark_ScriptString(const scr_string_t scrString)
|
||||
{
|
||||
assert(scrString < m_zone->m_script_strings.Count());
|
||||
|
||||
if (scrString >= m_zone->m_script_strings.Count())
|
||||
return;
|
||||
|
||||
m_used_script_strings.emplace(scrString);
|
||||
}
|
||||
|
||||
void AssetMarker::MarkArray_ScriptString(const scr_string_t* scrStringArray, const size_t count)
|
||||
{
|
||||
assert(scrStringArray != nullptr);
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
Mark_ScriptString(scrStringArray[index]);
|
||||
}
|
||||
|
||||
XAssetInfoGeneric* AssetMarker::GetAssetInfoByName(std::string name) const
|
||||
{
|
||||
return m_zone->m_pools->GetAsset(m_asset_type, std::move(name));
|
||||
}
|
||||
|
||||
std::vector<XAssetInfoGeneric*> AssetMarker::GetDependencies() const
|
||||
{
|
||||
std::vector<XAssetInfoGeneric*> dependencies;
|
||||
if (!m_dependencies.empty())
|
||||
{
|
||||
dependencies.reserve(m_dependencies.size());
|
||||
for (auto dependency : m_dependencies)
|
||||
dependencies.push_back(dependency);
|
||||
}
|
||||
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
std::vector<scr_string_t> AssetMarker::GetUsedScriptStrings() const
|
||||
{
|
||||
std::vector<scr_string_t> usedScriptStrings;
|
||||
if (!m_used_script_strings.empty())
|
||||
{
|
||||
usedScriptStrings.reserve(m_used_script_strings.size());
|
||||
for (auto scrString : m_used_script_strings)
|
||||
usedScriptStrings.push_back(scrString);
|
||||
|
||||
std::sort(usedScriptStrings.begin(), usedScriptStrings.end());
|
||||
}
|
||||
|
||||
return usedScriptStrings;
|
||||
}
|
32
src/ZoneLoading/Loading/AssetMarker.h
Normal file
32
src/ZoneLoading/Loading/AssetMarker.h
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include "ContentLoaderBase.h"
|
||||
#include "Pool/XAssetInfo.h"
|
||||
#include "Utils/ClassUtils.h"
|
||||
#include "Zone/ZoneTypes.h"
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
class AssetMarker
|
||||
{
|
||||
asset_type_t m_asset_type;
|
||||
|
||||
std::unordered_set<XAssetInfoGeneric*> m_dependencies;
|
||||
std::unordered_set<scr_string_t> m_used_script_strings;
|
||||
|
||||
protected:
|
||||
AssetMarker(asset_type_t assetType, Zone* zone);
|
||||
|
||||
void AddDependency(XAssetInfoGeneric* assetInfo);
|
||||
|
||||
void Mark_ScriptString(scr_string_t scrString);
|
||||
void MarkArray_ScriptString(const scr_string_t* scrStringArray, size_t count);
|
||||
|
||||
_NODISCARD XAssetInfoGeneric* GetAssetInfoByName(std::string name) const;
|
||||
|
||||
Zone* m_zone;
|
||||
|
||||
public:
|
||||
_NODISCARD std::vector<XAssetInfoGeneric*> GetDependencies() const;
|
||||
_NODISCARD std::vector<scr_string_t> GetUsedScriptStrings() const;
|
||||
};
|
@ -0,0 +1,46 @@
|
||||
#include "Game/IW3/AssetLoaders/AssetLoaderStringTable.h"
|
||||
|
||||
#include "Game/IW3/GameIW3.h"
|
||||
#include "Mock/MockAssetLoadingManager.h"
|
||||
#include "Mock/MockSearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <string>
|
||||
|
||||
using namespace IW3;
|
||||
using namespace std::literals;
|
||||
|
||||
namespace
|
||||
{
|
||||
TEST_CASE("AssetLoaderStringTable(IW3): Can parse string table", "[iw3][stringtable][assetloader]")
|
||||
{
|
||||
MockSearchPath searchPath;
|
||||
searchPath.AddFileData("mp/cooltable.csv",
|
||||
"test,data,lol\n"
|
||||
"lorem,ipsum");
|
||||
|
||||
Zone zone("MockZone", 0, &g_GameIW3);
|
||||
MockAssetLoadingManager assetLoadingManager(&zone, &searchPath);
|
||||
|
||||
AssetLoaderStringTable assetLoader;
|
||||
MemoryManager memory;
|
||||
|
||||
assetLoader.LoadFromRaw("mp/cooltable.csv", &searchPath, &memory, &assetLoadingManager, &zone);
|
||||
|
||||
auto* assetInfo = reinterpret_cast<XAssetInfo<StringTable>*>(assetLoadingManager.MockGetAddedAsset("mp/cooltable.csv"));
|
||||
REQUIRE(assetInfo != nullptr);
|
||||
|
||||
const auto* stringTable = assetInfo->Asset();
|
||||
REQUIRE(stringTable->name == "mp/cooltable.csv"s);
|
||||
REQUIRE(stringTable->columnCount == 3);
|
||||
REQUIRE(stringTable->rowCount == 2);
|
||||
|
||||
REQUIRE(stringTable->values[0] == "test"s);
|
||||
REQUIRE(stringTable->values[1] == "data"s);
|
||||
REQUIRE(stringTable->values[2] == "lol"s);
|
||||
REQUIRE(stringTable->values[3] == "lorem"s);
|
||||
REQUIRE(stringTable->values[4] == "ipsum"s);
|
||||
REQUIRE(stringTable->values[5] == ""s);
|
||||
}
|
||||
} // namespace
|
@ -0,0 +1,53 @@
|
||||
#include "Game/IW4/AssetLoaders/AssetLoaderStringTable.h"
|
||||
|
||||
#include "Game/IW4/CommonIW4.h"
|
||||
#include "Game/IW4/GameIW4.h"
|
||||
#include "Mock/MockAssetLoadingManager.h"
|
||||
#include "Mock/MockSearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <string>
|
||||
|
||||
using namespace IW4;
|
||||
using namespace std::literals;
|
||||
|
||||
namespace
|
||||
{
|
||||
TEST_CASE("AssetLoaderStringTable(IW4): Can parse string table", "[iw4][stringtable][assetloader]")
|
||||
{
|
||||
MockSearchPath searchPath;
|
||||
searchPath.AddFileData("mp/cooltable.csv",
|
||||
"test,data,lol\n"
|
||||
"lorem,ipsum");
|
||||
|
||||
Zone zone("MockZone", 0, &g_GameIW4);
|
||||
MockAssetLoadingManager assetLoadingManager(&zone, &searchPath);
|
||||
|
||||
AssetLoaderStringTable assetLoader;
|
||||
MemoryManager memory;
|
||||
|
||||
assetLoader.LoadFromRaw("mp/cooltable.csv", &searchPath, &memory, &assetLoadingManager, &zone);
|
||||
|
||||
auto* assetInfo = reinterpret_cast<XAssetInfo<StringTable>*>(assetLoadingManager.MockGetAddedAsset("mp/cooltable.csv"));
|
||||
REQUIRE(assetInfo != nullptr);
|
||||
|
||||
const auto* stringTable = assetInfo->Asset();
|
||||
REQUIRE(stringTable->name == "mp/cooltable.csv"s);
|
||||
REQUIRE(stringTable->columnCount == 3);
|
||||
REQUIRE(stringTable->rowCount == 2);
|
||||
|
||||
CHECK(stringTable->values[0].string == "test"s);
|
||||
CHECK(stringTable->values[0].hash == 0x364492);
|
||||
CHECK(stringTable->values[1].string == "data"s);
|
||||
CHECK(stringTable->values[1].hash == 0x2eefaa);
|
||||
CHECK(stringTable->values[2].string == "lol"s);
|
||||
CHECK(stringTable->values[2].hash == 0x1a349);
|
||||
CHECK(stringTable->values[3].string == "lorem"s);
|
||||
CHECK(stringTable->values[3].hash == 0x6261837);
|
||||
CHECK(stringTable->values[4].string == "ipsum"s);
|
||||
CHECK(stringTable->values[4].hash == 0x5fc4bc4);
|
||||
CHECK(stringTable->values[5].string == ""s);
|
||||
CHECK(stringTable->values[5].hash == 0x0);
|
||||
}
|
||||
} // namespace
|
@ -0,0 +1,52 @@
|
||||
#include "Game/IW5/AssetLoaders/AssetLoaderStringTable.h"
|
||||
|
||||
#include "Game/IW5/GameIW5.h"
|
||||
#include "Mock/MockAssetLoadingManager.h"
|
||||
#include "Mock/MockSearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <string>
|
||||
|
||||
using namespace IW5;
|
||||
using namespace std::literals;
|
||||
|
||||
namespace
|
||||
{
|
||||
TEST_CASE("AssetLoaderStringTable(IW5): Can parse string table", "[iw5][stringtable][assetloader]")
|
||||
{
|
||||
MockSearchPath searchPath;
|
||||
searchPath.AddFileData("mp/cooltable.csv",
|
||||
"test,data,lol\n"
|
||||
"lorem,ipsum");
|
||||
|
||||
Zone zone("MockZone", 0, &g_GameIW5);
|
||||
MockAssetLoadingManager assetLoadingManager(&zone, &searchPath);
|
||||
|
||||
AssetLoaderStringTable assetLoader;
|
||||
MemoryManager memory;
|
||||
|
||||
assetLoader.LoadFromRaw("mp/cooltable.csv", &searchPath, &memory, &assetLoadingManager, &zone);
|
||||
|
||||
auto* assetInfo = reinterpret_cast<XAssetInfo<StringTable>*>(assetLoadingManager.MockGetAddedAsset("mp/cooltable.csv"));
|
||||
REQUIRE(assetInfo != nullptr);
|
||||
|
||||
const auto* stringTable = assetInfo->Asset();
|
||||
REQUIRE(stringTable->name == "mp/cooltable.csv"s);
|
||||
REQUIRE(stringTable->columnCount == 3);
|
||||
REQUIRE(stringTable->rowCount == 2);
|
||||
|
||||
CHECK(stringTable->values[0].string == "test"s);
|
||||
CHECK(stringTable->values[0].hash == 0x364492);
|
||||
CHECK(stringTable->values[1].string == "data"s);
|
||||
CHECK(stringTable->values[1].hash == 0x2eefaa);
|
||||
CHECK(stringTable->values[2].string == "lol"s);
|
||||
CHECK(stringTable->values[2].hash == 0x1a349);
|
||||
CHECK(stringTable->values[3].string == "lorem"s);
|
||||
CHECK(stringTable->values[3].hash == 0x6261837);
|
||||
CHECK(stringTable->values[4].string == "ipsum"s);
|
||||
CHECK(stringTable->values[4].hash == 0x5fc4bc4);
|
||||
CHECK(stringTable->values[5].string == ""s);
|
||||
CHECK(stringTable->values[5].hash == 0x0);
|
||||
}
|
||||
} // namespace
|
@ -0,0 +1,59 @@
|
||||
#include "Game/T5/AssetLoaders/AssetLoaderStringTable.h"
|
||||
|
||||
#include "Game/T5/GameT5.h"
|
||||
#include "Mock/MockAssetLoadingManager.h"
|
||||
#include "Mock/MockSearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <string>
|
||||
|
||||
using namespace T5;
|
||||
using namespace std::literals;
|
||||
|
||||
namespace
|
||||
{
|
||||
TEST_CASE("AssetLoaderStringTable(T5): Can parse string table", "[t5][stringtable][assetloader]")
|
||||
{
|
||||
MockSearchPath searchPath;
|
||||
searchPath.AddFileData("mp/cooltable.csv",
|
||||
"test,data,lol\n"
|
||||
"lorem,ipsum");
|
||||
|
||||
Zone zone("MockZone", 0, &g_GameT5);
|
||||
MockAssetLoadingManager assetLoadingManager(&zone, &searchPath);
|
||||
|
||||
AssetLoaderStringTable assetLoader;
|
||||
MemoryManager memory;
|
||||
|
||||
assetLoader.LoadFromRaw("mp/cooltable.csv", &searchPath, &memory, &assetLoadingManager, &zone);
|
||||
|
||||
auto* assetInfo = reinterpret_cast<XAssetInfo<StringTable>*>(assetLoadingManager.MockGetAddedAsset("mp/cooltable.csv"));
|
||||
REQUIRE(assetInfo != nullptr);
|
||||
|
||||
const auto* stringTable = assetInfo->Asset();
|
||||
REQUIRE(stringTable->name == "mp/cooltable.csv"s);
|
||||
REQUIRE(stringTable->columnCount == 3);
|
||||
REQUIRE(stringTable->rowCount == 2);
|
||||
|
||||
CHECK(stringTable->values[0].string == "test"s);
|
||||
CHECK(stringTable->values[0].hash == 0x7c9e6865);
|
||||
CHECK(stringTable->values[1].string == "data"s);
|
||||
CHECK(stringTable->values[1].hash == 0x7c95915f);
|
||||
CHECK(stringTable->values[2].string == "lol"s);
|
||||
CHECK(stringTable->values[2].hash == 0xb888d0c);
|
||||
CHECK(stringTable->values[3].string == "lorem"s);
|
||||
CHECK(stringTable->values[3].hash == 0xfe02704);
|
||||
CHECK(stringTable->values[4].string == "ipsum"s);
|
||||
CHECK(stringTable->values[4].hash == 0xfaa7033);
|
||||
CHECK(stringTable->values[5].string == ""s);
|
||||
CHECK(stringTable->values[5].hash == 0x1505);
|
||||
|
||||
REQUIRE(stringTable->cellIndex != nullptr);
|
||||
CHECK(stringTable->cellIndex[0] == 2);
|
||||
CHECK(stringTable->cellIndex[1] == 4);
|
||||
CHECK(stringTable->cellIndex[2] == 3);
|
||||
CHECK(stringTable->cellIndex[3] == 1);
|
||||
CHECK(stringTable->cellIndex[4] == 0);
|
||||
}
|
||||
} // namespace
|
@ -0,0 +1,59 @@
|
||||
#include "Game/T6/AssetLoaders/AssetLoaderStringTable.h"
|
||||
|
||||
#include "Game/T6/GameT6.h"
|
||||
#include "Mock/MockAssetLoadingManager.h"
|
||||
#include "Mock/MockSearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <string>
|
||||
|
||||
using namespace T6;
|
||||
using namespace std::literals;
|
||||
|
||||
namespace
|
||||
{
|
||||
TEST_CASE("AssetLoaderStringTable(T6): Can parse string table", "[t6][stringtable][assetloader]")
|
||||
{
|
||||
MockSearchPath searchPath;
|
||||
searchPath.AddFileData("mp/cooltable.csv",
|
||||
"test,data,lol\n"
|
||||
"lorem,ipsum");
|
||||
|
||||
Zone zone("MockZone", 0, &g_GameT6);
|
||||
MockAssetLoadingManager assetLoadingManager(&zone, &searchPath);
|
||||
|
||||
AssetLoaderStringTable assetLoader;
|
||||
MemoryManager memory;
|
||||
|
||||
assetLoader.LoadFromRaw("mp/cooltable.csv", &searchPath, &memory, &assetLoadingManager, &zone);
|
||||
|
||||
auto* assetInfo = reinterpret_cast<XAssetInfo<StringTable>*>(assetLoadingManager.MockGetAddedAsset("mp/cooltable.csv"));
|
||||
REQUIRE(assetInfo != nullptr);
|
||||
|
||||
const auto* stringTable = assetInfo->Asset();
|
||||
REQUIRE(stringTable->name == "mp/cooltable.csv"s);
|
||||
REQUIRE(stringTable->columnCount == 3);
|
||||
REQUIRE(stringTable->rowCount == 2);
|
||||
|
||||
CHECK(stringTable->values[0].string == "test"s);
|
||||
CHECK(stringTable->values[0].hash == 0x7c9e6865);
|
||||
CHECK(stringTable->values[1].string == "data"s);
|
||||
CHECK(stringTable->values[1].hash == 0x7c95915f);
|
||||
CHECK(stringTable->values[2].string == "lol"s);
|
||||
CHECK(stringTable->values[2].hash == 0xb888d0c);
|
||||
CHECK(stringTable->values[3].string == "lorem"s);
|
||||
CHECK(stringTable->values[3].hash == 0xfe02704);
|
||||
CHECK(stringTable->values[4].string == "ipsum"s);
|
||||
CHECK(stringTable->values[4].hash == 0xfaa7033);
|
||||
CHECK(stringTable->values[5].string == ""s);
|
||||
CHECK(stringTable->values[5].hash == 0x1505);
|
||||
|
||||
REQUIRE(stringTable->cellIndex != nullptr);
|
||||
CHECK(stringTable->cellIndex[0] == 2);
|
||||
CHECK(stringTable->cellIndex[1] == 4);
|
||||
CHECK(stringTable->cellIndex[2] == 3);
|
||||
CHECK(stringTable->cellIndex[3] == 1);
|
||||
CHECK(stringTable->cellIndex[4] == 0);
|
||||
}
|
||||
} // namespace
|
2
thirdparty/catch2
vendored
2
thirdparty/catch2
vendored
@ -1 +1 @@
|
||||
Subproject commit 863c662c0eff026300f4d729a7054e90d6d12cdd
|
||||
Subproject commit 79205da6a67f5ad3d7874cf1c6423283dfeab199
|
2
thirdparty/json
vendored
2
thirdparty/json
vendored
@ -1 +1 @@
|
||||
Subproject commit a259ecc51e1951e12f757ce17db958e9881e9c6c
|
||||
Subproject commit 7efe875495a3ed7d805ddbb01af0c7725f50c88b
|
2
thirdparty/zlib
vendored
2
thirdparty/zlib
vendored
@ -1 +1 @@
|
||||
Subproject commit 643e17b7498d12ab8d15565662880579692f769d
|
||||
Subproject commit 7af6320ad78b390de42f414fabdc64dc6d67a5ea
|
36
tools/scripts/version.lua
Normal file
36
tools/scripts/version.lua
Normal file
@ -0,0 +1,36 @@
|
||||
local BuildSubFolderFolder = "premake"
|
||||
local HeaderFileName = "GitVersion.h"
|
||||
|
||||
function GetGitVersion()
|
||||
result, errorCode = os.outputof("git describe --tags")
|
||||
|
||||
if errorCode == 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
return "Unknown"
|
||||
end
|
||||
|
||||
function GetVersionHeaderFolder()
|
||||
return path.join(BuildFolder(), BuildSubFolderFolder)
|
||||
end
|
||||
|
||||
function WriteVersionHeader()
|
||||
local folder = GetVersionHeaderFolder()
|
||||
local file = path.join(folder, HeaderFileName)
|
||||
local content = string.format([[
|
||||
#pragma once
|
||||
|
||||
#define GIT_VERSION "%s"
|
||||
]], GetGitVersion())
|
||||
|
||||
if os.isdir(folder) ~= True then
|
||||
os.mkdir(folder)
|
||||
end
|
||||
|
||||
local ok, err = os.writefile_ifnotequal(content, file)
|
||||
|
||||
if ok == -1 then
|
||||
error("Could not create version file: " .. err)
|
||||
end
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user