1
0

Made cLightingThread own its callbacks

This commit is contained in:
tycho 2015-05-30 11:11:17 +01:00
parent 4feccaa64a
commit 06a74e45e2
11 changed files with 61 additions and 53 deletions

View File

@ -303,10 +303,9 @@ static int tolua_cWorld_PrepareChunk(lua_State * tolua_S)
cLuaState m_LuaState;
cLuaState::cRef m_Callback;
};
cCallback * callback = new cCallback(tolua_S);
// Call the chunk preparation:
world->PrepareChunk(chunkX, chunkZ, callback);
world->PrepareChunk(chunkX, chunkZ, cpp14::make_unique<cCallback>(tolua_S));
return 0;
}

View File

@ -2401,7 +2401,7 @@ void cChunkMap::TouchChunk(int a_ChunkX, int a_ChunkZ)
void cChunkMap::PrepareChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback)
void cChunkMap::PrepareChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr<cChunkCoordCallback> a_Callback)
{
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ);
@ -2409,7 +2409,7 @@ void cChunkMap::PrepareChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a
// If the chunk is not prepared, queue it in the lighting thread, that will do all the needed processing:
if ((Chunk == nullptr) || !Chunk->IsValid() || !Chunk->IsLightValid())
{
m_World->GetLightingThread().QueueChunk(a_ChunkX, a_ChunkZ, a_Callback);
m_World->GetLightingThread().QueueChunk(a_ChunkX, a_ChunkZ, std::move(a_Callback));
return;
}

View File

