summaryrefslogtreecommitdiff
path: root/src/server.cpp
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2011-04-10 20:18:34 +0300
committerPerttu Ahola <celeron55@gmail.com>2011-04-10 20:18:34 +0300
commit10eedbc1d233da36c244de67fcec555bcea87d5f (patch)
tree2a404f4b68371dcb1e89a8b02d791f8d529df60b /src/server.cpp
parent6fa85c8502ced2293cd7f56d47dce9ce8add57dc (diff)
downloadminetest-10eedbc1d233da36c244de67fcec555bcea87d5f.tar.gz
minetest-10eedbc1d233da36c244de67fcec555bcea87d5f.tar.bz2
minetest-10eedbc1d233da36c244de67fcec555bcea87d5f.zip
Map generation is now properly threaded and doesn't block block placement and other stuff.
Diffstat (limited to 'src/server.cpp')
-rw-r--r--src/server.cpp121
1 files changed, 61 insertions, 60 deletions
diff --git a/src/server.cpp b/src/server.cpp
index c5703bf33..63d8e31db 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -72,7 +72,7 @@ void * EmergeThread::Thread()
DSTACK(__FUNCTION_NAME);
- bool debug=false;
+ //bool debug=false;
BEGIN_DEBUG_EXCEPTION_HANDLER
@@ -91,7 +91,19 @@ void * EmergeThread::Thread()
SharedPtr<QueuedBlockEmerge> q(qptr);
v3s16 &p = q->pos;
-
+ v2s16 p2d(p.X,p.Z);
+
+ /*
+ Do not generate over-limit
+ */
+ if(p.X < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
+ || p.X > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
+ || p.Y < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
+ || p.Y > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
+ || p.Z < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
+ || p.Z > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE)
+ continue;
+
//derr_server<<"EmergeThread::Thread(): running"<<std::endl;
//TimeTaker timer("block emerge");
@@ -144,78 +156,67 @@ void * EmergeThread::Thread()
if(optional)
only_from_disk = true;
- /*
- TODO: Map loading logic here, so that the chunk can be
- generated asynchronously:
-
- - Check limits
- With the environment locked:
- - Check if block already is loaded and not dummy
- - If so, we're ready
- -
- */
-
- {//envlock
-
- //TimeTaker envlockwaittimer("block emerge envlock wait time");
-
- // 0-50ms
- JMutexAutoLock envlock(m_server->m_env_mutex);
-
- //envlockwaittimer.stop();
+ v2s16 chunkpos = map.sector_to_chunk(p2d);
- //TimeTaker timer("block emerge (while env locked)");
-
- try{
+ bool generate_chunk = false;
+ if(only_from_disk == false)
+ {
+ JMutexAutoLock envlock(m_server->m_env_mutex);
+ if(map.chunkNonVolatile(chunkpos) == false)
+ generate_chunk = true;
+ }
+ if(generate_chunk)
+ {
+ ChunkMakeData data;
- // First check if the block already exists
- //block = map.getBlockNoCreate(p);
-
- if(block == NULL)
{
- //dstream<<"Calling emergeBlock"<<std::endl;
- block = map.emergeBlock(
- p,
- only_from_disk,
- changed_blocks,
- lighting_invalidated_blocks);
+ JMutexAutoLock envlock(m_server->m_env_mutex);
+ map.initChunkMake(data, chunkpos);
}
- // If it is a dummy, block was not found on disk
- if(block->isDummy())
- {
- //dstream<<"EmergeThread: Got a dummy block"<<std::endl;
- got_block = false;
+ makeChunk(&data);
- if(only_from_disk == false)
- {
- dstream<<"EmergeThread: wanted to generate a block but got a dummy"<<std::endl;
- assert(0);
- }
+ {
+ JMutexAutoLock envlock(m_server->m_env_mutex);
+ map.finishChunkMake(data, changed_blocks);
}
}
- catch(InvalidPositionException &e)
- {
- // Block not found.
- // This happens when position is over limit.
- got_block = false;
- }
-
- if(got_block)
+
+ /*
+ Fetch block from map or generate a single block
+ */
{
- if(debug && changed_blocks.size() > 0)
+ JMutexAutoLock envlock(m_server->m_env_mutex);
+
+ // Load sector if it isn't loaded
+ if(map.getSectorNoGenerateNoEx(p2d) == NULL)
+ map.loadSectorFull(p2d);
+
+ block = map.getBlockNoCreateNoEx(p);
+ if(!block || block->isDummy())
{
- dout_server<<DTIME<<"Got changed_blocks: ";
- for(core::map<v3s16, MapBlock*>::Iterator i = changed_blocks.getIterator();
- i.atEnd() == false; i++)
+ if(only_from_disk)
+ {
+ got_block = false;
+ }
+ else
{
- MapBlock *block = i.getNode()->getValue();
- v3s16 p = block->getPos();
- dout_server<<"("<<p.X<<","<<p.Y<<","<<p.Z<<") ";
+ ServerMapSector *sector =
+ (ServerMapSector*)map.getSectorNoGenerateNoEx(p2d);
+ block = map.generateBlock(p, block, sector, changed_blocks,
+ lighting_invalidated_blocks);
}
- dout_server<<std::endl;
}
+ // TODO: Some additional checking and lighting updating,
+ // see emergeBlock
+ }
+
+ {//envlock
+ JMutexAutoLock envlock(m_server->m_env_mutex);
+
+ if(got_block)
+ {
/*
Collect a list of blocks that have been modified in
addition to the fetched one.