diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index 29d014afd1..6f39a3e602 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -196,28 +196,6 @@ namespace MWWorld { }; - struct RecNameIntChar - { - char name[6]; - RecNameIntChar(ESM::RecNameInts recName) - { - unsigned int FourCC = recName & ~ESM::sEsm4RecnameFlag; // Removes the flag - name[0] = FourCC & 0xFF; - name[1] = (FourCC >> 8) & 0xFF; - name[2] = (FourCC >> 16) & 0xFF; - name[3] = (FourCC >> 24) & 0xFF; - if (ESM::isESM4Rec(recName)) - { - name[4] = '4'; - name[5] = '\0'; - } - else - { - name[4] = '\0'; - } - } - }; - template static bool typedReadRecordESM4(ESM4::Reader& reader, Store& store) { @@ -241,39 +219,6 @@ namespace MWWorld return false; } - template - static unsigned int hasSameRecordId(const Store& store, ESM::RecNameInts RecName) - { - if constexpr (HasRecordId::value) - { - return T::sRecordId == RecName ? 1 : 0; - } - else - { - return 0; - } - } - - template - static void testRecNameIntCount(const Store& store, const ESMStore::StoreTuple& stores) - { - if constexpr (HasRecordId::value) - { - const unsigned int recordIdCount - = std::apply([](auto&&... x) { return (hasSameRecordId(x, T::sRecordId) + ...); }, stores); - if (recordIdCount != 1) - { - throw std::runtime_error( - "The same RecNameInt is used twice ESM::REC_" + std::string(RecNameIntChar(T::sRecordId).name)); - } - } - } - - static void testAllRecNameIntUnique(const ESMStore::StoreTuple& stores) - { - std::apply([&stores](auto&&... x) { (testRecNameIntCount(x, stores), ...); }, stores); - } - static bool readRecord(ESM4::Reader& reader, ESMStore& store) { return std::apply([&reader](auto&... x) { return (ESMStoreImp::typedReadRecordESM4(reader, x) || ...); }, @@ -305,7 +250,6 @@ namespace MWWorld { mStoreImp = std::make_unique(); std::apply([this](auto&... x) { (ESMStoreImp::assignStoreToIndex(*this, x), ...); }, mStoreImp->mStores); - ESMStoreImp::testAllRecNameIntUnique(mStoreImp->mStores); mDynamicCount = 0; getWritable().setCells(getWritable()); } diff --git a/apps/openmw/mwworld/esmstore.hpp b/apps/openmw/mwworld/esmstore.hpp index 1ed66a1c71..61083b3ec0 100644 --- a/apps/openmw/mwworld/esmstore.hpp +++ b/apps/openmw/mwworld/esmstore.hpp @@ -86,7 +86,7 @@ namespace MWWorld class ESMStore { friend struct ESMStoreImp; // This allows StoreImp to extend esmstore without beeing included everywhere - + public: using StoreTuple = std::tuple, Store, Store, Store, Store, Store, Store, Store, Store, Store, Store, Store, Store, @@ -107,6 +107,7 @@ namespace MWWorld Store, Store, Store>; + private: template static constexpr std::size_t getTypeIndex() { diff --git a/apps/openmw_test_suite/mwworld/test_store.cpp b/apps/openmw_test_suite/mwworld/test_store.cpp index f869f0e448..b69678c4d6 100644 --- a/apps/openmw_test_suite/mwworld/test_store.cpp +++ b/apps/openmw_test_suite/mwworld/test_store.cpp @@ -8,6 +8,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include #include #include @@ -289,6 +295,77 @@ TEST_F(StoreTest, delete_test) ASSERT_TRUE(mEsmStore.get().getSize() == 1); } +template > +struct HasRecordId : std::false_type +{ +}; + +template +struct HasRecordId> : std::true_type +{ +}; + +struct RecNameIntChar +{ + char name[6]; + RecNameIntChar(ESM::RecNameInts recName) + { + unsigned int FourCC = recName & ~ESM::sEsm4RecnameFlag; // Removes the flag + name[0] = FourCC & 0xFF; + name[1] = (FourCC >> 8) & 0xFF; + name[2] = (FourCC >> 16) & 0xFF; + name[3] = (FourCC >> 24) & 0xFF; + if (ESM::isESM4Rec(recName)) + { + name[4] = '4'; + name[5] = '\0'; + } + else + { + name[4] = '\0'; + } + } +}; + +template +static unsigned int hasSameRecordId(const MWWorld::Store& store, ESM::RecNameInts RecName) +{ + if constexpr (HasRecordId::value) + { + return T::sRecordId == RecName ? 1 : 0; + } + else + { + return 0; + } +} + +template +static void testRecNameIntCount(const MWWorld::Store& store, const MWWorld::ESMStore::StoreTuple& stores) +{ + if constexpr (HasRecordId::value) + { + const unsigned int recordIdCount + = std::apply([](auto&&... x) { return (hasSameRecordId(x, T::sRecordId) + ...); }, stores); + if (recordIdCount != 1) + { + std::cout << "The same RecNameInt is used twice ESM::REC_" + std::string(RecNameIntChar(T::sRecordId).name) + << std::endl; + } + ASSERT_TRUE(recordIdCount == 1); + } +} + +static void testAllRecNameIntUnique(const MWWorld::ESMStore::StoreTuple& stores) +{ + std::apply([&stores](auto&&... x) { (testRecNameIntCount(x, stores), ...); }, stores); +} + +TEST_F(StoreTest, recordId_Unique) // Test that each type has a unique recordId +{ + testAllRecNameIntUnique(MWWorld::ESMStore::StoreTuple()); +} + /// Tests overwriting of records. TEST_F(StoreTest, overwrite_test) {