Mapgen: Refactor mapgen creation and management
authorkwolekr <kwolekr@minetest.net>
Tue, 14 Jun 2016 04:10:55 +0000 (00:10 -0400)
committerkwolekr <kwolekr@minetest.net>
Sun, 3 Jul 2016 18:04:11 +0000 (14:04 -0400)
- Move mapgen creation logic out of EmergeManager and into Mapgen
- Internally represent mapgen type as an enum value, instead of a string
- Remove the need for a MapgenFactory per mapgen

12 files changed:
src/emerge.cpp
src/emerge.h
src/mapgen.cpp
src/mapgen.h
src/mapgen_flat.h
src/mapgen_fractal.h
src/mapgen_singlenode.h
src/mapgen_v5.h
src/mapgen_v6.h
src/mapgen_v7.h
src/mapgen_valleys.h
src/script/lua_api/l_mainmenu.cpp

index a2a10a177f1caa62d77da9055306edaaa2d31ef4..48de6cb1a7ee94573a31025a3ad5387e85d0b958 100644 (file)
@@ -34,13 +34,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "log.h"
 #include "map.h"
 #include "mapblock.h"
-#include "mapgen_flat.h"
-#include "mapgen_fractal.h"
-#include "mapgen_v5.h"
-#include "mapgen_v6.h"
-#include "mapgen_v7.h"
-#include "mapgen_valleys.h"
-#include "mapgen_singlenode.h"
 #include "mg_biome.h"
 #include "mg_ore.h"
 #include "mg_decoration.h"
@@ -53,13 +46,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "settings.h"
 #include "voxel.h"
 
-
-struct MapgenDesc {
-       const char *name;
-       MapgenFactory *factory;
-       bool is_user_visible;
-};
-
 class EmergeThread : public Thread {
 public:
        bool enable_mapgen_debug_info;
@@ -99,20 +85,6 @@ private:
        friend class EmergeManager;
 };
 
-////
-//// Built-in mapgens
-////
-
-MapgenDesc g_reg_mapgens[] = {
-       {"v5",         new MapgenFactoryV5,         true},
-       {"v6",         new MapgenFactoryV6,         true},
-       {"v7",         new MapgenFactoryV7,         true},
-       {"flat",       new MapgenFactoryFlat,       true},
-       {"fractal",    new MapgenFactoryFractal,    true},
-       {"valleys",    new MapgenFactoryValleys,    true},
-       {"singlenode", new MapgenFactorySinglenode, false},
-};
-
 ////
 //// EmergeManager
 ////
@@ -195,24 +167,24 @@ void EmergeManager::initMapgens()
        if (m_mapgens.size())
                return;
 
-       MapgenFactory *mgfactory = getMapgenFactory(params.mg_name);
-       if (!mgfactory) {
+       MapgenType mgtype = Mapgen::getMapgenType(params.mg_name);
+       if (mgtype == MAPGEN_INVALID) {
+               const char *default_mapgen_name = Mapgen::getMapgenName(MAPGEN_DEFAULT);
                errorstream << "EmergeManager: mapgen " << params.mg_name <<
-                       " not registered; falling back to " << DEFAULT_MAPGEN << std::endl;
-
-               params.mg_name = DEFAULT_MAPGEN;
+                       " not registered; falling back to " <<
+                       default_mapgen_name << std::endl;
 
-               mgfactory = getMapgenFactory(params.mg_name);
-               FATAL_ERROR_IF(mgfactory == NULL, "Couldn't use any mapgen!");
+               params.mg_name = default_mapgen_name;
+               mgtype = MAPGEN_DEFAULT;
        }
 
        if (!params.sparams) {
-               params.sparams = mgfactory->createMapgenParams();
+               params.sparams = Mapgen::createMapgenParams(mgtype);
                params.sparams->readParams(g_settings);
        }
 
        for (u32 i = 0; i != m_threads.size(); i++) {
-               Mapgen *mg = mgfactory->createMapgen(i, &params, this);
+               Mapgen *mg = Mapgen::createMapgen(mgtype, i, &params, this);
                m_mapgens.push_back(mg);
        }
 }
@@ -369,28 +341,6 @@ bool EmergeManager::isBlockUnderground(v3s16 blockpos)
        return blockpos.Y * (MAP_BLOCKSIZE + 1) <= params.water_level;
 }
 
