Use two lists and 2 chunk send prioritys.
This commit is contained in:
parent
a07456d712
commit
b0988e65aa
|
@ -1742,7 +1742,7 @@ void cChunk::SetAreaBiome(int a_MinRelX, int a_MaxRelX, int a_MinRelZ, int a_Max
|
||||||
// Re-send the chunk to all clients:
|
// Re-send the chunk to all clients:
|
||||||
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||||
{
|
{
|
||||||
m_World->ForceSendChunkTo(m_PosX, m_PosZ, cChunkSender::E_CHUNK_PRIORITY_MEDIUM, (*itr));
|
m_World->ForceSendChunkTo(m_PosX, m_PosZ, cChunkSender::E_CHUNK_PRIORITY_HIGH, (*itr));
|
||||||
} // for itr - m_LoadedByClient[]
|
} // for itr - m_LoadedByClient[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,18 +95,23 @@ void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, eChunkPriority a
|
||||||
{
|
{
|
||||||
ASSERT(a_Client != NULL);
|
ASSERT(a_Client != NULL);
|
||||||
{
|
{
|
||||||
sSendChunk Chunk(a_ChunkX, a_ChunkZ, a_Priority, a_Client);
|
sSendChunk Chunk(a_ChunkX, a_ChunkZ, a_Client);
|
||||||
|
|
||||||
cCSLock Lock(m_CS);
|
cCSLock Lock(m_CS);
|
||||||
if (std::find(m_SendChunks.begin(), m_SendChunks.end(), Chunk) != m_SendChunks.end())
|
if (
|
||||||
|
std::find(m_SendChunksLowPriority.begin(), m_SendChunksLowPriority.end(), Chunk) != m_SendChunksLowPriority.end() ||
|
||||||
|
std::find(m_SendChunksHighPriority.begin(), m_SendChunksHighPriority.end(), Chunk) != m_SendChunksHighPriority.end()
|
||||||
|
)
|
||||||
{
|
{
|
||||||
// Already queued, bail out
|
// Already queued, bail out
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_SendChunks.push_back(Chunk);
|
|
||||||
|
|
||||||
// Sort the list:
|
if (a_Priority == E_CHUNK_PRIORITY_LOW) {
|
||||||
m_SendChunks.sort();
|
m_SendChunksLowPriority.push_back(Chunk);
|
||||||
|
} else if (a_Priority == E_CHUNK_PRIORITY_HIGH) {
|
||||||
|
m_SendChunksHighPriority.push_back(Chunk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_evtQueue.Set();
|
m_evtQueue.Set();
|
||||||
}
|
}
|
||||||
|
@ -119,15 +124,23 @@ void cChunkSender::RemoveClient(cClientHandle * a_Client)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CS);
|
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)
|
if (itr->m_Client == a_Client)
|
||||||
{
|
{
|
||||||
itr = m_SendChunks.erase(itr);
|
itr = m_SendChunksLowPriority.erase(itr);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
++itr;
|
++itr;
|
||||||
} // for itr - m_SendChunks[]
|
} // for itr - m_SendChunksLowPriority[]
|
||||||
|
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_RemoveCount++;
|
||||||
}
|
}
|
||||||
m_evtQueue.Set();
|
m_evtQueue.Set();
|
||||||
|
@ -143,7 +156,7 @@ void cChunkSender::Execute(void)
|
||||||
while (!m_ShouldTerminate)
|
while (!m_ShouldTerminate)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CS);
|
cCSLock Lock(m_CS);
|
||||||
while (m_ChunksReady.empty() && m_SendChunks.empty())
|
while (m_ChunksReady.empty() && m_SendChunksLowPriority.empty() && m_SendChunksHighPriority.empty())
|
||||||
{
|
{
|
||||||
int RemoveCount = m_RemoveCount;
|
int RemoveCount = m_RemoveCount;
|
||||||
m_RemoveCount = 0;
|
m_RemoveCount = 0;
|
||||||
|
@ -158,8 +171,17 @@ void cChunkSender::Execute(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} // while (empty)
|
} // 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:
|
// Take one from the queue:
|
||||||
cChunkCoords Coords(m_ChunksReady.front());
|
cChunkCoords Coords(m_ChunksReady.front());
|
||||||
|
@ -171,8 +193,8 @@ void cChunkSender::Execute(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Take one from the queue:
|
// Take one from the queue:
|
||||||
sSendChunk Chunk(m_SendChunks.front());
|
sSendChunk Chunk(m_SendChunksLowPriority.front());
|
||||||
m_SendChunks.pop_front();
|
m_SendChunksLowPriority.pop_front();
|
||||||
Lock.Unlock();
|
Lock.Unlock();
|
||||||
|
|
||||||
SendChunk(Chunk.m_ChunkX, Chunk.m_ChunkZ, Chunk.m_Client);
|
SendChunk(Chunk.m_ChunkX, Chunk.m_ChunkZ, Chunk.m_Client);
|
||||||
|
|
|
@ -79,8 +79,7 @@ public:
|
||||||
enum eChunkPriority
|
enum eChunkPriority
|
||||||
{
|
{
|
||||||
E_CHUNK_PRIORITY_HIGH = 0,
|
E_CHUNK_PRIORITY_HIGH = 0,
|
||||||
E_CHUNK_PRIORITY_MEDIUM = 1,
|
E_CHUNK_PRIORITY_LOW = 1,
|
||||||
E_CHUNK_PRIORITY_LOW = 2,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool Start(cWorld * a_World);
|
bool Start(cWorld * a_World);
|
||||||
|
@ -103,13 +102,11 @@ protected:
|
||||||
{
|
{
|
||||||
int m_ChunkX;
|
int m_ChunkX;
|
||||||
int m_ChunkZ;
|
int m_ChunkZ;
|
||||||
eChunkPriority m_Priority;
|
|
||||||
cClientHandle * m_Client;
|
cClientHandle * m_Client;
|
||||||
|
|
||||||
sSendChunk(int a_ChunkX, int a_ChunkZ, eChunkPriority a_Priority, cClientHandle * a_Client) :
|
sSendChunk(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client) :
|
||||||
m_ChunkX(a_ChunkX),
|
m_ChunkX(a_ChunkX),
|
||||||
m_ChunkZ(a_ChunkZ),
|
m_ChunkZ(a_ChunkZ),
|
||||||
m_Priority(a_Priority),
|
|
||||||
m_Client(a_Client)
|
m_Client(a_Client)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -122,11 +119,6 @@ protected:
|
||||||
(a_Other.m_Client == m_Client)
|
(a_Other.m_Client == m_Client)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator < (const sSendChunk & a_Other)
|
|
||||||
{
|
|
||||||
return (m_Priority < a_Other.m_Priority);
|
|
||||||
}
|
|
||||||
} ;
|
} ;
|
||||||
typedef std::list<sSendChunk> sSendChunkList;
|
typedef std::list<sSendChunk> sSendChunkList;
|
||||||
|
|
||||||
|
@ -150,7 +142,8 @@ protected:
|
||||||
|
|
||||||
cCriticalSection m_CS;
|
cCriticalSection m_CS;
|
||||||
cChunkCoordsList m_ChunksReady;
|
cChunkCoordsList m_ChunksReady;
|
||||||
sSendChunkList m_SendChunks;
|
sSendChunkList m_SendChunksLowPriority;
|
||||||
|
sSendChunkList m_SendChunksHighPriority;
|
||||||
cEvent m_evtQueue; // Set when anything is added to m_ChunksReady
|
cEvent m_evtQueue; // Set when anything is added to m_ChunksReady
|
||||||
cEvent m_evtRemoved; // Set when removed clients are safe to be deleted
|
cEvent m_evtRemoved; // Set when removed clients are safe to be deleted
|
||||||
int m_RemoveCount; // Number of threads waiting for a client removal (m_evtRemoved needs to be set this many times)
|
int m_RemoveCount; // Number of threads waiting for a client removal (m_evtRemoved needs to be set this many times)
|
||||||
|
|
|
@ -469,47 +469,6 @@ bool cClientHandle::StreamNextChunk(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Medium priority: Load the chunks that are behind the player
|
|
||||||
LookVector = m_Player->GetLookVector() * -1;
|
|
||||||
for (int Range = 0; Range < 3; Range++)
|
|
||||||
{
|
|
||||||
Vector3d Vector = Position + LookVector * cChunkDef::Width * Range;
|
|
||||||
|
|
||||||
// Get the chunk from the x/z coords.
|
|
||||||
int RangeX, RangeZ = 0;
|
|
||||||
cChunkDef::BlockToChunk(FloorC(Vector.x), FloorC(Vector.z), RangeX, RangeZ);
|
|
||||||
|
|
||||||
for (size_t X = 0; X < 7; X++)
|
|
||||||
{
|
|
||||||
for (size_t Z = 0; Z < 7; Z++)
|
|
||||||
{
|
|
||||||
int ChunkX = RangeX + ((X >= 4) ? (3 - X) : X);
|
|
||||||
int ChunkZ = RangeZ + ((Z >= 4) ? (3 - Z) : Z);
|
|
||||||
cChunkCoords Coords(ChunkX, ChunkZ);
|
|
||||||
|
|
||||||
// Checks if the chunk is in distance
|
|
||||||
if ((Diff(ChunkX, ChunkPosX) > m_ViewDistance) || (Diff(ChunkZ, ChunkPosZ) > m_ViewDistance))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the chunk already loading/loaded -> skip
|
|
||||||
if (
|
|
||||||
(std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), Coords) != m_ChunksToSend.end()) ||
|
|
||||||
(std::find(m_LoadedChunks.begin(), m_LoadedChunks.end(), Coords) != m_LoadedChunks.end())
|
|
||||||
)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unloaded chunk found -> Send it to the client.
|
|
||||||
Lock.Unlock();
|
|
||||||
StreamChunk(ChunkX, ChunkZ, cChunkSender::E_CHUNK_PRIORITY_MEDIUM);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Low priority: Add all chunks that are in range. (From the center out to the edge)
|
// Low priority: Add all chunks that are in range. (From the center out to the edge)
|
||||||
for (int d = 0; d <= m_ViewDistance; ++d) // cycle through (square) distance, from nearest to furthest
|
for (int d = 0; d <= m_ViewDistance; ++d) // cycle through (square) distance, from nearest to furthest
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user