mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-03 23:56:43 +00:00 
			
		
		
		
	Cellstore uses RefId.
This commit is contained in:
		
							parent
							
								
									36502eaf75
								
							
						
					
					
						commit
						96e42d1666
					
				
					 3 changed files with 34 additions and 57 deletions
				
			
		| 
						 | 
				
			
			@ -1122,21 +1122,9 @@ namespace MWWorld
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct IsEqualVisitor
 | 
			
		||||
    {
 | 
			
		||||
        bool operator()(const ESM::Cell& a, const ESM::Cell& b) const { return a.getCellId() == b.getCellId(); }
 | 
			
		||||
        bool operator()(const ESM4::Cell& a, const ESM4::Cell& b) const { return a.mId == b.mId; }
 | 
			
		||||
 | 
			
		||||
        template <class L, class R>
 | 
			
		||||
        bool operator()(const L&, const R&) const
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    bool CellStore::operator==(const CellStore& right) const
 | 
			
		||||
    {
 | 
			
		||||
        return ESM::visit(IsEqualVisitor(), this->mCellVariant, right.mCellVariant);
 | 
			
		||||
        return right.mCellVariant.getId() == mCellVariant.getId();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void CellStore::setFog(std::unique_ptr<ESM::FogState>&& fog)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,8 @@
 | 
			
		|||
namespace
 | 
			
		||||
{
 | 
			
		||||
    template <class Visitor, class Key, class Comp>
 | 
			
		||||
    bool forEachInStore(const ESM::RefId& id, Visitor&& visitor, std::map<Key, MWWorld::CellStore, Comp>& cellStore)
 | 
			
		||||
    bool forEachInStore(
 | 
			
		||||
        const ESM::RefId& id, Visitor&& visitor, std::unordered_map<Key, MWWorld::CellStore, Comp>& cellStore)
 | 
			
		||||
    {
 | 
			
		||||
        for (auto& cell : cellStore)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -62,27 +63,25 @@ namespace
 | 
			
		|||
 | 
			
		||||
MWWorld::CellStore* MWWorld::WorldModel::getCellStore(const ESM::Cell* cell)
 | 
			
		||||
{
 | 
			
		||||
    CellStore* cellStore = &mCells.emplace(cell->mId, CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first->second;
 | 
			
		||||
    if (cell->mData.mFlags & ESM::Cell::Interior)
 | 
			
		||||
    {
 | 
			
		||||
        auto result = mInteriors.find(cell->mName);
 | 
			
		||||
 | 
			
		||||
        if (result == mInteriors.end())
 | 
			
		||||
            result = mInteriors.emplace(cell->mName, CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first;
 | 
			
		||||
            result = mInteriors.emplace(cell->mName, cellStore).first;
 | 
			
		||||
 | 
			
		||||
        return &result->second;
 | 
			
		||||
        return result->second;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        std::map<std::pair<int, int>, CellStore>::iterator result
 | 
			
		||||
        std::map<std::pair<int, int>, CellStore*>::iterator result
 | 
			
		||||
            = mExteriors.find(std::make_pair(cell->getGridX(), cell->getGridY()));
 | 
			
		||||
 | 
			
		||||
        if (result == mExteriors.end())
 | 
			
		||||
            result = mExteriors
 | 
			
		||||
                         .emplace(std::make_pair(cell->getGridX(), cell->getGridY()),
 | 
			
		||||
                             CellStore(MWWorld::Cell(*cell), mStore, mReaders))
 | 
			
		||||
                         .first;
 | 
			
		||||
            result = mExteriors.emplace(std::make_pair(cell->getGridX(), cell->getGridY()), cellStore).first;
 | 
			
		||||
 | 
			
		||||
        return &result->second;
 | 
			
		||||
        return result->second;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -160,7 +159,7 @@ MWWorld::WorldModel::WorldModel(const MWWorld::ESMStore& store, ESM::ReadersCach
 | 
			
		|||
 | 
			
		||||
MWWorld::CellStore* MWWorld::WorldModel::getExterior(int x, int y)
 | 
			
		||||
{
 | 
			
		||||
    std::map<std::pair<int, int>, CellStore>::iterator result = mExteriors.find(std::make_pair(x, y));
 | 
			
		||||
    std::map<std::pair<int, int>, CellStore*>::iterator result = mExteriors.find(std::make_pair(x, y));
 | 
			
		||||
 | 
			
		||||
    if (result == mExteriors.end())
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -185,15 +184,17 @@ MWWorld::CellStore* MWWorld::WorldModel::getExterior(int x, int y)
 | 
			
		|||
            cell = MWBase::Environment::get().getWorld()->createRecord(record);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        result = mExteriors.emplace(std::make_pair(x, y), CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first;
 | 
			
		||||
        CellStore* cellStore
 | 
			
		||||
            = &mCells.emplace(cell->mId, CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first->second;
 | 
			
		||||
        result = mExteriors.emplace(std::make_pair(x, y), cellStore).first;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (result->second.getState() != CellStore::State_Loaded)
 | 
			
		||||
    if (result->second->getState() != CellStore::State_Loaded)
 | 
			
		||||
    {
 | 
			
		||||
        result->second.load();
 | 
			
		||||
        result->second->load();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return &result->second;
 | 
			
		||||
    return result->second;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MWWorld::CellStore* MWWorld::WorldModel::getInterior(std::string_view name)
 | 
			
		||||
| 
						 | 
				
			
			@ -203,24 +204,26 @@ MWWorld::CellStore* MWWorld::WorldModel::getInterior(std::string_view name)
 | 
			
		|||
    if (result == mInteriors.end())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::Cell* cell4 = mStore.get<ESM4::Cell>().searchCellName(name);
 | 
			
		||||
 | 
			
		||||
        CellStore* newCellStore = nullptr;
 | 
			
		||||
        if (!cell4)
 | 
			
		||||
        {
 | 
			
		||||
            const ESM::Cell* cell = mStore.get<ESM::Cell>().find(name);
 | 
			
		||||
            result = mInteriors.emplace(name, CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first;
 | 
			
		||||
            newCellStore = &mCells.emplace(cell->mId, CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first->second;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            result = mInteriors.emplace(name, CellStore(MWWorld::Cell(*cell4), mStore, mReaders)).first;
 | 
			
		||||
            newCellStore
 | 
			
		||||
                = &mCells.emplace(cell4->mId, CellStore(MWWorld::Cell(*cell4), mStore, mReaders)).first->second;
 | 
			
		||||
        }
 | 
			
		||||
        result = mInteriors.emplace(name, newCellStore).first;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (result->second.getState() != CellStore::State_Loaded)
 | 
			
		||||
    if (result->second->getState() != CellStore::State_Loaded)
 | 
			
		||||
    {
 | 
			
		||||
        result->second.load();
 | 
			
		||||
        result->second->load();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return &result->second;
 | 
			
		||||
    return result->second;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MWWorld::CellStore* MWWorld::WorldModel::getCell(const ESM::CellId& id)
 | 
			
		||||
| 
						 | 
				
			
			@ -330,17 +333,17 @@ MWWorld::Ptr MWWorld::WorldModel::getPtr(const ESM::RefId& name)
 | 
			
		|||
    // Then check cells that are already listed
 | 
			
		||||
    // Search in reverse, this is a workaround for an ambiguous chargen_plank reference in the vanilla game.
 | 
			
		||||
    // there is one at -22,16 and one at -2,-9, the latter should be used.
 | 
			
		||||
    for (std::map<std::pair<int, int>, CellStore>::reverse_iterator iter = mExteriors.rbegin();
 | 
			
		||||
    for (std::map<std::pair<int, int>, CellStore*>::reverse_iterator iter = mExteriors.rbegin();
 | 
			
		||||
         iter != mExteriors.rend(); ++iter)
 | 
			
		||||
    {
 | 
			
		||||
        Ptr ptr = getPtrAndCache(name, iter->second);
 | 
			
		||||
        Ptr ptr = getPtrAndCache(name, *iter->second);
 | 
			
		||||
        if (!ptr.isEmpty())
 | 
			
		||||
            return ptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (auto iter = mInteriors.begin(); iter != mInteriors.end(); ++iter)
 | 
			
		||||
    {
 | 
			
		||||
        Ptr ptr = getPtrAndCache(name, iter->second);
 | 
			
		||||
        Ptr ptr = getPtrAndCache(name, *iter->second);
 | 
			
		||||
        if (!ptr.isEmpty())
 | 
			
		||||
            return ptr;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -390,8 +393,7 @@ void MWWorld::WorldModel::getExteriorPtrs(const ESM::RefId& name, std::vector<MW
 | 
			
		|||
std::vector<MWWorld::Ptr> MWWorld::WorldModel::getAll(const ESM::RefId& id)
 | 
			
		||||
{
 | 
			
		||||
    PtrCollector visitor;
 | 
			
		||||
    if (forEachInStore(id, visitor, mInteriors))
 | 
			
		||||
        forEachInStore(id, visitor, mExteriors);
 | 
			
		||||
    forEachInStore(id, visitor, mCells);
 | 
			
		||||
    return visitor.mPtrs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -399,12 +401,7 @@ int MWWorld::WorldModel::countSavedGameRecords() const
 | 
			
		|||
{
 | 
			
		||||
    int count = 0;
 | 
			
		||||
 | 
			
		||||
    for (auto iter(mInteriors.begin()); iter != mInteriors.end(); ++iter)
 | 
			
		||||
        if (iter->second.hasState())
 | 
			
		||||
            ++count;
 | 
			
		||||
 | 
			
		||||
    for (std::map<std::pair<int, int>, CellStore>::const_iterator iter(mExteriors.begin()); iter != mExteriors.end();
 | 
			
		||||
         ++iter)
 | 
			
		||||
    for (auto iter(mCells.begin()); iter != mCells.end(); ++iter)
 | 
			
		||||
        if (iter->second.hasState())
 | 
			
		||||
            ++count;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -413,14 +410,7 @@ int MWWorld::WorldModel::countSavedGameRecords() const
 | 
			
		|||
 | 
			
		||||
void MWWorld::WorldModel::write(ESM::ESMWriter& writer, Loading::Listener& progress) const
 | 
			
		||||
{
 | 
			
		||||
    for (std::map<std::pair<int, int>, CellStore>::iterator iter(mExteriors.begin()); iter != mExteriors.end(); ++iter)
 | 
			
		||||
        if (iter->second.hasState())
 | 
			
		||||
        {
 | 
			
		||||
            writeCell(writer, iter->second);
 | 
			
		||||
            progress.increaseProgress();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    for (auto iter(mInteriors.begin()); iter != mInteriors.end(); ++iter)
 | 
			
		||||
    for (auto iter(mCells.begin()); iter != mCells.end(); ++iter)
 | 
			
		||||
        if (iter->second.hasState())
 | 
			
		||||
        {
 | 
			
		||||
            writeCell(writer, iter->second);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,8 +42,9 @@ namespace MWWorld
 | 
			
		|||
        typedef std::vector<std::pair<ESM::RefId, CellStore*>> IdCache;
 | 
			
		||||
        const MWWorld::ESMStore& mStore;
 | 
			
		||||
        ESM::ReadersCache& mReaders;
 | 
			
		||||
        mutable std::map<std::string, CellStore, Misc::StringUtils::CiComp> mInteriors;
 | 
			
		||||
        mutable std::map<std::pair<int, int>, CellStore> mExteriors;
 | 
			
		||||
        mutable std::unordered_map<ESM::RefId, CellStore> mCells;
 | 
			
		||||
        mutable std::map<std::string, CellStore*, Misc::StringUtils::CiComp> mInteriors;
 | 
			
		||||
        mutable std::map<std::pair<int, int>, CellStore*> mExteriors;
 | 
			
		||||
        IdCache mIdCache;
 | 
			
		||||
        std::size_t mIdCacheIndex = 0;
 | 
			
		||||
        std::unordered_map<ESM::RefNum, Ptr> mPtrIndex;
 | 
			
		||||
| 
						 | 
				
			
			@ -91,9 +92,7 @@ namespace MWWorld
 | 
			
		|||
        template <typename Fn>
 | 
			
		||||
        void forEachLoadedCellStore(Fn&& fn)
 | 
			
		||||
        {
 | 
			
		||||
            for (auto& [_, store] : mInteriors)
 | 
			
		||||
                fn(store);
 | 
			
		||||
            for (auto& [_, store] : mExteriors)
 | 
			
		||||
            for (auto& [_, store] : mCells)
 | 
			
		||||
                fn(store);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue