From db3466dbe885f27b87ceca0a4bb115169f844a0c Mon Sep 17 00:00:00 2001
From: gregorycu <gregory.currie@gmail.com>
Date: Wed, 14 Jan 2015 01:19:54 +1100
Subject: [PATCH] Water fixes

Change must_reflow to a deque
Add overload for MapBlock::raiseModified that takes a const char*. This is a speed improvement.
Comment out unused variable
Optimisations to block offset calculations
---
 src/map.cpp        | 41 +++++++++++++++++++----------------------
 src/mapblock.h     | 33 +++++++++++++++++++++++++++++++++
 src/util/numeric.h | 20 ++++++++++++++++++++
 3 files changed, 72 insertions(+), 22 deletions(-)

diff --git a/src/map.cpp b/src/map.cpp
index 52303cd38..434243a10 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -43,6 +43,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "database.h"
 #include "database-dummy.h"
 #include "database-sqlite3.h"
+#include <deque>
 #if USE_LEVELDB
 #include "database-leveldb.h"
 #endif
@@ -334,7 +335,8 @@ void Map::unspreadLight(enum LightBank bank,
 			v3s16 n2pos = pos + dirs[i];
 
 			// Get the block where the node is located
-			v3s16 blockpos = getNodeBlockPos(n2pos);
+			v3s16 blockpos, relpos;
+			getNodeBlockPosWithOffset(n2pos, blockpos, relpos);
 
 			// Only fetch a new block if the block position has changed
 			try {
@@ -350,8 +352,6 @@ void Map::unspreadLight(enum LightBank bank,
 				continue;
 			}
 
-			// Calculate relative position in block
-			v3s16 relpos = n2pos - blockpos * MAP_BLOCKSIZE;
 			// Get node straight from the block
 			bool is_valid_position;
 			MapNode n2 = block->getNode(relpos, &is_valid_position);
@@ -418,9 +418,9 @@ void Map::unspreadLight(enum LightBank bank,
 	}
 
 	/*infostream<<"unspreadLight(): Changed block "
-			<<blockchangecount<<" times"
-			<<" for "<<from_nodes.size()<<" nodes"
-			<<std::endl;*/
+	<<blockchangecount<<" times"
+	<<" for "<<from_nodes.size()<<" nodes"
+	<<std::endl;*/
 
 	if(!unlighted_nodes.empty())
 		unspreadLight(bank, unlighted_nodes, light_sources, modified_blocks);
@@ -471,14 +471,16 @@ void Map::spreadLight(enum LightBank bank,
 	*/
 	v3s16 blockpos_last;
 	MapBlock *block = NULL;
-	// Cache this a bit, too
+		// Cache this a bit, too
 	bool block_checked_in_modified = false;
 
 	for(std::set<v3s16>::iterator j = from_nodes.begin();
 		j != from_nodes.end(); ++j)
 	{
 		v3s16 pos = *j;
-		v3s16 blockpos = getNodeBlockPos(pos);
+		v3s16 blockpos, relpos;
+
+		getNodeBlockPosWithOffset(pos, blockpos, relpos);
 
 		// Only fetch a new block if the block position has changed
 		try {
@@ -497,9 +499,6 @@ void Map::spreadLight(enum LightBank bank,
 		if(block->isDummy())
 			continue;
 
-		// Calculate relative position in block
-		v3s16 relpos = pos - blockpos_last * MAP_BLOCKSIZE;
-
 		// Get node straight from the block
 		bool is_valid_position;
 		MapNode n = block->getNode(relpos, &is_valid_position);
@@ -513,7 +512,8 @@ void Map::spreadLight(enum LightBank bank,
 			v3s16 n2pos = pos + dirs[i];
 
 			// Get the block where the node is located
-			v3s16 blockpos = getNodeBlockPos(n2pos);
+			v3s16 blockpos, relpos;
+			getNodeBlockPosWithOffset(n2pos, blockpos, relpos);
 
 			// Only fetch a new block if the block position has changed
 			try {
@@ -529,8 +529,6 @@ void Map::spreadLight(enum LightBank bank,
 				continue;
 			}
 
-			// Calculate relative position in block
-			v3s16 relpos = n2pos - blockpos * MAP_BLOCKSIZE;
 			// Get node straight from the block
 			MapNode n2 = block->getNode(relpos, &is_valid_position);
 			if (!is_valid_position)
@@ -700,7 +698,7 @@ void Map::updateLighting(enum LightBank bank,
 	//bool debug=true;
 	//u32 count_was = modified_blocks.size();
 
-	std::map<v3s16, MapBlock*> blocks_to_update;
+	//std::map<v3s16, MapBlock*> blocks_to_update;
 
 	std::set<v3s16> light_sources;
 
@@ -725,7 +723,7 @@ void Map::updateLighting(enum LightBank bank,
 			v3s16 pos = block->getPos();
 			v3s16 posnodes = block->getPosRelative();
 			modified_blocks[pos] = block;
-			blocks_to_update[pos] = block;
+			//blocks_to_update[pos] = block;
 
 			/*
 				Clear all light from block
@@ -1637,7 +1635,7 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks)
 		infostream<<"transformLiquids(): initial_size="<<initial_size<<std::endl;*/
 
 	// list of nodes that due to viscosity have not reached their max level height
-	UniqueQueue<v3s16> must_reflow;
+	std::deque<v3s16> must_reflow;
 
 	// List of MapBlocks that will require a lighting update (due to lava)
 	std::map<v3s16, MapBlock*> lighting_modified_blocks;
@@ -1918,11 +1916,10 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks)
 		}
 	}
 	//infostream<<"Map::transformLiquids(): loopcount="<<loopcount<<std::endl;
-	while (must_reflow.size() > 0)
-	{
-		m_transforming_liquid.push_back(must_reflow.front());
-		must_reflow.pop_front();
-	}
+
+	for (std::deque<v3s16>::iterator iter = must_reflow.begin(); iter != must_reflow.end(); ++iter)
+		m_transforming_liquid.push_back(*iter);
+
 	updateLighting(lighting_modified_blocks, modified_blocks);
 
 
diff --git a/src/mapblock.h b/src/mapblock.h
index 76c82c083..5cf2bc801 100644
--- a/src/mapblock.h
+++ b/src/mapblock.h
@@ -166,6 +166,29 @@ class MapBlock /*: public NodeContainer*/
 			}
 		}
 	}
+	void raiseModified(u32 mod, const char *reason)
+	{
+		if (mod > m_modified){
+			m_modified = mod;
+			m_modified_reason = reason;
+			m_modified_reason_too_long = false;
+
+			if (m_modified >= MOD_STATE_WRITE_AT_UNLOAD){
+				m_disk_timestamp = m_timestamp;
+			}
+		}
+		else if (mod == m_modified){
+			if (!m_modified_reason_too_long){
+				if (m_modified_reason.size() < 40)
+					m_modified_reason += ", " + std::string(reason);
+				else{
+					m_modified_reason += "...";
+					m_modified_reason_too_long = true;
+				}
+			}
+		}
+	}
+
 	u32 getModified()
 	{
 		return m_modified;
@@ -619,6 +642,16 @@ inline s16 getNodeBlockY(s16 y)
 	return getContainerPos(y, MAP_BLOCKSIZE);
 }
 
+inline void getNodeBlockPosWithOffset(const v3s16 &p, v3s16 &block, v3s16 &offset)
+{
+	getContainerPosWithOffset(p, MAP_BLOCKSIZE, block, offset);
+}
+
+inline void getNodeSectorPosWithOffset(const v2s16 &p, v2s16 &block, v2s16 &offset)
+{
+	getContainerPosWithOffset(p, MAP_BLOCKSIZE, block, offset);
+}
+
 /*
 	Get a quick string to describe what a block actually contains
 */
diff --git a/src/util/numeric.h b/src/util/numeric.h
index 098a5631c..db1eb003e 100644
--- a/src/util/numeric.h
+++ b/src/util/numeric.h
@@ -85,6 +85,26 @@ inline v3s16 getContainerPos(v3s16 p, v3s16 d)
 	);
 }
 
+inline void getContainerPosWithOffset(s16 p, s16 d, s16 &container, s16 &offset)
+{
+	container = (p >= 0 ? p : p - d + 1) / d;
+	offset = p & (d - 1);
+}
+
+inline void getContainerPosWithOffset(const v2s16 &p, s16 d, v2s16 &container, v2s16 &offset)
+{
+	getContainerPosWithOffset(p.X, d, container.X, offset.X);
+	getContainerPosWithOffset(p.Y, d, container.Y, offset.Y);
+}
+
+inline void getContainerPosWithOffset(const v3s16 &p, s16 d, v3s16 &container, v3s16 &offset)
+{
+	getContainerPosWithOffset(p.X, d, container.X, offset.X);
+	getContainerPosWithOffset(p.Y, d, container.Y, offset.Y);
+	getContainerPosWithOffset(p.Z, d, container.Z, offset.Z);
+}
+
+
 inline bool isInArea(v3s16 p, s16 d)
 {
 	return (
-- 
GitLab