C++11 patchset 2: remove util/cpp11.h and util/cpp11_container.h (#5821)
[oweals/minetest.git] / src / emerge.h
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 #ifndef EMERGE_HEADER
21 #define EMERGE_HEADER
22
23 #include <map>
24 #include "irr_v3d.h"
25 #include "util/container.h"
26 #include "mapgen.h" // for MapgenParams
27 #include "map.h"
28
29 #define BLOCK_EMERGE_ALLOW_GEN   (1 << 0)
30 #define BLOCK_EMERGE_FORCE_QUEUE (1 << 1)
31
32 #define EMERGE_DBG_OUT(x) do {                         \
33         if (enable_mapgen_debug_info)                      \
34                 infostream << "EmergeThread: " x << std::endl; \
35 } while (0)
36
37 class EmergeThread;
38 class INodeDefManager;
39 class Settings;
40
41 class BiomeManager;
42 class OreManager;
43 class DecorationManager;
44 class SchematicManager;
45 class Server;
46
47 // Structure containing inputs/outputs for chunk generation
48 struct BlockMakeData {
49         MMVManip *vmanip;
50         u64 seed;
51         v3s16 blockpos_min;
52         v3s16 blockpos_max;
53         v3s16 blockpos_requested;
54         UniqueQueue<v3s16> transforming_liquid;
55         INodeDefManager *nodedef;
56
57         BlockMakeData():
58                 vmanip(NULL),
59                 seed(0),
60                 nodedef(NULL)
61         {}
62
63         ~BlockMakeData() { delete vmanip; }
64 };
65
66 // Result from processing an item on the emerge queue
67 enum EmergeAction {
68         EMERGE_CANCELLED,
69         EMERGE_ERRORED,
70         EMERGE_FROM_MEMORY,
71         EMERGE_FROM_DISK,
72         EMERGE_GENERATED,
73 };
74
75 // Callback
76 typedef void (*EmergeCompletionCallback)(
77         v3s16 blockpos, EmergeAction action, void *param);
78
79 typedef std::vector<
80         std::pair<
81                 EmergeCompletionCallback,
82                 void *
83         >
84 > EmergeCallbackList;
85
86 struct BlockEmergeData {
87         u16 peer_requested;
88         u16 flags;
89         EmergeCallbackList callbacks;
90 };
91
92 class EmergeManager {
93 public:
94         INodeDefManager *ndef;
95         bool enable_mapgen_debug_info;
96
97         // Generation Notify
98         u32 gen_notify_on;
99         std::set<u32> gen_notify_on_deco_ids;
100
101         // Parameters passed to mapgens owned by ServerMap
102         // TODO(hmmmm): Remove this after mapgen helper methods using them
103         // are moved to ServerMap
104         MapgenParams *mgparams;
105
106         // Hackish workaround:
107         // For now, EmergeManager must hold onto a ptr to the Map's setting manager
108         // since the Map can only be accessed through the Environment, and the
109         // Environment is not created until after script initialization.
110         MapSettingsManager *map_settings_mgr;
111
112         // Managers of various map generation-related components
113         BiomeManager *biomemgr;
114         OreManager *oremgr;
115         DecorationManager *decomgr;
116         SchematicManager *schemmgr;
117
118         // Methods
119         EmergeManager(Server *server);
120         ~EmergeManager();
121
122         bool initMapgens(MapgenParams *mgparams);
123
124         void startThreads();
125         void stopThreads();
126         bool isRunning();
127
128         bool enqueueBlockEmerge(
129                 u16 peer_id,
130                 v3s16 blockpos,
131                 bool allow_generate,
132                 bool ignore_queue_limits=false);
133
134         bool enqueueBlockEmergeEx(
135                 v3s16 blockpos,
136                 u16 peer_id,
137                 u16 flags,
138                 EmergeCompletionCallback callback,
139                 void *callback_param);
140
141         v3s16 getContainingChunk(v3s16 blockpos);
142
143         Mapgen *getCurrentMapgen();
144
145         // Mapgen helpers methods
146         Biome *getBiomeAtPoint(v3s16 p);
147         int getSpawnLevelAtPoint(v2s16 p);
148         int getGroundLevelAtPoint(v2s16 p);
149         bool isBlockUnderground(v3s16 blockpos);
150
151         static v3s16 getContainingChunk(v3s16 blockpos, s16 chunksize);
152
153 private:
154         std::vector<Mapgen *> m_mapgens;
155         std::vector<EmergeThread *> m_threads;
156         bool m_threads_active;
157
158         Mutex m_queue_mutex;
159         std::map<v3s16, BlockEmergeData> m_blocks_enqueued;
160         std::unordered_map<u16, u16> m_peer_queue_count;
161
162         u16 m_qlimit_total;
163         u16 m_qlimit_diskonly;
164         u16 m_qlimit_generate;
165
166         // Requires m_queue_mutex held
167         EmergeThread *getOptimalThread();
168
169         bool pushBlockEmergeData(
170                 v3s16 pos,
171                 u16 peer_requested,
172                 u16 flags,
173                 EmergeCompletionCallback callback,
174                 void *callback_param,
175                 bool *entry_already_exists);
176
177         bool popBlockEmergeData(v3s16 pos, BlockEmergeData *bedata);
178
179         friend class EmergeThread;
180
181         DISABLE_CLASS_COPY(EmergeManager);
182 };
183
184 #endif