@ -322,7 +322,7 @@ public:
The specified chunk is queued to be loaded or generated, and lit if needed.
The specified callback is called after the chunk has been prepared. If there's no preparation to do, only the callback is called.
It is legal to call without the callback. */
void PrepareChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallAfter = nullptr); // Lua-accessible
void PrepareChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr<cChunkCoordCallback> a_CallAfter = {}); // Lua-accessible
/** Queues the chunk for generating.
First attempts to load the chunk from the storage. If that fails, queues the chunk for generating.

View File

@ -21,11 +21,22 @@
////////////////////////////////////////////////////////////////////////////////
// cNotifyChunkSender:
void cNotifyChunkSender::Call(int a_ChunkX, int a_ChunkZ)
/// Callback that can be used to notify chunk sender upon another chunkcoord notification
class cNotifyChunkSender :
public cChunkCoordCallback
{
virtual void Call(int a_ChunkX, int a_ChunkZ) override
{
m_ChunkSender->ChunkReady(a_ChunkX, a_ChunkZ);
}
cChunkSender * m_ChunkSender;
public:
cNotifyChunkSender(cChunkSender * a_ChunkSender) : m_ChunkSender(a_ChunkSender) {}
};
@ -36,10 +47,8 @@ void cNotifyChunkSender::Call(int a_ChunkX, int a_ChunkZ)
cChunkSender::cChunkSender(void) :
super("ChunkSender"),
m_World(nullptr),
m_RemoveCount(0),
m_Notify(nullptr)
m_RemoveCount(0)
{
m_Notify.SetChunkSender(this);
}
@ -272,7 +281,7 @@ void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Clien
// 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);
m_World->QueueLightChunk(a_ChunkX, a_ChunkZ, cpp14::make_unique<cNotifyChunkSender>(this));
return;
}

View File

@ -47,26 +47,6 @@ class cChunkSender;
/// Callback that can be used to notify chunk sender upon another chunkcoord notification
class cNotifyChunkSender :
public cChunkCoordCallback
{
virtual void Call(int a_ChunkX, int a_ChunkZ) override;
cChunkSender * m_ChunkSender;
public:
cNotifyChunkSender(cChunkSender * a_ChunkSender) : m_ChunkSender(a_ChunkSender) {}
void SetChunkSender(cChunkSender * a_ChunkSender)
{
m_ChunkSender = a_ChunkSender;
}
} ;
class cChunkSender:
public cIsThread,
public cChunkDataSeparateCollector
@ -150,8 +130,6 @@ protected:
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)
cNotifyChunkSender m_Notify; // Used for chunks that don't have a valid lighting - they will be re-queued after lightcalc
// Data about the chunk that is being sent:
// NOTE that m_BlockData[] is inherited from the cChunkDataCollector
unsigned char m_BiomeMap[cChunkDef::Width * cChunkDef::Width];

View File

@ -149,11 +149,11 @@ void cLightingThread::Stop(void)
void cLightingThread::QueueChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallbackAfter)
void cLightingThread::QueueChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr<cChunkCoordCallback> a_CallbackAfter)
{
ASSERT(m_World != nullptr); // Did you call Start() properly?
cChunkStay * ChunkStay = new cLightingChunkStay(*this, a_ChunkX, a_ChunkZ, a_CallbackAfter);
cChunkStay * ChunkStay = new cLightingChunkStay(*this, a_ChunkX, a_ChunkZ, std::move(a_CallbackAfter));
{
// The ChunkStay will enqueue itself using the QueueChunkStay() once it is fully loaded
// In the meantime, put it into the PendingQueue so that it can be removed when stopping the thread
@ -599,11 +599,11 @@ void cLightingThread::QueueChunkStay(cLightingChunkStay & a_ChunkStay)
////////////////////////////////////////////////////////////////////////////////
// cLightingThread::cLightingChunkStay:
cLightingThread::cLightingChunkStay::cLightingChunkStay(cLightingThread & a_LightingThread, int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallbackAfter) :
cLightingThread::cLightingChunkStay::cLightingChunkStay(cLightingThread & a_LightingThread, int a_ChunkX, int a_ChunkZ, std::unique_ptr<cChunkCoordCallback> a_CallbackAfter) :
m_LightingThread(a_LightingThread),
m_ChunkX(a_ChunkX),
m_ChunkZ(a_ChunkZ),
m_CallbackAfter(a_CallbackAfter)
m_CallbackAfter(std::move(a_CallbackAfter))
{
Add(a_ChunkX + 1, a_ChunkZ + 1);
Add(a_ChunkX + 1, a_ChunkZ);

View File

@ -61,7 +61,7 @@ public:
void Stop(void);
/** Queues the entire chunk for lighting */
void QueueChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallbackAfter = nullptr);
void QueueChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr<cChunkCoordCallback> a_CallbackAfter);
/** Blocks until the queue is empty or the thread is terminated */
void WaitForQueueEmpty(void);
@ -77,9 +77,9 @@ protected:
cLightingThread & m_LightingThread;
int m_ChunkX;
int m_ChunkZ;
cChunkCoordCallback * m_CallbackAfter;
std::unique_ptr<cChunkCoordCallback> m_CallbackAfter;
cLightingChunkStay(cLightingThread & a_LightingThread, int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallbackAfter);
cLightingChunkStay(cLightingThread & a_LightingThread, int a_ChunkX, int a_ChunkZ, std::unique_ptr<cChunkCoordCallback> a_CallbackAfter);
protected:
virtual void OnChunkAvailable(int a_ChunkX, int a_ChunkZ) override

View File

