summaryrefslogtreecommitdiffstats
path: root/src/ChunkSender.cpp
diff options
context:
space:
mode:
authorHowaner <franzi.moos@googlemail.com>2014-11-18 14:56:32 +0100
committerHowaner <franzi.moos@googlemail.com>2014-11-18 14:56:32 +0100
commit42120e2ea5db0cdb9920ff1c5efef33e0f496d48 (patch)
tree20ba1ae0a53f757cb8814b6cd6a466fe5acf1308 /src/ChunkSender.cpp
parentFixed compile errors. (diff)
parentMerge pull request #1598 from mc-server/SignEditor (diff)
downloadcuberite-42120e2ea5db0cdb9920ff1c5efef33e0f496d48.tar
cuberite-42120e2ea5db0cdb9920ff1c5efef33e0f496d48.tar.gz
cuberite-42120e2ea5db0cdb9920ff1c5efef33e0f496d48.tar.bz2
cuberite-42120e2ea5db0cdb9920ff1c5efef33e0f496d48.tar.lz
cuberite-42120e2ea5db0cdb9920ff1c5efef33e0f496d48.tar.xz
cuberite-42120e2ea5db0cdb9920ff1c5efef33e0f496d48.tar.zst
cuberite-42120e2ea5db0cdb9920ff1c5efef33e0f496d48.zip
Diffstat (limited to 'src/ChunkSender.cpp')
-rw-r--r--src/ChunkSender.cpp123
1 files changed, 92 insertions, 31 deletions
diff --git a/src/ChunkSender.cpp b/src/ChunkSender.cpp
index a3151eb3f..83d82884e 100644
--- a/src/ChunkSender.cpp
+++ b/src/ChunkSender.cpp
@@ -35,9 +35,9 @@ void cNotifyChunkSender::Call(int a_ChunkX, int a_ChunkZ)
cChunkSender::cChunkSender(void) :
super("ChunkSender"),
- m_World(NULL),
+ m_World(nullptr),
m_RemoveCount(0),
- m_Notify(NULL)
+ m_Notify(nullptr)
{
m_Notify.SetChunkSender(this);
}
@@ -91,17 +91,45 @@ void cChunkSender::ChunkReady(int a_ChunkX, int a_ChunkZ)
-void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client)
+void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, eChunkPriority a_Priority, cClientHandle * a_Client)
{
- ASSERT(a_Client != NULL);
+ ASSERT(a_Client != nullptr);
{
+ sSendChunk Chunk(a_ChunkX, a_ChunkZ, a_Client);
+
cCSLock Lock(m_CS);
- if (std::find(m_SendChunks.begin(), m_SendChunks.end(), sSendChunk(a_ChunkX, a_ChunkZ, a_Client)) != m_SendChunks.end())
+ if (
+ std::find(m_SendChunksLowPriority.begin(), m_SendChunksLowPriority.end(), Chunk) != m_SendChunksLowPriority.end() ||
+ std::find(m_SendChunksMediumPriority.begin(), m_SendChunksMediumPriority.end(), Chunk) != m_SendChunksMediumPriority.end() ||
+ std::find(m_SendChunksHighPriority.begin(), m_SendChunksHighPriority.end(), Chunk) != m_SendChunksHighPriority.end()
+ )
{
// Already queued, bail out
return;
}
- m_SendChunks.push_back(sSendChunk(a_ChunkX, a_ChunkZ, a_Client));
+
+ switch (a_Priority)
+ {
+ case E_CHUNK_PRIORITY_LOW:
+ {
+ m_SendChunksLowPriority.push_back(Chunk);
+ break;
+ }
+ case E_CHUNK_PRIORITY_MEDIUM:
+ {
+ m_SendChunksMediumPriority.push_back(Chunk);
+ break;
+ }
+ case E_CHUNK_PRIORITY_HIGH:
+ {
+ m_SendChunksHighPriority.push_back(Chunk);
+ break;
+ }
+ default:
+ {
+ ASSERT(!"Unknown chunk priority!");
+ }
+ }
}
m_evtQueue.Set();
}
@@ -114,15 +142,33 @@ void cChunkSender::RemoveClient(cClientHandle * a_Client)
{
{
cCSLock Lock(m_CS);
- for (sSendChunkList::iterator itr = m_SendChunks.begin(); itr != m_SendChunks.end();)
+ for (sSendChunkList::iterator itr = m_SendChunksLowPriority.begin(); itr != m_SendChunksLowPriority.end();)
{
if (itr->m_Client == a_Client)
{
- itr = m_SendChunks.erase(itr);
+ itr = m_SendChunksLowPriority.erase(itr);
continue;
}
++itr;
- } // for itr - m_SendChunks[]
+ } // for itr - m_SendChunksLowPriority[]
+ for (sSendChunkList::iterator itr = m_SendChunksMediumPriority.begin(); itr != m_SendChunksMediumPriority.end();)
+ {
+ if (itr->m_Client == a_Client)
+ {
+ itr = m_SendChunksMediumPriority.erase(itr);
+ continue;
+ }
+ ++itr;
+ } // for itr - m_SendChunksMediumPriority[]
+ for (sSendChunkList::iterator itr = m_SendChunksHighPriority.begin(); itr != m_SendChunksHighPriority.end();)
+ {
+ if (itr->m_Client == a_Client)
+ {
+ itr = m_SendChunksHighPriority.erase(itr);
+ continue;
+ }
+ ++itr;
+ } // for itr - m_SendChunksHighPriority[]
m_RemoveCount++;
}
m_evtQueue.Set();
@@ -138,7 +184,7 @@ void cChunkSender::Execute(void)
while (!m_ShouldTerminate)
{
cCSLock Lock(m_CS);
- while (m_ChunksReady.empty() && m_SendChunks.empty())
+ while (m_ChunksReady.empty() && m_SendChunksLowPriority.empty() && m_SendChunksMediumPriority.empty() && m_SendChunksHighPriority.empty())
{
int RemoveCount = m_RemoveCount;
m_RemoveCount = 0;
@@ -153,23 +199,41 @@ void cChunkSender::Execute(void)
return;
}
} // while (empty)
-
- if (!m_ChunksReady.empty())
+
+ if (!m_SendChunksHighPriority.empty())
+ {
+ // Take one from the queue:
+ sSendChunk Chunk(m_SendChunksHighPriority.front());
+ m_SendChunksHighPriority.pop_front();
+ Lock.Unlock();
+
+ SendChunk(Chunk.m_ChunkX, Chunk.m_ChunkZ, Chunk.m_Client);
+ }
+ else if (!m_ChunksReady.empty())
{
// Take one from the queue:
cChunkCoords Coords(m_ChunksReady.front());
m_ChunksReady.pop_front();
Lock.Unlock();
- SendChunk(Coords.m_ChunkX, Coords.m_ChunkZ, NULL);
+ SendChunk(Coords.m_ChunkX, Coords.m_ChunkZ, nullptr);
+ }
+ else if (!m_SendChunksMediumPriority.empty())
+ {
+ // Take one from the queue:
+ sSendChunk Chunk(m_SendChunksMediumPriority.front());
+ m_SendChunksMediumPriority.pop_front();
+ Lock.Unlock();
+
+ SendChunk(Chunk.m_ChunkX, Chunk.m_ChunkZ, Chunk.m_Client);
}
else
{
// Take one from the queue:
- sSendChunk Chunk(m_SendChunks.front());
- m_SendChunks.pop_front();
+ sSendChunk Chunk(m_SendChunksLowPriority.front());
+ m_SendChunksLowPriority.pop_front();
Lock.Unlock();
-
+
SendChunk(Chunk.m_ChunkX, Chunk.m_ChunkZ, Chunk.m_Client);
}
Lock.Lock();
@@ -189,45 +253,42 @@ void cChunkSender::Execute(void)
void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client)
{
- ASSERT(m_World != NULL);
+ ASSERT(m_World != nullptr);
// Ask the client if it still wants the chunk:
- if (a_Client != NULL)
+ if ((a_Client != nullptr) && !a_Client->WantsSendChunk(a_ChunkX, a_ChunkZ))
{
- if (!a_Client->WantsSendChunk(a_ChunkX, a_ChunkZ))
- {
- return;
- }
+ return;
}
-
+
// If the chunk has no clients, no need to packetize it:
if (!m_World->HasChunkAnyClients(a_ChunkX, a_ChunkZ))
{
return;
}
-
+
// If the chunk is not valid, do nothing - whoever needs it has queued it for loading / generating
if (!m_World->IsChunkValid(a_ChunkX, a_ChunkZ))
{
return;
}
-
+
// If the chunk is not lighted, queue it for relighting and get notified when it's ready:
if (!m_World->IsChunkLighted(a_ChunkX, a_ChunkZ))
{
m_World->QueueLightChunk(a_ChunkX, a_ChunkZ, &m_Notify);
return;
}
-
+
// Query and prepare chunk data:
if (!m_World->GetChunkData(a_ChunkX, a_ChunkZ, *this))
{
return;
}
cChunkDataSerializer Data(m_BlockTypes, m_BlockMetas, m_BlockLight, m_BlockSkyLight, m_BiomeMap);
-
+
// Send:
- if (a_Client == NULL)
+ if (a_Client == nullptr)
{
m_World->BroadcastChunkData(a_ChunkX, a_ChunkZ, Data);
}
@@ -235,11 +296,11 @@ void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Clien
{
a_Client->SendChunkData(a_ChunkX, a_ChunkZ, Data);
}
-
+
// Send block-entity packets:
for (sBlockCoords::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
{
- if (a_Client == NULL)
+ if (a_Client == nullptr)
{
m_World->BroadcastBlockEntity(itr->m_BlockX, itr->m_BlockY, itr->m_BlockZ);
}
@@ -249,7 +310,7 @@ void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Clien
}
} // for itr - m_Packets[]
m_BlockEntities.clear();
-
+
// TODO: Send entity spawn packets
}