Сохранение мира на фс

This commit is contained in:
2026-01-28 23:05:27 +03:00
parent 07ccd4dd68
commit 0b8326e278
8 changed files with 640 additions and 169 deletions

View File

@@ -1,6 +1,8 @@
#include "World.hpp"
#include "ContentManager.hpp"
#include "TOSLib.hpp"
#include <memory>
#include <unordered_set>
namespace LV::Server {
@@ -96,8 +98,94 @@ void World::onRemoteClient_RegionsLost(WorldId_t worldId, std::shared_ptr<Remote
}
}
World::SaveUnloadInfo World::onStepDatabaseSync() {
return {};
World::SaveUnloadInfo World::onStepDatabaseSync(ContentManager& cm, float dtime) {
SaveUnloadInfo out;
constexpr float kSaveDelay = 15.0f;
constexpr float kUnloadDelay = 15.0f;
std::vector<Pos::GlobalRegion> toErase;
toErase.reserve(16);
for(auto& [pos, regionPtr] : Regions) {
Region& region = *regionPtr;
region.LastSaveTime += dtime;
const bool hasChanges = region.IsChanged || region.IsChunkChanged_Voxels || region.IsChunkChanged_Nodes;
const bool needToSave = hasChanges && region.LastSaveTime > kSaveDelay;
const bool needToUnload = region.RMs.empty() && region.LastSaveTime > kUnloadDelay;
if(needToSave || needToUnload) {
SB_Region_In data;
data.Voxels = region.Voxels;
data.Nodes = region.Nodes;
data.Entityes.reserve(region.Entityes.size());
for(const Entity& entity : region.Entityes) {
if(entity.IsRemoved || entity.NeedRemove)
continue;
data.Entityes.push_back(entity);
}
std::unordered_set<DefVoxelId> voxelIds;
for(const auto& [chunkPos, voxels] : region.Voxels) {
(void) chunkPos;
for(const VoxelCube& cube : voxels)
voxelIds.insert(cube.VoxelId);
}
std::unordered_set<DefNodeId> nodeIds;
for(const auto& chunk : region.Nodes) {
for(const Node& node : chunk)
nodeIds.insert(node.NodeId);
}
std::unordered_set<DefEntityId> entityIds;
for(const Entity& entity : data.Entityes)
entityIds.insert(entity.getDefId());
data.VoxelsMap.reserve(voxelIds.size());
for(DefVoxelId id : voxelIds) {
auto dk = cm.getDK(EnumDefContent::Voxel, id);
if(!dk)
continue;
data.VoxelsMap.emplace_back(id, dk->Domain + ":" + dk->Key);
}
data.NodeMap.reserve(nodeIds.size());
for(DefNodeId id : nodeIds) {
auto dk = cm.getDK(EnumDefContent::Node, id);
if(!dk)
continue;
data.NodeMap.emplace_back(id, dk->Domain + ":" + dk->Key);
}
data.EntityMap.reserve(entityIds.size());
for(DefEntityId id : entityIds) {
auto dk = cm.getDK(EnumDefContent::Entity, id);
if(!dk)
continue;
data.EntityMap.emplace_back(id, dk->Domain + ":" + dk->Key);
}
out.ToSave.push_back({pos, std::move(data)});
region.LastSaveTime = 0.0f;
region.IsChanged = false;
}
if(needToUnload) {
out.ToUnload.push_back(pos);
toErase.push_back(pos);
}
}
for(const Pos::GlobalRegion& pos : toErase) {
Regions.erase(pos);
}
return out;
}
void World::pushRegions(std::vector<std::pair<Pos::GlobalRegion, RegionIn>> regions) {