From: sfan5 Date: Fri, 10 Apr 2020 00:05:20 +0000 (+0200) Subject: Give the Mapgen on each EmergeThread its own Biome/Ore/Deco/SchemManager copy X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=3c65d1acec27366d88fc3686d3f820175673e203;p=oweals%2Fminetest.git Give the Mapgen on each EmergeThread its own Biome/Ore/Deco/SchemManager copy --- diff --git a/src/emerge.cpp b/src/emerge.cpp index fe885447c..6e05a45c9 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -109,6 +109,28 @@ private: VoxelArea *m_ignorevariable; }; +EmergeParams::~EmergeParams() +{ + infostream << "EmergeParams: destroying " << this << std::endl; + // Delete everything that was cloned on creation of EmergeParams + delete biomemgr; + delete oremgr; + delete decomgr; + delete schemmgr; +} + +EmergeParams::EmergeParams(EmergeManager *parent, const BiomeManager *biomemgr, + const OreManager *oremgr, const DecorationManager *decomgr, + const SchematicManager *schemmgr) : + ndef(parent->ndef), + enable_mapgen_debug_info(parent->enable_mapgen_debug_info), + gen_notify_on(parent->gen_notify_on), + gen_notify_on_deco_ids(&parent->gen_notify_on_deco_ids), + biomemgr(biomemgr->clone()), oremgr(oremgr->clone()), + decomgr(decomgr->clone()), schemmgr(schemmgr->clone()) +{ +} + //// //// EmergeManager //// @@ -182,14 +204,48 @@ EmergeManager::~EmergeManager() } +BiomeManager *EmergeManager::getWritableBiomeManager() +{ + FATAL_ERROR_IF(!m_mapgens.empty(), + "Writable managers can only be returned before mapgen init"); + return biomemgr; +} + +OreManager *EmergeManager::getWritableOreManager() +{ + FATAL_ERROR_IF(!m_mapgens.empty(), + "Writable managers can only be returned before mapgen init"); + return oremgr; +} + +DecorationManager *EmergeManager::getWritableDecorationManager() +{ + FATAL_ERROR_IF(!m_mapgens.empty(), + "Writable managers can only be returned before mapgen init"); + return decomgr; +} + +SchematicManager *EmergeManager::getWritableSchematicManager() +{ + FATAL_ERROR_IF(!m_mapgens.empty(), + "Writable managers can only be returned before mapgen init"); + return schemmgr; +} + + void EmergeManager::initMapgens(MapgenParams *params) { FATAL_ERROR_IF(!m_mapgens.empty(), "Mapgen already initialised."); mgparams = params; - for (u32 i = 0; i != m_threads.size(); i++) - m_mapgens.push_back(Mapgen::createMapgen(params->mgtype, params, this)); + for (u32 i = 0; i != m_threads.size(); i++) { + EmergeParams *p = new EmergeParams( + this, biomemgr, oremgr, decomgr, schemmgr); + infostream << "EmergeManager: Created params " << p + << " for thread " << i << std::endl; + m_mapgens.push_back(Mapgen::createMapgen(params->mgtype, params, p)); + } } diff --git a/src/emerge.h b/src/emerge.h index df849e542..ab9fca2ba 100644 --- a/src/emerge.h +++ b/src/emerge.h @@ -86,6 +86,30 @@ struct BlockEmergeData { EmergeCallbackList callbacks; }; +class EmergeParams { + friend class EmergeManager; +public: + EmergeParams() = delete; + ~EmergeParams(); + DISABLE_CLASS_COPY(EmergeParams); + + const NodeDefManager *ndef; // shared + bool enable_mapgen_debug_info; + + u32 gen_notify_on; + const std::set *gen_notify_on_deco_ids; // shared + + BiomeManager *biomemgr; + OreManager *oremgr; + DecorationManager *decomgr; + SchematicManager *schemmgr; + +private: + EmergeParams(EmergeManager *parent, const BiomeManager *biomemgr, + const OreManager *oremgr, const DecorationManager *decomgr, + const SchematicManager *schemmgr); +}; + class EmergeManager { public: const NodeDefManager *ndef; @@ -106,17 +130,22 @@ public: // Environment is not created until after script initialization. MapSettingsManager *map_settings_mgr; - // Managers of various map generation-related components - BiomeManager *biomemgr; - OreManager *oremgr; - DecorationManager *decomgr; - SchematicManager *schemmgr; - // Methods EmergeManager(Server *server); ~EmergeManager(); DISABLE_CLASS_COPY(EmergeManager); + // no usage restrictions + const BiomeManager *getBiomeManager() const { return biomemgr; } + const OreManager *getOreManager() const { return oremgr; } + const DecorationManager *getDecorationManager() const { return decomgr; } + const SchematicManager *getSchematicManager() const { return schemmgr; } + // only usable before mapgen init + BiomeManager *getWritableBiomeManager(); + OreManager *getWritableOreManager(); + DecorationManager *getWritableDecorationManager(); + SchematicManager *getWritableSchematicManager(); + void initMapgens(MapgenParams *mgparams); void startThreads(); @@ -160,6 +189,13 @@ private: u16 m_qlimit_diskonly; u16 m_qlimit_generate; + // Managers of various map generation-related components + // Note that each Mapgen gets a copy(!) of these to work with + BiomeManager *biomemgr; + OreManager *oremgr; + DecorationManager *decomgr; + SchematicManager *schemmgr; + // Requires m_queue_mutex held EmergeThread *getOptimalThread(); diff --git a/src/mapgen/mapgen.cpp b/src/mapgen/mapgen.cpp index 0094608ec..f57529082 100644 --- a/src/mapgen/mapgen.cpp +++ b/src/mapgen/mapgen.cpp @@ -106,8 +106,8 @@ STATIC_ASSERT( //// Mapgen //// -Mapgen::Mapgen(int mapgenid, MapgenParams *params, EmergeManager *emerge) : - gennotify(emerge->gen_notify_on, &emerge->gen_notify_on_deco_ids) +Mapgen::Mapgen(int mapgenid, MapgenParams *params, EmergeParams *emerge) : + gennotify(emerge->gen_notify_on, emerge->gen_notify_on_deco_ids) { id = mapgenid; water_level = params->water_level; @@ -156,7 +156,7 @@ const char *Mapgen::getMapgenName(MapgenType mgtype) Mapgen *Mapgen::createMapgen(MapgenType mgtype, MapgenParams *params, - EmergeManager *emerge) + EmergeParams *emerge) { switch (mgtype) { case MAPGEN_CARPATHIAN: @@ -585,7 +585,7 @@ void Mapgen::spreadLight(const v3s16 &nmin, const v3s16 &nmax) //// MapgenBasic //// -MapgenBasic::MapgenBasic(int mapgenid, MapgenParams *params, EmergeManager *emerge) +MapgenBasic::MapgenBasic(int mapgenid, MapgenParams *params, EmergeParams *emerge) : Mapgen(mapgenid, params, emerge) { this->m_emerge = emerge; @@ -642,6 +642,8 @@ MapgenBasic::~MapgenBasic() { delete biomegen; delete []heightmap; + + delete m_emerge; // destroying EmergeParams is our responsibility } @@ -974,7 +976,7 @@ void MapgenBasic::generateDungeons(s16 max_stone_y) //// GenerateNotifier::GenerateNotifier(u32 notify_on, - std::set *notify_on_deco_ids) + const std::set *notify_on_deco_ids) { m_notify_on = notify_on; m_notify_on_deco_ids = notify_on_deco_ids; @@ -987,7 +989,8 @@ void GenerateNotifier::setNotifyOn(u32 notify_on) } -void GenerateNotifier::setNotifyOnDecoIds(std::set *notify_on_deco_ids) +void GenerateNotifier::setNotifyOnDecoIds( + const std::set *notify_on_deco_ids) { m_notify_on_deco_ids = notify_on_deco_ids; } @@ -999,7 +1002,7 @@ bool GenerateNotifier::addEvent(GenNotifyType type, v3s16 pos, u32 id) return false; if (type == GENNOTIFY_DECORATION && - m_notify_on_deco_ids->find(id) == m_notify_on_deco_ids->end()) + m_notify_on_deco_ids->find(id) == m_notify_on_deco_ids->cend()) return false; GenNotifyEvent gne; diff --git a/src/mapgen/mapgen.h b/src/mapgen/mapgen.h index dc325c791..7845c5349 100644 --- a/src/mapgen/mapgen.h +++ b/src/mapgen/mapgen.h @@ -51,6 +51,7 @@ class Biome; class BiomeGen; struct BiomeParams; class BiomeManager; +class EmergeParams; class EmergeManager; class MapBlock; class VoxelManipulator; @@ -87,10 +88,10 @@ struct GenNotifyEvent { class GenerateNotifier { public: GenerateNotifier() = default; - GenerateNotifier(u32 notify_on, std::set *notify_on_deco_ids); + GenerateNotifier(u32 notify_on, const std::set *notify_on_deco_ids); void setNotifyOn(u32 notify_on); - void setNotifyOnDecoIds(std::set *notify_on_deco_ids); + void setNotifyOnDecoIds(const std::set *notify_on_deco_ids); bool addEvent(GenNotifyType type, v3s16 pos, u32 id=0); void getEvents(std::map > &event_map); @@ -98,7 +99,7 @@ public: private: u32 m_notify_on = 0; - std::set *m_notify_on_deco_ids; + const std::set *m_notify_on_deco_ids; std::list m_notify_events; }; @@ -176,7 +177,7 @@ public: GenerateNotifier gennotify; Mapgen() = default; - Mapgen(int mapgenid, MapgenParams *params, EmergeManager *emerge); + Mapgen(int mapgenid, MapgenParams *params, EmergeParams *emerge); virtual ~Mapgen() = default; DISABLE_CLASS_COPY(Mapgen); @@ -215,7 +216,7 @@ public: static MapgenType getMapgenType(const std::string &mgname); static const char *getMapgenName(MapgenType mgtype); static Mapgen *createMapgen(MapgenType mgtype, MapgenParams *params, - EmergeManager *emerge); + EmergeParams *emerge); static MapgenParams *createMapgenParams(MapgenType mgtype); static void getMapgenNames(std::vector *mgnames, bool include_hidden); static void setDefaultSettings(Settings *settings); @@ -243,7 +244,7 @@ private: */ class MapgenBasic : public Mapgen { public: - MapgenBasic(int mapgenid, MapgenParams *params, EmergeManager *emerge); + MapgenBasic(int mapgenid, MapgenParams *params, EmergeParams *emerge); virtual ~MapgenBasic(); virtual void generateBiomes(); @@ -254,7 +255,7 @@ public: virtual void generateDungeons(s16 max_stone_y); protected: - EmergeManager *m_emerge; + EmergeParams *m_emerge; BiomeManager *m_bmgr; Noise *noise_filler_depth; diff --git a/src/mapgen/mapgen_carpathian.cpp b/src/mapgen/mapgen_carpathian.cpp index bd7ae5e7c..feb9b428c 100644 --- a/src/mapgen/mapgen_carpathian.cpp +++ b/src/mapgen/mapgen_carpathian.cpp @@ -49,7 +49,7 @@ FlagDesc flagdesc_mapgen_carpathian[] = { /////////////////////////////////////////////////////////////////////////////// -MapgenCarpathian::MapgenCarpathian(MapgenCarpathianParams *params, EmergeManager *emerge) +MapgenCarpathian::MapgenCarpathian(MapgenCarpathianParams *params, EmergeParams *emerge) : MapgenBasic(MAPGEN_CARPATHIAN, params, emerge) { base_level = params->base_level; diff --git a/src/mapgen/mapgen_carpathian.h b/src/mapgen/mapgen_carpathian.h index acd379958..31b2b91d8 100644 --- a/src/mapgen/mapgen_carpathian.h +++ b/src/mapgen/mapgen_carpathian.h @@ -79,7 +79,7 @@ struct MapgenCarpathianParams : public MapgenParams class MapgenCarpathian : public MapgenBasic { public: - MapgenCarpathian(MapgenCarpathianParams *params, EmergeManager *emerge); + MapgenCarpathian(MapgenCarpathianParams *params, EmergeParams *emerge); ~MapgenCarpathian(); virtual MapgenType getType() const { return MAPGEN_CARPATHIAN; } diff --git a/src/mapgen/mapgen_flat.cpp b/src/mapgen/mapgen_flat.cpp index 272964b51..369777ad2 100644 --- a/src/mapgen/mapgen_flat.cpp +++ b/src/mapgen/mapgen_flat.cpp @@ -47,7 +47,7 @@ FlagDesc flagdesc_mapgen_flat[] = { /////////////////////////////////////////////////////////////////////////////////////// -MapgenFlat::MapgenFlat(MapgenFlatParams *params, EmergeManager *emerge) +MapgenFlat::MapgenFlat(MapgenFlatParams *params, EmergeParams *emerge) : MapgenBasic(MAPGEN_FLAT, params, emerge) { spflags = params->spflags; diff --git a/src/mapgen/mapgen_flat.h b/src/mapgen/mapgen_flat.h index c314c7605..4902a802c 100644 --- a/src/mapgen/mapgen_flat.h +++ b/src/mapgen/mapgen_flat.h @@ -64,7 +64,7 @@ struct MapgenFlatParams : public MapgenParams class MapgenFlat : public MapgenBasic { public: - MapgenFlat(MapgenFlatParams *params, EmergeManager *emerge); + MapgenFlat(MapgenFlatParams *params, EmergeParams *emerge); ~MapgenFlat(); virtual MapgenType getType() const { return MAPGEN_FLAT; } diff --git a/src/mapgen/mapgen_fractal.cpp b/src/mapgen/mapgen_fractal.cpp index 97f77d947..cb55bc288 100644 --- a/src/mapgen/mapgen_fractal.cpp +++ b/src/mapgen/mapgen_fractal.cpp @@ -47,7 +47,7 @@ FlagDesc flagdesc_mapgen_fractal[] = { /////////////////////////////////////////////////////////////////////////////////////// -MapgenFractal::MapgenFractal(MapgenFractalParams *params, EmergeManager *emerge) +MapgenFractal::MapgenFractal(MapgenFractalParams *params, EmergeParams *emerge) : MapgenBasic(MAPGEN_FRACTAL, params, emerge) { spflags = params->spflags; diff --git a/src/mapgen/mapgen_fractal.h b/src/mapgen/mapgen_fractal.h index 971dfd822..23af925bc 100644 --- a/src/mapgen/mapgen_fractal.h +++ b/src/mapgen/mapgen_fractal.h @@ -72,7 +72,7 @@ struct MapgenFractalParams : public MapgenParams class MapgenFractal : public MapgenBasic { public: - MapgenFractal(MapgenFractalParams *params, EmergeManager *emerge); + MapgenFractal(MapgenFractalParams *params, EmergeParams *emerge); ~MapgenFractal(); virtual MapgenType getType() const { return MAPGEN_FRACTAL; } diff --git a/src/mapgen/mapgen_singlenode.cpp b/src/mapgen/mapgen_singlenode.cpp index b64524e1c..cade9e7a8 100644 --- a/src/mapgen/mapgen_singlenode.cpp +++ b/src/mapgen/mapgen_singlenode.cpp @@ -29,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "emerge.h" -MapgenSinglenode::MapgenSinglenode(MapgenParams *params, EmergeManager *emerge) +MapgenSinglenode::MapgenSinglenode(MapgenParams *params, EmergeParams *emerge) : Mapgen(MAPGEN_SINGLENODE, params, emerge) { const NodeDefManager *ndef = emerge->ndef; diff --git a/src/mapgen/mapgen_singlenode.h b/src/mapgen/mapgen_singlenode.h index c21089eda..e056d9ab1 100644 --- a/src/mapgen/mapgen_singlenode.h +++ b/src/mapgen/mapgen_singlenode.h @@ -38,7 +38,7 @@ public: content_t c_node; u8 set_light; - MapgenSinglenode(MapgenParams *params, EmergeManager *emerge); + MapgenSinglenode(MapgenParams *params, EmergeParams *emerge); ~MapgenSinglenode() = default; virtual MapgenType getType() const { return MAPGEN_SINGLENODE; } diff --git a/src/mapgen/mapgen_v5.cpp b/src/mapgen/mapgen_v5.cpp index 3bd7615c4..124667e5d 100644 --- a/src/mapgen/mapgen_v5.cpp +++ b/src/mapgen/mapgen_v5.cpp @@ -44,7 +44,7 @@ FlagDesc flagdesc_mapgen_v5[] = { }; -MapgenV5::MapgenV5(MapgenV5Params *params, EmergeManager *emerge) +MapgenV5::MapgenV5(MapgenV5Params *params, EmergeParams *emerge) : MapgenBasic(MAPGEN_V5, params, emerge) { spflags = params->spflags; diff --git a/src/mapgen/mapgen_v5.h b/src/mapgen/mapgen_v5.h index 17bc466f0..cf4ee4899 100644 --- a/src/mapgen/mapgen_v5.h +++ b/src/mapgen/mapgen_v5.h @@ -64,7 +64,7 @@ struct MapgenV5Params : public MapgenParams class MapgenV5 : public MapgenBasic { public: - MapgenV5(MapgenV5Params *params, EmergeManager *emerge); + MapgenV5(MapgenV5Params *params, EmergeParams *emerge); ~MapgenV5(); virtual MapgenType getType() const { return MAPGEN_V5; } diff --git a/src/mapgen/mapgen_v6.cpp b/src/mapgen/mapgen_v6.cpp index da9ae1428..e9692246c 100644 --- a/src/mapgen/mapgen_v6.cpp +++ b/src/mapgen/mapgen_v6.cpp @@ -54,7 +54,7 @@ FlagDesc flagdesc_mapgen_v6[] = { ///////////////////////////////////////////////////////////////////////////// -MapgenV6::MapgenV6(MapgenV6Params *params, EmergeManager *emerge) +MapgenV6::MapgenV6(MapgenV6Params *params, EmergeParams *emerge) : Mapgen(MAPGEN_V6, params, emerge) { m_emerge = emerge; @@ -160,6 +160,8 @@ MapgenV6::~MapgenV6() delete noise_humidity; delete[] heightmap; + + delete m_emerge; // our responsibility } diff --git a/src/mapgen/mapgen_v6.h b/src/mapgen/mapgen_v6.h index d8cdcb26f..ff565edec 100644 --- a/src/mapgen/mapgen_v6.h +++ b/src/mapgen/mapgen_v6.h @@ -83,7 +83,7 @@ struct MapgenV6Params : public MapgenParams { class MapgenV6 : public Mapgen { public: - EmergeManager *m_emerge; + EmergeParams *m_emerge; int ystride; u32 spflags; @@ -133,7 +133,7 @@ public: content_t c_stair_cobble; content_t c_stair_desert_stone; - MapgenV6(MapgenV6Params *params, EmergeManager *emerge); + MapgenV6(MapgenV6Params *params, EmergeParams *emerge); ~MapgenV6(); virtual MapgenType getType() const { return MAPGEN_V6; } diff --git a/src/mapgen/mapgen_v7.cpp b/src/mapgen/mapgen_v7.cpp index 82556cc4f..43d5d822f 100644 --- a/src/mapgen/mapgen_v7.cpp +++ b/src/mapgen/mapgen_v7.cpp @@ -51,7 +51,7 @@ FlagDesc flagdesc_mapgen_v7[] = { //////////////////////////////////////////////////////////////////////////////// -MapgenV7::MapgenV7(MapgenV7Params *params, EmergeManager *emerge) +MapgenV7::MapgenV7(MapgenV7Params *params, EmergeParams *emerge) : MapgenBasic(MAPGEN_V7, params, emerge) { spflags = params->spflags; diff --git a/src/mapgen/mapgen_v7.h b/src/mapgen/mapgen_v7.h index 0605c5c97..eeae3a956 100644 --- a/src/mapgen/mapgen_v7.h +++ b/src/mapgen/mapgen_v7.h @@ -75,7 +75,7 @@ struct MapgenV7Params : public MapgenParams { class MapgenV7 : public MapgenBasic { public: - MapgenV7(MapgenV7Params *params, EmergeManager *emerge); + MapgenV7(MapgenV7Params *params, EmergeParams *emerge); ~MapgenV7(); virtual MapgenType getType() const { return MAPGEN_V7; } diff --git a/src/mapgen/mapgen_valleys.cpp b/src/mapgen/mapgen_valleys.cpp index ff908b7bb..efcc8ee85 100644 --- a/src/mapgen/mapgen_valleys.cpp +++ b/src/mapgen/mapgen_valleys.cpp @@ -54,7 +54,7 @@ FlagDesc flagdesc_mapgen_valleys[] = { }; -MapgenValleys::MapgenValleys(MapgenValleysParams *params, EmergeManager *emerge) +MapgenValleys::MapgenValleys(MapgenValleysParams *params, EmergeParams *emerge) : MapgenBasic(MAPGEN_VALLEYS, params, emerge) { // NOTE: MapgenValleys has a hard dependency on BiomeGenOriginal diff --git a/src/mapgen/mapgen_valleys.h b/src/mapgen/mapgen_valleys.h index 1aec68842..34a923dfa 100644 --- a/src/mapgen/mapgen_valleys.h +++ b/src/mapgen/mapgen_valleys.h @@ -84,7 +84,7 @@ class MapgenValleys : public MapgenBasic { public: MapgenValleys(MapgenValleysParams *params, - EmergeManager *emerge); + EmergeParams *emerge); ~MapgenValleys(); virtual MapgenType getType() const { return MAPGEN_VALLEYS; } diff --git a/src/mapgen/mg_biome.cpp b/src/mapgen/mg_biome.cpp index 3a72c43bf..f3bc4e829 100644 --- a/src/mapgen/mg_biome.cpp +++ b/src/mapgen/mg_biome.cpp @@ -78,7 +78,7 @@ void BiomeManager::clear() EmergeManager *emerge = m_server->getEmergeManager(); // Remove all dangling references in Decorations - DecorationManager *decomgr = emerge->decomgr; + DecorationManager *decomgr = emerge->getWritableDecorationManager(); for (size_t i = 0; i != decomgr->getNumObjects(); i++) { Decoration *deco = (Decoration *)decomgr->getRaw(i); deco->biomes.clear(); @@ -104,7 +104,7 @@ BiomeManager *BiomeManager::clone() const // For BiomeGen type 'BiomeGenOriginal' float BiomeManager::getHeatAtPosOriginal(v3s16 pos, NoiseParams &np_heat, - NoiseParams &np_heat_blend, u64 seed) + NoiseParams &np_heat_blend, u64 seed) const { return NoisePerlin2D(&np_heat, pos.X, pos.Z, seed) + @@ -114,7 +114,7 @@ float BiomeManager::getHeatAtPosOriginal(v3s16 pos, NoiseParams &np_heat, // For BiomeGen type 'BiomeGenOriginal' float BiomeManager::getHumidityAtPosOriginal(v3s16 pos, NoiseParams &np_humidity, - NoiseParams &np_humidity_blend, u64 seed) + NoiseParams &np_humidity_blend, u64 seed) const { return NoisePerlin2D(&np_humidity, pos.X, pos.Z, seed) + @@ -123,7 +123,7 @@ float BiomeManager::getHumidityAtPosOriginal(v3s16 pos, NoiseParams &np_humidity // For BiomeGen type 'BiomeGenOriginal' -Biome *BiomeManager::getBiomeFromNoiseOriginal(float heat, float humidity, v3s16 pos) +Biome *BiomeManager::getBiomeFromNoiseOriginal(float heat, float humidity, v3s16 pos) const { Biome *biome_closest = nullptr; Biome *biome_closest_blend = nullptr; diff --git a/src/mapgen/mg_biome.h b/src/mapgen/mg_biome.h index 6aadc32fa..0a4471cc3 100644 --- a/src/mapgen/mg_biome.h +++ b/src/mapgen/mg_biome.h @@ -230,10 +230,10 @@ public: // For BiomeGen type 'BiomeGenOriginal' float getHeatAtPosOriginal(v3s16 pos, NoiseParams &np_heat, - NoiseParams &np_heat_blend, u64 seed); + NoiseParams &np_heat_blend, u64 seed) const; float getHumidityAtPosOriginal(v3s16 pos, NoiseParams &np_humidity, - NoiseParams &np_humidity_blend, u64 seed); - Biome *getBiomeFromNoiseOriginal(float heat, float humidity, v3s16 pos); + NoiseParams &np_humidity_blend, u64 seed) const; + Biome *getBiomeFromNoiseOriginal(float heat, float humidity, v3s16 pos) const; private: BiomeManager() {}; diff --git a/src/mapgen/mg_decoration.cpp b/src/mapgen/mg_decoration.cpp index db9c696ed..a9b67d239 100644 --- a/src/mapgen/mg_decoration.cpp +++ b/src/mapgen/mg_decoration.cpp @@ -391,6 +391,13 @@ size_t DecoSimple::generate(MMVManip *vm, PcgRandom *pr, v3s16 p, bool ceiling) /////////////////////////////////////////////////////////////////////////////// +DecoSchematic::~DecoSchematic() +{ + if (was_cloned) + delete schematic; +} + + ObjDef *DecoSchematic::clone() const { auto def = new DecoSchematic(); @@ -398,9 +405,12 @@ ObjDef *DecoSchematic::clone() const NodeResolver::cloneTo(def); def->rotation = rotation; - /* FIXME: This is not ideal, we only have a pointer to the schematic despite - * not owning it. Optimally this would be a handle. */ - def->schematic = schematic; // not cloned + /* FIXME: We do not own this schematic, yet we only have a pointer to it + * and not a handle. We are left with no option but to clone it ourselves. + * This is a waste of memory and should be replaced with an alternative + * approach sometime. */ + def->schematic = dynamic_cast(schematic->clone()); + def->was_cloned = true; return def; } diff --git a/src/mapgen/mg_decoration.h b/src/mapgen/mg_decoration.h index af8fcd7bf..1f9eb4510 100644 --- a/src/mapgen/mg_decoration.h +++ b/src/mapgen/mg_decoration.h @@ -99,11 +99,13 @@ public: ObjDef *clone() const; DecoSchematic() = default; + virtual ~DecoSchematic(); virtual size_t generate(MMVManip *vm, PcgRandom *pr, v3s16 p, bool ceiling); Rotation rotation; Schematic *schematic = nullptr; + bool was_cloned = false; // see FIXME inside DecoSchemtic::clone() }; diff --git a/src/mapgen/mg_schematic.cpp b/src/mapgen/mg_schematic.cpp index 2e04d30e6..c3bd89f3a 100644 --- a/src/mapgen/mg_schematic.cpp +++ b/src/mapgen/mg_schematic.cpp @@ -43,12 +43,21 @@ SchematicManager::SchematicManager(Server *server) : } +SchematicManager *SchematicManager::clone() const +{ + auto mgr = new SchematicManager(); + assert(mgr); + ObjDefManager::cloneTo(mgr); + return mgr; +} + + void SchematicManager::clear() { EmergeManager *emerge = m_server->getEmergeManager(); // Remove all dangling references in Decorations - DecorationManager *decomgr = emerge->decomgr; + DecorationManager *decomgr = emerge->getWritableDecorationManager(); for (size_t i = 0; i != decomgr->getNumObjects(); i++) { Decoration *deco = (Decoration *)decomgr->getRaw(i); @@ -79,7 +88,21 @@ Schematic::~Schematic() ObjDef *Schematic::clone() const { - FATAL_ERROR("not cloneable"); + auto def = new Schematic(); + ObjDef::cloneTo(def); + NodeResolver::cloneTo(def); + + def->c_nodes = c_nodes; + def->flags = flags; + def->size = size; + FATAL_ERROR_IF(!schemdata, "Schematic can only be cloned after loading"); + u32 nodecount = size.X * size.Y * size.Z; + def->schemdata = new MapNode[nodecount]; + memcpy(def->schemdata, schemdata, sizeof(MapNode) * nodecount); + def->slice_probs = new u8[size.Y]; + memcpy(def->slice_probs, slice_probs, sizeof(u8) * size.Y); + + return def; } diff --git a/src/mapgen/mg_schematic.h b/src/mapgen/mg_schematic.h index 770f74053..3222085e6 100644 --- a/src/mapgen/mg_schematic.h +++ b/src/mapgen/mg_schematic.h @@ -130,7 +130,7 @@ public: SchematicManager(Server *server); virtual ~SchematicManager() = default; - // not cloneable + SchematicManager *clone() const; virtual void clear(); @@ -145,6 +145,8 @@ public: } private: + SchematicManager() {}; + Server *m_server; }; diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index afe77826a..ba0304be3 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -91,7 +91,7 @@ struct EnumString ModApiMapgen::es_SchematicFormatType[] = {0, NULL}, }; -ObjDef *get_objdef(lua_State *L, int index, ObjDefManager *objmgr); +ObjDef *get_objdef(lua_State *L, int index, const ObjDefManager *objmgr); Biome *get_or_load_biome(lua_State *L, int index, BiomeManager *biomemgr); @@ -114,7 +114,7 @@ bool read_deco_schematic(lua_State *L, SchematicManager *schemmgr, DecoSchematic /////////////////////////////////////////////////////////////////////////////// -ObjDef *get_objdef(lua_State *L, int index, ObjDefManager *objmgr) +ObjDef *get_objdef(lua_State *L, int index, const ObjDefManager *objmgr) { if (index < 0) index = lua_gettop(L) + 1 + index; @@ -486,7 +486,7 @@ int ModApiMapgen::l_get_biome_id(lua_State *L) if (!biome_str) return 0; - BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; + const BiomeManager *bmgr = getServer(L)->getEmergeManager()->getBiomeManager(); if (!bmgr) return 0; @@ -508,7 +508,7 @@ int ModApiMapgen::l_get_biome_name(lua_State *L) int biome_id = luaL_checkinteger(L, 1); - BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; + const BiomeManager *bmgr = getServer(L)->getEmergeManager()->getBiomeManager(); if (!bmgr) return 0; @@ -546,7 +546,7 @@ int ModApiMapgen::l_get_heat(lua_State *L) u64 seed; ss >> seed; - BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; + const BiomeManager *bmgr = getServer(L)->getEmergeManager()->getBiomeManager(); if (!bmgr) return 0; @@ -587,7 +587,7 @@ int ModApiMapgen::l_get_humidity(lua_State *L) u64 seed; ss >> seed; - BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; + const BiomeManager *bmgr = getServer(L)->getEmergeManager()->getBiomeManager(); if (!bmgr) return 0; @@ -635,7 +635,7 @@ int ModApiMapgen::l_get_biome_data(lua_State *L) u64 seed; ss >> seed; - BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; + const BiomeManager *bmgr = getServer(L)->getEmergeManager()->getBiomeManager(); if (!bmgr) return 0; @@ -1066,7 +1066,8 @@ int ModApiMapgen::l_get_decoration_id(lua_State *L) if (!deco_str) return 0; - DecorationManager *dmgr = getServer(L)->getEmergeManager()->decomgr; + const DecorationManager *dmgr = + getServer(L)->getEmergeManager()->getDecorationManager(); if (!dmgr) return 0; @@ -1091,7 +1092,7 @@ int ModApiMapgen::l_register_biome(lua_State *L) luaL_checktype(L, index, LUA_TTABLE); const NodeDefManager *ndef = getServer(L)->getNodeDefManager(); - BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; + BiomeManager *bmgr = getServer(L)->getEmergeManager()->getWritableBiomeManager(); Biome *biome = read_biome_def(L, index, ndef); if (!biome) @@ -1117,9 +1118,10 @@ int ModApiMapgen::l_register_decoration(lua_State *L) luaL_checktype(L, index, LUA_TTABLE); const NodeDefManager *ndef = getServer(L)->getNodeDefManager(); - DecorationManager *decomgr = getServer(L)->getEmergeManager()->decomgr; - BiomeManager *biomemgr = getServer(L)->getEmergeManager()->biomemgr; - SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; + EmergeManager *emerge = getServer(L)->getEmergeManager(); + DecorationManager *decomgr = emerge->getWritableDecorationManager(); + BiomeManager *biomemgr = emerge->getWritableBiomeManager(); + SchematicManager *schemmgr = emerge->getWritableSchematicManager(); enum DecorationType decotype = (DecorationType)getenumfield(L, index, "deco_type", es_DecorationType, -1); @@ -1274,8 +1276,9 @@ int ModApiMapgen::l_register_ore(lua_State *L) luaL_checktype(L, index, LUA_TTABLE); const NodeDefManager *ndef = getServer(L)->getNodeDefManager(); - BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; - OreManager *oremgr = getServer(L)->getEmergeManager()->oremgr; + EmergeManager *emerge = getServer(L)->getEmergeManager(); + BiomeManager *bmgr = emerge->getWritableBiomeManager(); + OreManager *oremgr = emerge->getWritableOreManager(); enum OreType oretype = (OreType)getenumfield(L, index, "ore_type", es_OreType, ORE_SCATTER); @@ -1422,7 +1425,8 @@ int ModApiMapgen::l_register_schematic(lua_State *L) { NO_MAP_LOCK_REQUIRED; - SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; + SchematicManager *schemmgr = + getServer(L)->getEmergeManager()->getWritableSchematicManager(); StringMap replace_names; if (lua_istable(L, 2)) @@ -1449,7 +1453,8 @@ int ModApiMapgen::l_clear_registered_biomes(lua_State *L) { NO_MAP_LOCK_REQUIRED; - BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; + BiomeManager *bmgr = + getServer(L)->getEmergeManager()->getWritableBiomeManager(); bmgr->clear(); return 0; } @@ -1460,7 +1465,8 @@ int ModApiMapgen::l_clear_registered_decorations(lua_State *L) { NO_MAP_LOCK_REQUIRED; - DecorationManager *dmgr = getServer(L)->getEmergeManager()->decomgr; + DecorationManager *dmgr = + getServer(L)->getEmergeManager()->getWritableDecorationManager(); dmgr->clear(); return 0; } @@ -1471,7 +1477,8 @@ int ModApiMapgen::l_clear_registered_ores(lua_State *L) { NO_MAP_LOCK_REQUIRED; - OreManager *omgr = getServer(L)->getEmergeManager()->oremgr; + OreManager *omgr = + getServer(L)->getEmergeManager()->getWritableOreManager(); omgr->clear(); return 0; } @@ -1482,7 +1489,8 @@ int ModApiMapgen::l_clear_registered_schematics(lua_State *L) { NO_MAP_LOCK_REQUIRED; - SchematicManager *smgr = getServer(L)->getEmergeManager()->schemmgr; + SchematicManager *smgr = + getServer(L)->getEmergeManager()->getWritableSchematicManager(); smgr->clear(); return 0; } @@ -1508,7 +1516,8 @@ int ModApiMapgen::l_generate_ores(lua_State *L) u32 blockseed = Mapgen::getBlockSeed(pmin, mg.seed); - emerge->oremgr->placeAllOres(&mg, blockseed, pmin, pmax); + OreManager *oremgr = (OreManager*) emerge->getOreManager(); // FIXME FIXME + oremgr->placeAllOres(&mg, blockseed, pmin, pmax); return 0; } @@ -1534,7 +1543,8 @@ int ModApiMapgen::l_generate_decorations(lua_State *L) u32 blockseed = Mapgen::getBlockSeed(pmin, mg.seed); - emerge->decomgr->placeAllDecos(&mg, blockseed, pmin, pmax); + DecorationManager *decomgr = (DecorationManager*) emerge->getDecorationManager(); // FIXME FIXME + decomgr->placeAllDecos(&mg, blockseed, pmin, pmax); return 0; } @@ -1614,7 +1624,8 @@ int ModApiMapgen::l_place_schematic(lua_State *L) GET_ENV_PTR; ServerMap *map = &(env->getServerMap()); - SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; + SchematicManager *schemmgr = (SchematicManager*) + getServer(L)->getEmergeManager()->getSchematicManager(); // FIXME FIXME //// Read position v3s16 p = check_v3s16(L, 1); @@ -1659,7 +1670,8 @@ int ModApiMapgen::l_place_schematic_on_vmanip(lua_State *L) { NO_MAP_LOCK_REQUIRED; - SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; + SchematicManager *schemmgr = (SchematicManager*) + getServer(L)->getEmergeManager()->getSchematicManager(); // FIXME FIXME //// Read VoxelManip object MMVManip *vm = LuaVoxelManip::checkobject(L, 1)->vm; @@ -1707,7 +1719,7 @@ int ModApiMapgen::l_serialize_schematic(lua_State *L) { NO_MAP_LOCK_REQUIRED; - SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; + const SchematicManager *schemmgr = getServer(L)->getEmergeManager()->getSchematicManager(); //// Read options bool use_comments = getboolfield_default(L, 3, "lua_use_comments", false); @@ -1758,7 +1770,8 @@ int ModApiMapgen::l_read_schematic(lua_State *L) { NO_MAP_LOCK_REQUIRED; - SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; + const SchematicManager *schemmgr = + getServer(L)->getEmergeManager()->getSchematicManager(); //// Read options std::string write_yslice = getstringfield_default(L, 2, "write_yslice_prob", "all");