mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-26 14:56:39 +00:00 
			
		
		
		
	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(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 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 | ||||
|     { | ||||
|         std::string mId; | ||||
|         std::vector<std::pair<std::string, bool> > mRefs; // ID, modified
 | ||||
|         std::vector<std::string> mDeletedRefs; | ||||
| 
 | ||||
|         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; | ||||
|     mReader = 0; | ||||
|     mDialogue = 0; | ||||
|     mRefLoadCache.clear(); | ||||
| 
 | ||||
|     mReader = new ESM::ESMReader; | ||||
|     mReader->setEncoder (&mEncoder); | ||||
|  | @ -513,6 +514,7 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages) | |||
|         delete mReader; | ||||
|         mReader = 0; | ||||
|         mDialogue = 0; | ||||
|         mRefLoadCache.clear(); | ||||
|         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_CELL: | ||||
|         { | ||||
|             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; | ||||
|         } | ||||
| 
 | ||||
|         case ESM::REC_ACTI: mReferenceables.load (*mReader, mBase, UniversalId::Type_Activator); 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
 | ||||
|             bool mBase; | ||||
|             bool mProject; | ||||
|             std::map<std::string, std::map<ESM::CellRef::RefNum, std::string> > mRefLoadCache; | ||||
| 
 | ||||
|             // not implemented
 | ||||
|             Data (const Data&); | ||||
|  |  | |||
|  | @ -1,12 +1,2 @@ | |||
| 
 | ||||
| #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> | ||||
| 
 | ||||
| namespace ESM | ||||
| { | ||||
|     class ESMReader; | ||||
| } | ||||
| 
 | ||||
| namespace CSMWorld | ||||
| { | ||||
|     class Cell; | ||||
|  | @ -17,9 +12,6 @@ namespace CSMWorld | |||
|     { | ||||
|         std::string mId; | ||||
|         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 <components/misc/stringops.hpp> | ||||
| 
 | ||||
| #include "ref.hpp" | ||||
| #include "cell.hpp" | ||||
| #include "universalid.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); | ||||
| 
 | ||||
|  | @ -17,19 +20,48 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool | |||
|     CellRef ref; | ||||
| 
 | ||||
|     bool deleted = false; | ||||
|     while (cell2.getNextRef (reader, ref, deleted)) | ||||
| 
 | ||||
|     while (ESM::Cell::getNextRef (reader, ref, deleted)) | ||||
|     { | ||||
|         /// \todo handle deleted and moved references
 | ||||
|         ref.load (reader, cell2, getNewId()); | ||||
|         ref.mCell = cell2.mId; | ||||
| 
 | ||||
|         Record<CellRef> record2; | ||||
|         record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; | ||||
|         (base ? record2.mBase : record2.mModified) = ref; | ||||
|         /// \todo handle moved references
 | ||||
| 
 | ||||
|         appendRecord (record2); | ||||
|         if (deleted) | ||||
|         { | ||||
|             /// \todo handle deleted references
 | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|     mCells.setRecord (cellIndex, cell); | ||||
|         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); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| std::string CSMWorld::RefCollection::getNewId() | ||||
|  |  | |||
|  | @ -1,6 +1,8 @@ | |||
| #ifndef CSM_WOLRD_REFCOLLECTION_H | ||||
| #define CSM_WOLRD_REFCOLLECTION_H | ||||
| 
 | ||||
| #include <map> | ||||
| 
 | ||||
| #include "collection.hpp" | ||||
| #include "ref.hpp" | ||||
| #include "record.hpp" | ||||
|  | @ -22,7 +24,8 @@ namespace CSMWorld | |||
|               : 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.
 | ||||
| 
 | ||||
|             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; | ||||
| } | ||||
| 
 | ||||
| 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); | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue