BlockStorage.cpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #include "common/BlockStorage.h"
  2. static constexpr Block::Id EMPTY_BLOCK = 65535;
  3. BlockStorage::Map::Map(int length, Block::Id id) : blocks(length, 1) {
  4. blocks.fill(0);
  5. map.reserve(2);
  6. map.add(id);
  7. map.add(EMPTY_BLOCK);
  8. }
  9. Block::Id BlockStorage::Map::get(int index) const {
  10. return map[blocks.get(index)];
  11. }
  12. void BlockStorage::Map::set(int index, Block::Id id) {
  13. for(int i = 0; i < map.getLength(); i++) {
  14. if(map[i] == id) {
  15. blocks.set(index, i);
  16. return;
  17. } else if(map[i] == EMPTY_BLOCK) {
  18. map[i] = id;
  19. blocks.set(index, i);
  20. return;
  21. }
  22. }
  23. blocks.resize(blocks.getBits() + 1);
  24. int mapId = map.getLength();
  25. map.resize(mapId * 2, EMPTY_BLOCK);
  26. map[mapId] = id;
  27. blocks.set(index, mapId);
  28. }
  29. BlockStorage::BlockStorage(int sizeBits, int heightBits)
  30. : size(1 << sizeBits), height(1 << heightBits), sizeMask(size - 1) {
  31. maps.resize((size * size * height) / SEGMENT);
  32. }
  33. Block::Id BlockStorage::get(int x, int y, int z) const {
  34. if(y < 0 || y >= height) {
  35. return y < 0;
  36. }
  37. x &= (size - 1);
  38. z &= (size - 1);
  39. int index = y * size * size + x * size + z;
  40. int segmentIndex = index >> SEGMENT_BITS;
  41. if(maps[segmentIndex] == nullptr) {
  42. return 0;
  43. }
  44. return maps[segmentIndex]->get(index & SEGMENT_MASK);
  45. }
  46. void BlockStorage::set(int x, int y, int z, Block::Id id) {
  47. if(y < 0 || y >= height) {
  48. return;
  49. }
  50. x &= (size - 1);
  51. z &= (size - 1);
  52. int index = y * size * size + x * size + z;
  53. int segmentIndex = index >> SEGMENT_BITS;
  54. if(maps[segmentIndex] == nullptr) {
  55. if(id == 0) {
  56. return;
  57. }
  58. maps[segmentIndex] = new Map(SEGMENT, 0);
  59. }
  60. maps[segmentIndex]->set(index & SEGMENT_MASK, id);
  61. }
  62. int BlockStorage::getSize() const {
  63. return size;
  64. }
  65. int BlockStorage::getHeight() const {
  66. return height;
  67. }