Use unique_ptr for ESM records

C++20
ζeh Matt 3 years ago
parent 251327fb9c
commit 07eb6db030
No known key found for this signature in database
GPG Key ID: 18CE582C71A225B0

@ -6,6 +6,7 @@
#include <map> #include <map>
#include <fstream> #include <fstream>
#include <cmath> #include <cmath>
#include <memory>
#include <boost/program_options.hpp> #include <boost/program_options.hpp>
@ -27,7 +28,7 @@ struct ESMData
unsigned int version; unsigned int version;
std::vector<ESM::Header::MasterData> masters; std::vector<ESM::Header::MasterData> masters;
std::deque<EsmTool::RecordBase *> mRecords; std::deque<std::unique_ptr<EsmTool::RecordBase>> mRecords;
// Value: (Reference, Deleted flag) // Value: (Reference, Deleted flag)
std::map<ESM::Cell *, std::deque<std::pair<ESM::CellRef, bool> > > mCellRefs; std::map<ESM::Cell *, std::deque<std::pair<ESM::CellRef, bool> > > mCellRefs;
std::map<int, int> mRecordStats; std::map<int, int> mRecordStats;
@ -363,7 +364,7 @@ int load(Arguments& info)
uint32_t flags; uint32_t flags;
esm.getRecHeader(flags); esm.getRecHeader(flags);
EsmTool::RecordBase *record = EsmTool::RecordBase::create(n); auto record = EsmTool::RecordBase::create(n);
if (record == nullptr) if (record == nullptr)
{ {
if (skipped.count(n.toInt()) == 0) if (skipped.count(n.toInt()) == 0)
@ -408,11 +409,7 @@ int load(Arguments& info)
if (save) if (save)
{ {
info.data.mRecords.push_back(record); info.data.mRecords.push_back(std::move(record));
}
else
{
delete record;
} }
++info.data.mRecordStats[n.toInt()]; ++info.data.mRecordStats[n.toInt()];
} }
@ -420,9 +417,6 @@ int load(Arguments& info)
} catch(std::exception &e) { } catch(std::exception &e) {
std::cout << "\nERROR:\n\n " << e.what() << std::endl; std::cout << "\nERROR:\n\n " << e.what() << std::endl;
for (const EsmTool::RecordBase* record : info.data.mRecords)
delete record;
info.data.mRecords.clear(); info.data.mRecords.clear();
return 1; return 1;
} }
@ -485,7 +479,7 @@ int clone(Arguments& info)
esm.save(save); esm.save(save);
int saved = 0; int saved = 0;
for (EsmTool::RecordBase* record : info.data.mRecords) for (auto& record : info.data.mRecords)
{ {
if (i <= 0) if (i <= 0)
break; break;

@ -171,226 +171,227 @@ void printTransport(const std::vector<ESM::Transport::Dest>& transport)
namespace EsmTool { namespace EsmTool {
RecordBase * std::unique_ptr<RecordBase> RecordBase::create(const ESM::NAME type)
RecordBase::create(const ESM::NAME type)
{ {
RecordBase *record = nullptr; std::unique_ptr<RecordBase> record;
switch (type.toInt()) { switch (type.toInt())
{
case ESM::REC_ACTI: case ESM::REC_ACTI:
{ {
record = new EsmTool::Record<ESM::Activator>; record = std::make_unique<EsmTool::Record<ESM::Activator>>();
break; break;
} }
case ESM::REC_ALCH: case ESM::REC_ALCH:
{ {
record = new EsmTool::Record<ESM::Potion>; record = std::make_unique<EsmTool::Record<ESM::Potion>>();
break; break;
} }
case ESM::REC_APPA: case ESM::REC_APPA:
{ {
record = new EsmTool::Record<ESM::Apparatus>; record = std::make_unique<EsmTool::Record<ESM::Apparatus>>();
break; break;
} }
case ESM::REC_ARMO: case ESM::REC_ARMO:
{ {
record = new EsmTool::Record<ESM::Armor>; record = std::make_unique<EsmTool::Record<ESM::Armor>>();
break; break;
} }
case ESM::REC_BODY: case ESM::REC_BODY:
{ {
record = new EsmTool::Record<ESM::BodyPart>; record = std::make_unique<EsmTool::Record<ESM::BodyPart>>();
break; break;
} }
case ESM::REC_BOOK: case ESM::REC_BOOK:
{ {
record = new EsmTool::Record<ESM::Book>; record = std::make_unique<EsmTool::Record<ESM::Book>>();
break; break;
} }
case ESM::REC_BSGN: case ESM::REC_BSGN:
{ {
record = new EsmTool::Record<ESM::BirthSign>; record = std::make_unique<EsmTool::Record<ESM::BirthSign>>();
break; break;
} }
case ESM::REC_CELL: case ESM::REC_CELL:
{ {
record = new EsmTool::Record<ESM::Cell>; record = std::make_unique<EsmTool::Record<ESM::Cell>>();
break; break;
} }
case ESM::REC_CLAS: case ESM::REC_CLAS:
{ {
record = new EsmTool::Record<ESM::Class>; record = std::make_unique<EsmTool::Record<ESM::Class>>();
break; break;
} }
case ESM::REC_CLOT: case ESM::REC_CLOT:
{ {
record = new EsmTool::Record<ESM::Clothing>; record = std::make_unique<EsmTool::Record<ESM::Clothing>>();
break; break;
} }
case ESM::REC_CONT: case ESM::REC_CONT:
{ {
record = new EsmTool::Record<ESM::Container>; record = std::make_unique<EsmTool::Record<ESM::Container>>();
break; break;
} }
case ESM::REC_CREA: case ESM::REC_CREA:
{ {
record = new EsmTool::Record<ESM::Creature>; record = std::make_unique<EsmTool::Record<ESM::Creature>>();
break; break;
} }
case ESM::REC_DIAL: case ESM::REC_DIAL:
{ {
record = new EsmTool::Record<ESM::Dialogue>; record = std::make_unique<EsmTool::Record<ESM::Dialogue>>();
break; break;
} }
case ESM::REC_DOOR: case ESM::REC_DOOR:
{ {
record = new EsmTool::Record<ESM::Door>; record = std::make_unique<EsmTool::Record<ESM::Door>>();
break; break;
} }
case ESM::REC_ENCH: case ESM::REC_ENCH:
{ {
record = new EsmTool::Record<ESM::Enchantment>; record = std::make_unique<EsmTool::Record<ESM::Enchantment>>();
break; break;
} }
case ESM::REC_FACT: case ESM::REC_FACT:
{ {
record = new EsmTool::Record<ESM::Faction>; record = std::make_unique<EsmTool::Record<ESM::Faction>>();
break; break;
} }
case ESM::REC_GLOB: case ESM::REC_GLOB:
{ {
record = new EsmTool::Record<ESM::Global>; record = std::make_unique<EsmTool::Record<ESM::Global>>();
break; break;
} }
case ESM::REC_GMST: case ESM::REC_GMST:
{ {
record = new EsmTool::Record<ESM::GameSetting>; record = std::make_unique<EsmTool::Record<ESM::GameSetting>>();
break; break;
} }
case ESM::REC_INFO: case ESM::REC_INFO:
{ {
record = new EsmTool::Record<ESM::DialInfo>; record = std::make_unique<EsmTool::Record<ESM::DialInfo>>();
break; break;
} }
case ESM::REC_INGR: case ESM::REC_INGR:
{ {
record = new EsmTool::Record<ESM::Ingredient>; record = std::make_unique<EsmTool::Record<ESM::Ingredient>>();
break; break;
} }
case ESM::REC_LAND: case ESM::REC_LAND:
{ {
record = new EsmTool::Record<ESM::Land>; record = std::make_unique<EsmTool::Record<ESM::Land>>();
break; break;
} }
case ESM::REC_LEVI: case ESM::REC_LEVI:
{ {
record = new EsmTool::Record<ESM::ItemLevList>; record = std::make_unique<EsmTool::Record<ESM::ItemLevList>>();
break; break;
} }
case ESM::REC_LEVC: case ESM::REC_LEVC:
{ {
record = new EsmTool::Record<ESM::CreatureLevList>; record = std::make_unique<EsmTool::Record<ESM::CreatureLevList>>();
break; break;
} }
case ESM::REC_LIGH: case ESM::REC_LIGH:
{ {
record = new EsmTool::Record<ESM::Light>; record = std::make_unique<EsmTool::Record<ESM::Light>>();
break; break;
} }
case ESM::REC_LOCK: case ESM::REC_LOCK:
{ {
record = new EsmTool::Record<ESM::Lockpick>; record = std::make_unique<EsmTool::Record<ESM::Lockpick>>();
break; break;
} }
case ESM::REC_LTEX: case ESM::REC_LTEX:
{ {
record = new EsmTool::Record<ESM::LandTexture>; record = std::make_unique<EsmTool::Record<ESM::LandTexture>>();
break; break;
} }
case ESM::REC_MISC: case ESM::REC_MISC:
{ {
record = new EsmTool::Record<ESM::Miscellaneous>; record = std::make_unique<EsmTool::Record<ESM::Miscellaneous>>();
break; break;
} }
case ESM::REC_MGEF: case ESM::REC_MGEF:
{ {
record = new EsmTool::Record<ESM::MagicEffect>; record = std::make_unique<EsmTool::Record<ESM::MagicEffect>>();
break; break;
} }
case ESM::REC_NPC_: case ESM::REC_NPC_:
{ {
record = new EsmTool::Record<ESM::NPC>; record = std::make_unique<EsmTool::Record<ESM::NPC>>();
break; break;
} }
case ESM::REC_PGRD: case ESM::REC_PGRD:
{ {
record = new EsmTool::Record<ESM::Pathgrid>; record = std::make_unique<EsmTool::Record<ESM::Pathgrid>>();
break; break;
} }
case ESM::REC_PROB: case ESM::REC_PROB:
{ {
record = new EsmTool::Record<ESM::Probe>; record = std::make_unique<EsmTool::Record<ESM::Probe>>();
break; break;
} }
case ESM::REC_RACE: case ESM::REC_RACE:
{ {
record = new EsmTool::Record<ESM::Race>; record = std::make_unique<EsmTool::Record<ESM::Race>>();
break; break;
} }
case ESM::REC_REGN: case ESM::REC_REGN:
{ {
record = new EsmTool::Record<ESM::Region>; record = std::make_unique<EsmTool::Record<ESM::Region>>();
break; break;
} }
case ESM::REC_REPA: case ESM::REC_REPA:
{ {
record = new EsmTool::Record<ESM::Repair>; record = std::make_unique<EsmTool::Record<ESM::Repair>>();
break; break;
} }
case ESM::REC_SCPT: case ESM::REC_SCPT:
{ {
record = new EsmTool::Record<ESM::Script>; record = std::make_unique<EsmTool::Record<ESM::Script>>();
break; break;
} }
case ESM::REC_SKIL: case ESM::REC_SKIL:
{ {
record = new EsmTool::Record<ESM::Skill>; record = std::make_unique<EsmTool::Record<ESM::Skill>>();
break; break;
} }
case ESM::REC_SNDG: case ESM::REC_SNDG:
{ {
record = new EsmTool::Record<ESM::SoundGenerator>; record = std::make_unique<EsmTool::Record<ESM::SoundGenerator>>();
break; break;
} }
case ESM::REC_SOUN: case ESM::REC_SOUN:
{ {
record = new EsmTool::Record<ESM::Sound>; record = std::make_unique<EsmTool::Record<ESM::Sound>>();
break; break;
} }
case ESM::REC_SPEL: case ESM::REC_SPEL:
{ {
record = new EsmTool::Record<ESM::Spell>; record = std::make_unique<EsmTool::Record<ESM::Spell>>();
break; break;
} }
case ESM::REC_STAT: case ESM::REC_STAT:
{ {
record = new EsmTool::Record<ESM::Static>; record = std::make_unique<EsmTool::Record<ESM::Static>>();
break; break;
} }
case ESM::REC_WEAP: case ESM::REC_WEAP:
{ {
record = new EsmTool::Record<ESM::Weapon>; record = std::make_unique<EsmTool::Record<ESM::Weapon>>();
break; break;
} }
case ESM::REC_SSCR: case ESM::REC_SSCR:
{ {
record = new EsmTool::Record<ESM::StartScript>; record = std::make_unique<EsmTool::Record<ESM::StartScript>>();
break; break;
} }
default: default:
record = nullptr; break;
} }
if (record) { if (record)
{
record->mType = type; record->mType = type;
} }
return record; return record;

@ -2,6 +2,7 @@
#define OPENMW_ESMTOOL_RECORD_H #define OPENMW_ESMTOOL_RECORD_H
#include <string> #include <string>
#include <memory>
#include <components/esm/records.hpp> #include <components/esm/records.hpp>
@ -54,7 +55,7 @@ namespace EsmTool
virtual void save(ESM::ESMWriter &esm) = 0; virtual void save(ESM::ESMWriter &esm) = 0;
virtual void print() = 0; virtual void print() = 0;
static RecordBase *create(ESM::NAME type); static std::unique_ptr<RecordBase> create(ESM::NAME type);
// just make it a bit shorter // just make it a bit shorter
template <class T> template <class T>

Loading…
Cancel
Save