@ -8,6 +8,26 @@
class cSpawnPrepareCallback :
public cChunkCoordCallback
{
public:
cSpawnPrepareCallback(cSpawnPrepare & a_SpawnPrepare) :
m_SpawnPrepare(a_SpawnPrepare)
{
}
protected:
cSpawnPrepare & m_SpawnPrepare;
virtual void Call(int a_ChunkX, int a_ChunkZ) override
{
m_SpawnPrepare.PreparedChunkCallback(a_ChunkX, a_ChunkZ);
}
};
cSpawnPrepare::cSpawnPrepare(cWorld & a_World, int a_SpawnChunkX, int a_SpawnChunkZ, int a_PrepareDistance, int a_FirstIdx):
@ -40,7 +60,7 @@ void cSpawnPrepare::PrepareChunks(cWorld & a_World, int a_SpawnChunkX, int a_Spa
{
int chunkX, chunkZ;
prep.DecodeChunkCoords(i, chunkX, chunkZ);
a_World.PrepareChunk(chunkX, chunkZ, &prep);
a_World.PrepareChunk(chunkX, chunkZ, cpp14::make_unique<cSpawnPrepareCallback>(prep));
} // for i
// Wait for the lighting thread to prepare everything. Event is set in the Call() callback:
@ -69,7 +89,7 @@ void cSpawnPrepare::DecodeChunkCoords(int a_Idx, int & a_ChunkX, int & a_ChunkZ)
void cSpawnPrepare::Call(int a_ChunkX, int a_ChunkZ)
void cSpawnPrepare::PreparedChunkCallback(int a_ChunkX, int a_ChunkZ)
{
// Check if this was the last chunk:
m_NumPrepared += 1;
@ -85,7 +105,7 @@ void cSpawnPrepare::Call(int a_ChunkX, int a_ChunkZ)
{
int chunkX, chunkZ;
DecodeChunkCoords(m_NextIdx, chunkX, chunkZ);
m_World.GetLightingThread().QueueChunk(chunkX, chunkZ, this);
m_World.GetLightingThread().QueueChunk(chunkX, chunkZ, cpp14::make_unique<cSpawnPrepareCallback>(*this));
m_NextIdx += 1;
}

View File

@ -6,8 +6,7 @@ class cWorld;
/** Generates and lights the spawn area of the world. Runs as a separate thread. */
class cSpawnPrepare:
public cChunkCoordCallback
class cSpawnPrepare
{
public:
@ -39,9 +38,12 @@ protected:
cSpawnPrepare(cWorld & a_World, int a_SpawnChunkX, int a_SpawnChunkZ, int a_PrepareDistance, int a_FirstIdx);
virtual void Call(int a_ChunkX, int a_ChunkZ) override;
void PreparedChunkCallback(int a_ChunkX, int a_ChunkZ);
/** Decodes the index into chunk coords. Provides the specific chunk ordering. */
void DecodeChunkCoords(int a_Idx, int & a_ChunkX, int & a_ChunkZ);
friend class cSpawnPrepareCallback;
};

View File

@ -2872,9 +2872,9 @@ void cWorld::TouchChunk(int a_ChunkX, int a_ChunkZ)
void cWorld::PrepareChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallAfter)
void cWorld::PrepareChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr<cChunkCoordCallback> a_CallAfter)
{
m_ChunkMap->PrepareChunk(a_ChunkX, a_ChunkZ, a_CallAfter);
m_ChunkMap->PrepareChunk(a_ChunkX, a_ChunkZ, std::move(a_CallAfter));
}
@ -2998,9 +2998,9 @@ void cWorld::GenerateChunk(int a_ChunkX, int a_ChunkZ)
void cWorld::QueueLightChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback)
void cWorld::QueueLightChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr<cChunkCoordCallback> a_Callback)
{
m_Lighting.QueueChunk(a_ChunkX, a_ChunkZ, a_Callback);
m_Lighting.QueueChunk(a_ChunkX, a_ChunkZ, std::move(a_Callback));
}

View File

@ -385,7 +385,7 @@ public:
The specified chunk is queued to be loaded or generated, and lit if needed.
The specified callback is called after the chunk has been prepared. If there's no preparation to do, only the callback is called.
It is legal to call with no callback. */
void PrepareChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallAfter = nullptr);
void PrepareChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr<cChunkCoordCallback> a_CallAfter = {});
/** Marks the chunk as failed-to-load: */
void ChunkLoadFailed(int a_ChunkX, int a_ChunkZ);
@ -409,7 +409,7 @@ public:
void GenerateChunk(int a_ChunkX, int a_ChunkZ); // tolua_export
/** Queues a chunk for lighting; a_Callback is called after the chunk is lighted */
void QueueLightChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback = nullptr);
void QueueLightChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr<cChunkCoordCallback> a_Callback = {});
bool IsChunkLighted(int a_ChunkX, int a_ChunkZ);