From 78ba3f91f3e60eb4ff61425fec4f1a1c45e3d091 Mon Sep 17 00:00:00 2001 From: "florent.teppe" Date: Sun, 24 Jul 2022 12:37:27 +0200 Subject: [PATCH] Binds at compile time esm struct and RecNameInts to automatically populate mESM3RecordToStore fewer possible mistakes now, one macro takes all the information to create all the stores and maps from RecName to Store --- apps/openmw/mwworld/esmstore.cpp | 162 +++++++++++++------------------ 1 file changed, 70 insertions(+), 92 deletions(-) diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index 0182b103d5..9bc9775732 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -136,58 +136,65 @@ struct StoreIndexToRecordType { typedef void recordType; }; +template +struct RecordTypeToRecName +{ + static const ESM::RecNameInts sRecName; +}; + static int sRecordTypeCounter = 0; -#define OPENMW_ESM_ADD_STORE_TYPE(__Type, __ID_NUM) template<> const int MWWorld::SRecordType<__Type>::sStoreIndex = sRecordTypeCounter ++; \ -template<> struct StoreIndexToRecordType<__ID_NUM > {typedef __Type recordType;} +#define OPENMW_ESM_ADD_STORE_TYPE(__Type, __REC_NAME,__ID_NUM) template<> const int MWWorld::SRecordType<__Type>::sStoreIndex = sRecordTypeCounter ++; \ +template<> struct StoreIndexToRecordType<__ID_NUM > {typedef __Type recordType;}; \ +template<> const ESM::RecNameInts RecordTypeToRecName<__Type>::sRecName = __REC_NAME -OPENMW_ESM_ADD_STORE_TYPE(ESM::Activator,0); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Potion,1); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Apparatus,2); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Armor,3); -OPENMW_ESM_ADD_STORE_TYPE(ESM::BodyPart,4); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Book,5); -OPENMW_ESM_ADD_STORE_TYPE(ESM::BirthSign,6); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Class,7); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Clothing,8); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Container,9); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Creature,10); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Dialogue,11); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Door,12); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Enchantment,13); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Faction,14); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Global,15); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Ingredient,16); -OPENMW_ESM_ADD_STORE_TYPE(ESM::CreatureLevList,17); -OPENMW_ESM_ADD_STORE_TYPE(ESM::ItemLevList,18); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Light,19); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Lockpick,20); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Miscellaneous,21); -OPENMW_ESM_ADD_STORE_TYPE(ESM::NPC,22); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Probe,23); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Race,24); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Region,25); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Repair,26); -OPENMW_ESM_ADD_STORE_TYPE(ESM::SoundGenerator,27); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Sound,28); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Spell,29); -OPENMW_ESM_ADD_STORE_TYPE(ESM::StartScript,30); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Static,31); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Weapon,32); -OPENMW_ESM_ADD_STORE_TYPE(ESM::GameSetting,33); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Script,34); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Activator,ESM::REC_ACTI,0); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Potion,ESM::REC_ALCH,1); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Apparatus,ESM::REC_APPA,2); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Armor, ESM::REC_ARMO , 3); +OPENMW_ESM_ADD_STORE_TYPE(ESM::BodyPart, ESM::REC_BODY , 4); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Book, ESM::REC_BOOK , 5); +OPENMW_ESM_ADD_STORE_TYPE(ESM::BirthSign, ESM::REC_BSGN , 6); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Class, ESM::REC_CLAS , 7); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Clothing, ESM::REC_CLOT , 8); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Container, ESM::REC_CONT , 9); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Creature, ESM::REC_CREA , 10); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Dialogue, ESM::REC_DIAL , 11); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Door, ESM::REC_DOOR , 12); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Enchantment, ESM::REC_ENCH , 13); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Faction, ESM::REC_FACT , 14); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Global, ESM::REC_GLOB , 15); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Ingredient, ESM::REC_INGR , 16); +OPENMW_ESM_ADD_STORE_TYPE(ESM::CreatureLevList, ESM::REC_LEVC , 17); +OPENMW_ESM_ADD_STORE_TYPE(ESM::ItemLevList, ESM::REC_LEVI , 18); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Light, ESM::REC_LIGH , 19); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Lockpick, ESM::REC_LOCK , 20); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Miscellaneous, ESM::REC_MISC , 21); +OPENMW_ESM_ADD_STORE_TYPE(ESM::NPC, ESM::REC_NPC_ , 22); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Probe, ESM::REC_PROB , 23); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Race, ESM::REC_RACE , 24); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Region, ESM::REC_REGN , 25); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Repair, ESM::REC_REPA , 26); +OPENMW_ESM_ADD_STORE_TYPE(ESM::SoundGenerator, ESM::REC_SNDG , 27); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Sound, ESM::REC_SOUN , 28); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Spell, ESM::REC_SPEL , 29); +OPENMW_ESM_ADD_STORE_TYPE(ESM::StartScript, ESM::REC_SSCR , 30); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Static, ESM::REC_STAT , 31); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Weapon, ESM::REC_WEAP , 32); +OPENMW_ESM_ADD_STORE_TYPE(ESM::GameSetting, ESM::REC_GMST , 33); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Script, ESM::REC_SCPT , 34); // Lists that need special rules -OPENMW_ESM_ADD_STORE_TYPE(ESM::Cell,35); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Land,36); -OPENMW_ESM_ADD_STORE_TYPE(ESM::LandTexture,37); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Pathgrid,38); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Cell, ESM::REC_CELL , 35); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Land, ESM::REC_LAND , 36); +OPENMW_ESM_ADD_STORE_TYPE(ESM::LandTexture, ESM::REC_LTEX , 37); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Pathgrid, ESM::REC_PGRD , 38); -OPENMW_ESM_ADD_STORE_TYPE(ESM::MagicEffect,39); -OPENMW_ESM_ADD_STORE_TYPE(ESM::Skill,40); +OPENMW_ESM_ADD_STORE_TYPE(ESM::MagicEffect, ESM::REC_MGEF , 39); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Skill, ESM::REC_SKIL , 40); // Special entry which is hardcoded and not loaded from an ESM -OPENMW_ESM_ADD_STORE_TYPE(ESM::Attribute,41); +OPENMW_ESM_ADD_STORE_TYPE(ESM::Attribute, ESM::REC_INTERNAL_PLAYER , 41); static const int sRecordTypeCount = sRecordTypeCounter; constexpr int sRecordIndexCount = 42; @@ -286,51 +293,6 @@ namespace MWWorld ESMStoreImp(ESMStore& store) { - mESM3RecordToStore[ESM::REC_ACTI] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_ALCH] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_APPA] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_ARMO] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_BODY] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_BOOK] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_BSGN] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_CELL] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_CLAS] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_CLOT] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_CONT] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_CREA] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_DIAL] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_DOOR] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_ENCH] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_FACT] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_GLOB] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_GMST] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_INGR] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_LAND] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_LEVC] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_LEVI] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_LIGH] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_LOCK] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_LTEX] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_MISC] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_NPC_] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_PGRD] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_PROB] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_RACE] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_REGN] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_REPA] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_SCPT] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_SNDG] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_SOUN] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_SPEL] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_SSCR] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_STAT] = &store.getWritable(); - mESM3RecordToStore[ESM::REC_WEAP] = &store.getWritable(); - - for (const auto& recordStorePair : mESM3RecordToStore) - { - const StoreBase* storePtr = recordStorePair.second; - mStoreToEsm3Record[storePtr] = recordStorePair.first; - } } template @@ -338,7 +300,22 @@ namespace MWWorld { if constexpr (std::is_convertible*, StoreBase*>::value) { - stores.mStores[SRecordType::sStoreIndex] = std::make_unique>(); + int storeIndex = SRecordType::sStoreIndex; + stores.mStores[storeIndex] = std::make_unique>(); + constexpr ESM::RecNameInts recName = RecordTypeToRecName::sRecName; + if constexpr (recName != ESM::REC_INTERNAL_PLAYER) + { + stores.mStoreImp->mESM3RecordToStore[recName] = stores.mStores[storeIndex].get(); + } + } + } + + void SetupAfterStoresCreation(ESMStore& store) + { + for (const auto& recordStorePair : mESM3RecordToStore) + { + const StoreBase* storePtr = recordStorePair.second; + mStoreToEsm3Record[storePtr] = recordStorePair.first; } } }; @@ -368,14 +345,15 @@ namespace MWWorld { mStores.resize(sRecordTypeCount); assert(sRecordTypeCounter == sRecordIndexCount); //Otherwise something wen wrong with assigning index to stores + mStoreImp = std::make_unique(*this); + constexpr_for<0, sRecordIndexCount,1> ([this](auto storeIndex) { ESMStoreImp::createStore::recordType>(*this); }); - mStoreImp = std::make_unique(*this); mDynamicCount = 0; - + mStoreImp->SetupAfterStoresCreation(*this); getWritable().setCells(getWritable()); }