LocalPlayer::accelerateHorizontal: cleanups
[oweals/minetest.git] / src / mapblock.cpp
index ed4f096924982a3d2146ff0193793efe07522f7d..ca589479419438ab7df7ac56ad4822d0058730cc 100644 (file)
@@ -361,17 +361,24 @@ void MapBlock::actuallyUpdateDayNightDiff()
                return;
        }
 
-       bool differs;
+       bool differs = false;
 
        /*
                Check if any lighting value differs
        */
+
+       MapNode previous_n(CONTENT_IGNORE);
        for (u32 i = 0; i < nodecount; i++) {
-               MapNode &n = data[i];
+               MapNode n = data[i];
+
+               // If node is identical to previous node, don't verify if it differs
+               if (n == previous_n)
+                       continue;
 
                differs = !n.isLightDayNightEq(nodemgr);
                if (differs)
                        break;
+               previous_n = n;
        }
 
        /*
@@ -465,7 +472,7 @@ static void getBlockNodeIdMapping(NameIdMapping *nimap, MapNode *nodes,
 
                        const ContentFeatures &f = nodedef->get(global_id);
                        const std::string &name = f.name;
-                       if(name == "")
+                       if (name.empty())
                                unknown_contents.insert(global_id);
                        else
                                nimap->set(id, name);
@@ -494,22 +501,44 @@ static void correctBlockNodeIds(const NameIdMapping *nimap, MapNode *nodes,
        // correct ids.
        std::unordered_set<content_t> unnamed_contents;
        std::unordered_set<std::string> unallocatable_contents;
+
+       bool previous_exists = false;
+       content_t previous_local_id = CONTENT_IGNORE;
+       content_t previous_global_id = CONTENT_IGNORE;
+
        for (u32 i = 0; i < MapBlock::nodecount; i++) {
                content_t local_id = nodes[i].getContent();
+               // If previous node local_id was found and same than before, don't lookup maps
+               // apply directly previous resolved id
+               // This permits to massively improve loading performance when nodes are similar
+               // example: default:air, default:stone are massively present
+               if (previous_exists && local_id == previous_local_id) {
+                       nodes[i].setContent(previous_global_id);
+                       continue;
+               }
+
                std::string name;
                if (!nimap->getName(local_id, name)) {
                        unnamed_contents.insert(local_id);
+                       previous_exists = false;
                        continue;
                }
+
                content_t global_id;
                if (!nodedef->getId(name, global_id)) {
                        global_id = gamedef->allocateUnknownNodeId(name);
-                       if(global_id == CONTENT_IGNORE){
+                       if (global_id == CONTENT_IGNORE) {
                                unallocatable_contents.insert(name);
+                               previous_exists = false;
                                continue;
                        }
                }
                nodes[i].setContent(global_id);
+
+               // Save previous node local_id & global_id result
+               previous_local_id = local_id;
+               previous_global_id = global_id;
+               previous_exists = true;
        }
 
        for (const content_t c: unnamed_contents) {