Skip to content

Commit

Permalink
LoadClassAttributes: Mandate field order
Browse files Browse the repository at this point in the history
Makes parsing simpler.

Additional columns and rows are ignored.
  • Loading branch information
glebm committed Sep 16, 2023
1 parent 29d904c commit e49c604
Showing 1 changed file with 38 additions and 50 deletions.
88 changes: 38 additions & 50 deletions Source/playerdat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
#include <bitset>
#include <charconv>
#include <cstdint>
#include <unordered_map>
#include <variant>
#include <vector>

#include <expected.hpp>
Expand Down Expand Up @@ -169,65 +167,55 @@ void LoadClassAttributes(std::string_view classPath, ClassAttributes &out)
DataFile::reportFatalError(result.error(), filename);
}

struct KeyInfo {
std::variant<uint8_t *, int16_t *> out;
bool found = false;
};
std::unordered_map<std::string_view, KeyInfo> keyToField {
{ "baseStr", KeyInfo { &out.baseStr } },
{ "baseMag", KeyInfo { &out.baseMag } },
{ "baseDex", KeyInfo { &out.baseDex } },
{ "baseVit", KeyInfo { &out.baseVit } },
{ "maxStr", KeyInfo { &out.maxStr } },
{ "maxMag", KeyInfo { &out.maxMag } },
{ "maxDex", KeyInfo { &out.maxDex } },
{ "maxVit", KeyInfo { &out.maxVit } },
{ "blockBonus", KeyInfo { &out.blockBonus } },
{ "adjLife", KeyInfo { &out.adjLife } },
{ "adjMana", KeyInfo { &out.adjMana } },
{ "lvlLife", KeyInfo { &out.lvlLife } },
{ "lvlMana", KeyInfo { &out.lvlMana } },
{ "chrLife", KeyInfo { &out.chrLife } },
{ "chrMana", KeyInfo { &out.chrMana } },
{ "itmLife", KeyInfo { &out.itmLife } },
{ "itmMana", KeyInfo { &out.itmMana } },
};
for (DataFileRecord record : dataFile) {
auto recordIt = dataFile.begin();
const auto recordEnd = dataFile.end();

const auto getValueField = [&](std::string_view expectedKey) {
if (recordIt == recordEnd) {
app_fatal(fmt::format("Missing field {} in {}", expectedKey, filename));
}
DataFileRecord record = *recordIt;
FieldIterator fieldIt = record.begin();
const FieldIterator endField = record.end();

const std::string_view key = (*fieldIt).value();
if (key != expectedKey) {
app_fatal(fmt::format("Unexpected field in {}: got {}, expected {}", filename, key, expectedKey));
}

++fieldIt;
if (fieldIt == endField) {
DataFile::reportFatalError(DataFile::Error::NotEnoughColumns, filename);
}
DataFileField valueField = *fieldIt;
return *fieldIt;
};

auto mappingIt = keyToField.find(key);
if (mappingIt == keyToField.end()) {
app_fatal(fmt::format("Unknown field {} in {}", key, filename));
const auto readRecord = [&](std::string_view expectedKey, auto &outValue) {
DataFileField valueField = getValueField(expectedKey);
const std::errc parseIntResult = valueField.parseInt(outValue);
if (parseIntResult != std::errc()) {
DataFile::reportFatalFieldError(parseIntResult, filename, "Value", valueField);
}
KeyInfo &keyInfo = mappingIt->second;
if (keyInfo.found) {
app_fatal(fmt::format("Duplicate field {} in {}", key, filename));
}
std::visit([&](auto *outField) {
auto parseIntResult = valueField.parseInt(*outField);
if (parseIntResult != std::errc()) {
DataFile::reportFatalFieldError(parseIntResult, filename, "Value", valueField);
}
},
keyInfo.out);
keyInfo.found = true;

++fieldIt;
}
++recordIt;
};

for (const auto &[key, keyInfo] : keyToField) {
if (!keyInfo.found) {
app_fatal(fmt::format("Missing field {} in {}", key, filename));
}
}
readRecord("baseStr", out.baseStr);
readRecord("baseMag", out.baseMag);
readRecord("baseDex", out.baseDex);
readRecord("baseVit", out.baseVit);
readRecord("maxStr", out.maxStr);
readRecord("maxMag", out.maxMag);
readRecord("maxDex", out.maxDex);
readRecord("maxVit", out.maxVit);
readRecord("blockBonus", out.blockBonus);
readRecord("adjLife", out.adjLife);
readRecord("adjMana", out.adjMana);
readRecord("lvlLife", out.lvlLife);
readRecord("lvlMana", out.lvlMana);
readRecord("chrLife", out.chrLife);
readRecord("chrMana", out.chrMana);
readRecord("itmLife", out.itmLife);
readRecord("itmMana", out.itmMana);
}

std::vector<ClassAttributes> ClassAttributesPerClass;
Expand Down

0 comments on commit e49c604

Please sign in to comment.