Preserve zone definition meta data order

This commit is contained in:
Jan 2021-03-21 10:19:27 +01:00
parent 1d33cf2adf
commit c4aec3e147
5 changed files with 52 additions and 23 deletions

View File

@ -62,23 +62,23 @@ void ZoneCreator::HandleMetadata(Zone* zone, ZoneCreationContext& context) const
{ {
std::vector<KeyValuePair> kvpList; std::vector<KeyValuePair> kvpList;
for (const auto& [metaKey, metaValue] : context.m_definition->m_metadata) for (const auto& metaData : context.m_definition->m_metadata)
{ {
if (metaKey.rfind("level.", 0) == 0) if (metaData->m_key.rfind("level.", 0) == 0)
{ {
const std::string strValue = metaKey.substr(std::char_traits<char>::length("level.")); const std::string strValue = metaData->m_key.substr(std::char_traits<char>::length("level."));
if(strValue.empty()) if (strValue.empty())
continue; continue;
int keyHash; int keyHash;
if(strValue[0] == '@') if (strValue[0] == '@')
{ {
char* endPtr; char* endPtr;
keyHash = strtol(&strValue[1], &endPtr, 16); keyHash = strtol(&strValue[1], &endPtr, 16);
if(endPtr != &strValue[strValue.size()]) if (endPtr != &strValue[strValue.size()])
{ {
std::cout << "Could not parse metadata key \"" << metaKey << "\" as hash" << std::endl; std::cout << "Could not parse metadata key \"" << metaData->m_key << "\" as hash" << std::endl;
continue; continue;
} }
} }
@ -87,25 +87,24 @@ void ZoneCreator::HandleMetadata(Zone* zone, ZoneCreationContext& context) const
keyHash = CommonT6::Com_HashKey(strValue.c_str(), 64); keyHash = CommonT6::Com_HashKey(strValue.c_str(), 64);
} }
KeyValuePair kvp KeyValuePair kvp
{ {
keyHash, keyHash,
CommonT6::Com_HashKey(zone->m_name.c_str(), 64), CommonT6::Com_HashKey(zone->m_name.c_str(), 64),
zone->GetMemory()->Dup(metaValue.c_str()) zone->GetMemory()->Dup(metaData->m_value.c_str())
}; };
kvpList.push_back(kvp); kvpList.push_back(kvp);
} }
} }
if(!kvpList.empty()) if (!kvpList.empty())
{ {
auto* kvps = zone->GetMemory()->Create<KeyValuePairs>(); auto* kvps = zone->GetMemory()->Create<KeyValuePairs>();
kvps->name = zone->GetMemory()->Dup(zone->m_name.c_str()); kvps->name = zone->GetMemory()->Dup(zone->m_name.c_str());
kvps->numVariables = kvpList.size(); kvps->numVariables = kvpList.size();
kvps->keyValuePairs = static_cast<KeyValuePair*>(zone->GetMemory()->Alloc(sizeof(KeyValuePair) * kvpList.size())); kvps->keyValuePairs = static_cast<KeyValuePair*>(zone->GetMemory()->Alloc(sizeof(KeyValuePair) * kvpList.size()));
for(auto i = 0u; i < kvpList.size(); i++) for (auto i = 0u; i < kvpList.size(); i++)
kvps->keyValuePairs[i] = kvpList[i]; kvps->keyValuePairs[i] = kvpList[i];
zone->m_pools->AddAsset(ASSET_TYPE_KEYVALUEPAIRS, zone->m_name, kvps, std::vector<XAssetInfoGeneric*>(), std::vector<scr_string_t>()); zone->m_pools->AddAsset(ASSET_TYPE_KEYVALUEPAIRS, zone->m_name, kvps, std::vector<XAssetInfoGeneric*>(), std::vector<scr_string_t>());

View File

@ -362,17 +362,17 @@ class Linker::Impl
static bool GetGameNameFromZoneDefinition(std::string& gameName, const std::string& zoneName, const ZoneDefinition& zoneDefinition) static bool GetGameNameFromZoneDefinition(std::string& gameName, const std::string& zoneName, const ZoneDefinition& zoneDefinition)
{ {
auto firstGameEntry = true; auto firstGameEntry = true;
const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata.equal_range(METADATA_GAME); const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata_lookup.equal_range(METADATA_GAME);
for (auto i = rangeBegin; i != rangeEnd; ++i) for (auto i = rangeBegin; i != rangeEnd; ++i)
{ {
if (firstGameEntry) if (firstGameEntry)
{ {
gameName = i->second; gameName = i->second->m_value;
firstGameEntry = false; firstGameEntry = false;
} }
else else
{ {
if (gameName != i->second) 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 zone \"" << zoneName << "\": " << gameName << " != " << i->second << std::endl;
return false; return false;
@ -391,10 +391,10 @@ class Linker::Impl
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 std::string& zoneName, const ZoneDefinition& zoneDefinition, ISearchPath* gdtSearchPath)
{ {
const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata.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)
{ {
const auto gdtFile = gdtSearchPath->Open(i->second + ".gdt"); const auto gdtFile = gdtSearchPath->Open(i->second->m_value + ".gdt");
if (!gdtFile.IsOpen()) if (!gdtFile.IsOpen())
{ {
std::cout << "Failed to open file for gdt \"" << i->second << "\"" << std::endl; std::cout << "Failed to open file for gdt \"" << i->second << "\"" << std::endl;

View File

@ -16,5 +16,5 @@ SequenceZoneDefinitionMetaData::SequenceZoneDefinitionMetaData()
void SequenceZoneDefinitionMetaData::ProcessMatch(ZoneDefinition* state, SequenceResult<ZoneDefinitionParserValue>& result) const void SequenceZoneDefinitionMetaData::ProcessMatch(ZoneDefinition* state, SequenceResult<ZoneDefinitionParserValue>& result) const
{ {
state->m_metadata.insert(std::make_pair(result.NextCapture(CAPTURE_KEY).FieldValue(), result.NextCapture(CAPTURE_VALUE).FieldValue())); state->AddMetaData(result.NextCapture(CAPTURE_KEY).FieldValue(), result.NextCapture(CAPTURE_VALUE).FieldValue());
} }

View File

@ -5,26 +5,43 @@ ZoneDefinitionEntry::ZoneDefinitionEntry()
{ {
} }
ZoneDefinitionEntry::ZoneDefinitionEntry(std::string type, std::string name, bool isReference) ZoneDefinitionEntry::ZoneDefinitionEntry(std::string type, std::string name, const bool isReference)
: m_asset_type(std::move(type)), : m_asset_type(std::move(type)),
m_asset_name(std::move(name)), m_asset_name(std::move(name)),
m_is_reference(isReference) m_is_reference(isReference)
{ {
} }
ZoneMetaDataEntry::ZoneMetaDataEntry()
= default;
ZoneMetaDataEntry::ZoneMetaDataEntry(std::string key, std::string value)
: m_key(std::move(key)),
m_value(std::move(value))
{
}
void ZoneDefinition::AddMetaData(std::string key, std::string value)
{
auto metaData = std::make_unique<ZoneMetaDataEntry>(std::move(key), std::move(value));
auto* metaDataPtr = metaData.get();
m_metadata.emplace_back(std::move(metaData));
m_metadata_lookup.emplace(std::make_pair(metaDataPtr->m_key, metaDataPtr));
}
void ZoneDefinition::Include(ZoneDefinition& definitionToInclude) void ZoneDefinition::Include(ZoneDefinition& definitionToInclude)
{ {
for(const auto& [key, value] : definitionToInclude.m_metadata) for (const auto& metaData : definitionToInclude.m_metadata)
{ {
m_metadata.emplace(std::make_pair(key, value)); AddMetaData(metaData->m_key, metaData->m_value);
} }
for(const auto& ignore : definitionToInclude.m_ignores) for (const auto& ignore : definitionToInclude.m_ignores)
{ {
m_ignores.emplace_back(ignore); m_ignores.emplace_back(ignore);
} }
for(const auto& asset : definitionToInclude.m_assets) for (const auto& asset : definitionToInclude.m_assets)
{ {
m_assets.emplace_back(asset); m_assets.emplace_back(asset);
} }

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <memory>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
@ -14,13 +15,25 @@ public:
ZoneDefinitionEntry(std::string type, std::string name, bool isReference); ZoneDefinitionEntry(std::string type, std::string name, bool isReference);
}; };
class ZoneMetaDataEntry
{
public:
std::string m_key;
std::string m_value;
ZoneMetaDataEntry();
ZoneMetaDataEntry(std::string key, std::string value);
};
class ZoneDefinition class ZoneDefinition
{ {
public: public:
std::unordered_multimap<std::string, std::string> m_metadata; std::vector<std::unique_ptr<ZoneMetaDataEntry>> m_metadata;
std::unordered_multimap<std::string, ZoneMetaDataEntry*> m_metadata_lookup;
std::vector<std::string> m_includes; std::vector<std::string> m_includes;
std::vector<std::string> m_ignores; std::vector<std::string> m_ignores;
std::vector<ZoneDefinitionEntry> m_assets; std::vector<ZoneDefinitionEntry> m_assets;
void AddMetaData(std::string key, std::string value);
void Include(ZoneDefinition& definitionToInclude); void Include(ZoneDefinition& definitionToInclude);
}; };