1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-12-17 20:43:07 +00:00

The esm4 reader logic is mutualised

to avoid copy pasting code, readerutils gives functions that take visitors as params to decide how a record must be handled

Check encoder exists, and get value of stateless encoder.

fixes code formatting conventions

Fixed output of record with RefId

also fixed readTypedRecord and readRecord to have the proper return types

Check if the type has a sRecordId
This commit is contained in:
florent.teppe 2022-12-30 11:28:19 +01:00
parent c721a6cafa
commit 077cf97bc4
12 changed files with 440 additions and 340 deletions

View file

@ -8,6 +8,7 @@
#include <components/esm/esmcommon.hpp> #include <components/esm/esmcommon.hpp>
#include <components/esm4/reader.hpp> #include <components/esm4/reader.hpp>
#include <components/esm4/readerutils.hpp>
#include <components/esm4/records.hpp> #include <components/esm4/records.hpp>
#include <components/to_utf8/to_utf8.hpp> #include <components/to_utf8/to_utf8.hpp>
@ -69,6 +70,19 @@ namespace EsmTool
template <class T> template <class T>
constexpr bool hasFormId = HasFormId<T>::value; constexpr bool hasFormId = HasFormId<T>::value;
template <class T, class = std::void_t<>>
struct HasRefId : std::false_type
{
};
template <class T>
struct HasRefId<T, std::void_t<decltype(T::mId)>> : std::true_type
{
};
template <class T>
constexpr bool hasRefId = HasRefId<T>::value;
template <class T, class = std::void_t<>> template <class T, class = std::void_t<>>
struct HasFlags : std::false_type struct HasFlags : std::false_type
{ {
@ -169,6 +183,8 @@ namespace EsmTool
std::cout << "\n Record: " << ESM::NAME(reader.hdr().record.typeId).toStringView(); std::cout << "\n Record: " << ESM::NAME(reader.hdr().record.typeId).toStringView();
if constexpr (hasFormId<T>) if constexpr (hasFormId<T>)
std::cout << "\n FormId: " << value.mFormId; std::cout << "\n FormId: " << value.mFormId;
if constexpr (hasRefId<T>)
std::cout << "\n RefId: " << value.mId;
if constexpr (hasFlags<T>) if constexpr (hasFlags<T>)
std::cout << "\n Record flags: " << recordFlags(value.mFlags); std::cout << "\n Record flags: " << recordFlags(value.mFlags);
if constexpr (hasEditorId<T>) if constexpr (hasEditorId<T>)
@ -180,62 +196,80 @@ namespace EsmTool
if constexpr (hasKf<T>) if constexpr (hasKf<T>)
std::cout << "\n Kf:" << WriteArray("\n - ", value.mKf); std::cout << "\n Kf:" << WriteArray("\n - ", value.mKf);
std::cout << '\n'; std::cout << '\n';
return;
} }
void readRecord(const Params& params, ESM4::Reader& reader) bool readRecord(const Params& params, ESM4::Reader& reader)
{ {
switch (static_cast<ESM4::RecordTypes>(reader.hdr().record.typeId)) switch (static_cast<ESM4::RecordTypes>(reader.hdr().record.typeId))
{ {
case ESM4::REC_AACT: case ESM4::REC_AACT:
break; break;
case ESM4::REC_ACHR: case ESM4::REC_ACHR:
return readTypedRecord<ESM4::ActorCharacter>(params, reader); readTypedRecord<ESM4::ActorCharacter>(params, reader);
return true;
case ESM4::REC_ACRE: case ESM4::REC_ACRE:
return readTypedRecord<ESM4::ActorCreature>(params, reader); readTypedRecord<ESM4::ActorCreature>(params, reader);
return true;
case ESM4::REC_ACTI: case ESM4::REC_ACTI:
return readTypedRecord<ESM4::Activator>(params, reader); readTypedRecord<ESM4::Activator>(params, reader);
return true;
case ESM4::REC_ADDN: case ESM4::REC_ADDN:
break; break;
case ESM4::REC_ALCH: case ESM4::REC_ALCH:
return readTypedRecord<ESM4::Potion>(params, reader); readTypedRecord<ESM4::Potion>(params, reader);
return true;
case ESM4::REC_ALOC: case ESM4::REC_ALOC:
return readTypedRecord<ESM4::MediaLocationController>(params, reader); readTypedRecord<ESM4::MediaLocationController>(params, reader);
return true;
case ESM4::REC_AMMO: case ESM4::REC_AMMO:
return readTypedRecord<ESM4::Ammunition>(params, reader); readTypedRecord<ESM4::Ammunition>(params, reader);
return true;
case ESM4::REC_ANIO: case ESM4::REC_ANIO:
return readTypedRecord<ESM4::AnimObject>(params, reader); readTypedRecord<ESM4::AnimObject>(params, reader);
return true;
case ESM4::REC_APPA: case ESM4::REC_APPA:
return readTypedRecord<ESM4::Apparatus>(params, reader); readTypedRecord<ESM4::Apparatus>(params, reader);
return true;
case ESM4::REC_ARMA: case ESM4::REC_ARMA:
return readTypedRecord<ESM4::ArmorAddon>(params, reader); readTypedRecord<ESM4::ArmorAddon>(params, reader);
return true;
case ESM4::REC_ARMO: case ESM4::REC_ARMO:
return readTypedRecord<ESM4::Armor>(params, reader); readTypedRecord<ESM4::Armor>(params, reader);
return true;
case ESM4::REC_ARTO: case ESM4::REC_ARTO:
break; break;
case ESM4::REC_ASPC: case ESM4::REC_ASPC:
return readTypedRecord<ESM4::AcousticSpace>(params, reader); readTypedRecord<ESM4::AcousticSpace>(params, reader);
return true;
case ESM4::REC_ASTP: case ESM4::REC_ASTP:
break; break;
case ESM4::REC_AVIF: case ESM4::REC_AVIF:
break; break;
case ESM4::REC_BOOK: case ESM4::REC_BOOK:
return readTypedRecord<ESM4::Book>(params, reader); readTypedRecord<ESM4::Book>(params, reader);
return true;
case ESM4::REC_BPTD: case ESM4::REC_BPTD:
return readTypedRecord<ESM4::BodyPartData>(params, reader); readTypedRecord<ESM4::BodyPartData>(params, reader);
return true;
case ESM4::REC_CAMS: case ESM4::REC_CAMS:
break; break;
case ESM4::REC_CCRD: case ESM4::REC_CCRD:
break; break;
case ESM4::REC_CELL: case ESM4::REC_CELL:
return readTypedRecord<ESM4::Cell>(params, reader); readTypedRecord<ESM4::Cell>(params, reader);
return true;
case ESM4::REC_CLAS: case ESM4::REC_CLAS:
return readTypedRecord<ESM4::Class>(params, reader); readTypedRecord<ESM4::Class>(params, reader);
return true;
case ESM4::REC_CLFM: case ESM4::REC_CLFM:
return readTypedRecord<ESM4::Colour>(params, reader); readTypedRecord<ESM4::Colour>(params, reader);
return true;
case ESM4::REC_CLMT: case ESM4::REC_CLMT:
break; break;
case ESM4::REC_CLOT: case ESM4::REC_CLOT:
return readTypedRecord<ESM4::Clothing>(params, reader); readTypedRecord<ESM4::Clothing>(params, reader);
return true;
case ESM4::REC_CMNY: case ESM4::REC_CMNY:
break; break;
case ESM4::REC_COBJ: case ESM4::REC_COBJ:
@ -243,25 +277,30 @@ namespace EsmTool
case ESM4::REC_COLL: case ESM4::REC_COLL:
break; break;
case ESM4::REC_CONT: case ESM4::REC_CONT:
return readTypedRecord<ESM4::Container>(params, reader); readTypedRecord<ESM4::Container>(params, reader);
return true;
case ESM4::REC_CPTH: case ESM4::REC_CPTH:
break; break;
case ESM4::REC_CREA: case ESM4::REC_CREA:
return readTypedRecord<ESM4::Creature>(params, reader); readTypedRecord<ESM4::Creature>(params, reader);
return true;
case ESM4::REC_CSTY: case ESM4::REC_CSTY:
break; break;
case ESM4::REC_DEBR: case ESM4::REC_DEBR:
break; break;
case ESM4::REC_DIAL: case ESM4::REC_DIAL:
return readTypedRecord<ESM4::Dialogue>(params, reader); readTypedRecord<ESM4::Dialogue>(params, reader);
return true;
case ESM4::REC_DLBR: case ESM4::REC_DLBR:
break; break;
case ESM4::REC_DLVW: case ESM4::REC_DLVW:
break; break;
case ESM4::REC_DOBJ: case ESM4::REC_DOBJ:
return readTypedRecord<ESM4::DefaultObj>(params, reader); readTypedRecord<ESM4::DefaultObj>(params, reader);
return true;
case ESM4::REC_DOOR: case ESM4::REC_DOOR:
return readTypedRecord<ESM4::Door>(params, reader); readTypedRecord<ESM4::Door>(params, reader);
return true;
case ESM4::REC_DUAL: case ESM4::REC_DUAL:
break; break;
case ESM4::REC_ECZN: case ESM4::REC_ECZN:
@ -275,81 +314,103 @@ namespace EsmTool
case ESM4::REC_EXPL: case ESM4::REC_EXPL:
break; break;
case ESM4::REC_EYES: case ESM4::REC_EYES:
return readTypedRecord<ESM4::Eyes>(params, reader); readTypedRecord<ESM4::Eyes>(params, reader);
return true;
case ESM4::REC_FACT: case ESM4::REC_FACT:
break; break;
case ESM4::REC_FLOR: case ESM4::REC_FLOR:
return readTypedRecord<ESM4::Flora>(params, reader); readTypedRecord<ESM4::Flora>(params, reader);
return true;
case ESM4::REC_FLST: case ESM4::REC_FLST:
return readTypedRecord<ESM4::FormIdList>(params, reader); readTypedRecord<ESM4::FormIdList>(params, reader);
return true;
case ESM4::REC_FSTP: case ESM4::REC_FSTP:
break; break;
case ESM4::REC_FSTS: case ESM4::REC_FSTS:
break; break;
case ESM4::REC_FURN: case ESM4::REC_FURN:
return readTypedRecord<ESM4::Furniture>(params, reader); readTypedRecord<ESM4::Furniture>(params, reader);
return true;
case ESM4::REC_GLOB: case ESM4::REC_GLOB:
return readTypedRecord<ESM4::GlobalVariable>(params, reader); readTypedRecord<ESM4::GlobalVariable>(params, reader);
return true;
case ESM4::REC_GMST: case ESM4::REC_GMST:
break; break;
case ESM4::REC_GRAS: case ESM4::REC_GRAS:
return readTypedRecord<ESM4::Grass>(params, reader); readTypedRecord<ESM4::Grass>(params, reader);
return true;
case ESM4::REC_GRUP: case ESM4::REC_GRUP:
break; break;
case ESM4::REC_HAIR: case ESM4::REC_HAIR:
return readTypedRecord<ESM4::Hair>(params, reader); readTypedRecord<ESM4::Hair>(params, reader);
return true;
case ESM4::REC_HAZD: case ESM4::REC_HAZD:
break; break;
case ESM4::REC_HDPT: case ESM4::REC_HDPT:
return readTypedRecord<ESM4::HeadPart>(params, reader); readTypedRecord<ESM4::HeadPart>(params, reader);
return true;
case ESM4::REC_IDLE: case ESM4::REC_IDLE:
// FIXME: ESM4::IdleAnimation::load does not work with Oblivion.esm // FIXME: ESM4::IdleAnimation::load does not work with Oblivion.esm
// return readTypedRecord<ESM4::IdleAnimation>(params, reader); // readTypedRecord<ESM4::IdleAnimation>(params, reader);
return true;
break; break;
case ESM4::REC_IDLM: case ESM4::REC_IDLM:
return readTypedRecord<ESM4::IdleMarker>(params, reader); readTypedRecord<ESM4::IdleMarker>(params, reader);
return true;
case ESM4::REC_IMAD: case ESM4::REC_IMAD:
break; break;
case ESM4::REC_IMGS: case ESM4::REC_IMGS:
break; break;
case ESM4::REC_IMOD: case ESM4::REC_IMOD:
return readTypedRecord<ESM4::ItemMod>(params, reader); readTypedRecord<ESM4::ItemMod>(params, reader);
return true;
case ESM4::REC_INFO: case ESM4::REC_INFO:
return readTypedRecord<ESM4::DialogInfo>(params, reader); readTypedRecord<ESM4::DialogInfo>(params, reader);
return true;
case ESM4::REC_INGR: case ESM4::REC_INGR:
return readTypedRecord<ESM4::Ingredient>(params, reader); readTypedRecord<ESM4::Ingredient>(params, reader);
return true;
case ESM4::REC_IPCT: case ESM4::REC_IPCT:
break; break;
case ESM4::REC_IPDS: case ESM4::REC_IPDS:
break; break;
case ESM4::REC_KEYM: case ESM4::REC_KEYM:
return readTypedRecord<ESM4::Key>(params, reader); readTypedRecord<ESM4::Key>(params, reader);
return true;
case ESM4::REC_KYWD: case ESM4::REC_KYWD:
break; break;
case ESM4::REC_LAND: case ESM4::REC_LAND:
return readTypedRecord<ESM4::Land>(params, reader); readTypedRecord<ESM4::Land>(params, reader);
return true;
case ESM4::REC_LCRT: case ESM4::REC_LCRT:
break; break;
case ESM4::REC_LCTN: case ESM4::REC_LCTN:
break; break;
case ESM4::REC_LGTM: case ESM4::REC_LGTM:
return readTypedRecord<ESM4::LightingTemplate>(params, reader); readTypedRecord<ESM4::LightingTemplate>(params, reader);
return true;
case ESM4::REC_LIGH: case ESM4::REC_LIGH:
return readTypedRecord<ESM4::Light>(params, reader); readTypedRecord<ESM4::Light>(params, reader);
return true;
case ESM4::REC_LSCR: case ESM4::REC_LSCR:
break; break;
case ESM4::REC_LTEX: case ESM4::REC_LTEX:
return readTypedRecord<ESM4::LandTexture>(params, reader); readTypedRecord<ESM4::LandTexture>(params, reader);
return true;
case ESM4::REC_LVLC: case ESM4::REC_LVLC:
return readTypedRecord<ESM4::LevelledCreature>(params, reader); readTypedRecord<ESM4::LevelledCreature>(params, reader);
return true;
case ESM4::REC_LVLI: case ESM4::REC_LVLI:
return readTypedRecord<ESM4::LevelledItem>(params, reader); readTypedRecord<ESM4::LevelledItem>(params, reader);
return true;
case ESM4::REC_LVLN: case ESM4::REC_LVLN:
return readTypedRecord<ESM4::LevelledNpc>(params, reader); readTypedRecord<ESM4::LevelledNpc>(params, reader);
return true;
case ESM4::REC_LVSP: case ESM4::REC_LVSP:
break; break;
case ESM4::REC_MATO: case ESM4::REC_MATO:
return readTypedRecord<ESM4::Material>(params, reader); readTypedRecord<ESM4::Material>(params, reader);
return true;
case ESM4::REC_MATT: case ESM4::REC_MATT:
break; break;
case ESM4::REC_MESG: case ESM4::REC_MESG:
@ -357,49 +418,66 @@ namespace EsmTool
case ESM4::REC_MGEF: case ESM4::REC_MGEF:
break; break;
case ESM4::REC_MISC: case ESM4::REC_MISC:
return readTypedRecord<ESM4::MiscItem>(params, reader); readTypedRecord<ESM4::MiscItem>(params, reader);
return true;
case ESM4::REC_MOVT: case ESM4::REC_MOVT:
break; break;
case ESM4::REC_MSET: case ESM4::REC_MSET:
return readTypedRecord<ESM4::MediaSet>(params, reader); readTypedRecord<ESM4::MediaSet>(params, reader);
return true;
case ESM4::REC_MSTT: case ESM4::REC_MSTT:
return readTypedRecord<ESM4::MovableStatic>(params, reader); readTypedRecord<ESM4::MovableStatic>(params, reader);
return true;
case ESM4::REC_MUSC: case ESM4::REC_MUSC:
return readTypedRecord<ESM4::Music>(params, reader); readTypedRecord<ESM4::Music>(params, reader);
return true;
case ESM4::REC_MUST: case ESM4::REC_MUST:
break; break;
case ESM4::REC_NAVI: case ESM4::REC_NAVI:
return readTypedRecord<ESM4::Navigation>(params, reader); readTypedRecord<ESM4::Navigation>(params, reader);
return true;
case ESM4::REC_NAVM: case ESM4::REC_NAVM:
return readTypedRecord<ESM4::NavMesh>(params, reader); readTypedRecord<ESM4::NavMesh>(params, reader);
return true;
case ESM4::REC_NOTE: case ESM4::REC_NOTE:
return readTypedRecord<ESM4::Note>(params, reader); readTypedRecord<ESM4::Note>(params, reader);
return true;
case ESM4::REC_NPC_: case ESM4::REC_NPC_:
return readTypedRecord<ESM4::Npc>(params, reader); readTypedRecord<ESM4::Npc>(params, reader);
return true;
case ESM4::REC_OTFT: case ESM4::REC_OTFT:
return readTypedRecord<ESM4::Outfit>(params, reader); readTypedRecord<ESM4::Outfit>(params, reader);
return true;
case ESM4::REC_PACK: case ESM4::REC_PACK:
return readTypedRecord<ESM4::AIPackage>(params, reader); readTypedRecord<ESM4::AIPackage>(params, reader);
return true;
case ESM4::REC_PERK: case ESM4::REC_PERK:
break; break;
case ESM4::REC_PGRD: case ESM4::REC_PGRD:
return readTypedRecord<ESM4::Pathgrid>(params, reader); readTypedRecord<ESM4::Pathgrid>(params, reader);
return true;
case ESM4::REC_PGRE: case ESM4::REC_PGRE:
return readTypedRecord<ESM4::PlacedGrenade>(params, reader); readTypedRecord<ESM4::PlacedGrenade>(params, reader);
return true;
case ESM4::REC_PHZD: case ESM4::REC_PHZD:
break; break;
case ESM4::REC_PROJ: case ESM4::REC_PROJ:
break; break;
case ESM4::REC_PWAT: case ESM4::REC_PWAT:
return readTypedRecord<ESM4::PlaceableWater>(params, reader); readTypedRecord<ESM4::PlaceableWater>(params, reader);
return true;
case ESM4::REC_QUST: case ESM4::REC_QUST:
return readTypedRecord<ESM4::Quest>(params, reader); readTypedRecord<ESM4::Quest>(params, reader);
return true;
case ESM4::REC_RACE: case ESM4::REC_RACE:
return readTypedRecord<ESM4::Race>(params, reader); readTypedRecord<ESM4::Race>(params, reader);
return true;
case ESM4::REC_REFR: case ESM4::REC_REFR:
return readTypedRecord<ESM4::Reference>(params, reader); readTypedRecord<ESM4::Reference>(params, reader);
return true;
case ESM4::REC_REGN: case ESM4::REC_REGN:
return readTypedRecord<ESM4::Region>(params, reader); readTypedRecord<ESM4::Region>(params, reader);
return true;
case ESM4::REC_RELA: case ESM4::REC_RELA:
break; break;
case ESM4::REC_REVB: case ESM4::REC_REVB:
@ -407,23 +485,30 @@ namespace EsmTool
case ESM4::REC_RFCT: case ESM4::REC_RFCT:
break; break;
case ESM4::REC_ROAD: case ESM4::REC_ROAD:
return readTypedRecord<ESM4::Road>(params, reader); readTypedRecord<ESM4::Road>(params, reader);
return true;
case ESM4::REC_SBSP: case ESM4::REC_SBSP:
return readTypedRecord<ESM4::SubSpace>(params, reader); readTypedRecord<ESM4::SubSpace>(params, reader);
return true;
case ESM4::REC_SCEN: case ESM4::REC_SCEN:
break; break;
case ESM4::REC_SCOL: case ESM4::REC_SCOL:
return readTypedRecord<ESM4::StaticCollection>(params, reader); readTypedRecord<ESM4::StaticCollection>(params, reader);
return true;
case ESM4::REC_SCPT: case ESM4::REC_SCPT:
return readTypedRecord<ESM4::Script>(params, reader); readTypedRecord<ESM4::Script>(params, reader);
return true;
case ESM4::REC_SCRL: case ESM4::REC_SCRL:
return readTypedRecord<ESM4::Scroll>(params, reader); readTypedRecord<ESM4::Scroll>(params, reader);
return true;
case ESM4::REC_SGST: case ESM4::REC_SGST:
return readTypedRecord<ESM4::SigilStone>(params, reader); readTypedRecord<ESM4::SigilStone>(params, reader);
return true;
case ESM4::REC_SHOU: case ESM4::REC_SHOU:
break; break;
case ESM4::REC_SLGM: case ESM4::REC_SLGM:
return readTypedRecord<ESM4::SoulGem>(params, reader); readTypedRecord<ESM4::SoulGem>(params, reader);
return true;
case ESM4::REC_SMBN: case ESM4::REC_SMBN:
break; break;
case ESM4::REC_SMEN: case ESM4::REC_SMEN:
@ -433,97 +518,56 @@ namespace EsmTool
case ESM4::REC_SNCT: case ESM4::REC_SNCT:
break; break;
case ESM4::REC_SNDR: case ESM4::REC_SNDR:
return readTypedRecord<ESM4::SoundReference>(params, reader); readTypedRecord<ESM4::SoundReference>(params, reader);
return true;
case ESM4::REC_SOPM: case ESM4::REC_SOPM:
break; break;
case ESM4::REC_SOUN: case ESM4::REC_SOUN:
return readTypedRecord<ESM4::Sound>(params, reader); readTypedRecord<ESM4::Sound>(params, reader);
return true;
case ESM4::REC_SPEL: case ESM4::REC_SPEL:
break; break;
case ESM4::REC_SPGD: case ESM4::REC_SPGD:
break; break;
case ESM4::REC_STAT: case ESM4::REC_STAT:
return readTypedRecord<ESM4::Static>(params, reader); readTypedRecord<ESM4::Static>(params, reader);
return true;
case ESM4::REC_TACT: case ESM4::REC_TACT:
return readTypedRecord<ESM4::TalkingActivator>(params, reader); readTypedRecord<ESM4::TalkingActivator>(params, reader);
return true;
case ESM4::REC_TERM: case ESM4::REC_TERM:
return readTypedRecord<ESM4::Terminal>(params, reader); readTypedRecord<ESM4::Terminal>(params, reader);
return true;
case ESM4::REC_TES4: case ESM4::REC_TES4:
return readTypedRecord<ESM4::Header>(params, reader); readTypedRecord<ESM4::Header>(params, reader);
return true;
case ESM4::REC_TREE: case ESM4::REC_TREE:
return readTypedRecord<ESM4::Tree>(params, reader); readTypedRecord<ESM4::Tree>(params, reader);
return true;
case ESM4::REC_TXST: case ESM4::REC_TXST:
return readTypedRecord<ESM4::TextureSet>(params, reader); readTypedRecord<ESM4::TextureSet>(params, reader);
return true;
case ESM4::REC_VTYP: case ESM4::REC_VTYP:
break; break;
case ESM4::REC_WATR: case ESM4::REC_WATR:
break; break;
case ESM4::REC_WEAP: case ESM4::REC_WEAP:
return readTypedRecord<ESM4::Weapon>(params, reader); readTypedRecord<ESM4::Weapon>(params, reader);
return true;
case ESM4::REC_WOOP: case ESM4::REC_WOOP:
break; break;
case ESM4::REC_WRLD: case ESM4::REC_WRLD:
return readTypedRecord<ESM4::World>(params, reader); readTypedRecord<ESM4::World>(params, reader);
return true;
case ESM4::REC_WTHR: case ESM4::REC_WTHR:
break; break;
} }
if (!params.mQuite) if (!params.mQuite)
std::cout << "\n Unsupported record: " << ESM::NAME(reader.hdr().record.typeId).toStringView() << '\n'; std::cout << "\n Unsupported record: " << ESM::NAME(reader.hdr().record.typeId).toStringView() << '\n';
reader.skipRecordData();
}
bool readItem(const Params& params, ESM4::Reader& reader);
bool readGroup(const Params& params, ESM4::Reader& reader)
{
const ESM4::RecordHeader& header = reader.hdr();
if (!params.mQuite)
std::cout << "\nGroup: " << toString(static_cast<ESM4::GroupType>(header.group.type)) << " "
<< ESM::NAME(header.group.typeId).toStringView() << '\n';
switch (static_cast<ESM4::GroupType>(header.group.type))
{
case ESM4::Grp_RecordType:
case ESM4::Grp_InteriorCell:
case ESM4::Grp_InteriorSubCell:
case ESM4::Grp_ExteriorCell:
case ESM4::Grp_ExteriorSubCell:
reader.enterGroup();
return readItem(params, reader);
case ESM4::Grp_WorldChild:
case ESM4::Grp_CellChild:
case ESM4::Grp_TopicChild:
case ESM4::Grp_CellPersistentChild:
case ESM4::Grp_CellTemporaryChild:
case ESM4::Grp_CellVisibleDistChild:
reader.adjustGRUPFormId();
reader.enterGroup();
if (!reader.hasMoreRecs())
return false; return false;
return readItem(params, reader);
} }
reader.skipGroup();
return true;
}
bool readItem(const Params& params, ESM4::Reader& reader)
{
if (!reader.getRecordHeader() || !reader.hasMoreRecs())
return false;
const ESM4::RecordHeader& header = reader.hdr();
if (header.record.typeId == ESM4::REC_GRUP)
return readGroup(params, reader);
readRecord(params, reader);
return true;
}
} }
int loadTes4(const Arguments& info, std::unique_ptr<std::ifstream>&& stream) int loadTes4(const Arguments& info, std::unique_ptr<std::ifstream>&& stream)
@ -551,12 +595,15 @@ namespace EsmTool
} }
} }
while (reader.hasMoreRecs()) auto visitorRec = [&params](ESM4::Reader& reader) { return readRecord(params, reader); };
{ auto visistorGroup = [&params](ESM4::Reader& reader) {
reader.exitGroupCheck(); if (params.mQuite)
if (!readItem(params, reader)) return;
break; auto groupType = static_cast<ESM4::GroupType>(reader.hdr().group.type);
} std::cout << "\nGroup: " << toString(groupType) << " "
<< ESM::NAME(reader.hdr().group.typeId).toStringView() << '\n';
};
ESM4::ReaderUtils::readAll(reader, visitorRec, visistorGroup);
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {

View file

@ -1,13 +1,14 @@
#include "esmloader.hpp" #include "esmloader.hpp"
#include "esmstore.hpp" #include "esmstore.hpp"
#include <fstream>
#include <components/esm/format.hpp> #include <components/esm/format.hpp>
#include <components/esm3/esmreader.hpp> #include <components/esm3/esmreader.hpp>
#include <components/esm3/readerscache.hpp> #include <components/esm3/readerscache.hpp>
#include <components/esm4/reader.hpp> #include <components/esm4/reader.hpp>
#include <components/files/conversion.hpp> #include <components/files/conversion.hpp>
#include <components/files/openfile.hpp> #include <components/files/openfile.hpp>
#include <fstream>
namespace MWWorld namespace MWWorld
{ {
@ -30,7 +31,6 @@ namespace MWWorld
if (!stream->is_open()) if (!stream->is_open())
{ {
throw std::runtime_error(std::string("File Failed to open file: ") + std::strerror(errno) + "\n"); throw std::runtime_error(std::string("File Failed to open file: ") + std::strerror(errno) + "\n");
return;
} }
const ESM::Format format = ESM::readFormat(*stream); const ESM::Format format = ESM::readFormat(*stream);
stream->seekg(0); stream->seekg(0);
@ -63,12 +63,16 @@ namespace MWWorld
break; break;
} }
case ESM::Format::Tes4: case ESM::Format::Tes4:
{
if (mEncoder)
{ {
ESM4::Reader readerESM4(std::move(stream), filepath); ESM4::Reader readerESM4(std::move(stream), filepath);
readerESM4.setEncoder(mEncoder->getStatelessEncoder()); auto statelessEncoder = mEncoder->getStatelessEncoder();
readerESM4.setEncoder(&statelessEncoder);
mStore.loadESM4(readerESM4, listener, mDialogue); mStore.loadESM4(readerESM4, listener, mDialogue);
} }
} }
} }
}
} /* namespace MWWorld */ } /* namespace MWWorld */

