Noise: Prevent unittest crash caused by division by zero
[oweals/minetest.git] / src / mesh_generator_thread.h
1 /*
2 Minetest
3 Copyright (C) 2013, 2017 celeron55, Perttu Ahola <celeron55@gmail.com>
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 MESH_GENERATOR_THREAD_HEADER
21 #define MESH_GENERATOR_THREAD_HEADER
22
23 #include <ctime>
24 #include <mutex>
25 #include "mapblock_mesh.h"
26 #include "threading/mutex_auto_lock.h"
27 #include "util/thread.h"
28
29 struct CachedMapBlockData
30 {
31         v3s16 p = v3s16(-1337, -1337, -1337);
32         MapNode *data = nullptr; // A copy of the MapBlock's data member
33         int refcount_from_queue = 0;
34         std::time_t last_used_timestamp = std::time(0);
35
36         CachedMapBlockData() {}
37         ~CachedMapBlockData();
38 };
39
40 struct QueuedMeshUpdate
41 {
42         v3s16 p = v3s16(-1337, -1337, -1337);
43         bool ack_block_to_server = false;
44         bool urgent = false;
45         int crack_level = -1;
46         v3s16 crack_pos;
47         MeshMakeData *data = nullptr; // This is generated in MeshUpdateQueue::pop()
48
49         QueuedMeshUpdate(){};
50         ~QueuedMeshUpdate();
51 };
52
53 /*
54         A thread-safe queue of mesh update tasks and a cache of MapBlock data
55 */
56 class MeshUpdateQueue
57 {
58         enum UpdateMode
59         {
60                 FORCE_UPDATE,
61                 SKIP_UPDATE_IF_ALREADY_CACHED,
62         };
63
64 public:
65         MeshUpdateQueue(Client *client);
66
67         ~MeshUpdateQueue();
68
69         // Caches the block at p and its neighbors (if needed) and queues a mesh
70         // update for the block at p
71         void addBlock(Map *map, v3s16 p, bool ack_block_to_server, bool urgent);
72
73         // Returned pointer must be deleted
74         // Returns NULL if queue is empty
75         QueuedMeshUpdate *pop();
76
77         u32 size()
78         {
79                 MutexAutoLock lock(m_mutex);
80                 return m_queue.size();
81         }
82
83 private:
84         Client *m_client;
85         std::vector<QueuedMeshUpdate *> m_queue;
86         std::set<v3s16> m_urgents;
87         std::map<v3s16, CachedMapBlockData *> m_cache;
88         std::mutex m_mutex;
89
90         // TODO: Add callback to update these when g_settings changes
91         bool m_cache_enable_shaders;
92         bool m_cache_use_tangent_vertices;
93         bool m_cache_smooth_lighting;
94         int m_meshgen_block_cache_size;
95
96         CachedMapBlockData *cacheBlock(Map *map, v3s16 p, UpdateMode mode,
97                         size_t *cache_hit_counter = NULL);
98         CachedMapBlockData *getCachedBlock(const v3s16 &p);
99         void fillDataFromMapBlockCache(QueuedMeshUpdate *q);
100         void cleanupCache();
101 };
102
103 struct MeshUpdateResult
104 {
105         v3s16 p = v3s16(-1338, -1338, -1338);
106         MapBlockMesh *mesh = nullptr;
107         bool ack_block_to_server = false;
108
109         MeshUpdateResult() {}
110 };
111
112 class MeshUpdateThread : public UpdateThread
113 {
114 public:
115         MeshUpdateThread(Client *client);
116
117         // Caches the block at p and its neighbors (if needed) and queues a mesh
118         // update for the block at p
119         void updateBlock(Map *map, v3s16 p, bool ack_block_to_server, bool urgent);
120
121         v3s16 m_camera_offset;
122         MutexedQueue<MeshUpdateResult> m_queue_out;
123
124 private:
125         MeshUpdateQueue m_queue_in;
126
127         // TODO: Add callback to update these when g_settings changes
128         int m_generation_interval;
129
130 protected:
131         virtual void doUpdate();
132 };
133
134 #endif