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