diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h index f5b22a07..2bd177ea 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h +++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h @@ -315,6 +315,8 @@ namespace PolyVox std::shared_ptr< UncompressedBlock > getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const; + void purgeNullPtrsFromAllBlocks(void) const; + // The block data mutable WeakPtrBlockMap m_pAllBlocks; mutable SharedPtrBlockMap m_pRecentlyUsedBlocks; diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl index bb164054..0247f190 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl @@ -557,6 +557,7 @@ namespace PolyVox pUncompressedBlock = std::make_shared< UncompressedBlock >(v3dBlockPos, m_uBlockSideLength, m_pPager); // As we are loading a new block we should try to ensure we don't go over our target memory usage. + bool erasedBlock = false; while (m_pRecentlyUsedBlocks.size() + 1 > m_uMaxNumberOfUncompressedBlocks) // +1 ready for new block we will add next. { // This should never hit, because it should not have been possible for @@ -575,6 +576,14 @@ namespace PolyVox // Erase the least recently used block m_pRecentlyUsedBlocks.erase(itUnloadBlock); + erasedBlock = true; + } + + // If we've deleted any blocks from the recently used list then this + // seems like a good place to purge the 'all blocks' list as well. + if (erasedBlock) + { + purgeNullPtrsFromAllBlocks(); } // Add our new block to the maps. @@ -612,6 +621,18 @@ namespace PolyVox return uSizeInBytes; } + template + void LargeVolume::purgeNullPtrsFromAllBlocks(void) const + { + for (auto blockIter = m_pAllBlocks.begin(); blockIter != m_pAllBlocks.end(); blockIter++) + { + if (blockIter->second.expired()) + { + blockIter = m_pAllBlocks.erase(blockIter); + } + } + } + template template VoxelType LargeVolume::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType, VoxelType tBorder) const