Stream 4 chunks per tick. Added priority.
This commit is contained in:
parent
a59f2d15fb
commit
b493beb3bb
@ -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:
|
||||
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
m_World->ForceSendChunkTo(m_PosX, m_PosZ, (*itr));
|
||||
m_World->ForceSendChunkTo(m_PosX, m_PosZ, cChunkSender::E_CHUNK_PRIORITY_MEDIUM, (*itr));
|
||||
} // for itr - m_LoadedByClient[]
|
||||
}
|
||||
|
||||
|
@ -91,17 +91,22 @@ 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);
|
||||
{
|
||||
sSendChunk Chunk(a_ChunkX, a_ChunkZ, a_Priority, 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_SendChunks.begin(), m_SendChunks.end(), Chunk) != m_SendChunks.end())
|
||||
{
|
||||
// Already queued, bail out
|
||||
return;
|
||||
}
|
||||
m_SendChunks.push_back(sSendChunk(a_ChunkX, a_ChunkZ, a_Client));
|
||||
m_SendChunks.push_back(Chunk);
|
||||
|
||||
// Sort the list:
|
||||
m_SendChunks.sort();
|
||||
}
|
||||
m_evtQueue.Set();
|
||||
}
|
||||
@ -169,7 +174,7 @@ void cChunkSender::Execute(void)
|
||||
sSendChunk Chunk(m_SendChunks.front());
|
||||
m_SendChunks.pop_front();
|
||||
Lock.Unlock();
|
||||
|
||||
|
||||
SendChunk(Chunk.m_ChunkX, Chunk.m_ChunkZ, Chunk.m_Client);
|
||||
}
|
||||
Lock.Lock();
|
||||
|
@ -75,6 +75,13 @@ class cChunkSender:
|
||||
public:
|
||||
cChunkSender(void);
|
||||
~cChunkSender();
|
||||
|
||||
enum eChunkPriority
|
||||
{
|
||||
E_CHUNK_PRIORITY_HIGH = 0,
|
||||
E_CHUNK_PRIORITY_MEDIUM = 1,
|
||||
E_CHUNK_PRIORITY_LOW = 2,
|
||||
};
|
||||
|
||||
bool Start(cWorld * a_World);
|
||||
|
||||
@ -84,7 +91,7 @@ public:
|
||||
void ChunkReady(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
/// Queues a chunk to be sent to a specific client
|
||||
void QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client);
|
||||
void QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, eChunkPriority a_Priority, cClientHandle * a_Client);
|
||||
|
||||
/// Removes the a_Client from all waiting chunk send operations
|
||||
void RemoveClient(cClientHandle * a_Client);
|
||||
@ -96,11 +103,13 @@ protected:
|
||||
{
|
||||
int m_ChunkX;
|
||||
int m_ChunkZ;
|
||||
eChunkPriority m_Priority;
|
||||
cClientHandle * m_Client;
|
||||
|
||||
sSendChunk(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client) :
|
||||
sSendChunk(int a_ChunkX, int a_ChunkZ, eChunkPriority a_Priority, cClientHandle * a_Client) :
|
||||
m_ChunkX(a_ChunkX),
|
||||
m_ChunkZ(a_ChunkZ),
|
||||
m_Priority(a_Priority),
|
||||
m_Client(a_Client)
|
||||
{
|
||||
}
|
||||
@ -113,6 +122,11 @@ protected:
|
||||
(a_Other.m_Client == m_Client)
|
||||
);
|
||||
}
|
||||
|
||||
bool operator < (const sSendChunk & a_Other)
|
||||
{
|
||||
return (m_Priority < a_Other.m_Priority);
|
||||
}
|
||||
} ;
|
||||
typedef std::list<sSendChunk> sSendChunkList;
|
||||
|
||||
|
@ -402,11 +402,11 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID,
|
||||
|
||||
|
||||
|
||||
void cClientHandle::StreamNextChunk(void)
|
||||
bool cClientHandle::StreamNextChunk(void)
|
||||
{
|
||||
if ((m_State < csAuthenticated) || (m_State >= csDestroying))
|
||||
{
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
ASSERT(m_Player != NULL);
|
||||
|
||||
@ -415,7 +415,7 @@ void cClientHandle::StreamNextChunk(void)
|
||||
if ((m_LastStreamedChunkX == ChunkPosX) && (m_LastStreamedChunkZ == ChunkPosZ))
|
||||
{
|
||||
// All chunks are already loaded. Abort loading.
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the look vector and normalize it.
|
||||
@ -454,8 +454,8 @@ void cClientHandle::StreamNextChunk(void)
|
||||
|
||||
// Unloaded chunk found -> Send it to the client.
|
||||
Lock.Unlock();
|
||||
StreamChunk(ChunkX, ChunkZ);
|
||||
return;
|
||||
StreamChunk(ChunkX, ChunkZ, cChunkSender::E_CHUNK_PRIORITY_HIGH);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -489,8 +489,8 @@ void cClientHandle::StreamNextChunk(void)
|
||||
|
||||
// Unloaded chunk found -> Send it to the client.
|
||||
Lock.Unlock();
|
||||
StreamChunk(ChunkX, ChunkZ);
|
||||
return;
|
||||
StreamChunk(ChunkX, ChunkZ, cChunkSender::E_CHUNK_PRIORITY_MEDIUM);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -527,14 +527,15 @@ void cClientHandle::StreamNextChunk(void)
|
||||
|
||||
// Unloaded chunk found -> Send it to the client.
|
||||
Lock.Unlock();
|
||||
StreamChunk(Coords.m_ChunkX, Coords.m_ChunkZ);
|
||||
return;
|
||||
StreamChunk(Coords.m_ChunkX, Coords.m_ChunkZ, cChunkSender::E_CHUNK_PRIORITY_LOW);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// All chunks are loaded -> Sets the last loaded chunk coordinates to current coordinates
|
||||
m_LastStreamedChunkX = ChunkPosX;
|
||||
m_LastStreamedChunkZ = ChunkPosZ;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -590,7 +591,7 @@ void cClientHandle::UnloadOutOfRangeChunks(void)
|
||||
|
||||
|
||||
|
||||
void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkZ)
|
||||
void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkZ, cChunkSender::eChunkPriority a_Priority)
|
||||
{
|
||||
if (m_State >= csDestroying)
|
||||
{
|
||||
@ -608,7 +609,7 @@ void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkZ)
|
||||
m_LoadedChunks.push_back(cChunkCoords(a_ChunkX, a_ChunkZ));
|
||||
m_ChunksToSend.push_back(cChunkCoords(a_ChunkX, a_ChunkZ));
|
||||
}
|
||||
World->SendChunkTo(a_ChunkX, a_ChunkZ, this);
|
||||
World->SendChunkTo(a_ChunkX, a_ChunkZ, a_Priority, this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2028,8 +2029,16 @@ void cClientHandle::Tick(float a_Dt)
|
||||
|
||||
if ((m_State >= csAuthenticated) && (m_State < csDestroying))
|
||||
{
|
||||
|
||||
StreamNextChunk(); // Streams the next chunk
|
||||
// Stream 4 chunks per tick
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
// Stream the next chunk
|
||||
if (StreamNextChunk())
|
||||
{
|
||||
// Streaming finished. All chunks are loaded.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Unload all chunks that are out of the view distance (all 5 seconds)
|
||||
if ((m_Player->GetWorld()->GetWorldAge() % 100) == 0)
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "Enchantments.h"
|
||||
#include "UI/SlotArea.h"
|
||||
#include "json/json.h"
|
||||
#include "ChunkSender.h"
|
||||
|
||||
|
||||
|
||||
@ -113,8 +114,8 @@ public:
|
||||
/** Authenticates the specified user, called by cAuthenticator */
|
||||
void Authenticate(const AString & a_Name, const AString & a_UUID, const Json::Value & a_Properties);
|
||||
|
||||
/** This function sends a new unloaded chunk to the player. */
|
||||
void StreamNextChunk(void);
|
||||
/** This function sends a new unloaded chunk to the player. Returns true if all chunks are loaded. */
|
||||
bool StreamNextChunk();
|
||||
|
||||
/** Remove all loaded chunks that are no longer in range */
|
||||
void UnloadOutOfRangeChunks(void);
|
||||
@ -448,7 +449,7 @@ private:
|
||||
bool CheckBlockInteractionsRate(void);
|
||||
|
||||
/** Adds a single chunk to be streamed to the client; used by StreamChunks() */
|
||||
void StreamChunk(int a_ChunkX, int a_ChunkZ);
|
||||
void StreamChunk(int a_ChunkX, int a_ChunkZ, cChunkSender::eChunkPriority a_Priority);
|
||||
|
||||
/** Handles the DIG_STARTED dig packet: */
|
||||
void HandleBlockDigStarted (int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta);
|
||||
|
@ -2850,19 +2850,19 @@ void cWorld::RemoveClientFromChunks(cClientHandle * a_Client)
|
||||
|
||||
|
||||
|
||||
void cWorld::SendChunkTo(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client)
|
||||
void cWorld::SendChunkTo(int a_ChunkX, int a_ChunkZ, cChunkSender::eChunkPriority a_Priority, cClientHandle * a_Client)
|
||||
{
|
||||
m_ChunkSender.QueueSendChunkTo(a_ChunkX, a_ChunkZ, a_Client);
|
||||
m_ChunkSender.QueueSendChunkTo(a_ChunkX, a_ChunkZ, a_Priority, a_Client);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::ForceSendChunkTo(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client)
|
||||
void cWorld::ForceSendChunkTo(int a_ChunkX, int a_ChunkZ, cChunkSender::eChunkPriority a_Priority, cClientHandle * a_Client)
|
||||
{
|
||||
a_Client->AddWantedChunk(a_ChunkX, a_ChunkZ);
|
||||
m_ChunkSender.QueueSendChunkTo(a_ChunkX, a_ChunkZ, a_Client);
|
||||
m_ChunkSender.QueueSendChunkTo(a_ChunkX, a_ChunkZ, a_Priority, a_Client);
|
||||
}
|
||||
|
||||
|
||||
|
@ -359,11 +359,11 @@ public:
|
||||
|
||||
/** Sends the chunk to the client specified, if the client doesn't have the chunk yet.
|
||||
If chunk not valid, the request is postponed (ChunkSender will send that chunk when it becomes valid + lighted). */
|
||||
void SendChunkTo(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client);
|
||||
void SendChunkTo(int a_ChunkX, int a_ChunkZ, cChunkSender::eChunkPriority a_Priority, cClientHandle * a_Client);
|
||||
|
||||
/** Sends the chunk to the client specified, even if the client already has the chunk.
|
||||
If the chunk's not valid, the request is postponed (ChunkSender will send that chunk when it becomes valid + lighted). */
|
||||
void ForceSendChunkTo(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client);
|
||||
void ForceSendChunkTo(int a_ChunkX, int a_ChunkZ, cChunkSender::eChunkPriority a_Priority, cClientHandle * a_Client);
|
||||
|
||||
/** Removes client from ChunkSender's queue of chunks to be sent */
|
||||
void RemoveClientFromChunkSender(cClientHandle * a_Client);
|
||||
|
Loading…
Reference in New Issue
Block a user