From 4d65ffffc0b6f35ac84e310fd4bc9739ea7e0c0a Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Mon, 5 Mar 2012 16:41:57 +0000 Subject: ChunkSender: Chunks are now compressed and sent to clients from a separate threads, proper passive waiting between threads. Not much tested, just appears to work :) git-svn-id: http://mc-server.googlecode.com/svn/trunk@365 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/ChunkSender.cpp | 133 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 source/ChunkSender.cpp (limited to 'source/ChunkSender.cpp') diff --git a/source/ChunkSender.cpp b/source/ChunkSender.cpp new file mode 100644 index 000000000..527db4543 --- /dev/null +++ b/source/ChunkSender.cpp @@ -0,0 +1,133 @@ + +// ChunkSender.cpp + +// Interfaces to the cChunkSender class representing the thread that waits for chunks becoming ready (loaded / generated) and sends them to clients + + + + + +#include "Globals.h" +#include "ChunkSender.h" +#include "cWorld.h" +#include "packets/cPacket_MapChunk.h" +#include "packets/cPacket_PreChunk.h" +#include "cBlockEntity.h" + + + + + +cChunkSender::cChunkSender(void) : + super("ChunkSender"), + m_World(NULL) +{ +} + + + + + +cChunkSender::~cChunkSender() +{ + mShouldTerminate = true; + m_Event.Set(); +} + + + + + +bool cChunkSender::Start(cWorld * a_World) +{ + m_World = a_World; + return super::Start(); +} + + + + + +void cChunkSender::ChunkReady(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + // This is probably never gonna be called twice for the same chunk, and if it is, we don't mind, so we don't check + { + cCSLock Lock(m_CS); + m_ChunksReady.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); + } + m_Event.Set(); +} + + + + + +void cChunkSender::Execute(void) +{ + while (!mShouldTerminate) + { + cCSLock Lock(m_CS); + while (m_ChunksReady.empty()) + { + cCSUnlock Unlock(Lock); + m_Event.Wait(); + if (mShouldTerminate) + { + return; + } + } // while (empty) + + // Take one from the queue: + cChunkCoords Coords(m_ChunksReady.front()); + m_ChunksReady.pop_front(); + Lock.Unlock(); + + ASSERT(m_World != NULL); + + // Send it to anyone waiting: + m_World->GetChunkData(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, this); + cPacket_PreChunk PreChunk(Coords.m_ChunkX, Coords.m_ChunkZ, true); + cPacket_MapChunk MapChunk(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, m_BlockData); + m_World->BroadcastToChunk(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, PreChunk); + m_World->BroadcastToChunk(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, MapChunk); + + // Send entity creation packets: + for (PacketList::iterator itr = m_Packets.begin(); itr != m_Packets.end(); ++itr) + { + m_World->BroadcastToChunk(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, **itr); + delete *itr; + } // for itr - m_Packets + m_Packets.clear(); + + } // while (!mShouldTerminate) +} + + + + + +void cChunkSender::BlockData(const char * a_Data) +{ + memcpy(m_BlockData, a_Data, cChunk::c_BlockDataSize); +} + + + + + +void cChunkSender::BlockEntity(cBlockEntity * a_Entity) +{ + m_Packets.push_back(a_Entity->GetPacket()); +} + + + + +void cChunkSender::Entity(cEntity * a_Entity) +{ + // Nothing needed yet, perhaps in the future when we save entities into chunks we'd like to send them upon load, too ;) +} + + + + -- cgit v1.2.3