View file

@ -13,12 +13,12 @@
#include <components/lua/configuration.hpp> #include <components/lua/configuration.hpp>
#include <components/misc/algorithm.hpp> #include <components/misc/algorithm.hpp>
#include <components/esm4/common.hpp>
#include <components/esm4/loadcell.hpp> #include <components/esm4/loadcell.hpp>
#include <components/esm4/loadrefr.hpp> #include <components/esm4/loadrefr.hpp>
#include <components/esm4/loadstat.hpp> #include <components/esm4/loadstat.hpp>
#include <components/esm4/reader.hpp> #include <components/esm4/reader.hpp>
#include <components/esm4/readerutils.hpp>
#include <components/esm4/common.hpp>
#include <components/esmloader/load.hpp> #include <components/esmloader/load.hpp>
#include "../mwmechanics/spelllist.hpp" #include "../mwmechanics/spelllist.hpp"
@ -186,13 +186,23 @@ namespace MWWorld
} }
} }
template <class T, class = std::void_t<>>
struct HasRecordId : std::false_type
{
};
template <class T>
struct HasRecordId<T, std::void_t<decltype(T::sRecordId)>> : std::true_type
{
};
template <typename T> template <typename T>
static void typedReadRecordESM4(ESM4::Reader& reader, ESMStore& stores, Store<T>& store, int& found) static void typedReadRecordESM4(ESM4::Reader& reader, ESMStore& stores, Store<T>& store, int& found)
{ {
auto recordType = static_cast<ESM4::RecordTypes>(reader.hdr().record.typeId); auto recordType = static_cast<ESM4::RecordTypes>(reader.hdr().record.typeId);
ESM::RecNameInts esm4RecName = static_cast<ESM::RecNameInts>(ESM::esm4Recname(recordType)); ESM::RecNameInts esm4RecName = static_cast<ESM::RecNameInts>(ESM::esm4Recname(recordType));
if constexpr (std::is_convertible_v<Store<T>*, DynamicStore*>) if constexpr (std::is_convertible_v<Store<T>*, DynamicStore*> && HasRecordId<T>::value)
{ {
if constexpr (ESM::isESM4Rec(T::sRecordId)) if constexpr (ESM::isESM4Rec(T::sRecordId))
{ {
@ -208,60 +218,14 @@ namespace MWWorld
} }
} }
static void readRecord(ESM4::Reader& reader, ESMStore& store) static bool readRecord(ESM4::Reader& reader, ESMStore& store)
{ {
int found = 0; int found = 0;
std::apply([&reader, &store, &found]( std::apply([&reader, &store, &found](
auto&... x) { (ESMStoreImp::typedReadRecordESM4(reader, store, x, found), ...); }, auto&... x) { (ESMStoreImp::typedReadRecordESM4(reader, store, x, found), ...); },
store.mStoreImp->mStores); store.mStoreImp->mStores);
assert(found <= 1); assert(found <= 1);
if (found == 0) // unhandled record return found;
reader.skipRecordData();
}
static bool readItem(ESM4::Reader& reader, ESMStore& store)
{
if (!reader.getRecordHeader() || !reader.hasMoreRecs())
return false;
const ESM4::RecordHeader& header = reader.hdr();
if (header.record.typeId == ESM4::REC_GRUP)
return readGroup(reader, store);
readRecord(reader, store);
return true;
}
static bool readGroup(ESM4::Reader& reader, ESMStore& store)
{
const ESM4::RecordHeader& header = reader.hdr();
switch (static_cast<ESM4::GroupType>(header.group.type))
{
case ESM4::Grp_RecordType:
case ESM4::Grp_InteriorCell:
case ESM4::Grp_InteriorSubCell:
case ESM4::Grp_ExteriorCell:
case ESM4::Grp_ExteriorSubCell:
reader.enterGroup();
return readItem(reader, store);
case ESM4::Grp_WorldChild:
case ESM4::Grp_CellChild:
case ESM4::Grp_TopicChild:
case ESM4::Grp_CellPersistentChild:
case ESM4::Grp_CellTemporaryChild:
case ESM4::Grp_CellVisibleDistChild:
reader.adjustGRUPFormId();
reader.enterGroup();
if (!reader.hasMoreRecs())
return false;
return readItem(reader, store);
}
reader.skipGroup();
return true;
} }
}; };
@ -423,12 +387,8 @@ namespace MWWorld
void ESMStore::loadESM4(ESM4::Reader& reader, Loading::Listener* listener, ESM::Dialogue*& dialogue) void ESMStore::loadESM4(ESM4::Reader& reader, Loading::Listener* listener, ESM::Dialogue*& dialogue)
{ {
while (reader.hasMoreRecs()) auto visitorRec = [this](ESM4::Reader& reader) { return ESMStoreImp::readRecord(reader, *this); };
{ ESM4::ReaderUtils::readAll(reader, visitorRec, [](ESM4::Reader&) {});
reader.exitGroupCheck();
if (!ESMStoreImp::readItem(reader, *this))
break;
}
} }
void ESMStore::setIdType(const ESM::RefId& id, ESM::RecNameInts type) void ESMStore::setIdType(const ESM::RefId& id, ESM::RecNameInts type)

