Cuberite
A lightweight, fast and extensible game server for Minecraft
ChunkSender.h
Go to the documentation of this file.
1 
2 // ChunkSender.h
3 
4 // Interfaces to the cChunkSender class representing the thread that waits for chunks becoming ready (loaded / generated) and sends them to clients
5 
6 /*
7 The whole thing is a thread that runs in a loop, waiting for either:
8  "finished chunks" (ChunkReady()), or
9  "chunks to send" (QueueSendChunkTo())
10 to come to a queue.
11 And once they do, it requests the chunk data and sends it all away, either
12  broadcasting (ChunkReady), or
13  sends to a specific client (QueueSendChunkTo)
14 Chunk data is queried using the cChunkDataCallback interface.
15 It is cached inside the ChunkSender object during the query and then processed after the query ends.
16 Note that the data needs to be compressed only after the query finishes,
17 because the query callbacks run with ChunkMap's CS locked.
18 
19 A client may remove itself from all direct requests(QueueSendChunkTo()) by calling RemoveClient();
20 this ensures that the client's Send() won't be called anymore by ChunkSender.
21 Note that it may be called by world's BroadcastToChunk() if the client is still in the chunk.
22 */
23 
24 
25 
26 #pragma once
27 
28 #include "OSSupport/IsThread.h"
29 #include "ChunkDataCallback.h"
31 
32 
33 
34 
35 
36 class cWorld;
37 class cClientHandle;
38 
39 
40 
41 
42 
43 // fwd:
44 class cChunkSender;
45 
46 
47 
48 
49 
50 class cChunkSender final :
51  public cIsThread,
53 {
54  using Super = cIsThread;
55 
56 public:
57 
58  cChunkSender(cWorld & a_World);
59  virtual ~cChunkSender() override;
60 
63  enum class Priority
64  {
65  Low,
66  Medium,
67  High,
68  Critical
69  };
70 
71  void Stop(void);
72 
74  void QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, Priority a_Priority, cClientHandle * a_Client);
75  void QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, Priority a_Priority, const std::vector<cClientHandle *> & a_Clients);
76 
77 protected:
78 
79  using WeakClients = std::set<std::weak_ptr<cClientHandle>, std::owner_less<std::weak_ptr<cClientHandle>>>;
80 
81  struct sChunkQueue
82  {
85 
86  bool operator <(const sChunkQueue & a_Other) const
87  {
88  // The operator will return true to affirm we're less urgent than Other
89  // This comparison depends on the Priority enum ordering lower priority as smaller:
90  return m_Priority < a_Other.m_Priority;
91  }
92  };
93 
95  struct sSendChunk
96  {
100  sSendChunk(cChunkCoords a_Chunk, Priority a_Priority) :
101  m_Chunk(a_Chunk),
102  m_Priority(a_Priority)
103  {
104  }
105  };
106 
108 
111 
113  std::priority_queue<sChunkQueue> m_SendChunks;
114  std::unordered_map<cChunkCoords, sSendChunk, cChunkCoordsHash> m_ChunkInfo;
115  cEvent m_evtQueue; // Set when anything is added to m_ChunksReady
116 
117  // Data about the chunk that is being sent:
118  // NOTE that m_BlockData[] is inherited from the cChunkDataCollector
120  std::vector<Vector3i> m_BlockEntities; // Coords of the block entities to send
121  std::vector<UInt32> m_EntityIDs; // Entity-IDs of the entities to send
122 
123  // cIsThread override:
124  virtual void Execute(void) override;
125 
126  // cChunkDataCollector overrides:
127  // (Note that they are called while the ChunkMap's CS is locked - don't do heavy calculations here!)
128  virtual void BiomeMap (const cChunkDef::BiomeMap & a_BiomeMap) override;
129  virtual void Entity (cEntity * a_Entity) override;
130  virtual void BlockEntity (cBlockEntity * a_Entity) override;
131 
133  void SendChunk(int a_ChunkX, int a_ChunkZ, const WeakClients & a_Clients);
134 } ;
135 
136 
137 
A simple implementation of the cChunkDataCallback interface that just copies the cChunkData.
Wraps the chunk coords into a single structure.
Definition: ChunkDef.h:57
static const int Width
Definition: ChunkDef.h:124
EMCSBiome BiomeMap[Width *Width]
The type used for any biomemap operations and storage inside Cuberite, using Cuberite biomes (need no...
Definition: ChunkDef.h:137
virtual void BiomeMap(const cChunkDef::BiomeMap &a_BiomeMap) override
unsigned char m_BiomeMap[cChunkDef::Width *cChunkDef::Width]
Definition: ChunkSender.h:119
virtual void BlockEntity(cBlockEntity *a_Entity) override
virtual void Execute(void) override
This function, overloaded by the descendants, is called in the new thread.
std::set< std::weak_ptr< cClientHandle >, std::owner_less< std::weak_ptr< cClientHandle > >> WeakClients
Definition: ChunkSender.h:79
virtual ~cChunkSender() override
Definition: ChunkSender.cpp:72
void QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, Priority a_Priority, cClientHandle *a_Client)
Queues a chunk to be sent to a specific client.
Definition: ChunkSender.cpp:92
cCriticalSection m_CS
Definition: ChunkSender.h:112
void SendChunk(int a_ChunkX, int a_ChunkZ, const WeakClients &a_Clients)
Sends the specified chunk to all the specified clients.
std::vector< UInt32 > m_EntityIDs
Definition: ChunkSender.h:121
cChunkSender(cWorld &a_World)
Definition: ChunkSender.cpp:61
cChunkDataSerializer m_Serializer
An instance of a chunk serializer, held to maintain its internal cache.
Definition: ChunkSender.h:110
std::priority_queue< sChunkQueue > m_SendChunks
Definition: ChunkSender.h:113
std::unordered_map< cChunkCoords, sSendChunk, cChunkCoordsHash > m_ChunkInfo
Definition: ChunkSender.h:114
Priority
Tag indicating urgency of chunk to be sent.
Definition: ChunkSender.h:64
std::vector< Vector3i > m_BlockEntities
Definition: ChunkSender.h:120
cEvent m_evtQueue
Definition: ChunkSender.h:115
cWorld & m_World
Definition: ChunkSender.h:107
void Stop(void)
Definition: ChunkSender.cpp:81
virtual void Entity(cEntity *a_Entity) override
bool operator<(const sChunkQueue &a_Other) const
Definition: ChunkSender.h:86
Used for sending chunks to specific clients.
Definition: ChunkSender.h:96
sSendChunk(cChunkCoords a_Chunk, Priority a_Priority)
Definition: ChunkSender.h:100
Definition: Entity.h:76
Definition: Event.h:18
cIsThread(AString &&a_ThreadName)
Definition: IsThread.cpp:16
Serializes one chunk's data to (possibly multiple) protocol versions.
Definition: World.h:53