Merge pull request #14 from Laupetin/feature/rename-fastfiles

Introduce "project" concept and be able to rename built zones
This commit is contained in:
Jan 2023-09-28 21:19:01 +02:00 committed by GitHub
commit 98528db8aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 157 additions and 125 deletions

View File

@ -64,7 +64,7 @@ bool ZoneCreator::SupportsGame(const std::string& gameName) const
std::unique_ptr<Zone> ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const std::unique_ptr<Zone> ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const
{ {
auto zone = std::make_unique<Zone>(context.m_zone_name, 0, &g_GameIW3); auto zone = std::make_unique<Zone>(context.m_definition->m_name, 0, &g_GameIW3);
CreateZoneAssetPools(zone.get()); CreateZoneAssetPools(zone.get());
for (const auto& assetEntry : context.m_definition->m_assets) for (const auto& assetEntry : context.m_definition->m_assets)

View File

@ -63,7 +63,7 @@ bool ZoneCreator::SupportsGame(const std::string& gameName) const
std::unique_ptr<Zone> ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const std::unique_ptr<Zone> ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const
{ {
auto zone = std::make_unique<Zone>(context.m_zone_name, 0, &g_GameIW4); auto zone = std::make_unique<Zone>(context.m_definition->m_name, 0, &g_GameIW4);
CreateZoneAssetPools(zone.get()); CreateZoneAssetPools(zone.get());
for (const auto& assetEntry : context.m_definition->m_assets) for (const auto& assetEntry : context.m_definition->m_assets)

View File

@ -63,7 +63,7 @@ bool ZoneCreator::SupportsGame(const std::string& gameName) const
std::unique_ptr<Zone> ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const std::unique_ptr<Zone> ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const
{ {
auto zone = std::make_unique<Zone>(context.m_zone_name, 0, &g_GameIW5); auto zone = std::make_unique<Zone>(context.m_definition->m_name, 0, &g_GameIW5);
CreateZoneAssetPools(zone.get()); CreateZoneAssetPools(zone.get());
for (const auto& assetEntry : context.m_definition->m_assets) for (const auto& assetEntry : context.m_definition->m_assets)

View File

@ -64,7 +64,7 @@ bool ZoneCreator::SupportsGame(const std::string& gameName) const
std::unique_ptr<Zone> ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const std::unique_ptr<Zone> ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const
{ {
auto zone = std::make_unique<Zone>(context.m_zone_name, 0, &g_GameT5); auto zone = std::make_unique<Zone>(context.m_definition->m_name, 0, &g_GameT5);
CreateZoneAssetPools(zone.get()); CreateZoneAssetPools(zone.get());
for (const auto& assetEntry : context.m_definition->m_assets) for (const auto& assetEntry : context.m_definition->m_assets)

View File

@ -118,7 +118,7 @@ bool ZoneCreator::SupportsGame(const std::string& gameName) const
std::unique_ptr<Zone> ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const std::unique_ptr<Zone> ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const
{ {
auto zone = std::make_unique<Zone>(context.m_zone_name, 0, &g_GameT6); auto zone = std::make_unique<Zone>(context.m_definition->m_name, 0, &g_GameT6);
CreateZoneAssetPools(zone.get()); CreateZoneAssetPools(zone.get());
for (const auto& assetEntry : context.m_definition->m_assets) for (const auto& assetEntry : context.m_definition->m_assets)

View File

@ -42,11 +42,12 @@ const IZoneCreator* const ZONE_CREATORS[]
class Linker::Impl class Linker::Impl
{ {
static constexpr const char* METADATA_NAME = "name";
static constexpr const char* METADATA_GAME = "game"; static constexpr const char* METADATA_GAME = "game";
static constexpr const char* METADATA_GDT = "gdt"; static constexpr const char* METADATA_GDT = "gdt";
LinkerArgs m_args; LinkerArgs m_args;
std::vector<std::unique_ptr<ISearchPath>> m_loaded_zone_search_paths; std::vector<std::unique_ptr<ISearchPath>> m_loaded_project_search_paths;
SearchPaths m_asset_search_paths; SearchPaths m_asset_search_paths;
SearchPaths m_gdt_search_paths; SearchPaths m_gdt_search_paths;
SearchPaths m_source_search_paths; SearchPaths m_source_search_paths;
@ -80,11 +81,11 @@ class Linker::Impl
ObjLoading::UnloadIWDsInSearchPath(searchPath); ObjLoading::UnloadIWDsInSearchPath(searchPath);
} }
SearchPaths GetAssetSearchPathsForZone(const std::string& gameName, const std::string& zoneName) SearchPaths GetAssetSearchPathsForProject(const std::string& gameName, const std::string& projectName)
{ {
SearchPaths searchPathsForZone; SearchPaths searchPathsForProject;
for (const auto& searchPathStr : m_args.GetAssetSearchPathsForZone(gameName, zoneName)) for (const auto& searchPathStr : m_args.GetAssetSearchPathsForProject(gameName, projectName))
{ {
auto absolutePath = fs::absolute(searchPathStr); auto absolutePath = fs::absolute(searchPathStr);
@ -100,25 +101,25 @@ class Linker::Impl
auto searchPath = std::make_unique<SearchPathFilesystem>(searchPathStr); auto searchPath = std::make_unique<SearchPathFilesystem>(searchPathStr);
LoadSearchPath(searchPath.get()); LoadSearchPath(searchPath.get());
searchPathsForZone.IncludeSearchPath(searchPath.get()); searchPathsForProject.IncludeSearchPath(searchPath.get());
m_loaded_zone_search_paths.emplace_back(std::move(searchPath)); m_loaded_project_search_paths.emplace_back(std::move(searchPath));
} }
searchPathsForZone.IncludeSearchPath(&m_asset_search_paths); searchPathsForProject.IncludeSearchPath(&m_asset_search_paths);
for (auto* iwd : IWD::Repository) for (auto* iwd : IWD::Repository)
{ {
searchPathsForZone.IncludeSearchPath(iwd); searchPathsForProject.IncludeSearchPath(iwd);
} }
return searchPathsForZone; return searchPathsForProject;
} }
SearchPaths GetGdtSearchPathsForZone(const std::string& gameName, const std::string& zoneName) SearchPaths GetGdtSearchPathsForProject(const std::string& gameName, const std::string& projectName)
{ {
SearchPaths searchPathsForZone; SearchPaths searchPathsForProject;
for (const auto& searchPathStr : m_args.GetGdtSearchPathsForZone(gameName, zoneName)) for (const auto& searchPathStr : m_args.GetGdtSearchPathsForProject(gameName, projectName))
{ {
auto absolutePath = fs::absolute(searchPathStr); auto absolutePath = fs::absolute(searchPathStr);
@ -132,19 +133,19 @@ class Linker::Impl
if (m_args.m_verbose) if (m_args.m_verbose)
std::cout << "Adding gdt search path: " << absolutePath.string() << std::endl; std::cout << "Adding gdt search path: " << absolutePath.string() << std::endl;
searchPathsForZone.CommitSearchPath(std::make_unique<SearchPathFilesystem>(searchPathStr)); searchPathsForProject.CommitSearchPath(std::make_unique<SearchPathFilesystem>(searchPathStr));
} }
searchPathsForZone.IncludeSearchPath(&m_gdt_search_paths); searchPathsForProject.IncludeSearchPath(&m_gdt_search_paths);
return searchPathsForZone; return searchPathsForProject;
} }
SearchPaths GetSourceSearchPathsForZone(const std::string& zoneName) SearchPaths GetSourceSearchPathsForProject(const std::string& projectName)
{ {
SearchPaths searchPathsForZone; SearchPaths searchPathsForProject;
for (const auto& searchPathStr : m_args.GetSourceSearchPathsForZone(zoneName)) for (const auto& searchPathStr : m_args.GetSourceSearchPathsForProject(projectName))
{ {
auto absolutePath = fs::absolute(searchPathStr); auto absolutePath = fs::absolute(searchPathStr);
@ -158,21 +159,21 @@ class Linker::Impl
if (m_args.m_verbose) if (m_args.m_verbose)
std::cout << "Adding source search path: " << absolutePath.string() << std::endl; std::cout << "Adding source search path: " << absolutePath.string() << std::endl;
searchPathsForZone.CommitSearchPath(std::make_unique<SearchPathFilesystem>(searchPathStr)); searchPathsForProject.CommitSearchPath(std::make_unique<SearchPathFilesystem>(searchPathStr));
} }
searchPathsForZone.IncludeSearchPath(&m_source_search_paths); searchPathsForProject.IncludeSearchPath(&m_source_search_paths);
return searchPathsForZone; return searchPathsForProject;
} }
/** /**
* \brief Initializes the Linker object's search paths based on the user's input. * \brief Initializes the Linker object's search paths based on the user's input.
* \return \c true if building the search paths was successful, otherwise \c false. * \return \c true if building the search paths was successful, otherwise \c false.
*/ */
bool BuildZoneIndependentSearchPaths() bool BuildProjectIndependentSearchPaths()
{ {
for (const auto& path : m_args.GetZoneIndependentAssetSearchPaths()) for (const auto& path : m_args.GetProjectIndependentAssetSearchPaths())
{ {
auto absolutePath = fs::absolute(path); auto absolutePath = fs::absolute(path);
@ -191,7 +192,7 @@ class Linker::Impl
m_asset_search_paths.CommitSearchPath(std::move(searchPath)); m_asset_search_paths.CommitSearchPath(std::move(searchPath));
} }
for (const auto& path : m_args.GetZoneIndependentGdtSearchPaths()) for (const auto& path : m_args.GetProjectIndependentGdtSearchPaths())
{ {
auto absolutePath = fs::absolute(path); auto absolutePath = fs::absolute(path);
@ -208,7 +209,7 @@ class Linker::Impl
m_gdt_search_paths.CommitSearchPath(std::make_unique<SearchPathFilesystem>(absolutePath.string())); m_gdt_search_paths.CommitSearchPath(std::make_unique<SearchPathFilesystem>(absolutePath.string()));
} }
for (const auto& path : m_args.GetZoneIndependentSourceSearchPaths()) for (const auto& path : m_args.GetProjectIndependentSourceSearchPaths())
{ {
auto absolutePath = fs::absolute(path); auto absolutePath = fs::absolute(path);
@ -251,7 +252,7 @@ class Linker::Impl
const auto definitionStream = sourceSearchPath->Open(definitionFileName); const auto definitionStream = sourceSearchPath->Open(definitionFileName);
if (!definitionStream.IsOpen()) if (!definitionStream.IsOpen())
{ {
std::cout << "Could not find zone definition file for zone \"" << source << "\"." << std::endl; std::cout << "Could not find zone definition file for project \"" << source << "\"." << std::endl;
return false; return false;
} }
@ -261,7 +262,7 @@ class Linker::Impl
if (!includeDefinition) if (!includeDefinition)
{ {
std::cout << "Failed to read zone definition file for zone \"" << source << "\"." << std::endl; std::cout << "Failed to read zone definition file for project \"" << source << "\"." << std::endl;
return false; return false;
} }
@ -277,15 +278,42 @@ class Linker::Impl
return true; return true;
} }
std::unique_ptr<ZoneDefinition> ReadZoneDefinition(const std::string& zoneName, ISearchPath* sourceSearchPath) const static bool GetNameFromZoneDefinition(std::string& name, const std::string& projectName, const ZoneDefinition& zoneDefinition)
{
auto firstNameEntry = true;
const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata_lookup.equal_range(METADATA_NAME);
for (auto i = rangeBegin; i != rangeEnd; ++i)
{
if (firstNameEntry)
{
name = i->second->m_value;
firstNameEntry = false;
}
else
{
if (name != i->second->m_value)
{
std::cout << "Conflicting names in project \"" << projectName << "\": " << name << " != " << i->second << std::endl;
return false;
}
}
}
if (firstNameEntry)
name = projectName;
return true;
}
std::unique_ptr<ZoneDefinition> ReadZoneDefinition(const std::string& projectName, ISearchPath* sourceSearchPath) const
{ {
std::unique_ptr<ZoneDefinition> zoneDefinition; std::unique_ptr<ZoneDefinition> zoneDefinition;
{ {
const auto definitionFileName = zoneName + ".zone"; const auto definitionFileName = projectName + ".zone";
const auto definitionStream = sourceSearchPath->Open(definitionFileName); const auto definitionStream = sourceSearchPath->Open(definitionFileName);
if (!definitionStream.IsOpen()) if (!definitionStream.IsOpen())
{ {
std::cout << "Could not find zone definition file for zone \"" << zoneName << "\"." << std::endl; std::cout << "Could not find zone definition file for project \"" << projectName << "\"." << std::endl;
return nullptr; return nullptr;
} }
@ -295,11 +323,14 @@ class Linker::Impl
if (!zoneDefinition) if (!zoneDefinition)
{ {
std::cout << "Failed to read zone definition file for zone \"" << zoneName << "\"." << std::endl; std::cout << "Failed to read zone definition file for project \"" << projectName << "\"." << std::endl;
return nullptr; return nullptr;
} }
if (!IncludeAdditionalZoneDefinitions(zoneName, *zoneDefinition, sourceSearchPath)) if (!GetNameFromZoneDefinition(zoneDefinition->m_name, projectName, *zoneDefinition))
return nullptr;
if (!IncludeAdditionalZoneDefinitions(projectName, *zoneDefinition, sourceSearchPath))
return nullptr; return nullptr;
return zoneDefinition; return zoneDefinition;
@ -340,7 +371,7 @@ class Linker::Impl
return false; return false;
} }
bool ProcessZoneDefinitionIgnores(const std::string& zoneName, ZoneCreationContext& context, ISearchPath* sourceSearchPath) const bool ProcessZoneDefinitionIgnores(const std::string& projectName, ZoneCreationContext& context, ISearchPath* sourceSearchPath) const
{ {
if (context.m_definition->m_ignores.empty()) if (context.m_definition->m_ignores.empty())
return true; return true;
@ -353,20 +384,20 @@ class Linker::Impl
for (const auto& ignore : context.m_definition->m_ignores) for (const auto& ignore : context.m_definition->m_ignores)
{ {
if (ignore == zoneName) if (ignore == projectName)
continue; continue;
std::vector<AssetListEntry> assetList; std::vector<AssetListEntry> assetList;
if (!ReadAssetList(ignore, context.m_ignored_assets, sourceSearchPath)) if (!ReadAssetList(ignore, context.m_ignored_assets, sourceSearchPath))
{ {
std::cout << "Failed to read asset listing for ignoring assets of zone \"" << ignore << "\"." << std::endl; std::cout << "Failed to read asset listing for ignoring assets of project \"" << ignore << "\"." << std::endl;
return false; return false;
} }
} }
return true; return true;
} }
static bool GetGameNameFromZoneDefinition(std::string& gameName, const std::string& zoneName, const ZoneDefinition& zoneDefinition) static bool GetGameNameFromZoneDefinition(std::string& gameName, const std::string& projectName, const ZoneDefinition& zoneDefinition)
{ {
auto firstGameEntry = true; auto firstGameEntry = true;
const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata_lookup.equal_range(METADATA_GAME); const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata_lookup.equal_range(METADATA_GAME);
@ -381,7 +412,7 @@ class Linker::Impl
{ {
if (gameName != i->second->m_value) if (gameName != i->second->m_value)
{ {
std::cout << "Conflicting game names in zone \"" << zoneName << "\": " << gameName << " != " << i->second << std::endl; std::cout << "Conflicting game names in project \"" << projectName << "\": " << gameName << " != " << i->second << std::endl;
return false; return false;
} }
} }
@ -389,14 +420,14 @@ class Linker::Impl
if (firstGameEntry) if (firstGameEntry)
{ {
std::cout << "No game name was specified for zone \"" << zoneName << "\"" << std::endl; std::cout << "No game name was specified for project \"" << projectName << "\"" << std::endl;
return false; return false;
} }
return true; return true;
} }
static bool LoadGdtFilesFromZoneDefinition(std::vector<std::unique_ptr<Gdt>>& gdtList, const std::string& zoneName, const ZoneDefinition& zoneDefinition, ISearchPath* gdtSearchPath) static bool LoadGdtFilesFromZoneDefinition(std::vector<std::unique_ptr<Gdt>>& gdtList, const ZoneDefinition& zoneDefinition, ISearchPath* gdtSearchPath)
{ {
const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata_lookup.equal_range(METADATA_GDT); const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata_lookup.equal_range(METADATA_GDT);
for (auto i = rangeBegin; i != rangeEnd; ++i) for (auto i = rangeBegin; i != rangeEnd; ++i)
@ -422,15 +453,15 @@ class Linker::Impl
return true; return true;
} }
std::unique_ptr<Zone> CreateZoneForDefinition(const std::string& zoneName, ZoneDefinition& zoneDefinition, ISearchPath* assetSearchPath, ISearchPath* gdtSearchPath, std::unique_ptr<Zone> CreateZoneForDefinition(const std::string& projectName, ZoneDefinition& zoneDefinition, ISearchPath* assetSearchPath, ISearchPath* gdtSearchPath,
ISearchPath* sourceSearchPath) const ISearchPath* sourceSearchPath) const
{ {
auto context = std::make_unique<ZoneCreationContext>(zoneName, assetSearchPath, &zoneDefinition); const auto context = std::make_unique<ZoneCreationContext>(assetSearchPath, &zoneDefinition);
if (!ProcessZoneDefinitionIgnores(zoneName, *context, sourceSearchPath)) if (!ProcessZoneDefinitionIgnores(projectName, *context, sourceSearchPath))
return nullptr; return nullptr;
if (!GetGameNameFromZoneDefinition(context->m_game_name, zoneName, zoneDefinition)) if (!GetGameNameFromZoneDefinition(context->m_game_name, projectName, zoneDefinition))
return nullptr; return nullptr;
if (!LoadGdtFilesFromZoneDefinition(context->m_gdt_files, zoneName, zoneDefinition, gdtSearchPath)) if (!LoadGdtFilesFromZoneDefinition(context->m_gdt_files, zoneDefinition, gdtSearchPath))
return nullptr; return nullptr;
for (const auto* assetLoader : ZONE_CREATORS) for (const auto* assetLoader : ZONE_CREATORS)
@ -442,9 +473,9 @@ class Linker::Impl
return nullptr; return nullptr;
} }
bool WriteZoneToFile(Zone* zone) bool WriteZoneToFile(const std::string& projectName, Zone* zone) const
{ {
const fs::path zoneFolderPath(m_args.GetOutputFolderPathForZone(zone->m_name)); const fs::path zoneFolderPath(m_args.GetOutputFolderPathForProject(projectName));
auto zoneFilePath(zoneFolderPath); auto zoneFilePath(zoneFolderPath);
zoneFilePath.append(zone->m_name + ".ff"); zoneFilePath.append(zone->m_name + ".ff");
@ -461,38 +492,40 @@ class Linker::Impl
return false; return false;
} }
std::cout << "Created zone \"" << zoneFilePath.string() << "\"\n";
stream.close(); stream.close();
return true; return true;
} }
bool BuildZone(const std::string& zoneName) bool BuildProject(const std::string& projectName)
{ {
auto sourceSearchPaths = GetSourceSearchPathsForZone(zoneName); auto sourceSearchPaths = GetSourceSearchPathsForProject(projectName);
const auto zoneDefinition = ReadZoneDefinition(zoneName, &sourceSearchPaths); const auto zoneDefinition = ReadZoneDefinition(projectName, &sourceSearchPaths);
if (!zoneDefinition) if (!zoneDefinition)
return false; return false;
std::string gameName; std::string gameName;
if (!GetGameNameFromZoneDefinition(gameName, zoneName, *zoneDefinition)) if (!GetGameNameFromZoneDefinition(gameName, projectName, *zoneDefinition))
return false; return false;
for (auto& c : gameName) for (auto& c : gameName)
c = static_cast<char>(std::tolower(c)); c = static_cast<char>(std::tolower(c));
auto assetSearchPaths = GetAssetSearchPathsForZone(gameName, zoneName); auto assetSearchPaths = GetAssetSearchPathsForProject(gameName, projectName);
auto gdtSearchPaths = GetGdtSearchPathsForZone(gameName, zoneName); auto gdtSearchPaths = GetGdtSearchPathsForProject(gameName, projectName);
const auto zone = CreateZoneForDefinition(zoneName, *zoneDefinition, &assetSearchPaths, &gdtSearchPaths, &sourceSearchPaths); const auto zone = CreateZoneForDefinition(projectName, *zoneDefinition, &assetSearchPaths, &gdtSearchPaths, &sourceSearchPaths);
auto result = zone != nullptr; auto result = zone != nullptr;
if (zone) if (zone)
result = WriteZoneToFile(zone.get()); result = WriteZoneToFile(projectName, zone.get());
for (const auto& loadedSearchPath : m_loaded_zone_search_paths) for (const auto& loadedSearchPath : m_loaded_project_search_paths)
{ {
UnloadSearchPath(loadedSearchPath.get()); UnloadSearchPath(loadedSearchPath.get());
} }
m_loaded_zone_search_paths.clear(); m_loaded_project_search_paths.clear();
return result; return result;
} }
@ -554,16 +587,16 @@ public:
if (!m_args.ParseArgs(argc, argv)) if (!m_args.ParseArgs(argc, argv))
return false; return false;
if (!BuildZoneIndependentSearchPaths()) if (!BuildProjectIndependentSearchPaths())
return false; return false;
if (!LoadZones()) if (!LoadZones())
return false; return false;
auto result = true; auto result = true;
for (const auto& zone : m_args.m_zones_to_build) for (const auto& projectName : m_args.m_projects_to_build)
{ {
if (!BuildZone(zone)) if (!BuildProject(projectName))
{ {
result = false; result = false;
break; break;

View File

@ -36,7 +36,7 @@ const CommandLineOption* const OPTION_BASE_FOLDER =
const CommandLineOption* const OPTION_OUTPUT_FOLDER = const CommandLineOption* const OPTION_OUTPUT_FOLDER =
CommandLineOption::Builder::Create() CommandLineOption::Builder::Create()
.WithLongName("output-folder") .WithLongName("output-folder")
.WithDescription("Specifies the output folder containing the contents of the unlinked zones. Defaults to \"" + std::string(LinkerArgs::DEFAULT_OUTPUT_FOLDER) + "\".") .WithDescription("Specifies the output folder containing the build artifacts. Defaults to \"" + std::string(LinkerArgs::DEFAULT_OUTPUT_FOLDER) + "\".")
.WithParameter("outputFolderPath") .WithParameter("outputFolderPath")
.Build(); .Build();
@ -100,9 +100,9 @@ LinkerArgs::LinkerArgs()
: m_argument_parser(COMMAND_LINE_OPTIONS, std::extent<decltype(COMMAND_LINE_OPTIONS)>::value), : m_argument_parser(COMMAND_LINE_OPTIONS, std::extent<decltype(COMMAND_LINE_OPTIONS)>::value),
m_base_pattern(R"(\?base\?)"), m_base_pattern(R"(\?base\?)"),
m_game_pattern(R"(\?game\?)"), m_game_pattern(R"(\?game\?)"),
m_zone_pattern(R"(\?zone\?)"), m_project_pattern(R"(\?project\?)"),
m_base_folder_depends_on_zone(false), m_base_folder_depends_on_project(false),
m_out_folder_depends_on_zone(false), m_out_folder_depends_on_project(false),
m_verbose(false) m_verbose(false)
{ {
} }
@ -116,7 +116,7 @@ void LinkerArgs::PrintUsage()
usage.AddCommandLineOption(commandLineOption); usage.AddCommandLineOption(commandLineOption);
} }
usage.AddArgument("zoneName"); usage.AddArgument("projectName");
usage.SetVariableArguments(true); usage.SetVariableArguments(true);
usage.Print(); usage.Print();
@ -129,9 +129,9 @@ void LinkerArgs::SetVerbose(const bool isVerbose)
ObjWriting::Configuration.Verbose = isVerbose; ObjWriting::Configuration.Verbose = isVerbose;
} }
std::string LinkerArgs::GetBasePathForZone(const std::string& zoneName) const std::string LinkerArgs::GetBasePathForProject(const std::string& projectName) const
{ {
return std::regex_replace(m_base_folder, m_zone_pattern, zoneName); return std::regex_replace(m_base_folder, m_project_pattern, projectName);
} }
void LinkerArgs::SetDefaultBasePath() void LinkerArgs::SetDefaultBasePath()
@ -148,7 +148,7 @@ void LinkerArgs::SetDefaultBasePath()
} }
} }
std::set<std::string> LinkerArgs::GetZoneIndependentSearchPaths(const std::set<std::string>& set) const std::set<std::string> LinkerArgs::GetProjectIndependentSearchPaths(const std::set<std::string>& set) const
{ {
std::set<std::string> out; std::set<std::string> out;
@ -156,12 +156,12 @@ std::set<std::string> LinkerArgs::GetZoneIndependentSearchPaths(const std::set<s
{ {
if (path.find(PATTERN_GAME) != std::string::npos) if (path.find(PATTERN_GAME) != std::string::npos)
continue; continue;
if (path.find(PATTERN_ZONE) != std::string::npos) if (path.find(PATTERN_PROJECT) != std::string::npos)
continue; continue;
if (path.find(PATTERN_BASE) != std::string::npos) if (path.find(PATTERN_BASE) != std::string::npos)
{ {
if (m_base_folder_depends_on_zone) if (m_base_folder_depends_on_project)
continue; continue;
out.emplace(std::regex_replace(path, m_base_pattern, m_base_folder)); out.emplace(std::regex_replace(path, m_base_pattern, m_base_folder));
@ -175,21 +175,21 @@ std::set<std::string> LinkerArgs::GetZoneIndependentSearchPaths(const std::set<s
return out; return out;
} }
std::set<std::string> LinkerArgs::GetSearchPathsForZone(const std::set<std::string>& set, const std::string& gameName, const std::string& zoneName) const std::set<std::string> LinkerArgs::GetSearchPathsForProject(const std::set<std::string>& set, const std::string& gameName, const std::string& projectName) const
{ {
std::set<std::string> out; std::set<std::string> out;
const auto basePath = GetBasePathForZone(zoneName); const auto basePath = GetBasePathForProject(projectName);
for (const auto& path : set) for (const auto& path : set)
{ {
if (path.find(PATTERN_GAME) == std::string::npos if (path.find(PATTERN_GAME) == std::string::npos
&& path.find(PATTERN_ZONE) == std::string::npos && path.find(PATTERN_PROJECT) == std::string::npos
&& (!m_base_folder_depends_on_zone || path.find(PATTERN_BASE) == std::string::npos)) && (!m_base_folder_depends_on_project || path.find(PATTERN_BASE) == std::string::npos))
{ {
continue; continue;
} }
out.emplace(std::regex_replace(std::regex_replace(std::regex_replace(path, m_zone_pattern, zoneName), m_game_pattern, gameName), m_base_pattern, basePath)); out.emplace(std::regex_replace(std::regex_replace(std::regex_replace(path, m_project_pattern, projectName), m_game_pattern, gameName), m_base_pattern, basePath));
} }
return out; return out;
@ -210,10 +210,10 @@ bool LinkerArgs::ParseArgs(const int argc, const char** argv)
return false; return false;
} }
m_zones_to_build = m_argument_parser.GetArguments(); m_projects_to_build = m_argument_parser.GetArguments();
if (m_zones_to_build.empty()) if (m_projects_to_build.empty())
{ {
// No zones to build specified... // No projects to build specified...
PrintUsage(); PrintUsage();
return false; return false;
} }
@ -226,14 +226,14 @@ bool LinkerArgs::ParseArgs(const int argc, const char** argv)
m_base_folder = m_argument_parser.GetValueForOption(OPTION_BASE_FOLDER); m_base_folder = m_argument_parser.GetValueForOption(OPTION_BASE_FOLDER);
else else
SetDefaultBasePath(); SetDefaultBasePath();
m_base_folder_depends_on_zone = m_base_folder.find(PATTERN_GAME) != std::string::npos || m_base_folder.find(PATTERN_ZONE) != std::string::npos; m_base_folder_depends_on_project = m_base_folder.find(PATTERN_GAME) != std::string::npos || m_base_folder.find(PATTERN_PROJECT) != std::string::npos;
// --output-folder // --output-folder
if (m_argument_parser.IsOptionSpecified(OPTION_OUTPUT_FOLDER)) if (m_argument_parser.IsOptionSpecified(OPTION_OUTPUT_FOLDER))
m_out_folder = m_argument_parser.GetValueForOption(OPTION_OUTPUT_FOLDER); m_out_folder = m_argument_parser.GetValueForOption(OPTION_OUTPUT_FOLDER);
else else
m_out_folder = DEFAULT_OUTPUT_FOLDER; m_out_folder = DEFAULT_OUTPUT_FOLDER;
m_out_folder_depends_on_zone = m_out_folder.find(PATTERN_ZONE) != std::string::npos; m_out_folder_depends_on_project = m_out_folder.find(PATTERN_PROJECT) != std::string::npos;
// --asset-search-path // --asset-search-path
if (m_argument_parser.IsOptionSpecified(OPTION_ASSET_SEARCH_PATH)) if (m_argument_parser.IsOptionSpecified(OPTION_ASSET_SEARCH_PATH))
@ -286,37 +286,37 @@ bool LinkerArgs::ParseArgs(const int argc, const char** argv)
return true; return true;
} }
std::string LinkerArgs::GetOutputFolderPathForZone(const std::string& zoneName) const std::string LinkerArgs::GetOutputFolderPathForProject(const std::string& projectName) const
{ {
return std::regex_replace(std::regex_replace(m_out_folder, m_zone_pattern, zoneName), m_base_pattern, GetBasePathForZone(zoneName)); return std::regex_replace(std::regex_replace(m_out_folder, m_project_pattern, projectName), m_base_pattern, GetBasePathForProject(projectName));
} }
std::set<std::string> LinkerArgs::GetZoneIndependentAssetSearchPaths() const std::set<std::string> LinkerArgs::GetProjectIndependentAssetSearchPaths() const
{ {
return GetZoneIndependentSearchPaths(m_asset_search_paths); return GetProjectIndependentSearchPaths(m_asset_search_paths);
} }
std::set<std::string> LinkerArgs::GetZoneIndependentGdtSearchPaths() const std::set<std::string> LinkerArgs::GetProjectIndependentGdtSearchPaths() const
{ {
return GetZoneIndependentSearchPaths(m_gdt_search_paths); return GetProjectIndependentSearchPaths(m_gdt_search_paths);
} }
std::set<std::string> LinkerArgs::GetZoneIndependentSourceSearchPaths() const std::set<std::string> LinkerArgs::GetProjectIndependentSourceSearchPaths() const
{ {
return GetZoneIndependentSearchPaths(m_source_search_paths); return GetProjectIndependentSearchPaths(m_source_search_paths);
} }
std::set<std::string> LinkerArgs::GetAssetSearchPathsForZone(const std::string& gameName, const std::string& zoneName) const std::set<std::string> LinkerArgs::GetAssetSearchPathsForProject(const std::string& gameName, const std::string& projectName) const
{ {
return GetSearchPathsForZone(m_asset_search_paths, gameName, zoneName); return GetSearchPathsForProject(m_asset_search_paths, gameName, projectName);
} }
std::set<std::string> LinkerArgs::GetGdtSearchPathsForZone(const std::string& gameName, const std::string& zoneName) const std::set<std::string> LinkerArgs::GetGdtSearchPathsForProject(const std::string& gameName, const std::string& projectName) const
{ {
return GetSearchPathsForZone(m_gdt_search_paths, gameName, zoneName); return GetSearchPathsForProject(m_gdt_search_paths, gameName, projectName);
} }
std::set<std::string> LinkerArgs::GetSourceSearchPathsForZone(const std::string& zoneName) const std::set<std::string> LinkerArgs::GetSourceSearchPathsForProject(const std::string& projectName) const
{ {
return GetSearchPathsForZone(m_source_search_paths, "", zoneName); return GetSearchPathsForProject(m_source_search_paths, "", projectName);
} }

View File

@ -12,20 +12,20 @@ class LinkerArgs
public: public:
static constexpr const char* PATTERN_BASE = "?base?"; static constexpr const char* PATTERN_BASE = "?base?";
static constexpr const char* PATTERN_GAME = "?game?"; static constexpr const char* PATTERN_GAME = "?game?";
static constexpr const char* PATTERN_ZONE = "?zone?"; static constexpr const char* PATTERN_PROJECT = "?project?";
static constexpr const char* DEFAULT_BASE_FOLDER = "."; static constexpr const char* DEFAULT_BASE_FOLDER = ".";
static constexpr const char* DEFAULT_BASE_FOLDER_MOD_TOOLS = ".."; static constexpr const char* DEFAULT_BASE_FOLDER_MOD_TOOLS = "..";
static constexpr const char* DEFAULT_OUTPUT_FOLDER = "?base?/zone_out/?zone?"; static constexpr const char* DEFAULT_OUTPUT_FOLDER = "?base?/zone_out/?project?";
static constexpr const char* DEFAULT_ASSET_SEARCH_PATH = "?base?/raw;?base?/raw/?game?;?base?/zone_raw/?zone?"; static constexpr const char* DEFAULT_ASSET_SEARCH_PATH = "?base?/raw;?base?/raw/?game?;?base?/zone_raw/?project?";
static constexpr const char* DEFAULT_GDT_SEARCH_PATH = "?base?/source_data;?base?/zone_raw/?zone?/source_data"; static constexpr const char* DEFAULT_GDT_SEARCH_PATH = "?base?/source_data;?base?/zone_raw/?project?/source_data";
static constexpr const char* DEFAULT_SOURCE_SEARCH_PATH = "?base?/zone_source;?base?/zone_raw/?zone?/zone_source"; static constexpr const char* DEFAULT_SOURCE_SEARCH_PATH = "?base?/zone_source;?base?/zone_raw/?project?/zone_source";
private: private:
ArgumentParser m_argument_parser; ArgumentParser m_argument_parser;
std::regex m_base_pattern; std::regex m_base_pattern;
std::regex m_game_pattern; std::regex m_game_pattern;
std::regex m_zone_pattern; std::regex m_project_pattern;
/** /**
* \brief Prints a command line usage help text for the Linker tool to stdout. * \brief Prints a command line usage help text for the Linker tool to stdout.
@ -34,19 +34,19 @@ private:
void SetVerbose(bool isVerbose); void SetVerbose(bool isVerbose);
_NODISCARD std::string GetBasePathForZone(const std::string& zoneName) const; _NODISCARD std::string GetBasePathForProject(const std::string& projectName) const;
void SetDefaultBasePath(); void SetDefaultBasePath();
_NODISCARD std::set<std::string> GetZoneIndependentSearchPaths(const std::set<std::string>& set) const; _NODISCARD std::set<std::string> GetProjectIndependentSearchPaths(const std::set<std::string>& set) const;
_NODISCARD std::set<std::string> GetSearchPathsForZone(const std::set<std::string>& set, const std::string& gameName, const std::string& zoneName) const; _NODISCARD std::set<std::string> GetSearchPathsForProject(const std::set<std::string>& set, const std::string& gameName, const std::string& projectName) const;
public: public:
std::vector<std::string> m_zones_to_load; std::vector<std::string> m_zones_to_load;
std::vector<std::string> m_zones_to_build; std::vector<std::string> m_projects_to_build;
std::string m_base_folder; std::string m_base_folder;
std::string m_out_folder; std::string m_out_folder;
bool m_base_folder_depends_on_zone; bool m_base_folder_depends_on_project;
bool m_out_folder_depends_on_zone; bool m_out_folder_depends_on_project;
std::set<std::string> m_asset_search_paths; std::set<std::string> m_asset_search_paths;
std::set<std::string> m_gdt_search_paths; std::set<std::string> m_gdt_search_paths;
@ -58,17 +58,17 @@ public:
bool ParseArgs(int argc, const char** argv); bool ParseArgs(int argc, const char** argv);
/** /**
* \brief Converts the output path specified by command line arguments to a path applies for the specified zone. * \brief Converts the output path specified by command line arguments to a path applies for the specified project.
* \param zoneName The name of the zone to resolve the path input for. * \param projectName The name of the project to resolve the path input for.
* \return An output path for the zone based on the user input. * \return An output path for the project based on the user input.
*/ */
_NODISCARD std::string GetOutputFolderPathForZone(const std::string& zoneName) const; _NODISCARD std::string GetOutputFolderPathForProject(const std::string& projectName) const;
_NODISCARD std::set<std::string> GetZoneIndependentAssetSearchPaths() const; _NODISCARD std::set<std::string> GetProjectIndependentAssetSearchPaths() const;
_NODISCARD std::set<std::string> GetZoneIndependentGdtSearchPaths() const; _NODISCARD std::set<std::string> GetProjectIndependentGdtSearchPaths() const;
_NODISCARD std::set<std::string> GetZoneIndependentSourceSearchPaths() const; _NODISCARD std::set<std::string> GetProjectIndependentSourceSearchPaths() const;
_NODISCARD std::set<std::string> GetAssetSearchPathsForZone(const std::string& gameName, const std::string& zoneName) const; _NODISCARD std::set<std::string> GetAssetSearchPathsForProject(const std::string& gameName, const std::string& projectName) const;
_NODISCARD std::set<std::string> GetGdtSearchPathsForZone(const std::string& gameName, const std::string& zoneName) const; _NODISCARD std::set<std::string> GetGdtSearchPathsForProject(const std::string& gameName, const std::string& projectName) const;
_NODISCARD std::set<std::string> GetSourceSearchPathsForZone(const std::string& zoneName) const; _NODISCARD std::set<std::string> GetSourceSearchPathsForProject(const std::string& projectName) const;
}; };

View File

@ -6,9 +6,8 @@ ZoneCreationContext::ZoneCreationContext()
{ {
} }
ZoneCreationContext::ZoneCreationContext(std::string zoneName, ISearchPath* assetSearchPath, ZoneDefinition* definition) ZoneCreationContext::ZoneCreationContext(ISearchPath* assetSearchPath, ZoneDefinition* definition)
: m_zone_name(std::move(zoneName)), : m_asset_search_path(assetSearchPath),
m_asset_search_path(assetSearchPath),
m_definition(definition) m_definition(definition)
{ {
} }

View File

@ -12,7 +12,6 @@
class ZoneCreationContext class ZoneCreationContext
{ {
public: public:
std::string m_zone_name;
std::string m_game_name; std::string m_game_name;
ISearchPath* m_asset_search_path; ISearchPath* m_asset_search_path;
ZoneDefinition* m_definition; ZoneDefinition* m_definition;
@ -20,5 +19,5 @@ public:
std::vector<AssetListEntry> m_ignored_assets; std::vector<AssetListEntry> m_ignored_assets;
ZoneCreationContext(); ZoneCreationContext();
ZoneCreationContext(std::string zoneName, ISearchPath* assetSearchPath, ZoneDefinition* definition); ZoneCreationContext(ISearchPath* assetSearchPath, ZoneDefinition* definition);
}; };

View File

@ -29,6 +29,7 @@ public:
class ZoneDefinition class ZoneDefinition
{ {
public: public:
std::string m_name;
std::vector<std::unique_ptr<ZoneMetaDataEntry>> m_metadata; std::vector<std::unique_ptr<ZoneMetaDataEntry>> m_metadata;
std::unordered_multimap<std::string, ZoneMetaDataEntry*> m_metadata_lookup; std::unordered_multimap<std::string, ZoneMetaDataEntry*> m_metadata_lookup;
std::vector<std::string> m_includes; std::vector<std::string> m_includes;