1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-27 14:37:04 +00:00

Use unique_ptr to manage nif record lifetime

This commit is contained in:
elsid 2022-02-11 20:40:38 +01:00
parent 2a7d28712f
commit d097c16206
No known key found for this signature in database
GPG Key ID: B845CB9FEE18AB40
2 changed files with 9 additions and 17 deletions

View File

@ -17,17 +17,11 @@ NIFFile::NIFFile(Files::IStreamPtr stream, const std::string &name)
parse(stream); parse(stream);
} }
NIFFile::~NIFFile() template <typename NodeType> static std::unique_ptr<Record> construct() { return std::make_unique<NodeType>(); }
{
for (Record* record : records)
delete record;
}
template <typename NodeType> static Record* construct() { return new NodeType; }
struct RecordFactoryEntry { struct RecordFactoryEntry {
using create_t = Record* (*)(); using create_t = std::unique_ptr<Record> (*)();
create_t mCreate; create_t mCreate;
RecordType mType; RecordType mType;
@ -290,7 +284,7 @@ void NIFFile::parse(Files::IStreamPtr stream)
const bool hasRecordSeparators = ver >= NIFStream::generateVersion(10,0,0,0) && ver < NIFStream::generateVersion(10,2,0,0); const bool hasRecordSeparators = ver >= NIFStream::generateVersion(10,0,0,0) && ver < NIFStream::generateVersion(10,2,0,0);
for (std::size_t i = 0; i < recNum; i++) for (std::size_t i = 0; i < recNum; i++)
{ {
Record *r = nullptr; std::unique_ptr<Record> r;
std::string rec = hasRecTypeListings ? recTypes[recTypeIndices[i]] : nif.getString(); std::string rec = hasRecTypeListings ? recTypes[recTypeIndices[i]] : nif.getString();
if(rec.empty()) if(rec.empty())
@ -315,7 +309,7 @@ void NIFFile::parse(Files::IStreamPtr stream)
if (entry != factories.end()) if (entry != factories.end())
{ {
r = entry->second.mCreate (); r = entry->second.mCreate();
r->recType = entry->second.mType; r->recType = entry->second.mType;
} }
else else
@ -328,8 +322,8 @@ void NIFFile::parse(Files::IStreamPtr stream)
assert(r->recType != RC_MISSING); assert(r->recType != RC_MISSING);
r->recName = rec; r->recName = rec;
r->recIndex = i; r->recIndex = i;
records[i] = r;
r->read(&nif); r->read(&nif);
records[i] = std::move(r);
} }
const std::size_t rootNum = nif.getUInt(); const std::size_t rootNum = nif.getUInt();
@ -341,7 +335,7 @@ void NIFFile::parse(Files::IStreamPtr stream)
int idx = nif.getInt(); int idx = nif.getInt();
if (idx >= 0 && static_cast<std::size_t>(idx) < records.size()) if (idx >= 0 && static_cast<std::size_t>(idx) < records.size())
{ {
roots[i] = records[idx]; roots[i] = records[idx].get();
} }
else else
{ {
@ -351,7 +345,7 @@ void NIFFile::parse(Files::IStreamPtr stream)
} }
// Once parsing is done, do post-processing. // Once parsing is done, do post-processing.
for (Record* record : records) for (const auto& record : records)
record->post(this); record->post(this);
} }

View File

@ -55,7 +55,7 @@ class NIFFile final : public File
std::string hash; std::string hash;
/// Record list /// Record list
std::vector<Record*> records; std::vector<std::unique_ptr<Record>> records;
/// Root list. This is a select portion of the pointers from records /// Root list. This is a select portion of the pointers from records
std::vector<Record*> roots; std::vector<Record*> roots;
@ -107,13 +107,11 @@ public:
/// Open a NIF stream. The name is used for error messages. /// Open a NIF stream. The name is used for error messages.
NIFFile(Files::IStreamPtr stream, const std::string &name); NIFFile(Files::IStreamPtr stream, const std::string &name);
~NIFFile();
/// Get a given record /// Get a given record
Record *getRecord(size_t index) const override Record *getRecord(size_t index) const override
{ {
Record *res = records.at(index); return records.at(index).get();
return res;
} }
/// Number of records /// Number of records
size_t numRecords() const override { return records.size(); } size_t numRecords() const override { return records.size(); }