mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Remove MapSector, take 2
This commit is contained in:
parent
0ea89d4112
commit
1771b8c9a1
14 changed files with 236 additions and 649 deletions
|
@ -463,7 +463,6 @@ set(common_SRCS
|
||||||
map.cpp
|
map.cpp
|
||||||
mapblock.cpp
|
mapblock.cpp
|
||||||
mapnode.cpp
|
mapnode.cpp
|
||||||
mapsector.cpp
|
|
||||||
nodedef.cpp
|
nodedef.cpp
|
||||||
pathfinder.cpp
|
pathfinder.cpp
|
||||||
player.cpp
|
player.cpp
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#include "filesys.h"
|
#include "filesys.h"
|
||||||
#include "mapblock_mesh.h"
|
#include "mapblock_mesh.h"
|
||||||
#include "mapblock.h"
|
#include "mapblock.h"
|
||||||
#include "mapsector.h"
|
|
||||||
#include "minimap.h"
|
#include "minimap.h"
|
||||||
#include "modchannels.h"
|
#include "modchannels.h"
|
||||||
#include "content/mods.h"
|
#include "content/mods.h"
|
||||||
|
@ -589,15 +588,14 @@ void Client::step(float dtime)
|
||||||
bool do_mapper_update = true;
|
bool do_mapper_update = true;
|
||||||
|
|
||||||
ClientMap &map = m_env.getClientMap();
|
ClientMap &map = m_env.getClientMap();
|
||||||
MapSector *sector = map.emergeSector(v2s16(r.p.X, r.p.Z));
|
|
||||||
|
|
||||||
MapBlock *block = sector->getBlockNoCreateNoEx(r.p.Y);
|
MapBlock *block = map.getBlockNoCreateNoEx(r.p);
|
||||||
|
|
||||||
// The block in question is not visible (perhaps it is culled at the server),
|
// The block in question is not visible (perhaps it is culled at the server),
|
||||||
// create a blank block just to hold the chunk's mesh.
|
// create a blank block just to hold the chunk's mesh.
|
||||||
// If the block becomes visible later it will replace the blank block.
|
// If the block becomes visible later it will replace the blank block.
|
||||||
if (!block && r.mesh)
|
if (!block && r.mesh)
|
||||||
block = sector->createBlankBlock(r.p.Y);
|
block = map.createBlankBlock(r.p);
|
||||||
|
|
||||||
if (block) {
|
if (block) {
|
||||||
// Delete the old mesh
|
// Delete the old mesh
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include <IMaterialRenderer.h>
|
#include <IMaterialRenderer.h>
|
||||||
#include <IVideoDriver.h>
|
#include <IVideoDriver.h>
|
||||||
#include <matrix4.h>
|
#include <matrix4.h>
|
||||||
#include "mapsector.h"
|
|
||||||
#include "mapblock.h"
|
#include "mapblock.h"
|
||||||
#include "nodedef.h"
|
#include "nodedef.h"
|
||||||
#include "profiler.h"
|
#include "profiler.h"
|
||||||
|
@ -239,20 +238,6 @@ void ClientMap::updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset, video::SCo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MapSector * ClientMap::emergeSector(v2s16 p2d)
|
|
||||||
{
|
|
||||||
// Check that it doesn't exist already
|
|
||||||
MapSector *sector = getSectorNoGenerate(p2d);
|
|
||||||
|
|
||||||
// Create it if it does not exist yet
|
|
||||||
if (!sector) {
|
|
||||||
sector = new MapSector(this, p2d, m_gamedef);
|
|
||||||
m_sectors[p2d] = sector;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sector;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientMap::OnRegisterSceneNode()
|
void ClientMap::OnRegisterSceneNode()
|
||||||
{
|
{
|
||||||
if(IsVisible)
|
if(IsVisible)
|
||||||
|
@ -409,27 +394,12 @@ void ClientMap::updateDrawList()
|
||||||
frustum and display them.
|
frustum and display them.
|
||||||
*/
|
*/
|
||||||
if (m_control.range_all || m_loops_occlusion_culler) {
|
if (m_control.range_all || m_loops_occlusion_culler) {
|
||||||
// Number of blocks currently loaded by the client
|
|
||||||
u32 blocks_loaded = 0;
|
|
||||||
// Number of blocks with mesh in rendering range
|
// Number of blocks with mesh in rendering range
|
||||||
u32 blocks_in_range_with_mesh = 0;
|
u32 blocks_in_range_with_mesh = 0;
|
||||||
|
|
||||||
MapBlockVect sectorblocks;
|
// Loop through all blocks
|
||||||
|
for (const auto &entry : m_blocks) {
|
||||||
for (auto §or_it : m_sectors) {
|
MapBlock *block = entry.second;
|
||||||
const MapSector *sector = sector_it.second;
|
|
||||||
v2s16 sp = sector->getPos();
|
|
||||||
|
|
||||||
blocks_loaded += sector->size();
|
|
||||||
if (!m_control.range_all) {
|
|
||||||
if (sp.X < p_blocks_min.X || sp.X > p_blocks_max.X ||
|
|
||||||
sp.Y < p_blocks_min.Z || sp.Y > p_blocks_max.Z)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop through blocks in sector
|
|
||||||
for (const auto &entry : sector->getBlocks()) {
|
|
||||||
MapBlock *block = entry.second.get();
|
|
||||||
MapBlockMesh *mesh = block->mesh;
|
MapBlockMesh *mesh = block->mesh;
|
||||||
|
|
||||||
// Calculate the coordinates for range and frustum culling
|
// Calculate the coordinates for range and frustum culling
|
||||||
|
@ -490,10 +460,9 @@ void ClientMap::updateDrawList()
|
||||||
m_drawlist.emplace(block->getPos(), block);
|
m_drawlist.emplace(block->getPos(), block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
g_profiler->avg("MapBlock meshes in range [#]", blocks_in_range_with_mesh);
|
g_profiler->avg("MapBlock meshes in range [#]", blocks_in_range_with_mesh);
|
||||||
g_profiler->avg("MapBlocks loaded [#]", blocks_loaded);
|
g_profiler->avg("MapBlocks loaded [#]", m_blocks.size());
|
||||||
} else {
|
} else {
|
||||||
// Blocks visited by the algorithm
|
// Blocks visited by the algorithm
|
||||||
u32 blocks_visited = 0;
|
u32 blocks_visited = 0;
|
||||||
|
@ -529,10 +498,7 @@ void ClientMap::updateDrawList()
|
||||||
|
|
||||||
blocks_visited++;
|
blocks_visited++;
|
||||||
|
|
||||||
// Get the sector, block and mesh
|
MapBlock *block = getBlockNoCreateNoEx(block_coord);
|
||||||
MapSector *sector = this->getSectorNoGenerate(v2s16(block_coord.X, block_coord.Z));
|
|
||||||
|
|
||||||
MapBlock *block = sector ? sector->getBlockNoCreateNoEx(block_coord.Y) : nullptr;
|
|
||||||
|
|
||||||
MapBlockMesh *mesh = block ? block->mesh : nullptr;
|
MapBlockMesh *mesh = block ? block->mesh : nullptr;
|
||||||
|
|
||||||
|
@ -729,28 +695,11 @@ void ClientMap::touchMapBlocks()
|
||||||
v3s16 p_blocks_max;
|
v3s16 p_blocks_max;
|
||||||
getBlocksInViewRange(cam_pos_nodes, &p_blocks_min, &p_blocks_max);
|
getBlocksInViewRange(cam_pos_nodes, &p_blocks_min, &p_blocks_max);
|
||||||
|
|
||||||
// Number of blocks currently loaded by the client
|
|
||||||
u32 blocks_loaded = 0;
|
|
||||||
// Number of blocks with mesh in rendering range
|
// Number of blocks with mesh in rendering range
|
||||||
u32 blocks_in_range_with_mesh = 0;
|
u32 blocks_in_range_with_mesh = 0;
|
||||||
|
|
||||||
for (const auto §or_it : m_sectors) {
|
for (const auto &entry : m_blocks) {
|
||||||
const MapSector *sector = sector_it.second;
|
MapBlock *block = entry.second;
|
||||||
v2s16 sp = sector->getPos();
|
|
||||||
|
|
||||||
blocks_loaded += sector->size();
|
|
||||||
if (!m_control.range_all) {
|
|
||||||
if (sp.X < p_blocks_min.X || sp.X > p_blocks_max.X ||
|
|
||||||
sp.Y < p_blocks_min.Z || sp.Y > p_blocks_max.Z)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Loop through blocks in sector
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (const auto &entry : sector->getBlocks()) {
|
|
||||||
MapBlock *block = entry.second.get();
|
|
||||||
MapBlockMesh *mesh = block->mesh;
|
MapBlockMesh *mesh = block->mesh;
|
||||||
|
|
||||||
// Calculate the coordinates for range and frustum culling
|
// Calculate the coordinates for range and frustum culling
|
||||||
|
@ -779,10 +728,9 @@ void ClientMap::touchMapBlocks()
|
||||||
block->resetUsageTimer();
|
block->resetUsageTimer();
|
||||||
blocks_in_range_with_mesh++;
|
blocks_in_range_with_mesh++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
g_profiler->avg("MapBlock meshes in range [#]", blocks_in_range_with_mesh);
|
g_profiler->avg("MapBlock meshes in range [#]", blocks_in_range_with_mesh);
|
||||||
g_profiler->avg("MapBlocks loaded [#]", blocks_loaded);
|
g_profiler->avg("MapBlocks loaded [#]", m_blocks.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshBufListMaps::addFromBlock(v3s16 block_pos, MapBlockMesh *block_mesh,
|
void MeshBufListMaps::addFromBlock(v3s16 block_pos, MapBlockMesh *block_mesh,
|
||||||
|
@ -1532,22 +1480,11 @@ void ClientMap::updateDrawListShadow(v3f shadow_light_pos, v3f shadow_light_dir,
|
||||||
}
|
}
|
||||||
m_drawlist_shadow.clear();
|
m_drawlist_shadow.clear();
|
||||||
|
|
||||||
// Number of blocks currently loaded by the client
|
|
||||||
u32 blocks_loaded = 0;
|
|
||||||
// Number of blocks with mesh in rendering range
|
// Number of blocks with mesh in rendering range
|
||||||
u32 blocks_in_range_with_mesh = 0;
|
u32 blocks_in_range_with_mesh = 0;
|
||||||
|
|
||||||
for (auto §or_it : m_sectors) {
|
for (const auto &entry : m_blocks) {
|
||||||
const MapSector *sector = sector_it.second;
|
MapBlock *block = entry.second;
|
||||||
if (!sector)
|
|
||||||
continue;
|
|
||||||
blocks_loaded += sector->size();
|
|
||||||
|
|
||||||
/*
|
|
||||||
Loop through blocks in sector
|
|
||||||
*/
|
|
||||||
for (const auto &entry : sector->getBlocks()) {
|
|
||||||
MapBlock *block = entry.second.get();
|
|
||||||
MapBlockMesh *mesh = block->mesh;
|
MapBlockMesh *mesh = block->mesh;
|
||||||
if (!mesh) {
|
if (!mesh) {
|
||||||
// Ignore if mesh doesn't exist
|
// Ignore if mesh doesn't exist
|
||||||
|
@ -1569,11 +1506,10 @@ void ClientMap::updateDrawListShadow(v3f shadow_light_pos, v3f shadow_light_dir,
|
||||||
block->refGrab();
|
block->refGrab();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
g_profiler->avg("SHADOW MapBlock meshes in range [#]", blocks_in_range_with_mesh);
|
g_profiler->avg("SHADOW MapBlock meshes in range [#]", blocks_in_range_with_mesh);
|
||||||
g_profiler->avg("SHADOW MapBlocks drawn [#]", m_drawlist_shadow.size());
|
g_profiler->avg("SHADOW MapBlocks drawn [#]", m_drawlist_shadow.size());
|
||||||
g_profiler->avg("SHADOW MapBlocks loaded [#]", blocks_loaded);
|
g_profiler->avg("SHADOW MapBlocks loaded [#]", m_blocks.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientMap::reportMetrics(u64 save_time_us, u32 saved_blocks, u32 all_blocks)
|
void ClientMap::reportMetrics(u64 save_time_us, u32 saved_blocks, u32 all_blocks)
|
||||||
|
|
|
@ -69,11 +69,6 @@ public:
|
||||||
|
|
||||||
void updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset, video::SColor light_color);
|
void updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset, video::SColor light_color);
|
||||||
|
|
||||||
/*
|
|
||||||
Forcefully get a sector from somewhere
|
|
||||||
*/
|
|
||||||
MapSector * emergeSector(v2s16 p) override;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ISceneNode methods
|
ISceneNode methods
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -239,7 +239,6 @@ void MapDatabaseSQLite3::createDatabase()
|
||||||
// Declaring a primary key automatically creates an index and the
|
// Declaring a primary key automatically creates an index and the
|
||||||
// order largely dictates which range operations can be sped up.
|
// order largely dictates which range operations can be sped up.
|
||||||
// see also: <https://www.sqlite.org/optoverview.html#skipscan>
|
// see also: <https://www.sqlite.org/optoverview.html#skipscan>
|
||||||
// Putting XZ before Y matches our MapSector abstraction.
|
|
||||||
"PRIMARY KEY (`x`, `z`, `y`)"
|
"PRIMARY KEY (`x`, `z`, `y`)"
|
||||||
");\n"
|
");\n"
|
||||||
;
|
;
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "mapsector.h"
|
|
||||||
|
|
||||||
class DummyMap : public Map
|
class DummyMap : public Map
|
||||||
{
|
{
|
||||||
|
@ -13,12 +12,9 @@ public:
|
||||||
DummyMap(IGameDef *gamedef, v3s16 bpmin, v3s16 bpmax): Map(gamedef)
|
DummyMap(IGameDef *gamedef, v3s16 bpmin, v3s16 bpmax): Map(gamedef)
|
||||||
{
|
{
|
||||||
for (s16 z = bpmin.Z; z <= bpmax.Z; z++)
|
for (s16 z = bpmin.Z; z <= bpmax.Z; z++)
|
||||||
for (s16 x = bpmin.X; x <= bpmax.X; x++) {
|
for (s16 x = bpmin.X; x <= bpmax.X; x++)
|
||||||
v2s16 p2d(x, z);
|
for (s16 y = bpmin.Y; y <= bpmax.Y; y++) {
|
||||||
MapSector *sector = new MapSector(this, p2d, gamedef);
|
createBlankBlock(v3s16(x, y, z));
|
||||||
m_sectors[p2d] = sector;
|
|
||||||
for (s16 y = bpmin.Y; y <= bpmax.Y; y++)
|
|
||||||
sector->createBlankBlock(y);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
150
src/map.cpp
150
src/map.cpp
|
@ -3,7 +3,6 @@
|
||||||
// Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
// Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "mapsector.h"
|
|
||||||
#include "mapblock.h"
|
#include "mapblock.h"
|
||||||
#include "voxel.h"
|
#include "voxel.h"
|
||||||
#include "voxelalgorithms.h"
|
#include "voxelalgorithms.h"
|
||||||
|
@ -31,10 +30,10 @@ Map::Map(IGameDef *gamedef):
|
||||||
Map::~Map()
|
Map::~Map()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Free all MapSectors
|
Free all MapBlocks
|
||||||
*/
|
*/
|
||||||
for (auto §or : m_sectors) {
|
for (auto &entry : m_blocks) {
|
||||||
delete sector.second;
|
delete entry.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,40 +54,61 @@ void Map::dispatchEvent(const MapEditEvent &event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MapSector * Map::getSectorNoGenerateNoLock(v2s16 p)
|
MapBlock* Map::createBlankBlockNoInsert(v3s16 p)
|
||||||
{
|
{
|
||||||
if(m_sector_cache != NULL && p == m_sector_cache_p){
|
if (blockpos_over_max_limit(v3s16(p)))
|
||||||
MapSector * sector = m_sector_cache;
|
throw InvalidPositionException("createBlankBlockNoInsert(): pos over max mapgen limit");
|
||||||
return sector;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto n = m_sectors.find(p);
|
return new MapBlock(p, m_gamedef);
|
||||||
|
|
||||||
if (n == m_sectors.end())
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
MapSector *sector = n->second;
|
|
||||||
|
|
||||||
// Cache the last result
|
|
||||||
m_sector_cache_p = p;
|
|
||||||
m_sector_cache = sector;
|
|
||||||
|
|
||||||
return sector;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MapSector *Map::getSectorNoGenerate(v2s16 p)
|
MapBlock *Map::createBlankBlock(v3s16 p)
|
||||||
{
|
{
|
||||||
return getSectorNoGenerateNoLock(p);
|
MapBlock *block = createBlankBlockNoInsert(p);
|
||||||
|
|
||||||
|
m_blocks[p] = block;
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Map::deleteBlockImmediate(MapBlock *block)
|
||||||
|
{
|
||||||
|
detachBlock(block);
|
||||||
|
// returned smart-ptr is dropped
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<MapBlock> Map::detachBlock(MapBlock *block)
|
||||||
|
{
|
||||||
|
// Remove from container
|
||||||
|
auto it = m_blocks.find(block->getPos());
|
||||||
|
assert(it != m_blocks.end());
|
||||||
|
std::unique_ptr<MapBlock> ret(it->second);
|
||||||
|
assert(ret.get() == block);
|
||||||
|
m_blocks.erase(it);
|
||||||
|
|
||||||
|
// Mark as removed
|
||||||
|
block->makeOrphan();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Map::insertBlock(MapBlock *block)
|
||||||
|
{
|
||||||
|
v3s16 pos = block->getPos();
|
||||||
|
|
||||||
|
MapBlock *block2 = getBlockNoCreateNoEx(pos);
|
||||||
|
if (block2) {
|
||||||
|
throw AlreadyExistsException("Block already exists");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert into container
|
||||||
|
m_blocks[pos] = block;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapBlock *Map::getBlockNoCreateNoEx(v3s16 p3d)
|
MapBlock *Map::getBlockNoCreateNoEx(v3s16 p3d)
|
||||||
{
|
{
|
||||||
v2s16 p2d(p3d.X, p3d.Z);
|
auto it = m_blocks.find(p3d);
|
||||||
MapSector *sector = getSectorNoGenerate(p2d);
|
return it != m_blocks.end() ? it->second : nullptr;
|
||||||
if (!sector)
|
|
||||||
return nullptr;
|
|
||||||
MapBlock *block = sector->getBlockNoCreateNoEx(p3d.Y);
|
|
||||||
return block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MapBlock *Map::getBlockNoCreate(v3s16 p3d)
|
MapBlock *Map::getBlockNoCreate(v3s16 p3d)
|
||||||
|
@ -256,11 +276,9 @@ bool Map::removeNodeWithEvent(v3s16 p)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TimeOrderedMapBlock {
|
struct TimeOrderedMapBlock {
|
||||||
MapSector *sect;
|
|
||||||
MapBlock *block;
|
MapBlock *block;
|
||||||
|
|
||||||
TimeOrderedMapBlock(MapSector *sect, MapBlock *block) :
|
TimeOrderedMapBlock(MapBlock *block) :
|
||||||
sect(sect),
|
|
||||||
block(block)
|
block(block)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -281,7 +299,6 @@ void Map::timerUpdate(float dtime, float unload_timeout, s32 max_loaded_blocks,
|
||||||
// Profile modified reasons
|
// Profile modified reasons
|
||||||
Profiler modprofiler;
|
Profiler modprofiler;
|
||||||
|
|
||||||
std::vector<v2s16> sector_deletion_queue;
|
|
||||||
u32 deleted_blocks_count = 0;
|
u32 deleted_blocks_count = 0;
|
||||||
u32 saved_blocks_count = 0;
|
u32 saved_blocks_count = 0;
|
||||||
u32 block_count_all = 0;
|
u32 block_count_all = 0;
|
||||||
|
@ -292,16 +309,8 @@ void Map::timerUpdate(float dtime, float unload_timeout, s32 max_loaded_blocks,
|
||||||
|
|
||||||
// If there is no practical limit, we spare creation of mapblock_queue
|
// If there is no practical limit, we spare creation of mapblock_queue
|
||||||
if (max_loaded_blocks < 0) {
|
if (max_loaded_blocks < 0) {
|
||||||
MapBlockVect blocks;
|
for (auto it = m_blocks.begin(); it != m_blocks.end();) {
|
||||||
for (auto §or_it : m_sectors) {
|
MapBlock *block = it->second;
|
||||||
MapSector *sector = sector_it.second;
|
|
||||||
|
|
||||||
bool all_blocks_deleted = true;
|
|
||||||
|
|
||||||
blocks.clear();
|
|
||||||
sector->getBlocks(blocks);
|
|
||||||
|
|
||||||
for (MapBlock *block : blocks) {
|
|
||||||
block->incrementUsageTimer(dtime);
|
block->incrementUsageTimer(dtime);
|
||||||
|
|
||||||
if (block->refGet() == 0
|
if (block->refGet() == 0
|
||||||
|
@ -312,42 +321,32 @@ void Map::timerUpdate(float dtime, float unload_timeout, s32 max_loaded_blocks,
|
||||||
if (block->getModified() != MOD_STATE_CLEAN
|
if (block->getModified() != MOD_STATE_CLEAN
|
||||||
&& save_before_unloading) {
|
&& save_before_unloading) {
|
||||||
modprofiler.add(block->getModifiedReasonString(), 1);
|
modprofiler.add(block->getModifiedReasonString(), 1);
|
||||||
if (!saveBlock(block))
|
if (!saveBlock(block)) {
|
||||||
|
it++;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
saved_blocks_count++;
|
saved_blocks_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete from memory
|
// Delete directly from container
|
||||||
sector->deleteBlock(block);
|
it = m_blocks.erase(it);
|
||||||
|
delete block;
|
||||||
|
|
||||||
if (unloaded_blocks)
|
if (unloaded_blocks)
|
||||||
unloaded_blocks->push_back(p);
|
unloaded_blocks->push_back(p);
|
||||||
|
|
||||||
deleted_blocks_count++;
|
deleted_blocks_count++;
|
||||||
} else {
|
} else {
|
||||||
all_blocks_deleted = false;
|
|
||||||
block_count_all++;
|
block_count_all++;
|
||||||
}
|
it++;
|
||||||
}
|
|
||||||
|
|
||||||
// Delete sector if we emptied it
|
|
||||||
if (all_blocks_deleted) {
|
|
||||||
sector_deletion_queue.push_back(sector_it.first);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::priority_queue<TimeOrderedMapBlock> mapblock_queue;
|
std::priority_queue<TimeOrderedMapBlock> mapblock_queue;
|
||||||
MapBlockVect blocks;
|
for (auto &entry : m_blocks) {
|
||||||
for (auto §or_it : m_sectors) {
|
MapBlock *block = entry.second;
|
||||||
MapSector *sector = sector_it.second;
|
|
||||||
|
|
||||||
blocks.clear();
|
|
||||||
sector->getBlocks(blocks);
|
|
||||||
|
|
||||||
for (MapBlock *block : blocks) {
|
|
||||||
block->incrementUsageTimer(dtime);
|
block->incrementUsageTimer(dtime);
|
||||||
mapblock_queue.push(TimeOrderedMapBlock(sector, block));
|
mapblock_queue.push(TimeOrderedMapBlock(block));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
block_count_all = mapblock_queue.size();
|
block_count_all = mapblock_queue.size();
|
||||||
|
|
||||||
|
@ -375,7 +374,7 @@ void Map::timerUpdate(float dtime, float unload_timeout, s32 max_loaded_blocks,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete from memory
|
// Delete from memory
|
||||||
b.sect->deleteBlock(block);
|
deleteBlockImmediate(block);
|
||||||
|
|
||||||
if (unloaded_blocks)
|
if (unloaded_blocks)
|
||||||
unloaded_blocks->push_back(p);
|
unloaded_blocks->push_back(p);
|
||||||
|
@ -383,13 +382,6 @@ void Map::timerUpdate(float dtime, float unload_timeout, s32 max_loaded_blocks,
|
||||||
deleted_blocks_count++;
|
deleted_blocks_count++;
|
||||||
block_count_all--;
|
block_count_all--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete empty sectors
|
|
||||||
for (auto §or_it : m_sectors) {
|
|
||||||
if (sector_it.second->empty()) {
|
|
||||||
sector_deletion_queue.push_back(sector_it.first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
endSave();
|
endSave();
|
||||||
|
@ -397,9 +389,6 @@ void Map::timerUpdate(float dtime, float unload_timeout, s32 max_loaded_blocks,
|
||||||
|
|
||||||
reportMetrics(end_time - start_time, saved_blocks_count, block_count_all);
|
reportMetrics(end_time - start_time, saved_blocks_count, block_count_all);
|
||||||
|
|
||||||
// Finally delete the empty sectors
|
|
||||||
deleteSectors(sector_deletion_queue);
|
|
||||||
|
|
||||||
if(deleted_blocks_count != 0)
|
if(deleted_blocks_count != 0)
|
||||||
{
|
{
|
||||||
PrintInfo(infostream); // ServerMap/ClientMap:
|
PrintInfo(infostream); // ServerMap/ClientMap:
|
||||||
|
@ -422,19 +411,6 @@ void Map::unloadUnreferencedBlocks(std::vector<v3s16> *unloaded_blocks)
|
||||||
timerUpdate(0, -1, 0, unloaded_blocks);
|
timerUpdate(0, -1, 0, unloaded_blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::deleteSectors(const std::vector<v2s16> §orList)
|
|
||||||
{
|
|
||||||
for (v2s16 j : sectorList) {
|
|
||||||
MapSector *sector = m_sectors[j];
|
|
||||||
// If sector is in sector cache, remove it from there
|
|
||||||
if (m_sector_cache == sector)
|
|
||||||
m_sector_cache = nullptr;
|
|
||||||
// Remove from map and delete
|
|
||||||
m_sectors.erase(j);
|
|
||||||
delete sector;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Map::PrintInfo(std::ostream &out)
|
void Map::PrintInfo(std::ostream &out)
|
||||||
{
|
{
|
||||||
out<<"Map: ";
|
out<<"Map: ";
|
||||||
|
|
36
src/map.h
36
src/map.h
|
@ -7,6 +7,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "irrlichttypes_bloated.h"
|
#include "irrlichttypes_bloated.h"
|
||||||
#include "mapblock.h"
|
#include "mapblock.h"
|
||||||
|
@ -18,7 +19,6 @@
|
||||||
#include "nodetimer.h"
|
#include "nodetimer.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
class MapSector;
|
|
||||||
class NodeMetadata;
|
class NodeMetadata;
|
||||||
class IGameDef;
|
class IGameDef;
|
||||||
class IRollbackManager;
|
class IRollbackManager;
|
||||||
|
@ -113,22 +113,20 @@ public:
|
||||||
// event shall be deleted by caller after the call.
|
// event shall be deleted by caller after the call.
|
||||||
void dispatchEvent(const MapEditEvent &event);
|
void dispatchEvent(const MapEditEvent &event);
|
||||||
|
|
||||||
// On failure returns NULL
|
|
||||||
MapSector * getSectorNoGenerateNoLock(v2s16 p2d);
|
|
||||||
// Same as the above (there exists no lock anymore)
|
|
||||||
MapSector * getSectorNoGenerate(v2s16 p2d);
|
|
||||||
|
|
||||||
/*
|
|
||||||
This is overloaded by ClientMap and ServerMap to allow
|
|
||||||
their differing fetch methods.
|
|
||||||
*/
|
|
||||||
virtual MapSector * emergeSector(v2s16 p){ return NULL; }
|
|
||||||
|
|
||||||
// Returns InvalidPositionException if not found
|
// Returns InvalidPositionException if not found
|
||||||
MapBlock * getBlockNoCreate(v3s16 p);
|
MapBlock * getBlockNoCreate(v3s16 p);
|
||||||
// Returns NULL if not found
|
// Returns NULL if not found
|
||||||
MapBlock * getBlockNoCreateNoEx(v3s16 p);
|
MapBlock * getBlockNoCreateNoEx(v3s16 p);
|
||||||
|
|
||||||
|
MapBlock* createBlankBlockNoInsert(v3s16 p);
|
||||||
|
MapBlock *createBlankBlock(v3s16 p);
|
||||||
|
void insertBlock(MapBlock *block);
|
||||||
|
|
||||||
|
void deleteBlockImmediate(MapBlock *block);
|
||||||
|
// Remove a block from the map without deleting it
|
||||||
|
// Returns an owning ptr to block.
|
||||||
|
std::unique_ptr<MapBlock> detachBlock(MapBlock *block);
|
||||||
|
|
||||||
/* Server overrides */
|
/* Server overrides */
|
||||||
virtual MapBlock * emergeBlock(v3s16 p, bool create_blank=true)
|
virtual MapBlock * emergeBlock(v3s16 p, bool create_blank=true)
|
||||||
{ return getBlockNoCreateNoEx(p); }
|
{ return getBlockNoCreateNoEx(p); }
|
||||||
|
@ -179,7 +177,7 @@ public:
|
||||||
virtual bool deleteBlock(v3s16 blockpos) { return false; }
|
virtual bool deleteBlock(v3s16 blockpos) { return false; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Updates usage timers and unloads unused blocks and sectors.
|
Updates usage timers and unloads unused blocks.
|
||||||
Saves modified blocks before unloading if possible.
|
Saves modified blocks before unloading if possible.
|
||||||
*/
|
*/
|
||||||
void timerUpdate(float dtime, float unload_timeout, s32 max_loaded_blocks,
|
void timerUpdate(float dtime, float unload_timeout, s32 max_loaded_blocks,
|
||||||
|
@ -191,11 +189,6 @@ public:
|
||||||
*/
|
*/
|
||||||
void unloadUnreferencedBlocks(std::vector<v3s16> *unloaded_blocks=NULL);
|
void unloadUnreferencedBlocks(std::vector<v3s16> *unloaded_blocks=NULL);
|
||||||
|
|
||||||
// Deletes sectors and their blocks from memory
|
|
||||||
// Takes cache into account
|
|
||||||
// If deleted sector is in sector cache, clears cache
|
|
||||||
void deleteSectors(const std::vector<v2s16> &list);
|
|
||||||
|
|
||||||
// For debug printing. Prints "Map: ", "ServerMap: " or "ClientMap: "
|
// For debug printing. Prints "Map: ", "ServerMap: " or "ClientMap: "
|
||||||
virtual void PrintInfo(std::ostream &out);
|
virtual void PrintInfo(std::ostream &out);
|
||||||
|
|
||||||
|
@ -248,7 +241,6 @@ public:
|
||||||
for (s16 bz = bpmin.Z; bz <= bpmax.Z; bz++)
|
for (s16 bz = bpmin.Z; bz <= bpmax.Z; bz++)
|
||||||
for (s16 bx = bpmin.X; bx <= bpmax.X; bx++)
|
for (s16 bx = bpmin.X; bx <= bpmax.X; bx++)
|
||||||
for (s16 by = bpmin.Y; by <= bpmax.Y; by++) {
|
for (s16 by = bpmin.Y; by <= bpmax.Y; by++) {
|
||||||
// y is iterated innermost to make use of the sector cache.
|
|
||||||
v3s16 bp(bx, by, bz);
|
v3s16 bp(bx, by, bz);
|
||||||
MapBlock *block = getBlockNoCreateNoEx(bp);
|
MapBlock *block = getBlockNoCreateNoEx(bp);
|
||||||
v3s16 basep = bp * MAP_BLOCKSIZE;
|
v3s16 basep = bp * MAP_BLOCKSIZE;
|
||||||
|
@ -282,11 +274,7 @@ protected:
|
||||||
|
|
||||||
std::set<MapEventReceiver*> m_event_receivers;
|
std::set<MapEventReceiver*> m_event_receivers;
|
||||||
|
|
||||||
std::unordered_map<v2s16, MapSector*> m_sectors;
|
std::unordered_map<v3s16, MapBlock*> m_blocks;
|
||||||
|
|
||||||
// Be sure to set this to NULL when the cached sector is deleted
|
|
||||||
MapSector *m_sector_cache = nullptr;
|
|
||||||
v2s16 m_sector_cache_p;
|
|
||||||
|
|
||||||
// This stores the properties of the nodes on the map.
|
// This stores the properties of the nodes on the map.
|
||||||
const NodeDefManager *m_nodedef;
|
const NodeDefManager *m_nodedef;
|
||||||
|
|
|
@ -1,125 +0,0 @@
|
||||||
// Luanti
|
|
||||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
// Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
|
||||||
|
|
||||||
#include "mapsector.h"
|
|
||||||
#include "exceptions.h"
|
|
||||||
#include "mapblock.h"
|
|
||||||
#include "serialization.h"
|
|
||||||
|
|
||||||
MapSector::MapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
|
|
||||||
m_parent(parent),
|
|
||||||
m_pos(pos),
|
|
||||||
m_gamedef(gamedef)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MapSector::~MapSector()
|
|
||||||
{
|
|
||||||
deleteBlocks();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapSector::deleteBlocks()
|
|
||||||
{
|
|
||||||
// Clear cache
|
|
||||||
m_block_cache = nullptr;
|
|
||||||
|
|
||||||
// Delete all blocks
|
|
||||||
m_blocks.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
MapBlock *MapSector::getBlockBuffered(s16 y)
|
|
||||||
{
|
|
||||||
MapBlock *block;
|
|
||||||
|
|
||||||
if (m_block_cache && y == m_block_cache_y) {
|
|
||||||
return m_block_cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If block doesn't exist, return NULL
|
|
||||||
auto it = m_blocks.find(y);
|
|
||||||
block = it != m_blocks.end() ? it->second.get() : nullptr;
|
|
||||||
|
|
||||||
// Cache the last result
|
|
||||||
m_block_cache_y = y;
|
|
||||||
m_block_cache = block;
|
|
||||||
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
|
|
||||||
MapBlock *MapSector::getBlockNoCreateNoEx(s16 y)
|
|
||||||
{
|
|
||||||
return getBlockBuffered(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<MapBlock> MapSector::createBlankBlockNoInsert(s16 y)
|
|
||||||
{
|
|
||||||
assert(getBlockBuffered(y) == nullptr); // Pre-condition
|
|
||||||
|
|
||||||
if (blockpos_over_max_limit(v3s16(0, y, 0)))
|
|
||||||
throw InvalidPositionException("createBlankBlockNoInsert(): pos over max mapgen limit");
|
|
||||||
|
|
||||||
v3s16 blockpos_map(m_pos.X, y, m_pos.Y);
|
|
||||||
|
|
||||||
return std::make_unique<MapBlock>(blockpos_map, m_gamedef);
|
|
||||||
}
|
|
||||||
|
|
||||||
MapBlock *MapSector::createBlankBlock(s16 y)
|
|
||||||
{
|
|
||||||
std::unique_ptr<MapBlock> block_u = createBlankBlockNoInsert(y);
|
|
||||||
MapBlock *block = block_u.get();
|
|
||||||
|
|
||||||
m_blocks[y] = std::move(block_u);
|
|
||||||
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapSector::insertBlock(std::unique_ptr<MapBlock> block)
|
|
||||||
{
|
|
||||||
s16 block_y = block->getPos().Y;
|
|
||||||
|
|
||||||
MapBlock *block2 = getBlockBuffered(block_y);
|
|
||||||
if (block2) {
|
|
||||||
throw AlreadyExistsException("Block already exists");
|
|
||||||
}
|
|
||||||
|
|
||||||
v2s16 p2d(block->getPos().X, block->getPos().Z);
|
|
||||||
assert(p2d == m_pos);
|
|
||||||
|
|
||||||
// Insert into container
|
|
||||||
m_blocks[block_y] = std::move(block);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapSector::deleteBlock(MapBlock *block)
|
|
||||||
{
|
|
||||||
detachBlock(block);
|
|
||||||
// returned smart-ptr is dropped
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<MapBlock> MapSector::detachBlock(MapBlock *block)
|
|
||||||
{
|
|
||||||
s16 block_y = block->getPos().Y;
|
|
||||||
|
|
||||||
// Clear from cache
|
|
||||||
m_block_cache = nullptr;
|
|
||||||
|
|
||||||
// Remove from container
|
|
||||||
auto it = m_blocks.find(block_y);
|
|
||||||
assert(it != m_blocks.end());
|
|
||||||
std::unique_ptr<MapBlock> ret = std::move(it->second);
|
|
||||||
assert(ret.get() == block);
|
|
||||||
m_blocks.erase(it);
|
|
||||||
|
|
||||||
// Mark as removed
|
|
||||||
block->makeOrphan();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapSector::getBlocks(MapBlockVect &dest)
|
|
||||||
{
|
|
||||||
dest.reserve(dest.size() + m_blocks.size());
|
|
||||||
for (auto &block : m_blocks) {
|
|
||||||
dest.push_back(block.second.get());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,85 +0,0 @@
|
||||||
// Luanti
|
|
||||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
// Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "irrlichttypes.h"
|
|
||||||
#include "irr_v2d.h"
|
|
||||||
#include "mapblock.h"
|
|
||||||
#include <ostream>
|
|
||||||
#include <memory>
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class Map;
|
|
||||||
class IGameDef;
|
|
||||||
|
|
||||||
/*
|
|
||||||
This is an Y-wise stack of MapBlocks.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MAPSECTOR_SERVER 0
|
|
||||||
#define MAPSECTOR_CLIENT 1
|
|
||||||
|
|
||||||
class MapSector
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
MapSector(Map *parent, v2s16 pos, IGameDef *gamedef);
|
|
||||||
virtual ~MapSector();
|
|
||||||
|
|
||||||
void deleteBlocks();
|
|
||||||
|
|
||||||
v2s16 getPos() const
|
|
||||||
{
|
|
||||||
return m_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
MapBlock *getBlockNoCreateNoEx(s16 y);
|
|
||||||
std::unique_ptr<MapBlock> createBlankBlockNoInsert(s16 y);
|
|
||||||
MapBlock *createBlankBlock(s16 y);
|
|
||||||
|
|
||||||
void insertBlock(std::unique_ptr<MapBlock> block);
|
|
||||||
|
|
||||||
void deleteBlock(MapBlock *block);
|
|
||||||
|
|
||||||
// Remove a block from the map and the sector without deleting it
|
|
||||||
// Returns an owning ptr to block.
|
|
||||||
std::unique_ptr<MapBlock> detachBlock(MapBlock *block);
|
|
||||||
|
|
||||||
// This makes a copy of the internal collection.
|
|
||||||
// Prefer getBlocks() if possible.
|
|
||||||
void getBlocks(MapBlockVect &dest);
|
|
||||||
|
|
||||||
// Get access to the internal collection
|
|
||||||
// This is explicitly only allowed on a const object since modifying anything while iterating is unsafe.
|
|
||||||
// The caller needs to make sure that this does not happen.
|
|
||||||
const auto &getBlocks() const { return m_blocks; }
|
|
||||||
const auto &getBlocks() = delete;
|
|
||||||
|
|
||||||
bool empty() const { return m_blocks.empty(); }
|
|
||||||
|
|
||||||
int size() const { return m_blocks.size(); }
|
|
||||||
protected:
|
|
||||||
|
|
||||||
// The pile of MapBlocks
|
|
||||||
std::unordered_map<s16, std::unique_ptr<MapBlock>> m_blocks;
|
|
||||||
|
|
||||||
Map *m_parent;
|
|
||||||
// Position on parent (in MapBlock widths)
|
|
||||||
v2s16 m_pos;
|
|
||||||
|
|
||||||
IGameDef *m_gamedef;
|
|
||||||
|
|
||||||
// Last-used block is cached here for quicker access.
|
|
||||||
// Be sure to set this to nullptr when the cached block is deleted
|
|
||||||
MapBlock *m_block_cache = nullptr;
|
|
||||||
s16 m_block_cache_y;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Private methods
|
|
||||||
*/
|
|
||||||
MapBlock *getBlockBuffered(s16 y);
|
|
||||||
|
|
||||||
};
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include "client/clientmedia.h"
|
#include "client/clientmedia.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "servermap.h"
|
#include "servermap.h"
|
||||||
#include "mapsector.h"
|
|
||||||
#include "client/minimap.h"
|
#include "client/minimap.h"
|
||||||
#include "modchannels.h"
|
#include "modchannels.h"
|
||||||
#include "nodedef.h"
|
#include "nodedef.h"
|
||||||
|
@ -285,15 +284,7 @@ void Client::handleCommand_BlockData(NetworkPacket* pkt)
|
||||||
std::string datastring(pkt->getRemainingString(), pkt->getRemainingBytes());
|
std::string datastring(pkt->getRemainingString(), pkt->getRemainingBytes());
|
||||||
std::istringstream istr(datastring, std::ios_base::binary);
|
std::istringstream istr(datastring, std::ios_base::binary);
|
||||||
|
|
||||||
MapSector *sector;
|
MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(p);
|
||||||
MapBlock *block;
|
|
||||||
|
|
||||||
v2s16 p2d(p.X, p.Z);
|
|
||||||
sector = m_env.getMap().emergeSector(p2d);
|
|
||||||
|
|
||||||
assert(sector->getPos() == p2d);
|
|
||||||
|
|
||||||
block = sector->getBlockNoCreateNoEx(p.Y);
|
|
||||||
if (block) {
|
if (block) {
|
||||||
/*
|
/*
|
||||||
Update an existing block
|
Update an existing block
|
||||||
|
@ -305,7 +296,7 @@ void Client::handleCommand_BlockData(NetworkPacket* pkt)
|
||||||
/*
|
/*
|
||||||
Create a new block
|
Create a new block
|
||||||
*/
|
*/
|
||||||
block = sector->createBlankBlock(p.Y);
|
block = m_env.getMap().createBlankBlock(p);
|
||||||
block->deSerialize(istr, m_server_ser_ver, false);
|
block->deSerialize(istr, m_server_ser_ver, false);
|
||||||
block->deSerializeNetworkSpecific(istr);
|
block->deSerializeNetworkSpecific(istr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
// Copyright (C) 2010-2024 celeron55, Perttu Ahola <celeron55@gmail.com>
|
// Copyright (C) 2010-2024 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "mapsector.h"
|
|
||||||
#include "filesys.h"
|
#include "filesys.h"
|
||||||
#include "voxel.h"
|
#include "voxel.h"
|
||||||
#include "voxelalgorithms.h"
|
#include "voxelalgorithms.h"
|
||||||
|
@ -228,12 +227,7 @@ bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data)
|
||||||
Create the whole area of this and the neighboring blocks
|
Create the whole area of this and the neighboring blocks
|
||||||
*/
|
*/
|
||||||
for (s16 x = full_bpmin.X; x <= full_bpmax.X; x++)
|
for (s16 x = full_bpmin.X; x <= full_bpmax.X; x++)
|
||||||
for (s16 z = full_bpmin.Z; z <= full_bpmax.Z; z++) {
|
for (s16 z = full_bpmin.Z; z <= full_bpmax.Z; z++)
|
||||||
v2s16 sectorpos(x, z);
|
|
||||||
// Sector metadata is loaded from disk if not already loaded.
|
|
||||||
MapSector *sector = createSector(sectorpos);
|
|
||||||
FATAL_ERROR_IF(sector == NULL, "createSector() failed");
|
|
||||||
|
|
||||||
for (s16 y = full_bpmin.Y; y <= full_bpmax.Y; y++) {
|
for (s16 y = full_bpmin.Y; y <= full_bpmax.Y; y++) {
|
||||||
v3s16 p(x, y, z);
|
v3s16 p(x, y, z);
|
||||||
|
|
||||||
|
@ -247,7 +241,6 @@ bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data)
|
||||||
block->setIsUnderground(ug);
|
block->setIsUnderground(ug);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Now we have a big empty area.
|
Now we have a big empty area.
|
||||||
|
@ -322,61 +315,15 @@ void ServerMap::finishBlockMake(BlockMakeData *data,
|
||||||
m_chunks_in_progress.erase(bpmin);
|
m_chunks_in_progress.erase(bpmin);
|
||||||
}
|
}
|
||||||
|
|
||||||
MapSector *ServerMap::createSector(v2s16 p2d)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Check if it exists already in memory
|
|
||||||
*/
|
|
||||||
MapSector *sector = getSectorNoGenerate(p2d);
|
|
||||||
if (sector)
|
|
||||||
return sector;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Do not create over max mapgen limit
|
|
||||||
*/
|
|
||||||
if (blockpos_over_max_limit(v3s16(p2d.X, 0, p2d.Y)))
|
|
||||||
throw InvalidPositionException("createSector(): pos over max mapgen limit");
|
|
||||||
|
|
||||||
/*
|
|
||||||
Generate blank sector
|
|
||||||
*/
|
|
||||||
sector = new MapSector(this, p2d, m_gamedef);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Insert to container
|
|
||||||
*/
|
|
||||||
m_sectors[p2d] = sector;
|
|
||||||
|
|
||||||
return sector;
|
|
||||||
}
|
|
||||||
|
|
||||||
MapBlock * ServerMap::createBlock(v3s16 p)
|
MapBlock * ServerMap::createBlock(v3s16 p)
|
||||||
{
|
{
|
||||||
v2s16 p2d(p.X, p.Z);
|
MapBlock *block = getBlockNoCreateNoEx(p);
|
||||||
s16 block_y = p.Y;
|
|
||||||
|
|
||||||
/*
|
|
||||||
This will create or load a sector if not found in memory.
|
|
||||||
*/
|
|
||||||
MapSector *sector;
|
|
||||||
try {
|
|
||||||
sector = createSector(p2d);
|
|
||||||
} catch (InvalidPositionException &e) {
|
|
||||||
infostream<<"createBlock: createSector() failed"<<std::endl;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Try to get a block from the sector
|
|
||||||
*/
|
|
||||||
|
|
||||||
MapBlock *block = sector->getBlockNoCreateNoEx(block_y);
|
|
||||||
if (block)
|
if (block)
|
||||||
return block;
|
return block;
|
||||||
|
|
||||||
// Create blank
|
// Create blank
|
||||||
try {
|
try {
|
||||||
block = sector->createBlankBlock(block_y);
|
block = createBlankBlock(p);
|
||||||
} catch (InvalidPositionException &e) {
|
} catch (InvalidPositionException &e) {
|
||||||
infostream << "createBlock: createBlankBlock() failed" << std::endl;
|
infostream << "createBlock: createBlankBlock() failed" << std::endl;
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -401,8 +348,7 @@ MapBlock * ServerMap::emergeBlock(v3s16 p, bool create_blank)
|
||||||
|
|
||||||
if (create_blank) {
|
if (create_blank) {
|
||||||
try {
|
try {
|
||||||
MapSector *sector = createSector(v2s16(p.X, p.Z));
|
return createBlankBlock(p);
|
||||||
return sector->createBlankBlock(p.Y);
|
|
||||||
} catch (InvalidPositionException &e) {}
|
} catch (InvalidPositionException &e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,13 +448,8 @@ void ServerMap::save(ModifiedState save_level)
|
||||||
// Don't do anything with sqlite unless something is really saved
|
// Don't do anything with sqlite unless something is really saved
|
||||||
bool save_started = false;
|
bool save_started = false;
|
||||||
|
|
||||||
for (auto §or_it : m_sectors) {
|
for (auto &entry : m_blocks) {
|
||||||
MapSector *sector = sector_it.second;
|
MapBlock *block = entry.second;
|
||||||
|
|
||||||
MapBlockVect blocks;
|
|
||||||
sector->getBlocks(blocks);
|
|
||||||
|
|
||||||
for (MapBlock *block : blocks) {
|
|
||||||
block_count_all++;
|
block_count_all++;
|
||||||
|
|
||||||
if(block->getModified() >= (u32)save_level) {
|
if(block->getModified() >= (u32)save_level) {
|
||||||
|
@ -524,7 +465,6 @@ void ServerMap::save(ModifiedState save_level)
|
||||||
block_count++;
|
block_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(save_started)
|
if(save_started)
|
||||||
endSave();
|
endSave();
|
||||||
|
@ -557,17 +497,11 @@ void ServerMap::listAllLoadableBlocks(std::vector<v3s16> &dst)
|
||||||
|
|
||||||
void ServerMap::listAllLoadedBlocks(std::vector<v3s16> &dst)
|
void ServerMap::listAllLoadedBlocks(std::vector<v3s16> &dst)
|
||||||
{
|
{
|
||||||
for (auto §or_it : m_sectors) {
|
for (auto &entry : m_blocks) {
|
||||||
MapSector *sector = sector_it.second;
|
MapBlock *block = entry.second;
|
||||||
|
|
||||||
MapBlockVect blocks;
|
|
||||||
sector->getBlocks(blocks);
|
|
||||||
|
|
||||||
for (MapBlock *block : blocks) {
|
|
||||||
v3s16 p = block->getPos();
|
v3s16 p = block->getPos();
|
||||||
dst.push_back(p);
|
dst.push_back(p);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MapDatabase *ServerMap::createDatabase(
|
MapDatabase *ServerMap::createDatabase(
|
||||||
|
@ -666,14 +600,11 @@ MapBlock *ServerMap::loadBlock(const std::string &blob, v3s16 p3d, bool save_aft
|
||||||
bool created_new = false;
|
bool created_new = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
v2s16 p2d(p3d.X, p3d.Z);
|
MapBlock* block_created_new = nullptr;
|
||||||
MapSector *sector = createSector(p2d);
|
block = getBlockNoCreateNoEx(p3d);
|
||||||
|
|
||||||
std::unique_ptr<MapBlock> block_created_new;
|
|
||||||
block = sector->getBlockNoCreateNoEx(p3d.Y);
|
|
||||||
if (!block) {
|
if (!block) {
|
||||||
block_created_new = sector->createBlankBlockNoInsert(p3d.Y);
|
block_created_new = createBlankBlockNoInsert(p3d);
|
||||||
block = block_created_new.get();
|
block = block_created_new;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -683,7 +614,7 @@ MapBlock *ServerMap::loadBlock(const std::string &blob, v3s16 p3d, bool save_aft
|
||||||
|
|
||||||
// If it's a new block, insert it to the map
|
// If it's a new block, insert it to the map
|
||||||
if (block_created_new) {
|
if (block_created_new) {
|
||||||
sector->insertBlock(std::move(block_created_new));
|
insertBlock(block_created_new);
|
||||||
created_new = true;
|
created_new = true;
|
||||||
}
|
}
|
||||||
} catch (SerializationError &e) {
|
} catch (SerializationError &e) {
|
||||||
|
@ -751,13 +682,9 @@ bool ServerMap::deleteBlock(v3s16 blockpos)
|
||||||
|
|
||||||
MapBlock *block = getBlockNoCreateNoEx(blockpos);
|
MapBlock *block = getBlockNoCreateNoEx(blockpos);
|
||||||
if (block) {
|
if (block) {
|
||||||
v2s16 p2d(blockpos.X, blockpos.Z);
|
|
||||||
MapSector *sector = getSectorNoGenerate(p2d);
|
|
||||||
if (!sector)
|
|
||||||
return false;
|
|
||||||
// It may not be safe to delete the block from memory at the moment
|
// It may not be safe to delete the block from memory at the moment
|
||||||
// (pointers to it could still be in use)
|
// (pointers to it could still be in use)
|
||||||
m_detached_blocks.push_back(sector->detachBlock(block));
|
m_detached_blocks.push_back(detachBlock(block));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -49,14 +49,6 @@ public:
|
||||||
ServerMap(const std::string &savedir, IGameDef *gamedef, EmergeManager *emerge, MetricsBackend *mb);
|
ServerMap(const std::string &savedir, IGameDef *gamedef, EmergeManager *emerge, MetricsBackend *mb);
|
||||||
~ServerMap();
|
~ServerMap();
|
||||||
|
|
||||||
/*
|
|
||||||
Get a sector from somewhere.
|
|
||||||
- Check memory
|
|
||||||
- Check disk (doesn't load blocks)
|
|
||||||
- Create blank one
|
|
||||||
*/
|
|
||||||
MapSector *createSector(v2s16 p);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Blocks are generated by using these and makeBlock().
|
Blocks are generated by using these and makeBlock().
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -753,13 +753,13 @@ void update_block_border_lighting(Map *map, MapBlock *block,
|
||||||
/*!
|
/*!
|
||||||
* Resets the lighting of the given VoxelManipulator to
|
* Resets the lighting of the given VoxelManipulator to
|
||||||
* complete darkness and full sunlight.
|
* complete darkness and full sunlight.
|
||||||
* Operates in one map sector.
|
* Operates in one map column.
|
||||||
*
|
*
|
||||||
* \param offset contains the least x and z node coordinates
|
* \param offset contains the least x and z node coordinates
|
||||||
* of the map sector.
|
* of the map column.
|
||||||
* \param light incoming sunlight, light[x][z] is true if there
|
* \param light incoming sunlight, light[x][z] is true if there
|
||||||
* is sunlight above the voxel manipulator at the given x-z coordinates.
|
* is sunlight above the voxel manipulator at the given x-z coordinates.
|
||||||
* The array's indices are relative node coordinates in the sector.
|
* The array's indices are relative node coordinates in the column.
|
||||||
* After the procedure returns, this contains outgoing light at
|
* After the procedure returns, this contains outgoing light at
|
||||||
* the bottom of the voxel manipulator.
|
* the bottom of the voxel manipulator.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue