forked from teamnwah/openmw-tes3coop
implemented reference record merging
This commit is contained in:
parent
7c149e98e0
commit
d8440e1fdc
10 changed files with 65 additions and 38 deletions
|
@ -18,8 +18,3 @@ void CSMWorld::Cell::load (ESM::ESMReader &esm)
|
||||||
mId = stream.str();
|
mId = stream.str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMWorld::Cell::addRef (const std::string& id)
|
|
||||||
{
|
|
||||||
mRefs.push_back (std::make_pair (id, false));
|
|
||||||
}
|
|
|
@ -15,12 +15,9 @@ namespace CSMWorld
|
||||||
struct Cell : public ESM::Cell
|
struct Cell : public ESM::Cell
|
||||||
{
|
{
|
||||||
std::string mId;
|
std::string mId;
|
||||||
std::vector<std::pair<std::string, bool> > mRefs; // ID, modified
|
|
||||||
std::vector<std::string> mDeletedRefs;
|
|
||||||
|
|
||||||
void load (ESM::ESMReader &esm);
|
void load (ESM::ESMReader &esm);
|
||||||
|
|
||||||
void addRef (const std::string& id);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -489,6 +489,7 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base
|
||||||
delete mReader;
|
delete mReader;
|
||||||
mReader = 0;
|
mReader = 0;
|
||||||
mDialogue = 0;
|
mDialogue = 0;
|
||||||
|
mRefLoadCache.clear();
|
||||||
|
|
||||||
mReader = new ESM::ESMReader;
|
mReader = new ESM::ESMReader;
|
||||||
mReader->setEncoder (&mEncoder);
|
mReader->setEncoder (&mEncoder);
|
||||||
|
@ -513,6 +514,7 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
|
||||||
delete mReader;
|
delete mReader;
|
||||||
mReader = 0;
|
mReader = 0;
|
||||||
mDialogue = 0;
|
mDialogue = 0;
|
||||||
|
mRefLoadCache.clear();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,9 +536,12 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
|
||||||
case ESM::REC_SPEL: mSpells.load (*mReader, mBase); break;
|
case ESM::REC_SPEL: mSpells.load (*mReader, mBase); break;
|
||||||
|
|
||||||
case ESM::REC_CELL:
|
case ESM::REC_CELL:
|
||||||
|
{
|
||||||
mCells.load (*mReader, mBase);
|
mCells.load (*mReader, mBase);
|
||||||
mRefs.load (*mReader, mCells.getSize()-1, mBase);
|
std::string cellId = Misc::StringUtils::lowerCase (mCells.getId (mCells.getSize()-1));
|
||||||
|
mRefs.load (*mReader, mCells.getSize()-1, mBase, mRefLoadCache[cellId]);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ESM::REC_ACTI: mReferenceables.load (*mReader, mBase, UniversalId::Type_Activator); break;
|
case ESM::REC_ACTI: mReferenceables.load (*mReader, mBase, UniversalId::Type_Activator); break;
|
||||||
case ESM::REC_ALCH: mReferenceables.load (*mReader, mBase, UniversalId::Type_Potion); break;
|
case ESM::REC_ALCH: mReferenceables.load (*mReader, mBase, UniversalId::Type_Potion); break;
|
||||||
|
|
|
@ -77,6 +77,7 @@ namespace CSMWorld
|
||||||
const ESM::Dialogue *mDialogue; // last loaded dialogue
|
const ESM::Dialogue *mDialogue; // last loaded dialogue
|
||||||
bool mBase;
|
bool mBase;
|
||||||
bool mProject;
|
bool mProject;
|
||||||
|
std::map<std::string, std::map<ESM::CellRef::RefNum, std::string> > mRefLoadCache;
|
||||||
|
|
||||||
// not implemented
|
// not implemented
|
||||||
Data (const Data&);
|
Data (const Data&);
|
||||||
|
|
|
@ -1,12 +1,2 @@
|
||||||
|
|
||||||
#include "ref.hpp"
|
#include "ref.hpp"
|
||||||
|
|
||||||
#include "cell.hpp"
|
|
||||||
|
|
||||||
void CSMWorld::CellRef::load (ESM::ESMReader &esm, Cell& cell, const std::string& id)
|
|
||||||
{
|
|
||||||
mId = id;
|
|
||||||
mCell = cell.mId;
|
|
||||||
|
|
||||||
cell.addRef (mId);
|
|
||||||
}
|
|
|
@ -3,11 +3,6 @@
|
||||||
|
|
||||||
#include <components/esm/cellref.hpp>
|
#include <components/esm/cellref.hpp>
|
||||||
|
|
||||||
namespace ESM
|
|
||||||
{
|
|
||||||
class ESMReader;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
class Cell;
|
class Cell;
|
||||||
|
@ -17,9 +12,6 @@ namespace CSMWorld
|
||||||
{
|
{
|
||||||
std::string mId;
|
std::string mId;
|
||||||
std::string mCell;
|
std::string mCell;
|
||||||
|
|
||||||
void load (ESM::ESMReader &esm, Cell& cell, const std::string& id);
|
|
||||||
///< Load cell ref and register it with \a cell.
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,15 @@
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
#include "ref.hpp"
|
#include "ref.hpp"
|
||||||
#include "cell.hpp"
|
#include "cell.hpp"
|
||||||
#include "universalid.hpp"
|
#include "universalid.hpp"
|
||||||
#include "record.hpp"
|
#include "record.hpp"
|
||||||
|
|
||||||
void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool base)
|
void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool base,
|
||||||
|
std::map<ESM::CellRef::RefNum, std::string>& cache)
|
||||||
{
|
{
|
||||||
Record<Cell> cell = mCells.getRecord (cellIndex);
|
Record<Cell> cell = mCells.getRecord (cellIndex);
|
||||||
|
|
||||||
|
@ -17,19 +20,48 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
|
||||||
CellRef ref;
|
CellRef ref;
|
||||||
|
|
||||||
bool deleted = false;
|
bool deleted = false;
|
||||||
while (cell2.getNextRef (reader, ref, deleted))
|
|
||||||
|
while (ESM::Cell::getNextRef (reader, ref, deleted))
|
||||||
{
|
{
|
||||||
/// \todo handle deleted and moved references
|
ref.mCell = cell2.mId;
|
||||||
ref.load (reader, cell2, getNewId());
|
|
||||||
|
|
||||||
Record<CellRef> record2;
|
/// \todo handle moved references
|
||||||
record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
|
|
||||||
(base ? record2.mBase : record2.mModified) = ref;
|
|
||||||
|
|
||||||
appendRecord (record2);
|
if (deleted)
|
||||||
|
{
|
||||||
|
/// \todo handle deleted references
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<ESM::CellRef::RefNum, std::string>::iterator iter = cache.find (ref.mRefNum);
|
||||||
|
|
||||||
|
if (iter==cache.end())
|
||||||
|
{
|
||||||
|
// new reference
|
||||||
|
ref.mId = getNewId();
|
||||||
|
|
||||||
|
Record<CellRef> record;
|
||||||
|
record.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
|
||||||
|
(base ? record.mBase : record.mModified) = ref;
|
||||||
|
|
||||||
|
appendRecord (record);
|
||||||
|
|
||||||
|
cache.insert (std::make_pair (ref.mRefNum, ref.mId));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// old reference -> merge
|
||||||
|
ref.mId = iter->second;
|
||||||
|
|
||||||
|
int index = getIndex (ref.mId);
|
||||||
|
|
||||||
|
Record<CellRef> record = getRecord (index);
|
||||||
|
record.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_Modified;
|
||||||
|
(base ? record.mBase : record.mModified) = ref;
|
||||||
|
|
||||||
|
setRecord (index, record);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mCells.setRecord (cellIndex, cell);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CSMWorld::RefCollection::getNewId()
|
std::string CSMWorld::RefCollection::getNewId()
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef CSM_WOLRD_REFCOLLECTION_H
|
#ifndef CSM_WOLRD_REFCOLLECTION_H
|
||||||
#define CSM_WOLRD_REFCOLLECTION_H
|
#define CSM_WOLRD_REFCOLLECTION_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "collection.hpp"
|
#include "collection.hpp"
|
||||||
#include "ref.hpp"
|
#include "ref.hpp"
|
||||||
#include "record.hpp"
|
#include "record.hpp"
|
||||||
|
@ -22,7 +24,8 @@ namespace CSMWorld
|
||||||
: mCells (cells), mNextId (0)
|
: mCells (cells), mNextId (0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void load (ESM::ESMReader& reader, int cellIndex, bool base);
|
void load (ESM::ESMReader& reader, int cellIndex, bool base,
|
||||||
|
std::map<ESM::CellRef::RefNum, std::string>& cache);
|
||||||
///< Load a sequence of references.
|
///< Load a sequence of references.
|
||||||
|
|
||||||
std::string getNewId();
|
std::string getNewId();
|
||||||
|
|
|
@ -172,3 +172,14 @@ bool ESM::operator== (const CellRef::RefNum& left, const CellRef::RefNum& right)
|
||||||
{
|
{
|
||||||
return left.mIndex==right.mIndex && left.mContentFile==right.mContentFile;
|
return left.mIndex==right.mIndex && left.mContentFile==right.mContentFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ESM::operator< (const CellRef::RefNum& left, const CellRef::RefNum& right)
|
||||||
|
{
|
||||||
|
if (left.mIndex<right.mIndex)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (left.mIndex>right.mIndex)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return left.mContentFile<right.mContentFile;
|
||||||
|
}
|
|
@ -95,6 +95,7 @@ namespace ESM
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator== (const CellRef::RefNum& left, const CellRef::RefNum& right);
|
bool operator== (const CellRef::RefNum& left, const CellRef::RefNum& right);
|
||||||
|
bool operator< (const CellRef::RefNum& left, const CellRef::RefNum& right);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue