aboutsummaryrefslogtreecommitdiff
path: root/src/emerge.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emerge.cpp')
-rw-r--r--src/emerge.cpp244
1 files changed, 141 insertions, 103 deletions
diff --git a/src/emerge.cpp b/src/emerge.cpp
index e76383d09..0ac26a682 100644
--- a/src/emerge.cpp
+++ b/src/emerge.cpp
@@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+
#include "emerge.h"
#include <iostream>
@@ -44,8 +45,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h"
#include "voxel.h"
-class EmergeThread : public Thread
-{
+class EmergeThread : public Thread {
public:
bool enable_mapgen_debug_info;
int id;
@@ -61,8 +61,9 @@ public:
void cancelPendingItems();
- static void runCompletionCallbacks(const v3s16 &pos, EmergeAction action,
- const EmergeCallbackList &callbacks);
+ static void runCompletionCallbacks(
+ const v3s16 &pos, EmergeAction action,
+ const EmergeCallbackList &callbacks);
private:
Server *m_server;
@@ -75,10 +76,10 @@ private:
bool popBlockEmerge(v3s16 *pos, BlockEmergeData *bedata);
- EmergeAction getBlockOrStartGen(const v3s16 &pos, bool allow_gen,
- MapBlock **block, BlockMakeData *data);
+ EmergeAction getBlockOrStartGen(
+ const v3s16 &pos, bool allow_gen, MapBlock **block, BlockMakeData *data);
MapBlock *finishGen(v3s16 pos, BlockMakeData *bmdata,
- std::map<v3s16, MapBlock *> *modified_blocks);
+ std::map<v3s16, MapBlock *> *modified_blocks);
friend class EmergeManager;
};
@@ -86,10 +87,10 @@ private:
class MapEditEventAreaIgnorer
{
public:
- MapEditEventAreaIgnorer(VoxelArea *ignorevariable, const VoxelArea &a) :
- m_ignorevariable(ignorevariable)
+ MapEditEventAreaIgnorer(VoxelArea *ignorevariable, const VoxelArea &a):
+ m_ignorevariable(ignorevariable)
{
- if (m_ignorevariable->getVolume() == 0)
+ if(m_ignorevariable->getVolume() == 0)
*m_ignorevariable = a;
else
m_ignorevariable = NULL;
@@ -97,7 +98,8 @@ public:
~MapEditEventAreaIgnorer()
{
- if (m_ignorevariable) {
+ if(m_ignorevariable)
+ {
assert(m_ignorevariable->getVolume() != 0);
*m_ignorevariable = VoxelArea();
}
@@ -118,14 +120,14 @@ EmergeParams::~EmergeParams()
}
EmergeParams::EmergeParams(EmergeManager *parent, const BiomeManager *biomemgr,
- const OreManager *oremgr, const DecorationManager *decomgr,
- const SchematicManager *schemmgr) :
- ndef(parent->ndef),
- enable_mapgen_debug_info(parent->enable_mapgen_debug_info),
- gen_notify_on(parent->gen_notify_on),
- gen_notify_on_deco_ids(&parent->gen_notify_on_deco_ids),
- biomemgr(biomemgr->clone()), oremgr(oremgr->clone()),
- decomgr(decomgr->clone()), schemmgr(schemmgr->clone())
+ const OreManager *oremgr, const DecorationManager *decomgr,
+ const SchematicManager *schemmgr) :
+ ndef(parent->ndef),
+ enable_mapgen_debug_info(parent->enable_mapgen_debug_info),
+ gen_notify_on(parent->gen_notify_on),
+ gen_notify_on_deco_ids(&parent->gen_notify_on_deco_ids),
+ biomemgr(biomemgr->clone()), oremgr(oremgr->clone()),
+ decomgr(decomgr->clone()), schemmgr(schemmgr->clone())
{
}
@@ -135,11 +137,11 @@ EmergeParams::EmergeParams(EmergeManager *parent, const BiomeManager *biomemgr,
EmergeManager::EmergeManager(Server *server)
{
- this->ndef = server->getNodeDefManager();
- this->biomemgr = new BiomeManager(server);
- this->oremgr = new OreManager(server);
- this->decomgr = new DecorationManager(server);
- this->schemmgr = new SchematicManager(server);
+ this->ndef = server->getNodeDefManager();
+ this->biomemgr = new BiomeManager(server);
+ this->oremgr = new OreManager(server);
+ this->decomgr = new DecorationManager(server);
+ this->schemmgr = new SchematicManager(server);
// Note that accesses to this variable are not synchronized.
// This is because the *only* thread ever starting or stopping
@@ -177,6 +179,7 @@ EmergeManager::EmergeManager(Server *server)
infostream << "EmergeManager: using " << nthreads << " threads" << std::endl;
}
+
EmergeManager::~EmergeManager()
{
for (u32 i = 0; i != m_threads.size(); i++) {
@@ -201,34 +204,36 @@ EmergeManager::~EmergeManager()
delete schemmgr;
}
+
BiomeManager *EmergeManager::getWritableBiomeManager()
{
FATAL_ERROR_IF(!m_mapgens.empty(),
- "Writable managers can only be returned before mapgen init");
+ "Writable managers can only be returned before mapgen init");
return biomemgr;
}
OreManager *EmergeManager::getWritableOreManager()
{
FATAL_ERROR_IF(!m_mapgens.empty(),
- "Writable managers can only be returned before mapgen init");
+ "Writable managers can only be returned before mapgen init");
return oremgr;
}
DecorationManager *EmergeManager::getWritableDecorationManager()
{
FATAL_ERROR_IF(!m_mapgens.empty(),
- "Writable managers can only be returned before mapgen init");
+ "Writable managers can only be returned before mapgen init");
return decomgr;
}
SchematicManager *EmergeManager::getWritableSchematicManager()
{
FATAL_ERROR_IF(!m_mapgens.empty(),
- "Writable managers can only be returned before mapgen init");
+ "Writable managers can only be returned before mapgen init");
return schemmgr;
}
+
void EmergeManager::initMapgens(MapgenParams *params)
{
FATAL_ERROR_IF(!m_mapgens.empty(), "Mapgen already initialised.");
@@ -237,13 +242,14 @@ void EmergeManager::initMapgens(MapgenParams *params)
for (u32 i = 0; i != m_threads.size(); i++) {
EmergeParams *p = new EmergeParams(
- this, biomemgr, oremgr, decomgr, schemmgr);
- infostream << "EmergeManager: Created params " << p << " for thread " << i
- << std::endl;
+ this, biomemgr, oremgr, decomgr, schemmgr);
+ infostream << "EmergeManager: Created params " << p
+ << " for thread " << i << std::endl;
m_mapgens.push_back(Mapgen::createMapgen(params->mgtype, params, p));
}
}
+
Mapgen *EmergeManager::getCurrentMapgen()
{
if (!m_threads_active)
@@ -258,6 +264,7 @@ Mapgen *EmergeManager::getCurrentMapgen()
return nullptr;
}
+
void EmergeManager::startThreads()
{
if (m_threads_active)
@@ -269,6 +276,7 @@ void EmergeManager::startThreads()
m_threads_active = true;
}
+
void EmergeManager::stopThreads()
{
if (!m_threads_active)
@@ -287,13 +295,18 @@ void EmergeManager::stopThreads()
m_threads_active = false;
}
+
bool EmergeManager::isRunning()
{
return m_threads_active;
}
-bool EmergeManager::enqueueBlockEmerge(session_t peer_id, v3s16 blockpos,
- bool allow_generate, bool ignore_queue_limits)
+
+bool EmergeManager::enqueueBlockEmerge(
+ session_t peer_id,
+ v3s16 blockpos,
+ bool allow_generate,
+ bool ignore_queue_limits)
{
u16 flags = 0;
if (allow_generate)
@@ -304,8 +317,13 @@ bool EmergeManager::enqueueBlockEmerge(session_t peer_id, v3s16 blockpos,
return enqueueBlockEmergeEx(blockpos, peer_id, flags, NULL, NULL);
}
-bool EmergeManager::enqueueBlockEmergeEx(v3s16 blockpos, session_t peer_id, u16 flags,
- EmergeCompletionCallback callback, void *callback_param)
+
+bool EmergeManager::enqueueBlockEmergeEx(
+ v3s16 blockpos,
+ session_t peer_id,
+ u16 flags,
+ EmergeCompletionCallback callback,
+ void *callback_param)
{
EmergeThread *thread = NULL;
bool entry_already_exists = false;
@@ -313,8 +331,8 @@ bool EmergeManager::enqueueBlockEmergeEx(v3s16 blockpos, session_t peer_id, u16
{
MutexAutoLock queuelock(m_queue_mutex);
- if (!pushBlockEmergeData(blockpos, peer_id, flags, callback,
- callback_param, &entry_already_exists))
+ if (!pushBlockEmergeData(blockpos, peer_id, flags,
+ callback, callback_param, &entry_already_exists))
return false;
if (entry_already_exists)
@@ -329,10 +347,12 @@ bool EmergeManager::enqueueBlockEmergeEx(v3s16 blockpos, session_t peer_id, u16
return true;
}
+
//
// Mapgen-related helper functions
//
+
// TODO(hmmmm): Move this to ServerMap
v3s16 EmergeManager::getContainingChunk(v3s16 blockpos)
{
@@ -345,28 +365,28 @@ v3s16 EmergeManager::getContainingChunk(v3s16 blockpos, s16 chunksize)
s16 coff = -chunksize / 2;
v3s16 chunk_offset(coff, coff, coff);
- return getContainerPos(blockpos - chunk_offset, chunksize) * chunksize +
- chunk_offset;
+ return getContainerPos(blockpos - chunk_offset, chunksize)
+ * chunksize + chunk_offset;
}
+
int EmergeManager::getSpawnLevelAtPoint(v2s16 p)
{
if (m_mapgens.empty() || !m_mapgens[0]) {
errorstream << "EmergeManager: getSpawnLevelAtPoint() called"
- " before mapgen init"
- << std::endl;
+ " before mapgen init" << std::endl;
return 0;
}
return m_mapgens[0]->getSpawnLevelAtPoint(p);
}
+
int EmergeManager::getGroundLevelAtPoint(v2s16 p)
{
if (m_mapgens.empty() || !m_mapgens[0]) {
errorstream << "EmergeManager: getGroundLevelAtPoint() called"
- " before mapgen init"
- << std::endl;
+ " before mapgen init" << std::endl;
return 0;
}
@@ -387,9 +407,13 @@ bool EmergeManager::isBlockUnderground(v3s16 blockpos)
return blockpos.Y * (MAP_BLOCKSIZE + 1) <= mgparams->water_level;
}
-bool EmergeManager::pushBlockEmergeData(v3s16 pos, u16 peer_requested, u16 flags,
- EmergeCompletionCallback callback, void *callback_param,
- bool *entry_already_exists)
+bool EmergeManager::pushBlockEmergeData(
+ v3s16 pos,
+ u16 peer_requested,
+ u16 flags,
+ EmergeCompletionCallback callback,
+ void *callback_param,
+ bool *entry_already_exists)
{
u16 &count_peer = m_peer_queue_count[peer_requested];
@@ -398,9 +422,8 @@ bool EmergeManager::pushBlockEmergeData(v3s16 pos, u16 peer_requested, u16 flags
return false;
if (peer_requested != PEER_ID_INEXISTENT) {
- u16 qlimit_peer = (flags & BLOCK_EMERGE_ALLOW_GEN)
- ? m_qlimit_generate
- : m_qlimit_diskonly;
+ u16 qlimit_peer = (flags & BLOCK_EMERGE_ALLOW_GEN) ?
+ m_qlimit_generate : m_qlimit_diskonly;
if (count_peer >= qlimit_peer)
return false;
}
@@ -410,7 +433,7 @@ bool EmergeManager::pushBlockEmergeData(v3s16 pos, u16 peer_requested, u16 flags
findres = m_blocks_enqueued.insert(std::make_pair(pos, BlockEmergeData()));
BlockEmergeData &bedata = findres.first->second;
- *entry_already_exists = !findres.second;
+ *entry_already_exists = !findres.second;
if (callback)
bedata.callbacks.emplace_back(callback, callback_param);
@@ -427,6 +450,7 @@ bool EmergeManager::pushBlockEmergeData(v3s16 pos, u16 peer_requested, u16 flags
return true;
}
+
bool EmergeManager::popBlockEmergeData(v3s16 pos, BlockEmergeData *bedata)
{
std::map<v3s16, BlockEmergeData>::iterator it;
@@ -451,6 +475,7 @@ bool EmergeManager::popBlockEmergeData(v3s16 pos, BlockEmergeData *bedata)
return true;
}
+
EmergeThread *EmergeManager::getOptimalThread()
{
size_t nthreads = m_threads.size();
@@ -471,28 +496,36 @@ EmergeThread *EmergeManager::getOptimalThread()
return m_threads[index];
}
+
////
//// EmergeThread
////
EmergeThread::EmergeThread(Server *server, int ethreadid) :
- enable_mapgen_debug_info(false), id(ethreadid), m_server(server),
- m_map(NULL), m_emerge(NULL), m_mapgen(NULL)
+ enable_mapgen_debug_info(false),
+ id(ethreadid),
+ m_server(server),
+ m_map(NULL),
+ m_emerge(NULL),
+ m_mapgen(NULL)
{
m_name = "Emerge-" + itos(ethreadid);
}
+
void EmergeThread::signal()
{
m_queue_event.signal();
}
+
bool EmergeThread::pushBlock(const v3s16 &pos)
{
m_block_queue.push(pos);
return true;
}
+
void EmergeThread::cancelPendingItems()
{
MutexAutoLock queuelock(m_emerge->m_queue_mutex);
@@ -510,20 +543,22 @@ void EmergeThread::cancelPendingItems()
}
}
+
void EmergeThread::runCompletionCallbacks(const v3s16 &pos, EmergeAction action,
- const EmergeCallbackList &callbacks)
+ const EmergeCallbackList &callbacks)
{
for (size_t i = 0; i != callbacks.size(); i++) {
EmergeCompletionCallback callback;
void *param;
callback = callbacks[i].first;
- param = callbacks[i].second;
+ param = callbacks[i].second;
callback(pos, action, param);
}
}
+
bool EmergeThread::popBlockEmerge(v3s16 *pos, BlockEmergeData *bedata)
{
MutexAutoLock queuelock(m_emerge->m_queue_mutex);
@@ -539,8 +574,9 @@ bool EmergeThread::popBlockEmerge(v3s16 *pos, BlockEmergeData *bedata)
return true;
}
+
EmergeAction EmergeThread::getBlockOrStartGen(
- const v3s16 &pos, bool allow_gen, MapBlock **block, BlockMakeData *bmdata)
+ const v3s16 &pos, bool allow_gen, MapBlock **block, BlockMakeData *bmdata)
{
MutexAutoLock envlock(m_server->m_env_mutex);
@@ -564,11 +600,13 @@ EmergeAction EmergeThread::getBlockOrStartGen(
return EMERGE_CANCELLED;
}
+
MapBlock *EmergeThread::finishGen(v3s16 pos, BlockMakeData *bmdata,
- std::map<v3s16, MapBlock *> *modified_blocks)
+ std::map<v3s16, MapBlock *> *modified_blocks)
{
MutexAutoLock envlock(m_server->m_env_mutex);
- ScopeProfiler sp(g_profiler, "EmergeThread: after Mapgen::makeChunk", SPT_AVG);
+ ScopeProfiler sp(g_profiler,
+ "EmergeThread: after Mapgen::makeChunk", SPT_AVG);
/*
Perform post-processing on blocks (invalidate lighting, queue liquid
@@ -579,26 +617,26 @@ MapBlock *EmergeThread::finishGen(v3s16 pos, BlockMakeData *bmdata,
MapBlock *block = m_map->getBlockNoCreateNoEx(pos);
if (!block) {
errorstream << "EmergeThread::finishGen: Couldn't grab block we "
- "just generated: "
- << PP(pos) << std::endl;
+ "just generated: " << PP(pos) << std::endl;
return NULL;
}
v3s16 minp = bmdata->blockpos_min * MAP_BLOCKSIZE;
v3s16 maxp = bmdata->blockpos_max * MAP_BLOCKSIZE +
- v3s16(1, 1, 1) * (MAP_BLOCKSIZE - 1);
+ v3s16(1,1,1) * (MAP_BLOCKSIZE - 1);
// Ignore map edit events, they will not need to be sent
// to anybody because the block hasn't been sent to anybody
MapEditEventAreaIgnorer ign(
- &m_server->m_ignore_map_edit_events_area, VoxelArea(minp, maxp));
+ &m_server->m_ignore_map_edit_events_area,
+ VoxelArea(minp, maxp));
/*
Run Lua on_generated callbacks
*/
try {
m_server->getScriptIface()->environment_OnGenerated(
- minp, maxp, m_mapgen->blockseed);
+ minp, maxp, m_mapgen->blockseed);
} catch (LuaError &e) {
m_server->setAsyncFatalError("Lua: finishGen" + std::string(e.what()));
}
@@ -618,74 +656,74 @@ MapBlock *EmergeThread::finishGen(v3s16 pos, BlockMakeData *bmdata,
return block;
}
+
void *EmergeThread::run()
{
BEGIN_DEBUG_EXCEPTION_HANDLER
v3s16 pos;
- m_map = (ServerMap *)&(m_server->m_env->getMap());
+ m_map = (ServerMap *)&(m_server->m_env->getMap());
m_emerge = m_server->m_emerge;
m_mapgen = m_emerge->m_mapgens[id];
enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info;
try {
- while (!stopRequested()) {
- std::map<v3s16, MapBlock *> modified_blocks;
- BlockEmergeData bedata;
- BlockMakeData bmdata;
- EmergeAction action;
- MapBlock *block;
-
- if (!popBlockEmerge(&pos, &bedata)) {
- m_queue_event.wait();
- continue;
- }
+ while (!stopRequested()) {
+ std::map<v3s16, MapBlock *> modified_blocks;
+ BlockEmergeData bedata;
+ BlockMakeData bmdata;
+ EmergeAction action;
+ MapBlock *block;
- if (blockpos_over_max_limit(pos))
- continue;
+ if (!popBlockEmerge(&pos, &bedata)) {
+ m_queue_event.wait();
+ continue;
+ }
- bool allow_gen = bedata.flags & BLOCK_EMERGE_ALLOW_GEN;
- EMERGE_DBG_OUT("pos=" PP(pos) " allow_gen=" << allow_gen);
+ if (blockpos_over_max_limit(pos))
+ continue;
- action = getBlockOrStartGen(pos, allow_gen, &block, &bmdata);
- if (action == EMERGE_GENERATED) {
- {
- ScopeProfiler sp(g_profiler,
- "EmergeThread: Mapgen::makeChunk",
- SPT_AVG);
+ bool allow_gen = bedata.flags & BLOCK_EMERGE_ALLOW_GEN;
+ EMERGE_DBG_OUT("pos=" PP(pos) " allow_gen=" << allow_gen);
- m_mapgen->makeChunk(&bmdata);
- }
+ action = getBlockOrStartGen(pos, allow_gen, &block, &bmdata);
+ if (action == EMERGE_GENERATED) {
+ {
+ ScopeProfiler sp(g_profiler,
+ "EmergeThread: Mapgen::makeChunk", SPT_AVG);
- block = finishGen(pos, &bmdata, &modified_blocks);
+ m_mapgen->makeChunk(&bmdata);
}
- runCompletionCallbacks(pos, action, bedata.callbacks);
+ block = finishGen(pos, &bmdata, &modified_blocks);
+ }
- if (block)
- modified_blocks[pos] = block;
+ runCompletionCallbacks(pos, action, bedata.callbacks);
- if (!modified_blocks.empty())
- m_server->SetBlocksNotSent(modified_blocks);
- }
+ if (block)
+ modified_blocks[pos] = block;
+
+ if (!modified_blocks.empty())
+ m_server->SetBlocksNotSent(modified_blocks);
+ }
} catch (VersionMismatchException &e) {
std::ostringstream err;
err << "World data version mismatch in MapBlock " << PP(pos) << std::endl
- << "----" << std::endl
- << "\"" << e.what() << "\"" << std::endl
- << "See debug.txt." << std::endl
- << "World probably saved by a newer version of " PROJECT_NAME_C "."
- << std::endl;
+ << "----" << std::endl
+ << "\"" << e.what() << "\"" << std::endl
+ << "See debug.txt." << std::endl
+ << "World probably saved by a newer version of " PROJECT_NAME_C "."
+ << std::endl;
m_server->setAsyncFatalError(err.str());
} catch (SerializationError &e) {
std::ostringstream err;
err << "Invalid data in MapBlock " << PP(pos) << std::endl
- << "----" << std::endl
- << "\"" << e.what() << "\"" << std::endl
- << "See debug.txt." << std::endl
- << "You can ignore this using [ignore_world_load_errors = true]."
- << std::endl;
+ << "----" << std::endl
+ << "\"" << e.what() << "\"" << std::endl
+ << "See debug.txt." << std::endl
+ << "You can ignore this using [ignore_world_load_errors = true]."
+ << std::endl;
m_server->setAsyncFatalError(err.str());
}