-
-void EmergeManager::getMapgenNames(
-       std::vector<const char *> *mgnames, bool include_hidden)
-{
-       for (u32 i = 0; i != ARRLEN(g_reg_mapgens); i++) {
-               if (include_hidden || g_reg_mapgens[i].is_user_visible)
-                       mgnames->push_back(g_reg_mapgens[i].name);
-       }
-}
-
-
-MapgenFactory *EmergeManager::getMapgenFactory(const std::string &mgname)
-{
-       for (u32 i = 0; i != ARRLEN(g_reg_mapgens); i++) {
-               if (mgname == g_reg_mapgens[i].name)
-                       return g_reg_mapgens[i].factory;
-       }
-
-       return NULL;
-}
-
-
 bool EmergeManager::pushBlockEmergeData(
        v3s16 pos,
        u16 peer_requested,
index 825ac1c0fbf490a9204a687a0a2c34e9d1c5cab2..303a35529531673c95de0a04c2c80f343fec4f88 100644 (file)
@@ -140,9 +140,6 @@ public:
        int getGroundLevelAtPoint(v2s16 p);
        bool isBlockUnderground(v3s16 blockpos);
 
-       static MapgenFactory *getMapgenFactory(const std::string &mgname);
-       static void getMapgenNames(
-               std::vector<const char *> *mgnames, bool include_hidden);
        static v3s16 getContainingChunk(v3s16 blockpos, s16 chunksize);
 
 private:
index 1e0e3aa44232286e4061b9ad2eec5ceec9e0e771..e45233b33199b9ec38aca193c5591540d6d011ea 100644 (file)
@@ -39,6 +39,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "util/numeric.h"
 #include "filesys.h"
 #include "log.h"
+#include "mapgen_flat.h"
+#include "mapgen_fractal.h"
+#include "mapgen_v5.h"
+#include "mapgen_v6.h"
+#include "mapgen_v7.h"
+#include "mapgen_valleys.h"
+#include "mapgen_singlenode.h"
 #include "cavegen.h"
 #include "dungeongen.h"
 
@@ -63,6 +70,28 @@ FlagDesc flagdesc_gennotify[] = {
        {NULL,               0}
 };
 
+struct MapgenDesc {
+       const char *name;
+       bool is_user_visible;
+};
+
+////
+//// Built-in mapgens
+////
+
+static MapgenDesc g_reg_mapgens[] = {
+       {"v5",         true},
+       {"v6",         true},
+       {"v7",         true},
+       {"flat",       true},
+       {"fractal",    true},
+       {"valleys",    true},
+       {"singlenode", false},
+};
+
+STATIC_ASSERT(
+       ARRLEN(g_reg_mapgens) == MAPGEN_INVALID,
+       registered_mapgens_is_wrong_size);
 
 ////
 //// Mapgen
@@ -121,6 +150,83 @@ Mapgen::~Mapgen()
 }
 
 
