1
0
Fork 0

cWorld Threads: Seperate initialization and thread start.

Prevents nullptr dereferences before Start has been called.
This commit is contained in:
peterbell10 2017-09-22 17:16:47 +01:00 committed by Mattes D
parent 1537ebed6f
commit c54bf40ef9
6 changed files with 17 additions and 32 deletions

View File

@ -88,9 +88,9 @@ public:
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cLightingThread: // cLightingThread:
cLightingThread::cLightingThread(void) : cLightingThread::cLightingThread(cWorld & a_World):
super("cLightingThread"), super("cLightingThread"),
m_World(nullptr), m_World(a_World),
m_MaxHeight(0), m_MaxHeight(0),
m_NumSeeds(0) m_NumSeeds(0)
{ {
@ -109,18 +109,6 @@ cLightingThread::~cLightingThread()
bool cLightingThread::Start(cWorld * a_World)
{
ASSERT(m_World == nullptr); // Not started yet
m_World = a_World;
return super::Start();
}
void cLightingThread::Stop(void) void cLightingThread::Stop(void)
{ {
{ {
@ -150,8 +138,6 @@ void cLightingThread::Stop(void)
void cLightingThread::QueueChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr<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, std::move(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 // The ChunkStay will enqueue itself using the QueueChunkStay() once it is fully loaded
@ -159,7 +145,7 @@ void cLightingThread::QueueChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr<cCh
cCSLock Lock(m_CS); cCSLock Lock(m_CS);
m_PendingQueue.push_back(ChunkStay); m_PendingQueue.push_back(ChunkStay);
} }
ChunkStay->Enable(*m_World->GetChunkMap()); ChunkStay->Enable(*m_World.GetChunkMap());
} }
@ -238,7 +224,7 @@ void cLightingThread::Execute(void)
void cLightingThread::LightChunk(cLightingChunkStay & a_Item) void cLightingThread::LightChunk(cLightingChunkStay & a_Item)
{ {
// If the chunk is already lit, skip it (report as success): // If the chunk is already lit, skip it (report as success):
if (m_World->IsChunkLighted(a_Item.m_ChunkX, a_Item.m_ChunkZ)) if (m_World.IsChunkLighted(a_Item.m_ChunkX, a_Item.m_ChunkZ))
{ {
if (a_Item.m_CallbackAfter != nullptr) if (a_Item.m_CallbackAfter != nullptr)
{ {
@ -319,7 +305,7 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item)
CompressLight(m_BlockLight, BlockLight); CompressLight(m_BlockLight, BlockLight);
CompressLight(m_SkyLight, SkyLight); CompressLight(m_SkyLight, SkyLight);
m_World->ChunkLighted(a_Item.m_ChunkX, a_Item.m_ChunkZ, BlockLight, SkyLight); m_World.ChunkLighted(a_Item.m_ChunkX, a_Item.m_ChunkZ, BlockLight, SkyLight);
if (a_Item.m_CallbackAfter != nullptr) if (a_Item.m_CallbackAfter != nullptr)
{ {
@ -341,7 +327,7 @@ void cLightingThread::ReadChunks(int a_ChunkX, int a_ChunkZ)
for (int x = 0; x < 3; x++) for (int x = 0; x < 3; x++)
{ {
Reader.m_ReadingChunkX = x; Reader.m_ReadingChunkX = x;
VERIFY(m_World->GetChunkData(a_ChunkX + x - 1, a_ChunkZ + z - 1, Reader)); VERIFY(m_World.GetChunkData(a_ChunkX + x - 1, a_ChunkZ + z - 1, Reader));
} // for z } // for z
} // for x } // for x

View File

@ -52,11 +52,9 @@ class cLightingThread :
public: public:
cLightingThread(void); cLightingThread(cWorld & a_World);
virtual ~cLightingThread() override; virtual ~cLightingThread() override;
bool Start(cWorld * a_World);
void Stop(void); void Stop(void);
/** Queues the entire chunk for lighting. /** Queues the entire chunk for lighting.
@ -94,7 +92,7 @@ protected:
typedef std::list<cChunkStay *> cChunkStays; typedef std::list<cChunkStay *> cChunkStays;
cWorld * m_World; cWorld & m_World;
/** The mutex to protect m_Queue and m_PendingQueue */ /** The mutex to protect m_Queue and m_PendingQueue */
cCriticalSection m_CS; cCriticalSection m_CS;

View File

@ -196,6 +196,7 @@ cWorld::cWorld(
m_MapManager(this), m_MapManager(this),
m_GeneratorCallbacks(*this), m_GeneratorCallbacks(*this),
m_ChunkSender(*this), m_ChunkSender(*this),
m_Lighting(*this),
m_TickThread(*this) m_TickThread(*this)
{ {
LOGD("cWorld::cWorld(\"%s\")", a_WorldName.c_str()); LOGD("cWorld::cWorld(\"%s\")", a_WorldName.c_str());
@ -405,6 +406,7 @@ cWorld::cWorld(
m_SimulatorManager->RegisterSimulator(m_SandSimulator.get(), 1); m_SimulatorManager->RegisterSimulator(m_SandSimulator.get(), 1);
m_SimulatorManager->RegisterSimulator(m_FireSimulator.get(), 1); m_SimulatorManager->RegisterSimulator(m_FireSimulator.get(), 1);
m_Storage.Initialize(*this, m_StorageSchema, m_StorageCompressionFactor);
m_Generator.Initialize(m_GeneratorCallbacks, m_GeneratorCallbacks, IniFile); m_Generator.Initialize(m_GeneratorCallbacks, m_GeneratorCallbacks, IniFile);
m_MapManager.LoadMapData(); m_MapManager.LoadMapData();
@ -607,8 +609,8 @@ void cWorld::InitializeSpawn(void)
void cWorld::Start() void cWorld::Start()
{ {
m_Lighting.Start(this); m_Lighting.Start();
m_Storage.Start(this, m_StorageSchema, m_StorageCompressionFactor); m_Storage.Start();
m_Generator.Start(); m_Generator.Start();
m_ChunkSender.Start(); m_ChunkSender.Start();
m_TickThread.Start(); m_TickThread.Start();

View File

@ -962,7 +962,7 @@ private:
cCriticalSection m_CSPlayers; cCriticalSection m_CSPlayers;
cPlayerList m_Players; cPlayerList m_Players;
cWorldStorage m_Storage; cWorldStorage m_Storage;
unsigned int m_MaxPlayers; unsigned int m_MaxPlayers;

View File

@ -60,13 +60,11 @@ cWorldStorage::~cWorldStorage()
bool cWorldStorage::Start(cWorld * a_World, const AString & a_StorageSchemaName, int a_StorageCompressionFactor) void cWorldStorage::Initialize(cWorld & a_World, const AString & a_StorageSchemaName, int a_StorageCompressionFactor)
{ {
m_World = a_World; m_World = &a_World;
m_StorageSchemaName = a_StorageSchemaName; m_StorageSchemaName = a_StorageSchemaName;
InitSchemas(a_StorageCompressionFactor); InitSchemas(a_StorageCompressionFactor);
return super::Start();
} }

View File

@ -69,7 +69,8 @@ public:
The callback, if specified, will be called with the result of the save operation. */ The callback, if specified, will be called with the result of the save operation. */
void QueueSaveChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback = nullptr); void QueueSaveChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback = nullptr);
bool Start(cWorld * a_World, const AString & a_StorageSchemaName, int a_StorageCompressionFactor); // Hide the cIsThread's Start() method, we need to provide args /** Initializes the storage schemas, ready to be started. */
void Initialize(cWorld & a_World, const AString & a_StorageSchemaName, int a_StorageCompressionFactor);
void Stop(void); // Hide the cIsThread's Stop() method, we need to signal the event void Stop(void); // Hide the cIsThread's Stop() method, we need to signal the event
void WaitForFinish(void); void WaitForFinish(void);
void WaitForLoadQueueEmpty(void); void WaitForLoadQueueEmpty(void);