add blocks_agent templates & remove block.get_slow

This commit is contained in:
MihailRis
2024-12-16 11:26:57 +03:00
parent 5bf56d1f64
commit 6157f8193d
9 changed files with 158 additions and 104 deletions
+45 -38
View File
@@ -16,10 +16,10 @@
#include "Block.hpp"
#include "Chunk.hpp"
inline long long keyfrom(int x, int z) {
inline uint64_t keyfrom(int32_t x, int32_t z) {
union {
int pos[2];
long long key;
int32_t pos[2];
uint64_t key;
} ekey;
ekey.pos[0] = x;
ekey.pos[1] = z;
@@ -28,7 +28,9 @@ inline long long keyfrom(int x, int z) {
static debug::Logger logger("chunks-storage");
GlobalChunks::GlobalChunks(Level* level) : level(level) {
GlobalChunks::GlobalChunks(Level* level)
: level(level), indices(level ? level->content->getIndices() : nullptr) {
chunksMap.max_load_factor(CHUNKS_MAP_MAX_LOAD_FACTOR);
}
std::shared_ptr<Chunk> GlobalChunks::fetch(int x, int z) {
@@ -67,6 +69,29 @@ void GlobalChunks::erase(int x, int z) {
chunksMap.erase(keyfrom(x, z));
}
static inline auto load_inventories(
WorldRegions& regions,
const Chunk& chunk,
const ContentUnitIndices<Block>& defs
) {
auto invs = regions.fetchInventories(chunk.x, chunk.z);
auto iterator = invs.begin();
while (iterator != invs.end()) {
uint index = iterator->first;
const auto& def = defs.require(chunk.voxels[index].id);
if (def.inventorySize == 0) {
iterator = invs.erase(iterator);
continue;
}
auto& inventory = iterator->second;
if (def.inventorySize != inventory->size()) {
inventory->resize(def.inventorySize);
}
++iterator;
}
return invs;
}
std::shared_ptr<Chunk> GlobalChunks::create(int x, int z) {
const auto& found = chunksMap.find(keyfrom(x, z));
if (found != chunksMap.end()) {
@@ -84,22 +109,10 @@ std::shared_ptr<Chunk> GlobalChunks::create(int x, int z) {
chunk->decode(data.get());
check_voxels(indices, *chunk);
auto invs = regions.fetchInventories(chunk->x, chunk->z);
auto iterator = invs.begin();
while (iterator != invs.end()) {
uint index = iterator->first;
const auto& def = indices.blocks.require(chunk->voxels[index].id);
if (def.inventorySize == 0) {
iterator = invs.erase(iterator);
continue;
}
auto& inventory = iterator->second;
if (def.inventorySize != inventory->size()) {
inventory->resize(def.inventorySize);
}
++iterator;
}
chunk->setBlockInventories(std::move(invs));
chunk->setBlockInventories(
load_inventories(regions, *chunk, indices.blocks)
);
auto entitiesData = regions.fetchEntities(chunk->x, chunk->z);
if (entitiesData.getType() == dv::value_type::object) {
@@ -132,24 +145,6 @@ size_t GlobalChunks::size() const {
return chunksMap.size();
}
voxel* GlobalChunks::get(int x, int y, int z) const {
if (y < 0 || y >= CHUNK_H) {
return nullptr;
}
int cx = floordiv<CHUNK_W>(x);
int cz = floordiv<CHUNK_D>(z);
const auto& found = chunksMap.find(keyfrom(cx, cz));
if (found == chunksMap.end()) {
return nullptr;
}
const auto& chunk = found->second;
int lx = x - cx * CHUNK_W;
int lz = z - cz * CHUNK_D;
return &chunk->voxels[(y * CHUNK_D + lz) * CHUNK_W + lx];
}
void GlobalChunks::incref(Chunk* chunk) {
auto key = reinterpret_cast<ptrdiff_t>(chunk);
const auto& found = refCounters.find(key);
@@ -209,3 +204,15 @@ void GlobalChunks::saveAll() {
save(chunk.get());
}
}
void GlobalChunks::putChunk(std::shared_ptr<Chunk> chunk) {
chunksMap[keyfrom(chunk->x, chunk->z)] = std::move(chunk);
}
Chunk* GlobalChunks::getChunk(int cx, int cz) const {
const auto& found = chunksMap.find(keyfrom(cx, cz));
if (found == chunksMap.end()) {
return nullptr;
}
return found->second.get();
}