diff --git a/src/client.cpp b/src/client.cpp index f97acfd..6d0e686 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -5,7 +5,7 @@ Copyright (C) 2010 celeron55, Perttu Ahola This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. +MeshUpdateQueue::(at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -26,6 +26,104 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "porting.h" #include "mapsector.h" +#include "mapblock_mesh.h" +#include "mapblock.h" + +/* + QueuedMeshUpdate +*/ + +QueuedMeshUpdate::QueuedMeshUpdate(): + p(-1337,-1337,-1337), + data(NULL), + ack_block_to_server(false) +{ +} + +QueuedMeshUpdate::~QueuedMeshUpdate() +{ + if(data) + delete data; +} + +/* + MeshUpdateQueue +*/ + +MeshUpdateQueue::MeshUpdateQueue() +{ + m_mutex.Init(); +} + +MeshUpdateQueue::~MeshUpdateQueue() +{ + JMutexAutoLock lock(m_mutex); + + core::list::Iterator i; + for(i=m_queue.begin(); i!=m_queue.end(); i++) + { + QueuedMeshUpdate *q = *i; + delete q; + } +} + +/* + peer_id=0 adds with nobody to send to +*/ +void MeshUpdateQueue::addBlock(v3s16 p, MeshMakeData *data, bool ack_block_to_server) +{ + DSTACK(__FUNCTION_NAME); + + assert(data); + + JMutexAutoLock lock(m_mutex); + + /* + Find if block is already in queue. + If it is, update the data and quit. + */ + core::list::Iterator i; + for(i=m_queue.begin(); i!=m_queue.end(); i++) + { + QueuedMeshUpdate *q = *i; + if(q->p == p) + { + if(q->data) + delete q->data; + q->data = data; + if(ack_block_to_server) + q->ack_block_to_server = true; + return; + } + } + + /* + Add the block + */ + QueuedMeshUpdate *q = new QueuedMeshUpdate; + q->p = p; + q->data = data; + q->ack_block_to_server = ack_block_to_server; + m_queue.push_back(q); +} + +// Returned pointer must be deleted +// Returns NULL if queue is empty +QueuedMeshUpdate * MeshUpdateQueue::pop() +{ + JMutexAutoLock lock(m_mutex); + + core::list::Iterator i = m_queue.begin(); + if(i == m_queue.end()) + return NULL; + QueuedMeshUpdate *q = *i; + m_queue.erase(i); + return q; +} + +/* + MeshUpdateThread +*/ void * MeshUpdateThread::Thread() { @@ -1736,7 +1834,7 @@ void Client::addNode(v3s16 p, MapNode n) try { - TimeTaker timer3("Client::addNode(): addNodeAndUpdate"); + //TimeTaker timer3("Client::addNode(): addNodeAndUpdate"); m_env.getMap().addNodeAndUpdate(p, n, modified_blocks); } catch(InvalidPositionException &e) @@ -1964,12 +2062,6 @@ void Client::printDebugInfo(std::ostream &os) <= 0 && m_daynight_i < DAYNIGHT_CACHE_COUNT); - return m_daynight_i; -}*/ - u32 Client::getDayNightRatio() { //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out @@ -1983,6 +2075,40 @@ u16 Client::getHP() return player->hp; } +void Client::setTempMod(v3s16 p, NodeMod mod) +{ + //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out + assert(m_env.getMap().mapType() == MAPTYPE_CLIENT); + + core::map affected_blocks; + ((ClientMap&)m_env.getMap()).setTempMod(p, mod, + &affected_blocks); + + for(core::map::Iterator + i = affected_blocks.getIterator(); + i.atEnd() == false; i++) + { + i.getNode()->getValue()->updateMesh(m_env.getDayNightRatio()); + } +} + +void Client::clearTempMod(v3s16 p) +{ + //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out + assert(m_env.getMap().mapType() == MAPTYPE_CLIENT); + + core::map affected_blocks; + ((ClientMap&)m_env.getMap()).clearTempMod(p, + &affected_blocks); + + for(core::map::Iterator + i = affected_blocks.getIterator(); + i.atEnd() == false; i++) + { + i.getNode()->getValue()->updateMesh(m_env.getDayNightRatio()); + } +} + void Client::addUpdateMeshTask(v3s16 p, bool ack_to_server) { /*dstream<<"Client::addUpdateMeshTask(): " diff --git a/src/client.h b/src/client.h index a1b1c66..442eaef 100644 --- a/src/client.h +++ b/src/client.h @@ -29,6 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "clientobject.h" +struct MeshMakeData; + class ClientNotReadyException : public BaseException { public: @@ -43,18 +45,8 @@ struct QueuedMeshUpdate MeshMakeData *data; bool ack_block_to_server; - QueuedMeshUpdate(): - p(-1337,-1337,-1337), - data(NULL), - ack_block_to_server(false) - { - } - - ~QueuedMeshUpdate() - { - if(data) - delete data; - } + QueuedMeshUpdate(); + ~QueuedMeshUpdate(); }; /* @@ -63,76 +55,18 @@ struct QueuedMeshUpdate class MeshUpdateQueue { public: - MeshUpdateQueue() - { - m_mutex.Init(); - } + MeshUpdateQueue(); - ~MeshUpdateQueue() - { - JMutexAutoLock lock(m_mutex); - - core::list::Iterator i; - for(i=m_queue.begin(); i!=m_queue.end(); i++) - { - QueuedMeshUpdate *q = *i; - delete q; - } - } + ~MeshUpdateQueue(); /* peer_id=0 adds with nobody to send to */ - void addBlock(v3s16 p, MeshMakeData *data, bool ack_block_to_server) - { - DSTACK(__FUNCTION_NAME); - - assert(data); - - JMutexAutoLock lock(m_mutex); - - /* - Find if block is already in queue. - If it is, update the data and quit. - */ - core::list::Iterator i; - for(i=m_queue.begin(); i!=m_queue.end(); i++) - { - QueuedMeshUpdate *q = *i; - if(q->p == p) - { - if(q->data) - delete q->data; - q->data = data; - if(ack_block_to_server) - q->ack_block_to_server = true; - return; - } - } - - /* - Add the block - */ - QueuedMeshUpdate *q = new QueuedMeshUpdate; - q->p = p; - q->data = data; - q->ack_block_to_server = ack_block_to_server; - m_queue.push_back(q); - } + void addBlock(v3s16 p, MeshMakeData *data, bool ack_block_to_server); // Returned pointer must be deleted // Returns NULL if queue is empty - QueuedMeshUpdate * pop() - { - JMutexAutoLock lock(m_mutex); - - core::list::Iterator i = m_queue.begin(); - if(i == m_queue.end()) - return NULL; - QueuedMeshUpdate *q = *i; - m_queue.erase(i); - return q; - } + QueuedMeshUpdate * pop(); u32 size() { @@ -309,40 +243,8 @@ public: u16 getHP(); - //void updateSomeExpiredMeshes(); - - void setTempMod(v3s16 p, NodeMod mod) - { - //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out - assert(m_env.getMap().mapType() == MAPTYPE_CLIENT); - - core::map affected_blocks; - ((ClientMap&)m_env.getMap()).setTempMod(p, mod, - &affected_blocks); - - for(core::map::Iterator - i = affected_blocks.getIterator(); - i.atEnd() == false; i++) - { - i.getNode()->getValue()->updateMesh(m_env.getDayNightRatio()); - } - } - void clearTempMod(v3s16 p) - { - //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out - assert(m_env.getMap().mapType() == MAPTYPE_CLIENT); - - core::map affected_blocks; - ((ClientMap&)m_env.getMap()).clearTempMod(p, - &affected_blocks); - - for(core::map::Iterator - i = affected_blocks.getIterator(); - i.atEnd() == false; i++) - { - i.getNode()->getValue()->updateMesh(m_env.getDayNightRatio()); - } - } + void setTempMod(v3s16 p, NodeMod mod); + void clearTempMod(v3s16 p); float getAvgRtt() { diff --git a/src/environment.cpp b/src/environment.cpp index cd25534..6a7c847 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -22,7 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "porting.h" #include "collision.h" #include "content_mapnode.h" - +#include "mapblock.h" Environment::Environment(): m_time_of_day(9000) diff --git a/src/game.cpp b/src/game.cpp index f3fac0c..337879c 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -30,8 +30,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "clouds.h" #include "keycode.h" #include "farmesh.h" +#include "mapblock.h" -// TODO: Move content-aware stuff to separate file +/* + TODO: Move content-aware stuff to separate file by adding properties + and virtual interfaces +*/ #include "content_mapnode.h" #include "content_nodemeta.h" diff --git a/src/main.cpp b/src/main.cpp index 41da310..9c7cf2e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -238,8 +238,6 @@ FIXME: The new optimized map sending doesn't sometimes send enough blocks from big caves and such FIXME: Block send distance configuration does not take effect for some reason -TODO: Map saving should be done by EmergeThread - SUGG: Map unloading based on sector reference is not very good, it keeps unnecessary stuff in memory. I guess. Investigate this. diff --git a/src/map.cpp b/src/map.cpp index d8cc34c..3164028 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "serverobject.h" #include "content_mapnode.h" #include "mapgen.h" +#include "nodemetadata.h" extern "C" { #include "sqlite3.h" @@ -141,19 +142,6 @@ MapBlock * Map::getBlockNoCreate(v3s16 p3d) return block; } - -/*MapBlock * Map::getBlockCreate(v3s16 p3d) -{ - v2s16 p2d(p3d.X, p3d.Z); - MapSector * sector = getSectorCreate(p2d); - assert(sector); - MapBlock *block = sector->getBlockNoCreate(p3d.Y); - if(block) - return block; - block = sector->createBlankBlock(p3d.Y); - return block; -}*/ - bool Map::isNodeUnderground(v3s16 p) { v3s16 blockpos = getNodeBlockPos(p); @@ -167,6 +155,45 @@ bool Map::isNodeUnderground(v3s16 p) } } +bool Map::isValidPosition(v3s16 p) +{ + v3s16 blockpos = getNodeBlockPos(p); + MapBlock *block = getBlockNoCreate(blockpos); + return (block != NULL); +} + +// Returns a CONTENT_IGNORE node if not found +MapNode Map::getNodeNoEx(v3s16 p) +{ + v3s16 blockpos = getNodeBlockPos(p); + MapBlock *block = getBlockNoCreateNoEx(blockpos); + if(block == NULL) + return MapNode(CONTENT_IGNORE); + v3s16 relpos = p - blockpos*MAP_BLOCKSIZE; + return block->getNodeNoCheck(relpos); +} + +// throws InvalidPositionException if not found +MapNode Map::getNode(v3s16 p) +{ + v3s16 blockpos = getNodeBlockPos(p); + MapBlock *block = getBlockNoCreateNoEx(blockpos); + if(block == NULL) + throw InvalidPositionException(); + v3s16 relpos = p - blockpos*MAP_BLOCKSIZE; + return block->getNodeNoCheck(relpos); +} + +// throws InvalidPositionException if not found +void Map::setNode(v3s16 p, MapNode & n) +{ + v3s16 blockpos = getNodeBlockPos(p); + MapBlock *block = getBlockNoCreate(blockpos); + v3s16 relpos = p - blockpos*MAP_BLOCKSIZE; + block->setNodeNoCheck(relpos, n); +} + + /* Goes recursively through the neighbours of the node. @@ -2096,22 +2123,25 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data, /* Update lighting */ - - core::map lighting_update_blocks; - // Center block - lighting_update_blocks.insert(block->getPos(), block); -#if 0 - // All modified blocks - for(core::map::Iterator - i = changed_blocks.getIterator(); - i.atEnd() == false; i++) { - lighting_update_blocks.insert(i.getNode()->getKey(), - i.getNode()->getValue()); + TimeTaker t("finishBlockMake lighting update"); + + core::map lighting_update_blocks; + // Center block + lighting_update_blocks.insert(block->getPos(), block); + #if 0 + // All modified blocks + for(core::map::Iterator + i = changed_blocks.getIterator(); + i.atEnd() == false; i++) + { + lighting_update_blocks.insert(i.getNode()->getKey(), + i.getNode()->getValue()); + } + #endif + updateLighting(lighting_update_blocks, changed_blocks); } -#endif - updateLighting(lighting_update_blocks, changed_blocks); - + /* Add random objects to block */ diff --git a/src/map.h b/src/map.h index 406b1bc..c64f8cb 100644 --- a/src/map.h +++ b/src/map.h @@ -25,27 +25,17 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include -#ifdef _WIN32 - #include - #define sleep_s(x) Sleep((x*1000)) -#else - #include - #define sleep_s(x) sleep(x) -#endif - #include "common_irrlicht.h" #include "mapnode.h" -#include "mapblock.h" +#include "mapblock_nodemod.h" #include "constants.h" #include "voxel.h" -#include "mapchunk.h" -#include "nodemetadata.h" class MapSector; class ServerMapSector; class ClientMapSector; - class MapBlock; +class NodeMetadata; namespace mapgen{ struct BlockMakeData; @@ -161,66 +151,20 @@ public: MapBlock * getBlockNoCreate(v3s16 p); // Returns NULL if not found MapBlock * getBlockNoCreateNoEx(v3s16 p); - // Gets an existing block or creates an empty one - //MapBlock * getBlockCreate(v3s16 p); // Returns InvalidPositionException if not found bool isNodeUnderground(v3s16 p); - // virtual from NodeContainer - bool isValidPosition(v3s16 p) - { - v3s16 blockpos = getNodeBlockPos(p); - MapBlock *blockref; - try{ - blockref = getBlockNoCreate(blockpos); - } - catch(InvalidPositionException &e) - { - return false; - } - return true; - /*v3s16 relpos = p - blockpos*MAP_BLOCKSIZE; - bool is_valid = blockref->isValidPosition(relpos); - return is_valid;*/ - } + bool isValidPosition(v3s16 p); - // virtual from NodeContainer // throws InvalidPositionException if not found - MapNode getNode(v3s16 p) - { - v3s16 blockpos = getNodeBlockPos(p); - MapBlock * blockref = getBlockNoCreate(blockpos); - v3s16 relpos = p - blockpos*MAP_BLOCKSIZE; + MapNode getNode(v3s16 p); - return blockref->getNodeNoCheck(relpos); - } - - // virtual from NodeContainer // throws InvalidPositionException if not found - void setNode(v3s16 p, MapNode & n) - { - v3s16 blockpos = getNodeBlockPos(p); - MapBlock * blockref = getBlockNoCreate(blockpos); - v3s16 relpos = p - blockpos*MAP_BLOCKSIZE; - blockref->setNodeNoCheck(relpos, n); - } + void setNode(v3s16 p, MapNode & n); // Returns a CONTENT_IGNORE node if not found - MapNode getNodeNoEx(v3s16 p) - { - try{ - v3s16 blockpos = getNodeBlockPos(p); - MapBlock * blockref = getBlockNoCreate(blockpos); - v3s16 relpos = p - blockpos*MAP_BLOCKSIZE; - - return blockref->getNodeNoCheck(relpos); - } - catch(InvalidPositionException &e) - { - return MapNode(CONTENT_IGNORE); - } - } + MapNode getNodeNoEx(v3s16 p); void unspreadLight(enum LightBank bank, core::map & from_nodes, diff --git a/src/mapblockobject.cpp b/src/mapblockobject.cpp index 51ac4c6..ab1c202 100644 --- a/src/mapblockobject.cpp +++ b/src/mapblockobject.cpp @@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "map.h" #include "inventory.h" #include "utility.h" +#include "mapblock.h" /* MapBlockObject diff --git a/src/mapchunk.h b/src/mapchunk.h index 9860aba..98df7ce 100644 --- a/src/mapchunk.h +++ b/src/mapchunk.h @@ -20,6 +20,11 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef MAPCHUNK_HEADER #define MAPCHUNK_HEADER +/* + TODO: Remove +*/ + +#if 0 /* MapChunk contains map-generation-time metadata for an area of some MapSectors. (something like 16x16) @@ -66,6 +71,7 @@ private: u8 m_generation_level; bool m_modified; }; +#endif #endif diff --git a/src/server.cpp b/src/server.cpp index cf8b577..671c3bd 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "content_mapnode.h" #include "content_craft.h" #include "content_nodemeta.h" +#include "mapblock.h" #define BLOCK_EMERGE_FLAG_FROMDISK (1<<0)