Clean up numeric.h and split FacePositionCache from it
authorShadowNinja <shadowninja@minetest.net>
Mon, 6 Jul 2015 16:53:30 +0000 (12:53 -0400)
committerShadowNinja <shadowninja@minetest.net>
Sat, 6 May 2017 20:09:45 +0000 (16:09 -0400)
I also optiized FacePositionCache a bit: I removed a map
lookup and vector copy from both branches of getFacePosition.

17 files changed:
build/android/jni/Android.mk
src/CMakeLists.txt
src/clientenvironment.cpp
src/clientiface.cpp
src/content_cao.cpp
src/face_position_cache.cpp [new file with mode: 0644]
src/face_position_cache.h [new file with mode: 0644]
src/mg_decoration.cpp
src/mg_ore.cpp
src/script/lua_api/l_env.cpp
src/script/lua_api/l_server.cpp
src/unittest/test_noderesolver.cpp
src/util/basic_macros.h
src/util/numeric.cpp
src/util/numeric.h
src/util/string.cpp
util/travis/clang-format-whitelist.txt

index d4a8d988f8e8f8364744932b99c164537973106b..44d98fada81c0ef4e39699b09df38f24630826ae 100644 (file)
@@ -143,6 +143,7 @@ LOCAL_SRC_FILES := \
                jni/src/dungeongen.cpp                    \
                jni/src/emerge.cpp                        \
                jni/src/environment.cpp                   \
+               jni/src/face_position_cache.cpp           \
                jni/src/filecache.cpp                     \
                jni/src/filesys.cpp                       \
                jni/src/fontengine.cpp                    \
