Support generated RefId as std::uint64_t

depth-refraction
elsid 2 years ago
parent 0992624c8b
commit 86293af084
No known key found for this signature in database
GPG Key ID: 4DE04C198CBA7625

@ -729,7 +729,7 @@ namespace MWWorld
{
return npcs.insert(npc);
}
const ESM::RefId id = ESM::RefId::stringRefId("$dynamic" + std::to_string(mDynamicCount++));
const ESM::RefId id = ESM::RefId::generated(mDynamicCount++);
if (npcs.search(id) != nullptr)
throw std::runtime_error("Try to override existing record: " + id.toDebugString());
ESM::NPC record = npc;

@ -185,7 +185,7 @@ namespace MWWorld
template <class T>
const T* insert(const T& x)
{
const ESM::RefId id = ESM::RefId::stringRefId("$dynamic" + std::to_string(mDynamicCount++));
const ESM::RefId id = ESM::RefId::generated(mDynamicCount++);
Store<T>& store = getWritable<T>();
if (store.search(id) != nullptr)

@ -212,6 +212,7 @@ namespace ESM
{ RefId::stringRefId("foo"), "foo" },
{ RefId::stringRefId(std::string({ 'a', 0, -1, '\n', '\t' })), { 'a', 0, -1, '\n', '\t' } },
{ RefId::formIdRefId(42), "42" },
{ RefId::generated(42), "42" },
};
INSTANTIATE_TEST_SUITE_P(ESMRefIdToString, ESMRefIdToStringTest, ValuesIn(toStringParams));
@ -241,6 +242,7 @@ namespace ESM
{ RefId::stringRefId("foo"), "String{foo}" },
{ RefId::stringRefId(std::string({ 'a', 0, -1, '\n', '\t' })), "String{a\\x0\\xFF\\xA\\x9}" },
{ RefId::formIdRefId(42), "FormId{42}" },
{ RefId::generated(42), "Generated{42}" },
};
INSTANTIATE_TEST_SUITE_P(ESMRefIdToDebugString, ESMRefIdToDebugStringTest, ValuesIn(toDebugStringParams));

@ -88,7 +88,8 @@ add_component_dir (to_utf8
add_component_dir(esm attr common defs esmcommon records util luascripts format refid esmbridge
formidrefid
stringrefid
)
generatedrefid
)
add_component_dir(fx pass technique lexer widgets stateupdater)

@ -0,0 +1,24 @@
#include "generatedrefid.hpp"
#include <ostream>
#include <sstream>
namespace ESM
{
std::string GeneratedRefId::toString() const
{
return std::to_string(mValue);
}
std::string GeneratedRefId::toDebugString() const
{
std::ostringstream stream;
stream << *this;
return stream.str();
}
std::ostream& operator<<(std::ostream& stream, GeneratedRefId value)
{
return stream << "Generated{" << value.mValue << '}';
}
}

@ -0,0 +1,49 @@
#ifndef OPENMW_COMPONENTS_ESM_GENERATEDREFID_HPP
#define OPENMW_COMPONENTS_ESM_GENERATEDREFID_HPP
#include <cstdint>
#include <functional>
#include <iosfwd>
namespace ESM
{
class GeneratedRefId
{
public:
constexpr explicit GeneratedRefId(std::uint64_t value) noexcept
: mValue(value)
{
}
constexpr std::uint64_t getValue() const { return mValue; }
std::string toString() const;
std::string toDebugString() const;
constexpr bool operator==(GeneratedRefId rhs) const noexcept { return mValue == rhs.mValue; }
constexpr bool operator<(GeneratedRefId rhs) const noexcept { return mValue < rhs.mValue; }
friend std::ostream& operator<<(std::ostream& stream, GeneratedRefId value);
friend struct std::hash<GeneratedRefId>;
private:
std::uint64_t mValue;
};
}
namespace std
{
template <>
struct hash<ESM::GeneratedRefId>
{
std::size_t operator()(ESM::GeneratedRefId value) const noexcept
{
return std::hash<std::uint64_t>{}(value.mValue);
}
};
}
#endif

@ -11,6 +11,7 @@
#include <components/misc/notnullptr.hpp>
#include "formidrefid.hpp"
#include "generatedrefid.hpp"
#include "stringrefid.hpp"
namespace ESM
@ -34,6 +35,7 @@ namespace ESM
SizedString = 1,
UnsizedString = 2,
FormId = 3,
Generated = 4,
};
// RefId is used to represent an Id that identifies an ESM record. These Ids can then be used in
@ -50,6 +52,10 @@ namespace ESM
// Constructs RefId from ESM4 FormId storing the value in-place.
static RefId formIdRefId(ESM4::FormId value) noexcept { return RefId(FormIdRefId(value)); }
// Constructs RefId from uint64 storing the value in-place. Should be used for generated records where id is a
// global counter.
static RefId generated(std::uint64_t value) { return RefId(GeneratedRefId{ value }); }
constexpr RefId() = default;
constexpr RefId(EmptyRefId value) noexcept
@ -67,6 +73,11 @@ namespace ESM
{
}
constexpr RefId(GeneratedRefId value) noexcept
: mValue(value)
{
}
// Returns a reference to the value of StringRefId if it's the underlying value or throws an exception.
const std::string& getRefIdString() const;
@ -109,7 +120,7 @@ namespace ESM
friend struct std::hash<ESM::RefId>;
private:
std::variant<EmptyRefId, StringRefId, FormIdRefId> mValue{ EmptyRefId{} };
std::variant<EmptyRefId, StringRefId, FormIdRefId, GeneratedRefId> mValue{ EmptyRefId{} };
};
}

@ -457,6 +457,12 @@ namespace ESM
getT(formId);
return RefId::formIdRefId(formId);
}
case RefIdType::Generated:
{
std::uint64_t generated{};
getExact(&generated, sizeof(std::uint64_t));
return RefId::generated(generated);
}
}
fail("Unsupported RefIdType: " + std::to_string(static_cast<unsigned>(refIdType)));

@ -47,6 +47,12 @@ namespace ESM
mWriter.writeT(RefIdType::FormId);
mWriter.writeT(v.getValue());
}
void operator()(GeneratedRefId v) const
{
mWriter.writeT(RefIdType::Generated);
mWriter.writeT(v.getValue());
}
};
}

Loading…
Cancel
Save