From 6a3b6c6e4fd9af977ab1d4265011c5fe2ad8541a Mon Sep 17 00:00:00 2001 From: elsid Date: Thu, 1 Jun 2023 23:08:47 +0200 Subject: [PATCH] Fix handling deleted DIAL records * Use composite RefId to remove INFO record of deleted DIAL record. OrderedInfo stores original RefId while InfoCollection stores composite one. * Do not erase deleted topic from InfoOrderByTopic map. To keep all deleted record ids for InfoCollection::sort call to make sure reorderRowsImp is called with correct number of indices. --- apps/opencs/model/world/data.cpp | 9 ++++----- apps/opencs/model/world/infocollection.cpp | 14 +++++++------- apps/opencs/model/world/infocollection.hpp | 2 ++ 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 44b162ac15..78fa2dd066 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -73,17 +73,18 @@ namespace CSMWorld for (const OrderedInfo& info : topicInfoOrder->second.getOrderedInfo()) { - const Record& record = infoCollection.getRecord(info.mId); + const ESM::RefId id = makeCompositeInfoRefId(dialogueId, info.mId); + const Record& record = infoCollection.getRecord(id); if (record.mState == RecordBase::State_ModifiedOnly) { - erasedRecords.push_back(infoCollection.searchId(info.mId)); + erasedRecords.push_back(infoCollection.searchId(id)); continue; } auto deletedRecord = std::make_unique>(record); deletedRecord->mState = RecordBase::State_Deleted; - infoCollection.setRecord(infoCollection.searchId(info.mId), std::move(deletedRecord)); + infoCollection.setRecord(infoCollection.searchId(id), std::move(deletedRecord)); } while (!erasedRecords.empty()) @@ -91,8 +92,6 @@ namespace CSMWorld infoCollection.removeRows(erasedRecords.back(), 1); erasedRecords.pop_back(); } - - infoOrders.erase(topicInfoOrder); } } } diff --git a/apps/opencs/model/world/infocollection.cpp b/apps/opencs/model/world/infocollection.cpp index a038b1046b..736d72ddef 100644 --- a/apps/opencs/model/world/infocollection.cpp +++ b/apps/opencs/model/world/infocollection.cpp @@ -18,16 +18,16 @@ namespace CSMWorld { namespace { - ESM::RefId makeCompositeRefId(const ESM::RefId& topicId, const ESM::RefId& infoId) - { - return ESM::RefId::stringRefId(topicId.getRefIdString() + '#' + infoId.getRefIdString()); - } - std::string_view getInfoTopicId(const ESM::RefId& infoId) { return parseInfoRefId(infoId).first; } } + + ESM::RefId makeCompositeInfoRefId(const ESM::RefId& topicId, const ESM::RefId& infoId) + { + return ESM::RefId::stringRefId(topicId.getRefIdString() + '#' + infoId.getRefIdString()); + } } void CSMWorld::InfoCollection::load(const Info& value, bool base) @@ -65,7 +65,7 @@ void CSMWorld::InfoCollection::load( info.load(reader, isDeleted); - const ESM::RefId id = makeCompositeRefId(dialogue.mId, info.mId); + const ESM::RefId id = makeCompositeInfoRefId(dialogue.mId, info.mId); if (isDeleted) { @@ -107,7 +107,7 @@ void CSMWorld::InfoCollection::sort(const InfoOrderByTopic& infoOrders) order.reserve(getSize()); for (const auto& [topicId, infoOrder] : infoOrders) for (const OrderedInfo& info : infoOrder.getOrderedInfo()) - order.push_back(getIndex(makeCompositeRefId(topicId, info.mId))); + order.push_back(getIndex(makeCompositeInfoRefId(topicId, info.mId))); reorderRowsImp(order); } diff --git a/apps/opencs/model/world/infocollection.hpp b/apps/opencs/model/world/infocollection.hpp index 3853954a08..a26bd50dfd 100644 --- a/apps/opencs/model/world/infocollection.hpp +++ b/apps/opencs/model/world/infocollection.hpp @@ -55,6 +55,8 @@ namespace CSMWorld bool reorderRows(int baseIndex, const std::vector& newOrder) override; }; + + ESM::RefId makeCompositeInfoRefId(const ESM::RefId& topicId, const ESM::RefId& infoId); } #endif