+MapgenType Mapgen::getMapgenType(const std::string &mgname)
+{
+       for (size_t i = 0; i != ARRLEN(g_reg_mapgens); i++) {
+               if (mgname == g_reg_mapgens[i].name)
+                       return (MapgenType)i;
+       }
+
+       return MAPGEN_INVALID;
+}
+
+
+const char *Mapgen::getMapgenName(MapgenType mgtype)
+{
+       size_t index = (size_t)mgtype;
+       if (index == MAPGEN_INVALID || index >= ARRLEN(g_reg_mapgens))
+               return "invalid";
+
+       return g_reg_mapgens[index].name;
+}
+
+
+Mapgen *Mapgen::createMapgen(MapgenType mgtype, int mgid,
+       MapgenParams *params, EmergeManager *emerge)
+{
+       switch (mgtype) {
+       case MAPGEN_FLAT:
+               return new MapgenFlat(mgid, params, emerge);
+       case MAPGEN_FRACTAL:
+               return new MapgenFractal(mgid, params, emerge);
+       case MAPGEN_SINGLENODE:
+               return new MapgenSinglenode(mgid, params, emerge);
+       case MAPGEN_V5:
+               return new MapgenV5(mgid, params, emerge);
+       case MAPGEN_V6:
+               return new MapgenV6(mgid, params, emerge);
+       case MAPGEN_V7:
+               return new MapgenV7(mgid, params, emerge);
+       case MAPGEN_VALLEYS:
+               return new MapgenValleys(mgid, params, emerge);
+       default:
+               return NULL;
+       }
+}
+
+
+MapgenSpecificParams *Mapgen::createMapgenParams(MapgenType mgtype)
+{
+       switch (mgtype) {
+       case MAPGEN_FLAT:
+               return new MapgenFlatParams;
+       case MAPGEN_FRACTAL:
+               return new MapgenFractalParams;
+       case MAPGEN_SINGLENODE:
+               return new MapgenSinglenodeParams;
+       case MAPGEN_V5:
+               return new MapgenV5Params;
+       case MAPGEN_V6:
+               return new MapgenV6Params;
+       case MAPGEN_V7:
+               return new MapgenV7Params;
+       case MAPGEN_VALLEYS:
+               return new MapgenValleysParams;
+       default:
+               return NULL;
+       }
+}
+
+
+void Mapgen::getMapgenNames(std::vector<const char *> *mgnames, bool include_hidden)
+{
+       for (u32 i = 0; i != ARRLEN(g_reg_mapgens); i++) {
+               if (include_hidden || g_reg_mapgens[i].is_user_visible)
+                       mgnames->push_back(g_reg_mapgens[i].name);
+       }
+}
+
+
 u32 Mapgen::getBlockSeed(v3s16 p, s32 seed)
 {
        return (u32)seed   +
@@ -891,9 +997,9 @@ void MapgenParams::load(const Settings &settings)
        }
 
        delete sparams;
-       MapgenFactory *mgfactory = EmergeManager::getMapgenFactory(mg_name);
-       if (mgfactory) {
-               sparams = mgfactory->createMapgenParams();
+       MapgenType mgtype = Mapgen::getMapgenType(mg_name);
+       if (mgtype != MAPGEN_INVALID) {
+               sparams = Mapgen::createMapgenParams(mgtype);
                sparams->readParams(&settings);
        }
 }
index 90ac84bd8cffbfdfcd9cafd861d4ec00f9fc6bc9..618a2f6b8996adbc2965f0634856320faa16b90c 100644 (file)
@@ -26,7 +26,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "util/string.h"
 #include "util/container.h"
 
-#define DEFAULT_MAPGEN "v6"
+#define MAPGEN_DEFAULT MAPGEN_V6
+#define MAPGEN_DEFAULT_NAME "v6"
 
 /////////////////// Mapgen flags
 #define MG_TREES       0x01
@@ -107,6 +108,17 @@ private:
        std::list<GenNotifyEvent> m_notify_events;
 };
 
+enum MapgenType {
+       MAPGEN_V5,
+       MAPGEN_V6,
+       MAPGEN_V7,
+       MAPGEN_FLAT,
+       MAPGEN_FRACTAL,
+       MAPGEN_VALLEYS,
+       MAPGEN_SINGLENODE,
+       MAPGEN_INVALID,
+};
+
 struct MapgenSpecificParams {
        virtual void readParams(const Settings *settings) = 0;
        virtual void writeParams(Settings *settings) const = 0;
@@ -124,7 +136,7 @@ struct MapgenParams {
        MapgenSpecificParams *sparams;
 
        MapgenParams() :
-               mg_name(DEFAULT_MAPGEN),
+               mg_name(MAPGEN_DEFAULT_NAME),
                chunksize(5),
                seed(0),
                water_level(1),
@@ -173,6 +185,8 @@ public:
        Mapgen(int mapgenid, MapgenParams *params, EmergeManager *emerge);
        virtual ~Mapgen();
 
+       virtual MapgenType getType() const { return MAPGEN_INVALID; }
+
        static u32 getBlockSeed(v3s16 p, s32 seed);
        static u32 getBlockSeed2(v3s16 p, s32 seed);
        s16 findGroundLevelFull(v2s16 p2d);
@@ -198,6 +212,14 @@ public:
        // signify this and to cause Server::findSpawnPos() to try another (X, Z).
        virtual int getSpawnLevelAtPoint(v2s16 p) { return 0; }
 
+       // Mapgen management functions
+       static MapgenType getMapgenType(const std::string &mgname);
+       static const char *getMapgenName(MapgenType mgtype);
+       static Mapgen *createMapgen(MapgenType mgtype, int mgid,
+               MapgenParams *params, EmergeManager *emerge);
+       static MapgenSpecificParams *createMapgenParams(MapgenType mgtype);
+       static void getMapgenNames(std::vector<const char *> *mgnames, bool include_hidden);
+
 private:
        // isLiquidHorizontallyFlowable() is a helper function for updateLiquid()
        // that checks whether there are floodable nodes without liquid beneath
@@ -267,11 +289,4 @@ protected:
        float cave_width;
 };
 
-struct MapgenFactory {
-       virtual Mapgen *createMapgen(int mgid, MapgenParams *params,
-               EmergeManager *emerge) = 0;
-       virtual MapgenSpecificParams *createMapgenParams() = 0;
-       virtual ~MapgenFactory() {}
-};
-
 #endif
index afe67b04e449b46a6e724dfa779a35321fccbd35..39b6dc30272c2da368c5c47bf5d82a58039692fe 100644 (file)
@@ -58,6 +58,8 @@ public:
        MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge);
        ~MapgenFlat();
 