View file

@ -1,21 +1,18 @@
#include "store.hpp" #include "store.hpp"
#include <components/debug/debuglog.hpp>
#include <components/esm/records.hpp>
#include <components/esm3/esmreader.hpp>
#include <components/esm3/esmwriter.hpp>
#include <components/loadinglistener/loadinglistener.hpp>
#include <components/misc/rng.hpp>
#include <iterator> #include <iterator>
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
#include <components/debug/debuglog.hpp>
#include <components/esm/records.hpp>
#include <components/esm3/esmreader.hpp>
#include <components/esm3/esmwriter.hpp>
#include <components/esm4/loadcell.hpp> #include <components/esm4/loadcell.hpp>
#include <components/esm4/loadrefr.hpp> #include <components/esm4/loadrefr.hpp>
#include <components/esm4/loadstat.hpp> #include <components/esm4/loadstat.hpp>
#include <components/loadinglistener/loadinglistener.hpp>
#include <components/misc/rng.hpp>
namespace namespace
{ {

View file

@ -1,12 +1,13 @@
project (Components) project(Components)
# Version file # Version file
set (VERSION_IN_FILE "${OpenMW_SOURCE_DIR}/files/version.in") set(VERSION_IN_FILE "${OpenMW_SOURCE_DIR}/files/version.in")
set (VERSION_FILE_PATH_BASE "${OpenMW_BINARY_DIR}") set(VERSION_FILE_PATH_BASE "${OpenMW_BINARY_DIR}")
set (VERSION_FILE_PATH_RELATIVE resources/version) set(VERSION_FILE_PATH_RELATIVE resources/version)
if (GIT_CHECKOUT)
if(GIT_CHECKOUT)
get_generator_is_multi_config(multi_config) get_generator_is_multi_config(multi_config)
add_custom_target (git-version add_custom_target(git-version
COMMAND ${CMAKE_COMMAND} COMMAND ${CMAKE_COMMAND}
-DGIT_EXECUTABLE=${GIT_EXECUTABLE} -DGIT_EXECUTABLE=${GIT_EXECUTABLE}
-DPROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR} -DPROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR}
@ -22,63 +23,62 @@ if (GIT_CHECKOUT)
-Dgenerator_is_multi_config_var=${multi_config} -Dgenerator_is_multi_config_var=${multi_config}
-P ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/GitVersion.cmake -P ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/GitVersion.cmake
VERBATIM) VERBATIM)
else (GIT_CHECKOUT) else(GIT_CHECKOUT)
configure_resource_file(${VERSION_IN_FILE} ${VERSION_FILE_PATH_BASE} ${VERSION_FILE_PATH_RELATIVE}) configure_resource_file(${VERSION_IN_FILE} ${VERSION_FILE_PATH_BASE} ${VERSION_FILE_PATH_RELATIVE})
endif (GIT_CHECKOUT) endif(GIT_CHECKOUT)
# source files # source files
add_component_dir(lua
add_component_dir (lua
luastate scriptscontainer utilpackage serialization configuration l10n storage luastate scriptscontainer utilpackage serialization configuration l10n storage
) )
add_component_dir (l10n add_component_dir(l10n
messagebundles manager messagebundles manager
) )
add_component_dir (settings add_component_dir(settings
settings parser settings parser
) )
add_component_dir (bsa add_component_dir(bsa
bsa_file compressedbsafile bsa_file compressedbsafile
) )
add_component_dir (vfs add_component_dir(vfs
manager archive bsaarchive filesystemarchive registerarchives manager archive bsaarchive filesystemarchive registerarchives
) )
add_component_dir (resource add_component_dir(resource
scenemanager keyframemanager imagemanager bulletshapemanager bulletshape niffilemanager objectcache multiobjectcache resourcesystem scenemanager keyframemanager imagemanager bulletshapemanager bulletshape niffilemanager objectcache multiobjectcache resourcesystem
resourcemanager stats animation foreachbulletobject errormarker resourcemanager stats animation foreachbulletobject errormarker
) )
add_component_dir (shader add_component_dir(shader
shadermanager shadervisitor removedalphafunc shadermanager shadervisitor removedalphafunc
) )
add_component_dir (sceneutil add_component_dir(sceneutil
clone attach visitor util statesetupdater controller skeleton riggeometry morphgeometry lightcontroller clone attach visitor util statesetupdater controller skeleton riggeometry morphgeometry lightcontroller
lightmanager lightutil positionattitudetransform workqueue pathgridutil waterutil writescene serialize optimizer lightmanager lightutil positionattitudetransform workqueue pathgridutil waterutil writescene serialize optimizer
actorutil detourdebugdraw navmesh agentpath shadow mwshadowtechnique recastmesh shadowsbin osgacontroller rtt actorutil detourdebugdraw navmesh agentpath shadow mwshadowtechnique recastmesh shadowsbin osgacontroller rtt
screencapture depth color riggeometryosgaextension extradata unrefqueue screencapture depth color riggeometryosgaextension extradata unrefqueue
) )
add_component_dir (nif add_component_dir(nif
controlled effect niftypes record controller extra node record_ptr data niffile property nifkey base nifstream physics controlled effect niftypes record controller extra node record_ptr data niffile property nifkey base nifstream physics
) )
add_component_dir (nifosg add_component_dir(nifosg
nifloader controller particle matrixtransform nifloader controller particle matrixtransform
) )
add_component_dir (nifbullet add_component_dir(nifbullet
bulletnifloader bulletnifloader
) )
add_component_dir (to_utf8 add_component_dir(to_utf8
to_utf8 to_utf8
) )
add_component_dir(esm attr common defs esmcommon records util luascripts format refid) add_component_dir(esm attr common defs esmcommon records util luascripts format refid)
@ -86,7 +86,7 @@ add_component_dir(fx pass technique lexer widgets stateupdater)
add_component_dir(std140 ubo) add_component_dir(std140 ubo)
add_component_dir (esm3 add_component_dir(esm3
esmreader esmwriter loadacti loadalch loadappa loadarmo loadbody loadbook loadbsgn loadcell esmreader esmwriter loadacti loadalch loadappa loadarmo loadbody loadbook loadbsgn loadcell
loadclas loadclot loadcont loadcrea loaddial loaddoor loadench loadfact loadglob loadgmst loadclas loadclot loadcont loadcrea loaddial loaddoor loadench loadfact loadglob loadgmst
loadinfo loadingr loadland loadlevlist loadligh loadlock loadprob loadrepa loadltex loadmgef loadmisc loadinfo loadingr loadland loadlevlist loadligh loadlock loadprob loadrepa loadltex loadmgef loadmisc
@ -96,13 +96,13 @@ add_component_dir (esm3
inventorystate containerstate npcstate creaturestate dialoguestate statstate npcstats creaturestats inventorystate containerstate npcstate creaturestate dialoguestate statstate npcstats creaturestats
weatherstate quickkeys fogstate spellstate activespells creaturelevliststate doorstate projectilestate debugprofile weatherstate quickkeys fogstate spellstate activespells creaturelevliststate doorstate projectilestate debugprofile
aisequence magiceffects custommarkerstate stolenitems transport animationstate controlsstate mappings readerscache aisequence magiceffects custommarkerstate stolenitems transport animationstate controlsstate mappings readerscache
) )
add_component_dir (esm3terrain add_component_dir(esm3terrain
storage storage
) )
add_component_dir (esm4 add_component_dir(esm4
acti acti
actor actor
common common
@ -191,96 +191,97 @@ add_component_dir (esm4
loadweap loadweap
loadwrld loadwrld
reader reader
readerutils
reference reference
script script
) )
add_component_dir (misc add_component_dir(misc
constants utf8stream resourcehelpers rng messageformatparser weakcache thread constants utf8stream resourcehelpers rng messageformatparser weakcache thread
compression osguservalues color tuplemeta tuplehelpers compression osguservalues color tuplemeta tuplehelpers
) )
add_component_dir (stereo add_component_dir(stereo
frustum multiview stereomanager types frustum multiview stereomanager types
) )
add_component_dir (debug add_component_dir(debug
debugging debuglog gldebug debugdraw debugging debuglog gldebug debugdraw
) )
IF(NOT WIN32 AND NOT APPLE) IF(NOT WIN32 AND NOT APPLE)
add_definitions(-DGLOBAL_DATA_PATH="${GLOBAL_DATA_PATH}") add_definitions(-DGLOBAL_DATA_PATH="${GLOBAL_DATA_PATH}")
add_definitions(-DGLOBAL_CONFIG_PATH="${GLOBAL_CONFIG_PATH}") add_definitions(-DGLOBAL_CONFIG_PATH="${GLOBAL_CONFIG_PATH}")
ENDIF() ENDIF()
add_component_dir (files
add_component_dir(files
linuxpath androidpath windowspath macospath fixedpath multidircollection collections configurationmanager linuxpath androidpath windowspath macospath fixedpath multidircollection collections configurationmanager
constrainedfilestream memorystream hash configfileparser openfile constrainedfilestreambuf conversion constrainedfilestream memorystream hash configfileparser openfile constrainedfilestreambuf conversion
) )
add_component_dir (compiler add_component_dir(compiler
context controlparser errorhandler exception exprparser extensions fileparser generator context controlparser errorhandler exception exprparser extensions fileparser generator
lineparser literals locals output parser scanner scriptparser skipparser streamerrorhandler lineparser literals locals output parser scanner scriptparser skipparser streamerrorhandler
stringparser tokenloc nullerrorhandler opcodes extensions0 declarationparser stringparser tokenloc nullerrorhandler opcodes extensions0 declarationparser
quickfileparser discardparser junkparser quickfileparser discardparser junkparser
) )
add_component_dir (interpreter add_component_dir(interpreter
context controlopcodes genericopcodes installopcodes interpreter localopcodes mathopcodes context controlopcodes genericopcodes installopcodes interpreter localopcodes mathopcodes
miscopcodes opcodes runtime types defines miscopcodes opcodes runtime types defines
) )
add_component_dir (translation add_component_dir(translation
translation translation
) )
add_component_dir (terrain add_component_dir(terrain
storage world buffercache defs terraingrid material terraindrawable texturemanager chunkmanager compositemaprenderer storage world buffercache defs terraingrid material terraindrawable texturemanager chunkmanager compositemaprenderer
quadtreeworld quadtreenode viewdata cellborder view heightcull quadtreeworld quadtreenode viewdata cellborder view heightcull
) )
add_component_dir (loadinglistener add_component_dir(loadinglistener
loadinglistener loadinglistener
) )
add_component_dir (myguiplatform add_component_dir(myguiplatform
myguirendermanager myguidatamanager myguiplatform myguitexture myguiloglistener additivelayer scalinglayer myguirendermanager myguidatamanager myguiplatform myguitexture myguiloglistener additivelayer scalinglayer
) )
add_component_dir (widgets add_component_dir(widgets
box fontwrapper imagebutton tags list numericeditbox sharedstatebutton windowcaption widgets box fontwrapper imagebutton tags list numericeditbox sharedstatebutton windowcaption widgets
) )
add_component_dir (fontloader add_component_dir(fontloader
fontloader fontloader
) )
add_component_dir (sdlutil add_component_dir(sdlutil
gl4es_init sdlgraphicswindow imagetosurface sdlinputwrapper sdlvideowrapper events sdlcursormanager sdlmappings gl4es_init sdlgraphicswindow imagetosurface sdlinputwrapper sdlvideowrapper events sdlcursormanager sdlmappings
) )
add_component_dir (version add_component_dir(version
version version
) )
add_component_dir (fallback add_component_dir(fallback
fallback validate fallback validate
) )
add_component_dir (lua_ui add_component_dir(lua_ui
registerscriptsettings scriptsettings registerscriptsettings scriptsettings
properties widget element util layers content alignment resources properties widget element util layers content alignment resources
adapter text textedit window image container flex adapter text textedit window image container flex
) )
if(WIN32) if(WIN32)
add_component_dir (crashcatcher add_component_dir(crashcatcher
windows_crashcatcher windows_crashcatcher
windows_crashmonitor windows_crashmonitor
windows_crashshm windows_crashshm
) )
elseif(NOT ANDROID) elseif(NOT ANDROID)
add_component_dir (crashcatcher add_component_dir(crashcatcher
crashcatcher crashcatcher
) )
endif() endif()
@ -316,11 +317,11 @@ add_component_dir(detournavigator
stats stats
commulativeaabb commulativeaabb
recastcontext recastcontext
) )
add_component_dir(loadinglistener add_component_dir(loadinglistener
reporter reporter
) )
add_component_dir(sqlite3 add_component_dir(sqlite3
db db
@ -335,63 +336,63 @@ add_component_dir(esmloader
add_component_dir(navmeshtool add_component_dir(navmeshtool
protocol protocol
) )
add_component_dir(platform add_component_dir(platform
platform platform
file file
) )
if (WIN32) if(WIN32)
add_component_dir(platform add_component_dir(platform
file.win32 file.win32
) )
elseif (UNIX) elseif(UNIX)
add_component_dir(platform add_component_dir(platform
file.posix file.posix
) )
else () else()
add_component_dir(platform add_component_dir(platform
file.stdio file.stdio
) )
endif() endif()
set (ESM_UI ${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui set(ESM_UI ${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui
) )
if (USE_QT) if(USE_QT)
add_component_qt_dir (contentselector add_component_qt_dir(contentselector
model/modelitem model/esmfile model/modelitem model/esmfile
model/naturalsort model/contentmodel model/naturalsort model/contentmodel
model/loadordererror model/loadordererror
view/combobox view/contentselector view/combobox view/contentselector
) )
add_component_qt_dir (config add_component_qt_dir(config
gamesettings gamesettings
launchersettings launchersettings
settingsbase settingsbase
) )
add_component_qt_dir (process add_component_qt_dir(process
processinvoker processinvoker
) )
add_component_qt_dir (misc add_component_qt_dir(misc
helpviewer helpviewer
) )
add_component_qt_dir (files add_component_qt_dir(files
qtconversion qtconversion
) )
QT5_WRAP_UI(ESM_UI_HDR ${ESM_UI}) QT5_WRAP_UI(ESM_UI_HDR ${ESM_UI})
endif() endif()
if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64" AND NOT APPLE) if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64" AND NOT APPLE)
add_definitions(-fPIC) add_definitions(-fPIC)
endif() endif()
endif () endif()
include_directories(${BULLET_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}) include_directories(${BULLET_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
@ -436,7 +437,7 @@ target_link_libraries(components
smhasher smhasher
${ICU_LIBRARIES} ${ICU_LIBRARIES}
yaml-cpp yaml-cpp
) )
if(Boost_VERSION_STRING VERSION_GREATER_EQUAL 1.77.0) if(Boost_VERSION_STRING VERSION_GREATER_EQUAL 1.77.0)
target_link_libraries(components ${Boost_ATOMIC_LIBRARY}) target_link_libraries(components ${Boost_ATOMIC_LIBRARY})
@ -444,46 +445,46 @@ endif()
target_link_libraries(components ${BULLET_LIBRARIES}) target_link_libraries(components ${BULLET_LIBRARIES})
if (WIN32) if(WIN32)
target_link_libraries(components target_link_libraries(components
${Boost_LOCALE_LIBRARY} ${Boost_LOCALE_LIBRARY}
${Boost_ZLIB_LIBRARY}) ${Boost_ZLIB_LIBRARY})
endif() endif()
if (USE_QT) if(USE_QT)
add_library(components_qt STATIC ${COMPONENT_QT_FILES} ${ESM_UI_HDR}) add_library(components_qt STATIC ${COMPONENT_QT_FILES} ${ESM_UI_HDR})
target_link_libraries(components_qt components Qt5::Widgets Qt5::Core) target_link_libraries(components_qt components Qt5::Widgets Qt5::Core)
target_compile_definitions(components_qt PRIVATE OPENMW_DOC_BASEURL="${OPENMW_DOC_BASEURL}") target_compile_definitions(components_qt PRIVATE OPENMW_DOC_BASEURL="${OPENMW_DOC_BASEURL}")
endif() endif()
if (GIT_CHECKOUT) if(GIT_CHECKOUT)
add_dependencies (components git-version) add_dependencies(components git-version)
endif (GIT_CHECKOUT) endif(GIT_CHECKOUT)
if (OSG_STATIC AND CMAKE_SYSTEM_NAME MATCHES "Linux") if(OSG_STATIC AND CMAKE_SYSTEM_NAME MATCHES "Linux")
find_package(X11 REQUIRED COMPONENTS Xinerama Xrandr) find_package(X11 REQUIRED COMPONENTS Xinerama Xrandr)
target_link_libraries(components ${CMAKE_DL_LIBS} X11::X11 X11::Xinerama X11::Xrandr) target_link_libraries(components ${CMAKE_DL_LIBS} X11::X11 X11::Xinerama X11::Xrandr)
find_package(Fontconfig MODULE) find_package(Fontconfig MODULE)
if(Fontconfig_FOUND) if(Fontconfig_FOUND)
target_link_libraries(components Fontconfig::Fontconfig) target_link_libraries(components Fontconfig::Fontconfig)
endif() endif()
endif() endif()
if (WIN32) if(WIN32)
target_link_libraries(components shlwapi) target_link_libraries(components shlwapi)
endif() endif()
# Fix for not visible pthreads functions for linker with glibc 2.15 # Fix for not visible pthreads functions for linker with glibc 2.15
if (UNIX AND NOT APPLE) if(UNIX AND NOT APPLE)
target_link_libraries(components ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries(components ${CMAKE_THREAD_LIBS_INIT})
endif() endif()
if (BUILD_WITH_CODE_COVERAGE) if(BUILD_WITH_CODE_COVERAGE)
add_definitions(--coverage) add_definitions(--coverage)
target_link_libraries(components gcov) target_link_libraries(components gcov)
endif() endif()
# Make the variable accessible for other subdirectories # Make the variable accessible for other subdirectories
set(COMPONENT_FILES ${COMPONENT_FILES} PARENT_SCOPE) set(COMPONENT_FILES ${COMPONENT_FILES} PARENT_SCOPE)
@ -492,8 +493,10 @@ target_compile_definitions(components PUBLIC BT_USE_DOUBLE_PRECISION)
if(OSG_STATIC) if(OSG_STATIC)
unset(_osg_plugins_static_files) unset(_osg_plugins_static_files)
add_library(components_osg_plugins INTERFACE) add_library(components_osg_plugins INTERFACE)
foreach(_plugin ${USED_OSG_PLUGINS}) foreach(_plugin ${USED_OSG_PLUGINS})
string(TOUPPER ${_plugin} _plugin_uc) string(TOUPPER ${_plugin} _plugin_uc)
if(OPENMW_USE_SYSTEM_OSG) if(OPENMW_USE_SYSTEM_OSG)
list(APPEND _osg_plugins_static_files ${${_plugin_uc}_LIBRARY}) list(APPEND _osg_plugins_static_files ${${_plugin_uc}_LIBRARY})
else() else()
@ -502,6 +505,7 @@ if(OSG_STATIC)
add_dependencies(components_osg_plugins ${${_plugin_uc}_LIBRARY}) add_dependencies(components_osg_plugins ${${_plugin_uc}_LIBRARY})
endif() endif()
endforeach() endforeach()
# We use --whole-archive because OSG plugins use registration. # We use --whole-archive because OSG plugins use registration.
get_whole_archive_options(_opts ${_osg_plugins_static_files}) get_whole_archive_options(_opts ${_osg_plugins_static_files})
target_link_options(components_osg_plugins INTERFACE ${_opts}) target_link_options(components_osg_plugins INTERFACE ${_opts})
@ -521,7 +525,7 @@ if(USE_QT)
set_property(TARGET components_qt PROPERTY AUTOMOC ON) set_property(TARGET components_qt PROPERTY AUTOMOC ON)
endif(USE_QT) endif(USE_QT)
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.16 AND MSVC) if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.16 AND MSVC)
target_precompile_headers(components PUBLIC target_precompile_headers(components PUBLIC
<sol/sol.hpp> <sol/sol.hpp>

View file

@ -1,12 +1,13 @@
#ifndef OPENMW_COMPONENTS_ESM_REFID_HPP #ifndef OPENMW_COMPONENTS_ESM_REFID_HPP
#define OPENMW_COMPONENTS_ESM_REFID_HPP #define OPENMW_COMPONENTS_ESM_REFID_HPP
#include <compare> #include <compare>
#include <components/esm4/formid.hpp>
#include <functional> #include <functional>
#include <iosfwd> #include <iosfwd>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <components/esm4/formid.hpp>
namespace ESM namespace ESM
{ {
struct RefId struct RefId

View file

@ -32,11 +32,11 @@
#include <cassert> #include <cassert>
#include <cfloat> // FLT_MAX for gcc #include <cfloat> // FLT_MAX for gcc
#include <iostream> // FIXME: debug only
#include <stdexcept> #include <stdexcept>
#include <iostream> // FIXME: debug only
#include "reader.hpp" #include "reader.hpp"
#include <components/esm/refid.hpp> #include <components/esm/refid.hpp>
// #include "writer.hpp" // #include "writer.hpp"

View file

@ -33,6 +33,7 @@
#include "formid.hpp" #include "formid.hpp"
#include "lighting.hpp" #include "lighting.hpp"
#include <components/esm/defs.hpp> #include <components/esm/defs.hpp>
#include <components/esm/refid.hpp> #include <components/esm/refid.hpp>

View file

@ -30,6 +30,7 @@
#include <cstdint> #include <cstdint>
#include "reference.hpp" // FormId, Placement, EnableParent #include "reference.hpp" // FormId, Placement, EnableParent
#include <components/esm/defs.hpp> #include <components/esm/defs.hpp>
#include <components/esm/refid.hpp> #include <components/esm/refid.hpp>

View file

@ -32,6 +32,7 @@
#include <vector> #include <vector>
#include "formid.hpp" #include "formid.hpp"
#include <components/esm/defs.hpp> #include <components/esm/defs.hpp>
#include <components/esm/refid.hpp> #include <components/esm/refid.hpp>

View file

@ -0,0 +1,84 @@
#ifndef OPENMW_COMPONENTS_ESM4_READERUTILS
#define OPENMW_COMPONENTS_ESM4_READERUTILS
#include <components/esm4/reader.hpp>
namespace ESM4
{
struct ReaderUtils
{
/* RecordInvocable must be an invocable, takes an ESM4::Reader& as input, and outputs a boolean that indicates
if the record was read or ignored. Will be invoked for every record
GroupInvocable's invocable must take a ESM4::Reader& as input, doesn't need to output anything. Will be invoked
for every group*/
template <typename RecordInvocable, typename GroupInvocable>
static void readAll(ESM4::Reader& reader, RecordInvocable&& recordInvocable, GroupInvocable&& groupInvocable)
{
while (reader.hasMoreRecs())
{
reader.exitGroupCheck();
if (!readItem(reader, recordInvocable, groupInvocable))
break;
}
}
template <typename RecordInvocable>
static void readRecord(ESM4::Reader& reader, RecordInvocable&& recordInvocable)
{
if (!recordInvocable(reader))
reader.skipRecordData();
}
template <typename RecordInvocable, typename GroupInvocable>
static bool readGroup(ESM4::Reader& reader, RecordInvocable&& recordInvocable, GroupInvocable&& groupInvocable)
{
const ESM4::RecordHeader& header = reader.hdr();
groupInvocable(reader);
switch (static_cast<ESM4::GroupType>(header.group.type))
{
case ESM4::Grp_RecordType:
case ESM4::Grp_InteriorCell:
case ESM4::Grp_InteriorSubCell:
case ESM4::Grp_ExteriorCell:
case ESM4::Grp_ExteriorSubCell:
reader.enterGroup();
return readItem(reader, recordInvocable, groupInvocable);
case ESM4::Grp_WorldChild:
case ESM4::Grp_CellChild:
case ESM4::Grp_TopicChild:
case ESM4::Grp_CellPersistentChild:
case ESM4::Grp_CellTemporaryChild:
case ESM4::Grp_CellVisibleDistChild:
reader.adjustGRUPFormId();
reader.enterGroup();
if (!reader.hasMoreRecs())
return false;
return readItem(reader, recordInvocable, groupInvocable);
}
reader.skipGroup();
return true;
}
template <typename RecordInvocable, typename GroupInvocable>
static bool readItem(ESM4::Reader& reader, RecordInvocable&& recordInvocable, GroupInvocable&& groupInvocable)
{
if (!reader.getRecordHeader() || !reader.hasMoreRecs())
return false;
const ESM4::RecordHeader& header = reader.hdr();
if (header.record.typeId == ESM4::REC_GRUP)
return readGroup(reader, recordInvocable, groupInvocable);
readRecord(reader, recordInvocable);
return true;
}
};
}
#endif // !OPENMW_COMPONENTS_ESM4_READERUTILS

View file

@ -68,7 +68,7 @@ namespace ToUTF8
/// ASCII-only string. Otherwise returns a view to the input. /// ASCII-only string. Otherwise returns a view to the input.
std::string_view getLegacyEnc(std::string_view input); std::string_view getLegacyEnc(std::string_view input);
const StatelessUtf8Encoder* getStatelessEncoder() const { return &mImpl; } const StatelessUtf8Encoder getStatelessEncoder() const { return mImpl; }
private: private:
std::string mBuffer; std::string mBuffer;