1 /* 2 Minetest 3 Copyright (C) 2010-2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net> 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU Lesser General Public License as published by 7 the Free Software Foundation; either version 2.1 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public License along 16 with this program; if not, write to the Free Software Foundation, Inc., 17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 #pragma once 21 22 #include <map> 23 #include <mutex> 24 #include "network/networkprotocol.h" 25 #include "irr_v3d.h" 26 #include "util/container.h" 27 #include "mapgen/mapgen.h" // for MapgenParams 28 #include "map.h" 29 30 #define BLOCK_EMERGE_ALLOW_GEN (1 << 0) 31 #define BLOCK_EMERGE_FORCE_QUEUE (1 << 1) 32 33 #define EMERGE_DBG_OUT(x) { \ 34 if (enable_mapgen_debug_info) \ 35 infostream << "EmergeThread: " x << std::endl; \ 36 } 37 38 class EmergeThread; 39 class NodeDefManager; 40 class Settings; 41 42 class BiomeManager; 43 class OreManager; 44 class DecorationManager; 45 class SchematicManager; 46 class Server; 47 class ModApiMapgen; 48 49 // Structure containing inputs/outputs for chunk generation 50 struct BlockMakeData { 51 MMVManip *vmanip = nullptr; 52 u64 seed = 0; 53 v3s16 blockpos_min; 54 v3s16 blockpos_max; 55 UniqueQueue<v3s16> transforming_liquid; 56 const NodeDefManager *nodedef = nullptr; 57 58 BlockMakeData() = default; 59 ~BlockMakeDataBlockMakeData60 ~BlockMakeData() { delete vmanip; } 61 }; 62 63 // Result from processing an item on the emerge queue 64 enum EmergeAction { 65 EMERGE_CANCELLED, 66 EMERGE_ERRORED, 67 EMERGE_FROM_MEMORY, 68 EMERGE_FROM_DISK, 69 EMERGE_GENERATED, 70 }; 71 72 // Callback 73 typedef void (*EmergeCompletionCallback)( 74 v3s16 blockpos, EmergeAction action, void *param); 75 76 typedef std::vector< 77 std::pair< 78 EmergeCompletionCallback, 79 void * 80 > 81 > EmergeCallbackList; 82 83 struct BlockEmergeData { 84 u16 peer_requested; 85 u16 flags; 86 EmergeCallbackList callbacks; 87 }; 88 89 class EmergeParams { 90 friend class EmergeManager; 91 public: 92 EmergeParams() = delete; 93 ~EmergeParams(); 94 DISABLE_CLASS_COPY(EmergeParams); 95 96 const NodeDefManager *ndef; // shared 97 bool enable_mapgen_debug_info; 98 99 u32 gen_notify_on; 100 const std::set<u32> *gen_notify_on_deco_ids; // shared 101 102 BiomeManager *biomemgr; 103 OreManager *oremgr; 104 DecorationManager *decomgr; 105 SchematicManager *schemmgr; 106 107 private: 108 EmergeParams(EmergeManager *parent, const BiomeManager *biomemgr, 109 const OreManager *oremgr, const DecorationManager *decomgr, 110 const SchematicManager *schemmgr); 111 }; 112 113 class EmergeManager { 114 /* The mod API needs unchecked access to allow: 115 * - using decomgr or oremgr to place decos/ores 116 * - using schemmgr to load and place schematics 117 */ 118 friend class ModApiMapgen; 119 public: 120 const NodeDefManager *ndef; 121 bool enable_mapgen_debug_info; 122 123 // Generation Notify 124 u32 gen_notify_on = 0; 125 std::set<u32> gen_notify_on_deco_ids; 126 127 // Parameters passed to mapgens owned by ServerMap 128 // TODO(hmmmm): Remove this after mapgen helper methods using them 129 // are moved to ServerMap 130 MapgenParams *mgparams; 131 132 // Hackish workaround: 133 // For now, EmergeManager must hold onto a ptr to the Map's setting manager 134 // since the Map can only be accessed through the Environment, and the 135 // Environment is not created until after script initialization. 136 MapSettingsManager *map_settings_mgr; 137 138 // Methods 139 EmergeManager(Server *server); 140 ~EmergeManager(); 141 DISABLE_CLASS_COPY(EmergeManager); 142 143 // no usage restrictions getBiomeManager()144 const BiomeManager *getBiomeManager() const { return biomemgr; } getOreManager()145 const OreManager *getOreManager() const { return oremgr; } getDecorationManager()146 const DecorationManager *getDecorationManager() const { return decomgr; } getSchematicManager()147 const SchematicManager *getSchematicManager() const { return schemmgr; } 148 // only usable before mapgen init 149 BiomeManager *getWritableBiomeManager(); 150 OreManager *getWritableOreManager(); 151 DecorationManager *getWritableDecorationManager(); 152 SchematicManager *getWritableSchematicManager(); 153 154 void initMapgens(MapgenParams *mgparams); 155 156 void startThreads(); 157 void stopThreads(); 158 bool isRunning(); 159 160 bool enqueueBlockEmerge( 161 session_t peer_id, 162 v3s16 blockpos, 163 bool allow_generate, 164 bool ignore_queue_limits=false); 165 166 bool enqueueBlockEmergeEx( 167 v3s16 blockpos, 168 session_t peer_id, 169 u16 flags, 170 EmergeCompletionCallback callback, 171 void *callback_param); 172 173 v3s16 getContainingChunk(v3s16 blockpos); 174 175 Mapgen *getCurrentMapgen(); 176 177 // Mapgen helpers methods 178 int getSpawnLevelAtPoint(v2s16 p); 179 int getGroundLevelAtPoint(v2s16 p); 180 bool isBlockUnderground(v3s16 blockpos); 181 182 static v3s16 getContainingChunk(v3s16 blockpos, s16 chunksize); 183 184 private: 185 std::vector<Mapgen *> m_mapgens; 186 std::vector<EmergeThread *> m_threads; 187 bool m_threads_active = false; 188 189 std::mutex m_queue_mutex; 190 std::map<v3s16, BlockEmergeData> m_blocks_enqueued; 191 std::unordered_map<u16, u16> m_peer_queue_count; 192 193 u16 m_qlimit_total; 194 u16 m_qlimit_diskonly; 195 u16 m_qlimit_generate; 196 197 // Managers of various map generation-related components 198 // Note that each Mapgen gets a copy(!) of these to work with 199 BiomeManager *biomemgr; 200 OreManager *oremgr; 201 DecorationManager *decomgr; 202 SchematicManager *schemmgr; 203 204 // Requires m_queue_mutex held 205 EmergeThread *getOptimalThread(); 206 207 bool pushBlockEmergeData( 208 v3s16 pos, 209 u16 peer_requested, 210 u16 flags, 211 EmergeCompletionCallback callback, 212 void *callback_param, 213 bool *entry_already_exists); 214 215 bool popBlockEmergeData(v3s16 pos, BlockEmergeData *bedata); 216 217 friend class EmergeThread; 218 }; 219