diff options
author | kwolekr <kwolekr@minetest.net> | 2014-09-01 14:20:31 -0400 |
---|---|---|
committer | kwolekr <kwolekr@minetest.net> | 2014-09-01 15:12:22 -0400 |
commit | 9e4e7072da8f565eef37da7558053a436b9cbba3 (patch) | |
tree | d1bb4ac82b4a25880695aec4df163dd0002cd526 /src | |
parent | 3fa4f782d90dac0d800251a9ab0f0afb9d32560c (diff) | |
download | minetest-9e4e7072da8f565eef37da7558053a436b9cbba3.tar.gz minetest-9e4e7072da8f565eef37da7558053a436b9cbba3.tar.bz2 minetest-9e4e7072da8f565eef37da7558053a436b9cbba3.zip |
Update Mapgen VoxelManipulator on buffer invalidation
Diffstat (limited to 'src')
-rw-r--r-- | src/environment.cpp | 39 | ||||
-rw-r--r-- | src/map.cpp | 25 | ||||
-rw-r--r-- | src/map.h | 4 | ||||
-rw-r--r-- | src/script/lua_api/l_vmanip.cpp | 13 | ||||
-rw-r--r-- | src/script/lua_api/l_vmanip.h | 2 |
5 files changed, 73 insertions, 10 deletions
diff --git a/src/environment.cpp b/src/environment.cpp index 24a498aa9..c8af72f6b 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -778,19 +778,26 @@ bool ServerEnvironment::setNode(v3s16 p, const MapNode &n) { INodeDefManager *ndef = m_gamedef->ndef(); MapNode n_old = m_map->getNodeNoEx(p); + // Call destructor - if(ndef->get(n_old).has_on_destruct) + if (ndef->get(n_old).has_on_destruct) m_script->node_on_destruct(p, n_old); + // Replace node - bool succeeded = m_map->addNodeWithEvent(p, n); - if(!succeeded) + if (!m_map->addNodeWithEvent(p, n)) return false; + + // Update active VoxelManipulator if a mapgen thread + m_map->updateVManip(p); + // Call post-destructor - if(ndef->get(n_old).has_after_destruct) + if (ndef->get(n_old).has_after_destruct) m_script->node_after_destruct(p, n_old); + // Call constructor - if(ndef->get(n).has_on_construct) + if (ndef->get(n).has_on_construct) m_script->node_on_construct(p, n); + return true; } @@ -798,24 +805,36 @@ bool ServerEnvironment::removeNode(v3s16 p) { INodeDefManager *ndef = m_gamedef->ndef(); MapNode n_old = m_map->getNodeNoEx(p); + // Call destructor - if(ndef->get(n_old).has_on_destruct) + if (ndef->get(n_old).has_on_destruct) m_script->node_on_destruct(p, n_old); + // Replace with air // This is slightly optimized compared to addNodeWithEvent(air) - bool succeeded = m_map->removeNodeWithEvent(p); - if(!succeeded) + if (!m_map->removeNodeWithEvent(p)) return false; + + // Update active VoxelManipulator if a mapgen thread + m_map->updateVManip(p); + // Call post-destructor - if(ndef->get(n_old).has_after_destruct) + if (ndef->get(n_old).has_after_destruct) m_script->node_after_destruct(p, n_old); + // Air doesn't require constructor return true; } bool ServerEnvironment::swapNode(v3s16 p, const MapNode &n) { - return m_map->addNodeWithEvent(p, n, false); + if (!m_map->addNodeWithEvent(p, n, false)) + return false; + + // Update active VoxelManipulator if a mapgen thread + m_map->updateVManip(p); + + return true; } std::set<u16> ServerEnvironment::getObjectsInsideRadius(v3f pos, float radius) diff --git a/src/map.cpp b/src/map.cpp index 147bd3584..236972ae9 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -2757,6 +2757,28 @@ MapBlock *ServerMap::getBlockOrEmerge(v3s16 p3d) void ServerMap::prepareBlock(MapBlock *block) { } +// N.B. This requires no synchronization, since data will not be modified unless +// the VoxelManipulator being updated belongs to the same thread. +void ServerMap::updateVManip(v3s16 pos) +{ + Mapgen *mg = m_emerge->getCurrentMapgen(); + if (!mg) + return; + + ManualMapVoxelManipulator *vm = mg->vm; + if (!vm) + return; + + if (!vm->m_area.contains(pos)) + return; + + s32 idx = vm->m_area.index(pos); + vm->m_data[idx] = getNodeNoEx(pos); + vm->m_flags[idx] &= ~VOXELFLAG_NO_DATA; + + vm->m_is_dirty = true; +} + s16 ServerMap::findGroundLevel(v2s16 p2d) { #if 0 @@ -3523,6 +3545,7 @@ void ServerMap::PrintInfo(std::ostream &out) ManualMapVoxelManipulator::ManualMapVoxelManipulator(Map *map): VoxelManipulator(), + m_is_dirty(false), m_create_area(false), m_map(map) { @@ -3617,6 +3640,8 @@ void ManualMapVoxelManipulator::initialEmerge(v3s16 blockpos_min, m_loaded_blocks[p] = flags; } + + m_is_dirty = false; } void ManualMapVoxelManipulator::blitBackAll( @@ -493,6 +493,8 @@ public: // Database version void loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool save_after_load=false); + void updateVManip(v3s16 pos); + // For debug printing virtual void PrintInfo(std::ostream &out); @@ -550,6 +552,8 @@ public: void blitBackAll(std::map<v3s16, MapBlock*> * modified_blocks, bool overwrite_generated = true); + bool m_is_dirty; + protected: bool m_create_area; Map *m_map; diff --git a/src/script/lua_api/l_vmanip.cpp b/src/script/lua_api/l_vmanip.cpp index f3c1fa67a..2a3cfcafa 100644 --- a/src/script/lua_api/l_vmanip.cpp +++ b/src/script/lua_api/l_vmanip.cpp @@ -304,6 +304,18 @@ int LuaVoxelManip::l_update_map(lua_State *L) return 0; } +int LuaVoxelManip::l_was_modified(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + ManualMapVoxelManipulator *vm = o->vm; + + lua_pushboolean(L, vm->m_is_dirty); + + return 1; +} + LuaVoxelManip::LuaVoxelManip(ManualMapVoxelManipulator *mmvm, bool is_mg_vm) { this->vm = mmvm; @@ -396,5 +408,6 @@ const luaL_reg LuaVoxelManip::methods[] = { luamethod(LuaVoxelManip, set_light_data), luamethod(LuaVoxelManip, get_param2_data), luamethod(LuaVoxelManip, set_param2_data), + luamethod(LuaVoxelManip, was_modified), {0,0} }; diff --git a/src/script/lua_api/l_vmanip.h b/src/script/lua_api/l_vmanip.h index fc7ef30e6..70468b344 100644 --- a/src/script/lua_api/l_vmanip.h +++ b/src/script/lua_api/l_vmanip.h @@ -58,6 +58,8 @@ private: static int l_get_param2_data(lua_State *L); static int l_set_param2_data(lua_State *L); + static int l_was_modified(lua_State *L); + public: LuaVoxelManip(ManualMapVoxelManipulator *mmvm, bool is_mapgen_vm); LuaVoxelManip(Map *map); |