mapsector.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. Minetest
  3. Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #include "mapsector.h"
  17. #include "exceptions.h"
  18. #include "mapblock.h"
  19. #include "serialization.h"
  20. MapSector::MapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
  21. m_parent(parent),
  22. m_pos(pos),
  23. m_gamedef(gamedef)
  24. {
  25. }
  26. MapSector::~MapSector()
  27. {
  28. deleteBlocks();
  29. }
  30. void MapSector::deleteBlocks()
  31. {
  32. // Clear cache
  33. m_block_cache = nullptr;
  34. // Delete all blocks
  35. m_blocks.clear();
  36. }
  37. MapBlock *MapSector::getBlockBuffered(s16 y)
  38. {
  39. MapBlock *block;
  40. if (m_block_cache && y == m_block_cache_y) {
  41. return m_block_cache;
  42. }
  43. // If block doesn't exist, return NULL
  44. auto it = m_blocks.find(y);
  45. block = it != m_blocks.end() ? it->second.get() : nullptr;
  46. // Cache the last result
  47. m_block_cache_y = y;
  48. m_block_cache = block;
  49. return block;
  50. }
  51. MapBlock *MapSector::getBlockNoCreateNoEx(s16 y)
  52. {
  53. return getBlockBuffered(y);
  54. }
  55. std::unique_ptr<MapBlock> MapSector::createBlankBlockNoInsert(s16 y)
  56. {
  57. assert(getBlockBuffered(y) == nullptr); // Pre-condition
  58. if (blockpos_over_max_limit(v3s16(0, y, 0)))
  59. throw InvalidPositionException("createBlankBlockNoInsert(): pos over max mapgen limit");
  60. v3s16 blockpos_map(m_pos.X, y, m_pos.Y);
  61. return std::make_unique<MapBlock>(blockpos_map, m_gamedef);
  62. }
  63. MapBlock *MapSector::createBlankBlock(s16 y)
  64. {
  65. std::unique_ptr<MapBlock> block_u = createBlankBlockNoInsert(y);
  66. MapBlock *block = block_u.get();
  67. m_blocks[y] = std::move(block_u);
  68. return block;
  69. }
  70. void MapSector::insertBlock(std::unique_ptr<MapBlock> block)
  71. {
  72. s16 block_y = block->getPos().Y;
  73. MapBlock *block2 = getBlockBuffered(block_y);
  74. if (block2) {
  75. throw AlreadyExistsException("Block already exists");
  76. }
  77. v2s16 p2d(block->getPos().X, block->getPos().Z);
  78. assert(p2d == m_pos);
  79. // Insert into container
  80. m_blocks[block_y] = std::move(block);
  81. }
  82. void MapSector::deleteBlock(MapBlock *block)
  83. {
  84. detachBlock(block);
  85. // returned smart-ptr is dropped
  86. }
  87. std::unique_ptr<MapBlock> MapSector::detachBlock(MapBlock *block)
  88. {
  89. s16 block_y = block->getPos().Y;
  90. // Clear from cache
  91. m_block_cache = nullptr;
  92. // Remove from container
  93. auto it = m_blocks.find(block_y);
  94. assert(it != m_blocks.end());
  95. std::unique_ptr<MapBlock> ret = std::move(it->second);
  96. assert(ret.get() == block);
  97. m_blocks.erase(it);
  98. // Mark as removed
  99. block->makeOrphan();
  100. return ret;
  101. }
  102. void MapSector::getBlocks(MapBlockVect &dest)
  103. {
  104. dest.reserve(dest.size() + m_blocks.size());
  105. for (auto &block : m_blocks) {
  106. dest.push_back(block.second.get());
  107. }
  108. }