+       virtual MapgenType getType() const { return MAPGEN_FLAT; }
+
        virtual void makeChunk(BlockMakeData *data);
        int getSpawnLevelAtPoint(v2s16 p);
        s16 generateTerrain();
@@ -72,16 +74,4 @@ private:
        Noise *noise_terrain;
 };
 
-struct MapgenFactoryFlat : public MapgenFactory {
-       Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge)
-       {
-               return new MapgenFlat(mgid, params, emerge);
-       };
-
-       MapgenSpecificParams *createMapgenParams()
-       {
-               return new MapgenFlatParams();
-       };
-};
-
 #endif
index 065142b8471d515d79445a5dc0d0b657a7c5fa34..cbd5567c4b4ce65c561ce70b915eb54d3d26cca7 100644 (file)
@@ -62,6 +62,8 @@ public:
        MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager *emerge);
        ~MapgenFractal();
 
+       virtual MapgenType getType() const { return MAPGEN_FRACTAL; }
+
        virtual void makeChunk(BlockMakeData *data);
        int getSpawnLevelAtPoint(v2s16 p);
        bool getFractalAtPoint(s16 x, s16 y, s16 z);
@@ -83,16 +85,4 @@ private:
        Noise *noise_seabed;
 };
 
-struct MapgenFactoryFractal : public MapgenFactory {
-       Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge)
-       {
-               return new MapgenFractal(mgid, params, emerge);
-       };
-
-       MapgenSpecificParams *createMapgenParams()
-       {
-               return new MapgenFractalParams();
-       };
-};
-
 #endif
index 2c6496c00693f49139d06d9feb641caa8b769853..58672a0ede4dfeeb24b5c300f1169f3e7361c9b2 100644 (file)
@@ -23,10 +23,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mapgen.h"
 
 struct MapgenSinglenodeParams : public MapgenSpecificParams {
-       
        MapgenSinglenodeParams() {}
        ~MapgenSinglenodeParams() {}
-       
+
        void readParams(const Settings *settings) {}
        void writeParams(Settings *settings) const {}
 };
@@ -39,19 +38,11 @@ public:
 
        MapgenSinglenode(int mapgenid, MapgenParams *params, EmergeManager *emerge);
        ~MapgenSinglenode();
-       
+
+       virtual MapgenType getType() const { return MAPGEN_SINGLENODE; }
+
        void makeChunk(BlockMakeData *data);
        int getSpawnLevelAtPoint(v2s16 p);
 };
 
-struct MapgenFactorySinglenode : public MapgenFactory {
-       Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) {
-               return new MapgenSinglenode(mgid, params, emerge);
-       };
-       
-       MapgenSpecificParams *createMapgenParams() {
-               return new MapgenSinglenodeParams();
-       };
-};
-
 #endif
index 4e1772a64f792d9d6ef0ab0df9acd397703ee0b7..5f6b1038375424afd36cb95b1beb1c29b7008979 100644 (file)
@@ -53,6 +53,8 @@ public:
        MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge);
        ~MapgenV5();
 