index 4c705cec8279f46a9b9c5dbadd78f7baf360fbe1..7c1a4eee0959b1ba92393b3c27d3b59cdfc19be9 100644 (file)
@@ -388,6 +388,7 @@ set(common_SRCS
        dungeongen.cpp
        emerge.cpp
        environment.cpp
+       face_position_cache.cpp
        filesys.cpp
        genericobject.cpp
        gettext.cpp
index 36e4437b6cecc6dd3d53fe9847bc0adc2a8f1b93..47df49b845dee3b13a134e6d604b857609633e40 100644 (file)
@@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "raycast.h"
 #include "voxelalgorithms.h"
 #include "settings.h"
+#include <algorithm>
 
 /*
        ClientEnvironment
index 7f476f0ea50fc0ae931a06050a81bdaa737e2c95..78339055feafa38d01ea465d15862e13f2243df9 100644 (file)
@@ -20,7 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <sstream>
 
 #include "clientiface.h"
-#include "util/numeric.h"
 #include "remoteplayer.h"
 #include "settings.h"
 #include "mapblock.h"
@@ -32,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "log.h"
 #include "network/serveropcodes.h"
 #include "util/srp.h"
+#include "face_position_cache.h"
 
 const char *ClientInterface::statenames[] = {
        "Invalid",
index d18a0233f14b7e9657b695033623cc8884992c90..d0d3eb84f8629fe08921edfa13c98422d5070987 100644 (file)
@@ -44,6 +44,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "camera.h" // CameraModes
 #include "wieldmesh.h"
 #include "log.h"
+#include <algorithm>
 
 class Settings;
 struct ToolCapabilities;
diff --git a/src/face_position_cache.cpp b/src/face_position_cache.cpp
new file mode 100644 (file)
index 0000000..f57e75d
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+Minetest
+Copyright (C) 2015 Nerzhul, Loic Blot <loic.blot@unix-experience.fr>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(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
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "face_position_cache.h"
+#include "threading/mutex_auto_lock.h"
+
+
+UNORDERED_MAP<u16, std::vector<v3s16> > FacePositionCache::cache;
+Mutex FacePositionCache::cache_mutex;
+
+// Calculate the borders of a "d-radius" cube
+const std::vector<v3s16> &FacePositionCache::getFacePositions(u16 d)
+{
+       MutexAutoLock lock(cache_mutex);
+       UNORDERED_MAP<u16, std::vector<v3s16> >::iterator it = cache.find(d);
+       if (it != cache.end())
+               return it->second;
+
+       return generateFacePosition(d);
+}
+
+const std::vector<v3s16> &FacePositionCache::generateFacePosition(u16 d)
+{
+       cache[d] = std::vector<v3s16>();
+       std::vector<v3s16> &c = cache[d];
+       if (d == 0) {
+               c.push_back(v3s16(0,0,0));
+               return c;
+       }
+       if (d == 1) {
+               // This is an optimized sequence of coordinates.
+               c.push_back(v3s16( 0, 1, 0)); // Top
+               c.push_back(v3s16( 0, 0, 1)); // Back
+               c.push_back(v3s16(-1, 0, 0)); // Left
+               c.push_back(v3s16( 1, 0, 0)); // Right
+               c.push_back(v3s16( 0, 0,-1)); // Front
+               c.push_back(v3s16( 0,-1, 0)); // Bottom
+               // 6
+               c.push_back(v3s16(-1, 0, 1)); // Back left
+               c.push_back(v3s16( 1, 0, 1)); // Back right
+               c.push_back(v3s16(-1, 0,-1)); // Front left
+               c.push_back(v3s16( 1, 0,-1)); // Front right
+               c.push_back(v3s16(-1,-1, 0)); // Bottom left
+               c.push_back(v3s16( 1,-1, 0)); // Bottom right
+               c.push_back(v3s16( 0,-1, 1)); // Bottom back
+               c.push_back(v3s16( 0,-1,-1)); // Bottom front
+               c.push_back(v3s16(-1, 1, 0)); // Top left
+               c.push_back(v3s16( 1, 1, 0)); // Top right
+               c.push_back(v3s16( 0, 1, 1)); // Top back
+               c.push_back(v3s16( 0, 1,-1)); // Top front
+               // 18
+               c.push_back(v3s16(-1, 1, 1)); // Top back-left
+               c.push_back(v3s16( 1, 1, 1)); // Top back-right
+               c.push_back(v3s16(-1, 1,-1)); // Top front-left
+               c.push_back(v3s16( 1, 1,-1)); // Top front-right
+               c.push_back(v3s16(-1,-1, 1)); // Bottom back-left
+               c.push_back(v3s16( 1,-1, 1)); // Bottom back-right
+               c.push_back(v3s16(-1,-1,-1)); // Bottom front-left
+               c.push_back(v3s16( 1,-1,-1)); // Bottom front-right
+               // 26
+               return c;
+       }
+
+       // Take blocks in all sides, starting from y=0 and going +-y
+       for (s16 y = 0; y <= d - 1; y++) {
+               // Left and right side, including borders
+               for (s16 z =- d; z <= d; z++) {
+                       c.push_back(v3s16( d, y, z));
+                       c.push_back(v3s16(-d, y, z));
+                       if (y != 0) {
+                               c.push_back(v3s16( d, -y, z));
+                               c.push_back(v3s16(-d, -y, z));
+                       }
+               }
+               // Back and front side, excluding borders
+               for (s16 x = -d + 1; x <= d - 1; x++) {
+                       c.push_back(v3s16(x, y, d));
+                       c.push_back(v3s16(x, y, -d));
+                       if (y != 0) {
+                               c.push_back(v3s16(x, -y, d));
+                               c.push_back(v3s16(x, -y, -d));
+                       }
+               }
+       }
+
+       // Take the bottom and top face with borders
+       // -d < x < d, y = +-d, -d < z < d
+       for (s16 x = -d; x <= d; x++)
+       for (s16 z = -d; z <= d; z++) {
+               c.push_back(v3s16(x, -d, z));
+               c.push_back(v3s16(x, d, z));
+       }
+       return c;
+}
diff --git a/src/face_position_cache.h b/src/face_position_cache.h
new file mode 100644 (file)
index 0000000..c1d2841
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+Minetest
+Copyright (C) 2015 Nerzhul, Loic Blot <loic.blot@unix-experience.fr>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(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
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef FACE_POSITION_CACHE_HEADER
+#define FACE_POSITION_CACHE_HEADER
+
+#include "irr_v3d.h"
+#include "threading/mutex.h"
+#include "util/cpp11_container.h"
+
+#include <map>
+#include <vector>
+
+/*
+ * This class permits caching getFacePosition call results.
+ * This reduces CPU usage and vector calls.
+ */
+class FacePositionCache {
+public:
+       static const std::vector<v3s16> &getFacePositions(u16 d);
+
+private:
+       static const std::vector<v3s16> &generateFacePosition(u16 d);
+       static UNORDERED_MAP<u16, std::vector<v3s16> > cache;
+       static Mutex cache_mutex;
+};
+
+#endif
index 51e4fbbcc9e3714f14fcffe994b1084a387c8e45..ec31a9c0184b1680e42cb0052facb6110af7fa0e 100644 (file)
@@ -24,6 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "map.h"
 #include "log.h"
 #include "util/numeric.h"
+#include <algorithm>
+
 
 FlagDesc flagdesc_deco[] = {
        {"place_center_x",  DECO_PLACE_CENTER_X},
index d840d745a1ae6136f6ef76aeb5e98b3fdfa3d4cd..c6c1c45a782bd2270d0e239bd9ea41b76c8c3bec 100644 (file)
@@ -20,9 +20,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mg_ore.h"
 #include "mapgen.h"
 #include "noise.h"
-#include "util/numeric.h"
 #include "map.h"
 #include "log.h"
+#include <algorithm>
+
 
 FlagDesc flagdesc_ore[] = {
        {"absheight",                 OREFLAG_ABSHEIGHT},
index 0ded1265841f23d4aa17e739631fbcfd50c9479c..b8b6bc5bae7658eb7dadc8f05f198a66f5290e74 100644 (file)
@@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "treegen.h"
 #include "emerge.h"
 #include "pathfinder.h"
+#include "face_position_cache.h"
 
 struct EnumString ModApiEnvMod::es_ClearObjectsMode[] =
 {
index ea993d7b7f8e002d73609129e632f8a235e830b3..a0e475decaa267a50864f60a78aa058498f7be5c 100644 (file)
@@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "environment.h"
 #include "player.h"
 #include "log.h"
+#include <algorithm>
 
 // request_shutdown()
 int ModApiServer::l_request_shutdown(lua_State *L)
index 55acece6af958a2d7860c1c93c01dddec53a07fe..b009f5d2e5f201b0de66667f4f3fe282ee7df6da 100644 (file)
@@ -24,6 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "gamedef.h"
 #include "nodedef.h"
 
+#include <algorithm>
+
 
 class TestNodeResolver : public TestBase {
 public:
index bd4b890eb20443f19fdbef48693e3ff4cf438b33..687d7cf85cbd35266c7990ba66227b3dc14eeefb 100644 (file)
@@ -20,14 +20,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef BASICMACROS_HEADER
 #define BASICMACROS_HEADER
 
-#include <algorithm>
-
 #define ARRLEN(x) (sizeof(x) / sizeof((x)[0]))
 
 #define MYMIN(a, b) ((a) < (b) ? (a) : (b))
 
 #define MYMAX(a, b) ((a) > (b) ? (a) : (b))
 
+// Requires <algorithm>
 #define CONTAINS(c, v) (std::find((c).begin(), (c).end(), (v)) != (c).end())
 
 // To disable copy constructors and assignment operations for some class
index 87f1040ea2207778fd4ba200a0263de3903c90c0..e6a9cb75ebddc549631867c17a0b8c2bd5c65e09 100644 (file)
@@ -24,100 +24,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "../noise.h" // PseudoRandom, PcgRandom
 #include "../threading/mutex_auto_lock.h"
 #include <string.h>
-#include <iostream>
 
-UNORDERED_MAP<u16, std::vector<v3s16> > FacePositionCache::m_cache;
-Mutex FacePositionCache::m_cache_mutex;
-// Calculate the borders of a "d-radius" cube
-// TODO: Make it work without mutex and data races, probably thread-local
-std::vector<v3s16> FacePositionCache::getFacePositions(u16 d)
-{
-       MutexAutoLock cachelock(m_cache_mutex);
-       if (m_cache.find(d) != m_cache.end())
-               return m_cache[d];
-
-       generateFacePosition(d);
-       return m_cache[d];
-
-}
-
-void FacePositionCache::generateFacePosition(u16 d)
-{
-       m_cache[d] = std::vector<v3s16>();
-       if(d == 0) {
-               m_cache[d].push_back(v3s16(0,0,0));
-               return;
-       }
-       if(d == 1) {
-               /*
-                       This is an optimized sequence of coordinates.
-               */
-               m_cache[d].push_back(v3s16( 0, 1, 0)); // top
-               m_cache[d].push_back(v3s16( 0, 0, 1)); // back
-               m_cache[d].push_back(v3s16(-1, 0, 0)); // left
-               m_cache[d].push_back(v3s16( 1, 0, 0)); // right
-               m_cache[d].push_back(v3s16( 0, 0,-1)); // front
-               m_cache[d].push_back(v3s16( 0,-1, 0)); // bottom
-               // 6
-               m_cache[d].push_back(v3s16(-1, 0, 1)); // back left
-               m_cache[d].push_back(v3s16( 1, 0, 1)); // back right
-               m_cache[d].push_back(v3s16(-1, 0,-1)); // front left
-               m_cache[d].push_back(v3s16( 1, 0,-1)); // front right
-               m_cache[d].push_back(v3s16(-1,-1, 0)); // bottom left
-               m_cache[d].push_back(v3s16( 1,-1, 0)); // bottom right
-               m_cache[d].push_back(v3s16( 0,-1, 1)); // bottom back
-               m_cache[d].push_back(v3s16( 0,-1,-1)); // bottom front
-               m_cache[d].push_back(v3s16(-1, 1, 0)); // top left
-               m_cache[d].push_back(v3s16( 1, 1, 0)); // top right
-               m_cache[d].push_back(v3s16( 0, 1, 1)); // top back
-               m_cache[d].push_back(v3s16( 0, 1,-1)); // top front
-               // 18
-               m_cache[d].push_back(v3s16(-1, 1, 1)); // top back-left
-               m_cache[d].push_back(v3s16( 1, 1, 1)); // top back-right
-               m_cache[d].push_back(v3s16(-1, 1,-1)); // top front-left
-               m_cache[d].push_back(v3s16( 1, 1,-1)); // top front-right
-               m_cache[d].push_back(v3s16(-1,-1, 1)); // bottom back-left
-               m_cache[d].push_back(v3s16( 1,-1, 1)); // bottom back-right
-               m_cache[d].push_back(v3s16(-1,-1,-1)); // bottom front-left
-               m_cache[d].push_back(v3s16( 1,-1,-1)); // bottom front-right
-               // 26
-               return;
-       }
 
-       // Take blocks in all sides, starting from y=0 and going +-y
-       for(s16 y=0; y<=d-1; y++) {
-               // Left and right side, including borders
-               for(s16 z=-d; z<=d; z++) {
-                       m_cache[d].push_back(v3s16(d,y,z));
-                       m_cache[d].push_back(v3s16(-d,y,z));
-                       if(y != 0) {
-                               m_cache[d].push_back(v3s16(d,-y,z));
-                               m_cache[d].push_back(v3s16(-d,-y,z));
-                       }
-               }
-               // Back and front side, excluding borders
-               for(s16 x=-d+1; x<=d-1; x++) {
-                       m_cache[d].push_back(v3s16(x,y,d));
-                       m_cache[d].push_back(v3s16(x,y,-d));
-                       if(y != 0) {
-                               m_cache[d].push_back(v3s16(x,-y,d));
-                               m_cache[d].push_back(v3s16(x,-y,-d));
-                       }
-               }
-       }
-
-       // Take the bottom and top face with borders
-       // -d<x<d, y=+-d, -d<z<d
-       for(s16 x=-d; x<=d; x++)
-       for(s16 z=-d; z<=d; z++) {
-               m_cache[d].push_back(v3s16(x,-d,z));
-               m_cache[d].push_back(v3s16(x,d,z));
-       }
-}
-
-/*
-    myrand
-*/
+// myrand
 
 PcgRandom g_pcgrand;
 
index 760657171834a29b64af0dfc10a8a13b1207b08a..0954b715154831167ccd27053af5541f45bc4d82 100644 (file)
@@ -26,28 +26,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "../irr_v3d.h"
 #include "../irr_aabb3d.h"
 #include "../threading/mutex.h"
-#include "cpp11_container.h"
-#include <list>
-#include <vector>
 
+#define rangelim(d, min, max) ((d) < (min) ? (min) : ((d) > (max) ? (max) : (d)))
+#define myfloor(x) ((x) > 0.0 ? (int)(x) : (int)(x) - 1)
+// The naive swap performs better than the xor version
+#define SWAP(t, x, y) do { \
+       t temp = x; \
+       x = y; \
+       y = temp; \
+} while (0)
 
-/*
- * This class permits to cache getFacePosition call results
- * This reduces CPU usage and vector calls
- */
-class FacePositionCache
-{
-public:
-       static std::vector<v3s16> getFacePositions(u16 d);
-private:
-       static void generateFacePosition(u16 d);
-       static UNORDERED_MAP<u16, std::vector<v3s16> > m_cache;
-       static Mutex m_cache_mutex;
-};
 
 inline s16 getContainerPos(s16 p, s16 d)
 {
-       return (p>=0 ? p : p-d+1) / d;
+       return (p >= 0 ? p : p - d + 1) / d;
 }
 
 inline v2s16 getContainerPos(v2s16 p, s16 d)
@@ -130,16 +122,6 @@ inline bool isInArea(v3s16 p, v3s16 d)
        );
 }
 
-#define rangelim(d, min, max) ((d) < (min) ? (min) : ((d)>(max)?(max):(d)))
-#define myfloor(x) ((x) > 0.0 ? (int)(x) : (int)(x) - 1)
-
-// The naive swap performs better than the xor version
-#define SWAP(t, x, y) do { \
-       t temp = x;            \
-       x = y;                 \
-       y = temp;              \
-} while (0)
-
 inline void sortBoxVerticies(v3s16 &p1, v3s16 &p2) {
        if (p1.X > p2.X)
                SWAP(s16, p1.X, p2.X);
@@ -266,11 +248,10 @@ inline s32 myround(f32 f)
 */
 inline v3s16 floatToInt(v3f p, f32 d)
 {
-       v3s16 p2(
-               (p.X + (p.X>0 ? d/2 : -d/2))/d,
-               (p.Y + (p.Y>0 ? d/2 : -d/2))/d,
-               (p.Z + (p.Z>0 ? d/2 : -d/2))/d);
-       return p2;
+       return v3s16(
+               (p.X + (p.X > 0 ? d / 2 : -d / 2)) / d,
+               (p.Y + (p.Y > 0 ? d / 2 : -d / 2)) / d,
+               (p.Z + (p.Z > 0 ? d / 2 : -d / 2)) / d);
 }
 
 /*
@@ -278,34 +259,31 @@ inline v3s16 floatToInt(v3f p, f32 d)
 */
 inline v3f intToFloat(v3s16 p, f32 d)
 {
-       v3f p2(
+       return v3f(
                (f32)p.X * d,
                (f32)p.Y * d,
                (f32)p.Z * d
        );
-       return p2;
 }
 
 // Random helper. Usually d=BS
 inline aabb3f getNodeBox(v3s16 p, float d)
 {
        return aabb3f(
-               (float)p.X * d - 0.5*d,
-               (float)p.Y * d - 0.5*d,
-               (float)p.Z * d - 0.5*d,
-               (float)p.X * d + 0.5*d,
-               (float)p.Y * d + 0.5*d,
-               (float)p.Z * d + 0.5*d
+               (float)p.X * d - 0.5 * d,
+               (float)p.Y * d - 0.5 * d,
+               (float)p.Z * d - 0.5 * d,
+               (float)p.X * d + 0.5 * d,
+               (float)p.Y * d + 0.5 * d,
+               (float)p.Z * d + 0.5 * d
        );
 }
 
+
 class IntervalLimiter
 {
 public:
-       IntervalLimiter():
-               m_accumulator(0)
-       {
-       }
+       IntervalLimiter() : m_accumulator(0) {}
        /*
                dtime: time from last call to this method
                wanted_interval: interval wanted
@@ -316,15 +294,17 @@ public:
        bool step(float dtime, float wanted_interval)
        {
                m_accumulator += dtime;
-               if(m_accumulator < wanted_interval)
+               if (m_accumulator < wanted_interval)
                        return false;
                m_accumulator -= wanted_interval;
                return true;
        }
-protected:
+
+private:
        float m_accumulator;
 };
 
+
 /*
        Splits a list into "pages". For example, the list [1,2,3,4,5] split
        into two pages would be [1,2,3],[4,5]. This function computes the
@@ -340,29 +320,21 @@ protected:
 */
 inline void paging(u32 length, u32 page, u32 pagecount, u32 &minindex, u32 &maxindex)
 {
-       if(length < 1 || pagecount < 1 || page < 1 || page > pagecount)
-       {
+       if (length < 1 || pagecount < 1 || page < 1 || page > pagecount) {
                // Special cases or invalid parameters
                minindex = maxindex = 0;
-       }
-       else if(pagecount <= length)
-       {
+       } else if(pagecount <= length) {
                // Less pages than entries in the list:
                // Each page contains at least one entry
                minindex = (length * (page-1) + (pagecount-1)) / pagecount;
                maxindex = (length * page + (pagecount-1)) / pagecount;
-       }
-       else
-       {
+       } else {
                // More pages than entries in the list:
                // Make sure the empty pages are at the end
-               if(page < length)
-               {
+               if (page < length) {
                        minindex = page-1;
                        maxindex = page;
-               }
-               else
-               {
+               } else {
                        minindex = 0;
                        maxindex = 0;
                }
@@ -371,14 +343,14 @@ inline void paging(u32 length, u32 page, u32 pagecount, u32 &minindex, u32 &maxi
 
 inline float cycle_shift(float value, float by = 0, float max = 1)
 {
-    if (value + by < 0) return max + by + value;
+    if (value + by < 0)   return value + by + max;
     if (value + by > max) return value + by - max;
     return value + by;
 }
 
 inline bool is_power_of_two(u32 n)
 {
-       return n != 0 && (n & (n-1)) == 0;
+       return n != 0 && (n & (n - 1)) == 0;
 }
 
 // Compute next-higher power of 2 efficiently, e.g. for power-of-2 texture sizes.
index 141068512b0dc3362fc1acbc32e496bab972534d..d41b91f24a09c3ee09244c59b0686ff00e3efe55 100644 (file)
@@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "hex.h"
 #include "../porting.h"
 
+#include <algorithm>
 #include <sstream>
 #include <iomanip>
 #include <map>
index cac2faf2d4e7e8cbc513edb3e8de3cb8d28e7383..0b290ae8726bc2f55af39ab077f883f0053a47ef 100644 (file)
@@ -72,6 +72,8 @@ src/environment.cpp
 src/event.h
 src/event_manager.h
 src/exceptions.h
+src/face_position_cache.cpp
+src/face_position_cache.h
 src/filecache.cpp
 src/filesys.cpp
 src/filesys.h