diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h index 1f080523..17954659 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h +++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h @@ -302,8 +302,6 @@ namespace PolyVox typedef std::map >, BlockPositionCompare> UncompressedBlockMap; - void ensureUncompressedBlockMapHasFreeSpace(void) const; - void initialise(); // A trick to implement specialization of template member functions in template classes. See http://stackoverflow.com/a/4951057 diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl index 44116cd5..47068b36 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl @@ -551,32 +551,49 @@ namespace PolyVox return m_pLastAccessedBlock; } + // Try to find the required block in our block list. std::shared_ptr< UncompressedBlock > pUncompressedBlock = nullptr; - typename UncompressedBlockMap::iterator itUncompressedBlock = m_pBlocks.find(v3dBlockPos); - // check whether the block is already loaded + + // Check whether the block was found. if(itUncompressedBlock != m_pBlocks.end()) { + // The block was found so we can use it. pUncompressedBlock = itUncompressedBlock->second; } else { - // At this point we know that the uncompresed block did not exist in the cache. We will - // create it and add it to the cache, which means we need to make sure there is space. - ensureUncompressedBlockMapHasFreeSpace(); - - // We can now create a new block. - //pUncompressedBlock = new UncompressedBlock(m_uBlockSideLength); + // The blcok was not found so we will create a new one. pUncompressedBlock = std::make_shared< UncompressedBlock >(m_uBlockSideLength); // Pass the block to the Pager to give it a chance to initialise it with any data - Vector3DInt32 v3dLower(uBlockX << m_uBlockSideLengthPower, uBlockY << m_uBlockSideLengthPower, uBlockZ << m_uBlockSideLengthPower); - Vector3DInt32 v3dUpper = v3dLower + Vector3DInt32(m_uBlockSideLength - 1, m_uBlockSideLength - 1, m_uBlockSideLength - 1); - Region reg(v3dLower, v3dUpper); - m_pPager->pageIn(reg, pUncompressedBlock); - + if (m_pPager) + { + Vector3DInt32 v3dLower(uBlockX << m_uBlockSideLengthPower, uBlockY << m_uBlockSideLengthPower, uBlockZ << m_uBlockSideLengthPower); + Vector3DInt32 v3dUpper = v3dLower + Vector3DInt32(m_uBlockSideLength - 1, m_uBlockSideLength - 1, m_uBlockSideLength - 1); + Region reg(v3dLower, v3dUpper); + m_pPager->pageIn(reg, pUncompressedBlock); + } + + while (m_pBlocks.size() + 1 > m_uMaxNumberOfUncompressedBlocks) // +1 ready for new block we will add next. + { + // Find the least recently used block. Hopefully this isn't too slow. + typename UncompressedBlockMap::iterator i; + typename UncompressedBlockMap::iterator itUnloadBlock = m_pBlocks.begin(); + for (i = m_pBlocks.begin(); i != m_pBlocks.end(); i++) + { + if (i->second->m_uBlockLastAccessed < itUnloadBlock->second->m_uBlockLastAccessed) + { + itUnloadBlock = i; + } + } + + // Erase the least recently used block + eraseBlock(itUnloadBlock); + } + // Add our new block to the map. - m_pBlocks.insert(std::make_pair(v3dBlockPos, pUncompressedBlock)); + m_pBlocks.insert(std::make_pair(v3dBlockPos, pUncompressedBlock)); } pUncompressedBlock->m_uBlockLastAccessed = ++m_uTimestamper; @@ -609,28 +626,6 @@ namespace PolyVox return uSizeInBytes; } - template - void LargeVolume::ensureUncompressedBlockMapHasFreeSpace(void) const - { - while(m_pBlocks.size() > m_uMaxNumberOfUncompressedBlocks) - { - // Find the least recently used block. The uncompressed block cache should be - // much smaller than the total number of blocks, so hopefully this isn't too slow. - typename UncompressedBlockMap::iterator i; - typename UncompressedBlockMap::iterator itUnloadBlock = m_pBlocks.begin(); - for(i = m_pBlocks.begin(); i != m_pBlocks.end(); i++) - { - if(i->second->m_uBlockLastAccessed < itUnloadBlock->second->m_uBlockLastAccessed) - { - itUnloadBlock = i; - } - } - - // Erase the least recently used block - eraseBlock(itUnloadBlock); - } - } - template template VoxelType LargeVolume::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType, VoxelType tBorder) const