+       virtual MapgenType getType() const { return MAPGEN_V5; }
+
        virtual void makeChunk(BlockMakeData *data);
        int getSpawnLevelAtPoint(v2s16 p);
        int generateBaseTerrain();
@@ -63,17 +65,4 @@ private:
        Noise *noise_ground;
 };
 
-
-struct MapgenFactoryV5 : public MapgenFactory {
-       Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge)
-       {
-               return new MapgenV5(mgid, params, emerge);
-       };
-
-       MapgenSpecificParams *createMapgenParams()
-       {
-               return new MapgenV5Params();
-       };
-};
-
 #endif
index a55fc6d534083dd458a6f38f26f1b05692c65397..20b0bf92ecc6a89af65ec3f4905c51f8ec95f98c 100644 (file)
@@ -127,6 +127,8 @@ public:
        MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge);
        ~MapgenV6();
 
+       virtual MapgenType getType() const { return MAPGEN_V6; }
+
        void makeChunk(BlockMakeData *data);
        int getGroundLevelAtPoint(v2s16 p);
        int getSpawnLevelAtPoint(v2s16 p);
@@ -162,18 +164,4 @@ public:
        virtual void generateCaves(int max_stone_y);
 };
 
-
-struct MapgenFactoryV6 : public MapgenFactory {
-       Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge)
-       {
-               return new MapgenV6(mgid, params, emerge);
-       };
-
-       MapgenSpecificParams *createMapgenParams()
-       {
-               return new MapgenV6Params();
-       };
-};
-
-
 #endif
index 9ed89a5115c52bad11260f3d9bec5f44fec038c2..c75f18a93b5c251d4a28ca697a35e12164bdfd77 100644 (file)
@@ -59,6 +59,8 @@ public:
        MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge);
        ~MapgenV7();
 
+       virtual MapgenType getType() const { return MAPGEN_V7; }
+
        virtual void makeChunk(BlockMakeData *data);
        int getSpawnLevelAtPoint(v2s16 p);
 
@@ -80,16 +82,4 @@ private:
        Noise *noise_ridge;
 };
 
-struct MapgenFactoryV7 : public MapgenFactory {
-       Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge)
-       {
-               return new MapgenV7(mgid, params, emerge);
-       };
-
-       MapgenSpecificParams *createMapgenParams()
-       {
-               return new MapgenV7Params();
-       };
-};
-
 #endif
index faaffa905c22f4273ae3413198d5afbe2808d298..00f6aff0765f2ad78066e32a63730a8dd5534a9d 100644 (file)
@@ -91,6 +91,8 @@ public:
        MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *emerge);
        ~MapgenValleys();
 
+       virtual MapgenType getType() const { return MAPGEN_VALLEYS; }
+
        virtual void makeChunk(BlockMakeData *data);
        int getSpawnLevelAtPoint(v2s16 p);
 
@@ -137,16 +139,4 @@ private:
        virtual void generateCaves(s16 max_stone_y, s16 large_cave_depth);
 };
 
-struct MapgenFactoryValleys : public MapgenFactory {
-       Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge)
-       {
-               return new MapgenValleys(mgid, params, emerge);
-       };
-
-       MapgenSpecificParams *createMapgenParams()
-       {
-               return new MapgenValleysParams();
-       };
-};
-
 #endif
index 7b29db159acf59b231f94b5dcfb01c96b8a2f6f5..8b078eafd20ec371cb878f3ab1bade331623ca5f 100644 (file)
@@ -31,7 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "filesys.h"
 #include "convert_json.h"
 #include "serverlist.h"
-#include "emerge.h"
+#include "mapgen.h"
 #include "sound.h"
 #include "settings.h"
 #include "log.h"
@@ -707,7 +707,7 @@ int ModApiMainMenu::l_set_topleft_text(lua_State *L)
 int ModApiMainMenu::l_get_mapgen_names(lua_State *L)
 {
        std::vector<const char *> names;
-       EmergeManager::getMapgenNames(&names, lua_toboolean(L, 1));
+       Mapgen::getMapgenNames(&names, lua_toboolean(L, 1));
 
        lua_newtable(L);
        for (size_t i = 0; i != names.size(); i++) {