From c67e4b04bb3b28424d62b88f26b72b92182f44f9 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 7 Jun 2024 14:04:25 +0300 Subject: [PATCH] refactor: WorldRegions and chunks saving --- src/files/WorldRegions.cpp | 24 +++++++++++++++++------- src/files/WorldRegions.hpp | 2 +- src/voxels/Chunk.cpp | 11 +++++++---- src/voxels/Chunk.hpp | 24 ++++++++++++++---------- src/voxels/Chunks.cpp | 11 +++-------- src/voxels/ChunksStorage.cpp | 2 ++ src/world/World.cpp | 20 ++++++-------------- src/world/World.hpp | 1 - 8 files changed, 50 insertions(+), 45 deletions(-) diff --git a/src/files/WorldRegions.cpp b/src/files/WorldRegions.cpp index 7c9f0f5b..24aaa694 100644 --- a/src/files/WorldRegions.cpp +++ b/src/files/WorldRegions.cpp @@ -103,8 +103,9 @@ WorldRegion* WorldRegions::getRegion(int x, int z, int layer) { RegionsLayer& regions = layers[layer]; std::lock_guard lock(regions.mutex); auto found = regions.regions.find(glm::ivec2(x, z)); - if (found == regions.regions.end()) + if (found == regions.regions.end()) { return nullptr; + } return found->second.get(); } @@ -357,6 +358,13 @@ static std::unique_ptr write_inventories(Chunk* chunk, uint& datasize) /// @brief Store chunk data (voxels and lights) in region (existing or new) void WorldRegions::put(Chunk* chunk){ assert(chunk != nullptr); + if (!chunk->flags.lighted) { + return; + } + bool lightsUnsaved = !chunk->flags.loadedLights && doWriteLights; + if (!chunk->flags.unsaved && !lightsUnsaved) { + return; + } int regionX, regionZ, localX, localZ; calc_reg_coords(chunk->x, chunk->z, regionX, regionZ, localX, localZ); @@ -399,11 +407,12 @@ std::unique_ptr WorldRegions::getLights(int x, int z) { } chunk_inventories_map WorldRegions::fetchInventories(int x, int z) { - chunk_inventories_map inventories; + chunk_inventories_map meta; uint32_t bytesSize; const ubyte* data = getData(x, z, REGION_LAYER_INVENTORIES, bytesSize); - if (data == nullptr) - return inventories; + if (data == nullptr) { + return meta; + } ByteReader reader(data, bytesSize); int count = reader.getInt32(); for (int i = 0; i < count; i++) { @@ -413,9 +422,9 @@ chunk_inventories_map WorldRegions::fetchInventories(int x, int z) { reader.skip(size); auto inv = std::make_shared(0, 0); inv->deserialize(map.get()); - inventories[index] = inv; + meta[index] = inv; } - return inventories; + return meta; } void WorldRegions::processRegionVoxels(int x, int z, const regionproc& func) { @@ -456,8 +465,9 @@ void WorldRegions::write() { bool WorldRegions::parseRegionFilename(const std::string& name, int& x, int& z) { size_t sep = name.find('_'); - if (sep == std::string::npos || sep == 0 || sep == name.length()-1) + if (sep == std::string::npos || sep == 0 || sep == name.length()-1) { return false; + } try { x = std::stoi(name.substr(0, sep)); z = std::stoi(name.substr(sep+1)); diff --git a/src/files/WorldRegions.hpp b/src/files/WorldRegions.hpp index b12ceb11..39a2a6b3 100644 --- a/src/files/WorldRegions.hpp +++ b/src/files/WorldRegions.hpp @@ -128,7 +128,7 @@ public: bool generatorTestMode = false; bool doWriteLights = true; - WorldRegions(const fs::path &directory); + WorldRegions(const fs::path& directory); WorldRegions(const WorldRegions&) = delete; ~WorldRegions(); diff --git a/src/voxels/Chunk.cpp b/src/voxels/Chunk.cpp index b437b8a2..be8238c6 100644 --- a/src/voxels/Chunk.cpp +++ b/src/voxels/Chunk.cpp @@ -113,8 +113,11 @@ bool Chunk::decode(const ubyte* data) { ubyte bst1 = data[CHUNK_VOL*2 + i]; ubyte bst2 = data[CHUNK_VOL*3 + i]; - vox.id = (blockid_t(bid1) << 8) | (blockid_t(bid2)); - vox.state = int2blockstate((blockstate_t(bst1) << 8) | (blockstate_t(bst2))); + vox.id = (static_cast(bid1) << 8) | + static_cast(bid2); + vox.state = int2blockstate( + (static_cast(bst1) << 8) | + static_cast(bst2)); } return true; } @@ -122,8 +125,8 @@ bool Chunk::decode(const ubyte* data) { void Chunk::convert(ubyte* data, const ContentLUT* lut) { for (uint i = 0; i < CHUNK_VOL; i++) { // see encode method to understand what the hell is going on here - blockid_t id = ((blockid_t(data[i]) << 8) | - blockid_t(data[CHUNK_VOL+i])); + blockid_t id = ((static_cast(data[i]) << 8) | + static_cast(data[CHUNK_VOL+i])); blockid_t replacement = lut->getBlockId(id); data[i] = replacement >> 8; data[CHUNK_VOL+i] = replacement & 0xFF; diff --git a/src/voxels/Chunk.hpp b/src/voxels/Chunk.hpp index 535b6125..a0157763 100644 --- a/src/voxels/Chunk.hpp +++ b/src/voxels/Chunk.hpp @@ -5,8 +5,9 @@ #include #include -#include "../constants.hpp" #include "voxel.hpp" + +#include "../constants.hpp" #include "../lighting/Lightmap.hpp" inline constexpr int CHUNK_DATA_LEN = CHUNK_VOL*4; @@ -15,6 +16,10 @@ class Lightmap; class ContentLUT; class Inventory; +namespace dynamic { + class Map; +} + using chunk_inventories_map = std::unordered_map>; class Chunk { @@ -32,7 +37,7 @@ public: bool loadedLights: 1; } flags {}; - /* Block inventories map where key is index of block in voxels array */ + /// @brief Block inventories map where key is index of block in voxels array chunk_inventories_map inventories; Chunk(int x, int z); @@ -44,14 +49,15 @@ public: // unused std::unique_ptr clone() const; - /* Creates new block inventory given size - @return inventory id or 0 if block does not exists */ - void addBlockInventory(std::shared_ptr inventory, - uint x, uint y, uint z); + /// @brief Creates new block inventory given size + /// @return inventory id or 0 if block does not exists + void addBlockInventory( + std::shared_ptr inventory, uint x, uint y, uint z + ); void removeBlockInventory(uint x, uint y, uint z); void setBlockInventories(chunk_inventories_map map); - /* @return inventory bound to the given block or nullptr */ + /// @return inventory bound to the given block or nullptr std::shared_ptr getBlockInventory(uint x, uint y, uint z) const; inline void setModifiedAndUnsaved() { @@ -61,9 +67,7 @@ public: std::unique_ptr encode() const; - /** - * @return true if all is fine - **/ + /// @return true if all is fine bool decode(const ubyte* data); static void convert(ubyte* data, const ContentLUT* lut); diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index b2386455..2805c94b 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -497,14 +497,9 @@ void Chunks::saveAndClear(){ for (size_t i = 0; i < volume; i++){ Chunk* chunk = chunks[i].get(); chunks[i] = nullptr; - if (chunk == nullptr || !chunk->flags.lighted) - continue; - - bool lightsUnsaved = !chunk->flags.loadedLights && - worldFiles->doesWriteLights(); - if (!chunk->flags.unsaved && !lightsUnsaved) - continue; - regions.put(chunk); + if (chunk) { + regions.put(chunk); + } } chunksCount = 0; } diff --git a/src/voxels/ChunksStorage.cpp b/src/voxels/ChunksStorage.cpp index ab6f9714..1ffb2b03 100644 --- a/src/voxels/ChunksStorage.cpp +++ b/src/voxels/ChunksStorage.cpp @@ -59,8 +59,10 @@ std::shared_ptr ChunksStorage::create(int x, int z) { auto data = regions.getChunk(chunk->x, chunk->z); if (data) { chunk->decode(data.get()); + auto invs = regions.fetchInventories(chunk->x, chunk->z); chunk->setBlockInventories(std::move(invs)); + chunk->flags.loaded = true; for(auto& entry : chunk->inventories) { level->inventories->store(entry.second); diff --git a/src/world/World.cpp b/src/world/World.cpp index fe9a8eba..3e92ccb6 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -35,12 +35,10 @@ World::World( ) : name(std::move(name)), generator(std::move(generator)), seed(seed), - settings(settings), content(content), - packs(packs) -{ - wfile = std::make_unique(directory, settings.debug); -} + packs(packs), + wfile(std::make_unique(directory, settings.debug)) +{} World::~World(){ } @@ -57,16 +55,10 @@ void World::write(Level* level) { auto& regions = wfile->getRegions(); for (size_t i = 0; i < chunks->volume; i++) { - auto chunk = chunks->chunks[i]; - if (chunk == nullptr || !chunk->flags.lighted) - continue; - bool lightsUnsaved = !chunk->flags.loadedLights && - settings.debug.doWriteLights.get(); - if (!chunk->flags.unsaved && !lightsUnsaved) - continue; - regions.put(chunk.get()); + if (auto chunk = chunks->chunks[i]) { + regions.put(chunk.get()); + } } - wfile->write(this, content); auto playerFile = dynamic::Map(); diff --git a/src/world/World.hpp b/src/world/World.hpp index fdde86e2..904ed027 100644 --- a/src/world/World.hpp +++ b/src/world/World.hpp @@ -30,7 +30,6 @@ class World : Serializable { std::string name; std::string generator; uint64_t seed; - EngineSettings& settings; const Content* const content; std::vector packs;