/* Minetest Copyright (C) 2010-2013 kwolekr, Ryan Kwolek 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. */ #pragma once #include #include #include "network/networkprotocol.h" #include "irr_v3d.h" #include "util/container.h" #include "util/metricsbackend.h" #include "mapgen/mapgen.h" // for MapgenParams #include "map.h" #define BLOCK_EMERGE_ALLOW_GEN (1 << 0) #define BLOCK_EMERGE_FORCE_QUEUE (1 << 1) #define EMERGE_DBG_OUT(x) { \ if (enable_mapgen_debug_info) \ infostream << "EmergeThread: " x << std::endl; \ } class EmergeThread; class NodeDefManager; class Settings; class BiomeManager; class OreManager; class DecorationManager; class SchematicManager; class Server; class ModApiMapgen; // Structure containing inputs/outputs for chunk generation struct BlockMakeData { MMVManip *vmanip = nullptr; u64 seed = 0; v3s16 blockpos_min; v3s16 blockpos_max; UniqueQueue transforming_liquid; const NodeDefManager *nodedef = nullptr; BlockMakeData() = default; ~BlockMakeData() { delete vmanip; } }; // Result from processing an item on the emerge queue enum EmergeAction { EMERGE_CANCELLED, EMERGE_ERRORED, EMERGE_FROM_MEMORY, EMERGE_FROM_DISK, EMERGE_GENERATED, }; const static std::string emergeActionStrs[] = { "cancelled", "errored", "from_memory", "from_disk", "generated", }; // Callback typedef void (*EmergeCompletionCallback)( v3s16 blockpos, EmergeAction action, void *param); typedef std::vector< std::pair< EmergeCompletionCallback, void * > > EmergeCallbackList; struct BlockEmergeData { u16 peer_requested; u16 flags; 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 BiomeGen *biomegen; BiomeManager *biomemgr; OreManager *oremgr; DecorationManager *decomgr; SchematicManager *schemmgr; private: EmergeParams(EmergeManager *parent, const BiomeGen *biomegen, const BiomeManager *biomemgr, const OreManager *oremgr, const DecorationManager *decomgr, const SchematicManager *schemmgr); }; class EmergeManager { /* The mod API needs unchecked access to allow: * - using decomgr or oremgr to place decos/ores * - using schemmgr to load and place schematics */ friend class ModApiMapgen; public: const NodeDefManager *ndef; bool enable_mapgen_debug_info; // Generation Notify u32 gen_notify_on = 0; std::set gen_notify_on_deco_ids; // Parameters passed to mapgens owned by ServerMap // TODO(hmmmm): Remove this after mapgen helper methods using them // are moved to ServerMap MapgenParams *mgparams; // Hackish workaround: // For now, EmergeManager must hold onto a ptr to the Map's setting manager // since the Map can only be accessed through the Environment, and the // Environment is not created until after script initialization. MapSettingsManager *map_settings_mgr; // Methods EmergeManager(Server *server, MetricsBackend *mb); ~EmergeManager(); DISABLE_CLASS_COPY(EmergeManager); const BiomeGen *getBiomeGen() const { return biomegen; } // 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(); void stopThreads(); bool isRunning(); bool enqueueBlockEmerge( session_t peer_id, v3s16 blockpos, bool allow_generate, bool ignore_queue_limits=false); bool enqueueBlockEmergeEx( v3s16 blockpos, session_t peer_id, u16 flags, EmergeCompletionCallback callback, void *callback_param); bool isBlockInQueue(v3s16 pos); Mapgen *getCurrentMapgen(); // Mapgen helpers methods int getSpawnLevelAtPoint(v2s16 p); bool isBlockUnderground(v3s16 blockpos); static v3s16 getContainingChunk(v3s16 blockpos, s16 chunksize); private: std::vector m_mapgens; std::vector m_threads; bool m_threads_active = false; std::mutex m_queue_mutex; std::map m_blocks_enqueued; std::unordered_map m_peer_queue_count; u32 m_qlimit_total; u32 m_qlimit_diskonly; u32 m_qlimit_generate; // Emerge metrics MetricCounterPtr m_completed_emerge_counter[5]; // Managers of various map generation-related components // Note that each Mapgen gets a copy(!) of these to work with BiomeGen *biomegen; BiomeManager *biomemgr; OreManager *oremgr; DecorationManager *decomgr; SchematicManager *schemmgr; // Requires m_queue_mutex held EmergeThread *getOptimalThread(); bool pushBlockEmergeData( v3s16 pos, u16 peer_requested, u16 flags, EmergeCompletionCallback callback, void *callback_param, bool *entry_already_exists); bool popBlockEmergeData(v3s16 pos, BlockEmergeData *bedata); void reportCompletedEmerge(EmergeAction action); friend class EmergeThread; };