1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-06-25 06:11:35 +00:00

Add rudimentary support for ESM::RefId in UniversalId

Ideally std::string support should be removed but this may affect too much code.
This commit is contained in:
elsid 2023-05-22 02:17:52 +02:00
parent 4cd5efc6ee
commit ceab7557f3
No known key found for this signature in database
GPG key ID: 4DE04C198CBA7625
3 changed files with 40 additions and 10 deletions

View file

@ -184,7 +184,7 @@ namespace
{ {
std::ostream& mStream; std::ostream& mStream;
void operator()(std::monostate) const {} void operator()(std::monostate /*value*/) const {}
template <class T> template <class T>
void operator()(const T& value) const void operator()(const T& value) const
@ -192,6 +192,19 @@ namespace
mStream << ": " << value; mStream << ": " << value;
} }
}; };
struct GetTypeData
{
const TypeData* operator()(std::monostate /*value*/) const { return sNoArg; }
const TypeData* operator()(int /*value*/) const { return sIndexArg; }
template <class T>
const TypeData* operator()(const T& /*value*/) const
{
return sIdArg;
}
};
} }
CSMWorld::UniversalId::UniversalId(const std::string& universalId) CSMWorld::UniversalId::UniversalId(const std::string& universalId)
@ -287,9 +300,17 @@ CSMWorld::UniversalId::UniversalId(Type type, const std::string& id)
throw std::logic_error("invalid ID argument UniversalId type: " + std::to_string(type)); throw std::logic_error("invalid ID argument UniversalId type: " + std::to_string(type));
} }
CSMWorld::UniversalId::UniversalId(Type type, const ESM::RefId& id) CSMWorld::UniversalId::UniversalId(Type type, ESM::RefId id)
: UniversalId(type, id.getRefIdString()) : mType(type)
, mValue(id)
{ {
for (int i = 0; sIdArg[i].mName; ++i)
if (type == sIdArg[i].mType)
{
mClass = sIdArg[i].mClass;
return;
}
throw std::logic_error("invalid RefId argument UniversalId type: " + std::to_string(type));
} }
CSMWorld::UniversalId::UniversalId(Type type, int index) CSMWorld::UniversalId::UniversalId(Type type, int index)
@ -339,8 +360,7 @@ int CSMWorld::UniversalId::getIndex() const
std::string CSMWorld::UniversalId::getTypeName() const std::string CSMWorld::UniversalId::getTypeName() const
{ {
const TypeData* typeData const TypeData* typeData = std::visit(GetTypeData{}, mValue);
= getArgumentType() == ArgumentType_None ? sNoArg : (getArgumentType() == ArgumentType_Id ? sIdArg : sIndexArg);
for (int i = 0; typeData[i].mName; ++i) for (int i = 0; typeData[i].mName; ++i)
if (typeData[i].mType == mType) if (typeData[i].mType == mType)
@ -362,8 +382,7 @@ std::string CSMWorld::UniversalId::toString() const
std::string CSMWorld::UniversalId::getIcon() const std::string CSMWorld::UniversalId::getIcon() const
{ {
const TypeData* typeData const TypeData* typeData = std::visit(GetTypeData{}, mValue);
= getArgumentType() == ArgumentType_None ? sNoArg : (getArgumentType() == ArgumentType_Id ? sIdArg : sIndexArg);
for (int i = 0; typeData[i].mName; ++i) for (int i = 0; typeData[i].mName; ++i)
if (typeData[i].mType == mType) if (typeData[i].mType == mType)

View file

@ -33,6 +33,7 @@ namespace CSMWorld
ArgumentType_None, ArgumentType_None,
ArgumentType_Id, ArgumentType_Id,
ArgumentType_Index, ArgumentType_Index,
ArgumentType_RefId,
}; };
/// \note A record list type must always be immediately followed by the matching /// \note A record list type must always be immediately followed by the matching
@ -152,7 +153,7 @@ namespace CSMWorld
UniversalId(Type type, const std::string& id); UniversalId(Type type, const std::string& id);
///< Using a type for a non-ID-argument UniversalId will throw an exception. ///< Using a type for a non-ID-argument UniversalId will throw an exception.
UniversalId(Type type, const ESM::RefId& id); UniversalId(Type type, ESM::RefId id);
UniversalId(Type type, int index); UniversalId(Type type, int index);
///< Using a type for a non-index-argument UniversalId will throw an exception. ///< Using a type for a non-index-argument UniversalId will throw an exception.
@ -188,7 +189,7 @@ namespace CSMWorld
private: private:
Class mClass; Class mClass;
Type mType; Type mType;
std::variant<std::monostate, std::string, int> mValue; std::variant<std::monostate, std::string, int, ESM::RefId> mValue;
friend bool operator==(const UniversalId& left, const UniversalId& right); friend bool operator==(const UniversalId& left, const UniversalId& right);

View file

@ -73,6 +73,13 @@ namespace CSMWorld
std::string mIcon; std::string mIcon;
}; };
std::ostream& operator<<(std::ostream& stream, const Params& value)
{
return stream << ".mType = " << value.mType << " .mClass = " << value.mClass
<< " .mArgumentType = " << value.mArgumentType << " .mTypeName = " << value.mTypeName
<< " .mString = " << value.mString << " .mIcon = " << value.mIcon;
}
struct CSMWorldUniversalIdValidPerTypeTest : TestWithParam<Params> struct CSMWorldUniversalIdValidPerTypeTest : TestWithParam<Params>
{ {
}; };
@ -152,8 +159,11 @@ namespace CSMWorld
UniversalId::ArgumentType_Id, "Instance", "Instance: f", ":./instance.png" }, UniversalId::ArgumentType_Id, "Instance", "Instance: f", ":./instance.png" },
Params{ UniversalId(UniversalId::Type_Reference, ESM::RefId::stringRefId("g")), UniversalId::Type_Reference, Params{ UniversalId(UniversalId::Type_Reference, ESM::RefId::stringRefId("g")), UniversalId::Type_Reference,
UniversalId::Class_SubRecord, UniversalId::ArgumentType_Id, "Instance", "Instance: g", UniversalId::Class_SubRecord, UniversalId::ArgumentType_RefId, "Instance", "Instance: \"g\"",
":./instance.png" }, ":./instance.png" },
Params{ UniversalId(UniversalId::Type_Reference, ESM::RefId::index(ESM::REC_SKIL, 42)),
UniversalId::Type_Reference, UniversalId::Class_SubRecord, UniversalId::ArgumentType_RefId, "Instance",
"Instance: Index:SKIL:0x2a", ":./instance.png" },
}; };
INSTANTIATE_TEST_SUITE_P(ValidParams, CSMWorldUniversalIdValidPerTypeTest, ValuesIn(validParams)); INSTANTIATE_TEST_SUITE_P(ValidParams, CSMWorldUniversalIdValidPerTypeTest, ValuesIn(validParams));