1
0
Fork 0

Implemented support for forced chunk ticking.

Fixes #1160.
This commit is contained in:
madmaxoft 2014-07-10 18:18:32 +02:00
parent e4828f0072
commit 9e22f46b15
6 changed files with 95 additions and 8 deletions

View File

@ -87,7 +87,8 @@ cChunk::cChunk(
m_NeighborZM(a_NeighborZM),
m_NeighborZP(a_NeighborZP),
m_WaterSimulatorData(a_World->GetWaterSimulator()->CreateChunkData()),
m_LavaSimulatorData (a_World->GetLavaSimulator ()->CreateChunkData())
m_LavaSimulatorData (a_World->GetLavaSimulator ()->CreateChunkData()),
m_AlwaysTicked(0)
{
if (a_NeighborXM != NULL)
{
@ -1641,6 +1642,31 @@ cBlockEntity * cChunk::GetBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ)
bool cChunk::ShouldBeTicked(void) const
{
return (HasAnyClients() || (m_AlwaysTicked > 0));
}
void cChunk::SetAlwaysTicked(bool a_AlwaysTicked)
{
if (a_AlwaysTicked)
{
m_AlwaysTicked += 1;
}
else
{
m_AlwaysTicked -= 1;
}
}
void cChunk::UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z)
{
cBlockEntity * be = GetBlockEntity(a_X, a_Y, a_Z);
@ -1852,7 +1878,7 @@ bool cChunk::HasClient( cClientHandle* a_Client )
bool cChunk::HasAnyClients(void)
bool cChunk::HasAnyClients(void) const
{
return !m_LoadedByClient.empty();
}

View File

@ -200,11 +200,16 @@ public:
void SendBlockTo(int a_RelX, int a_RelY, int a_RelZ, cClientHandle * a_Client);
/** Adds a client to the chunk; returns true if added, false if already there */
bool AddClient (cClientHandle* a_Client );
bool AddClient(cClientHandle * a_Client);
void RemoveClient (cClientHandle* a_Client );
bool HasClient (cClientHandle* a_Client );
bool HasAnyClients(void); // Returns true if theres any client in the chunk; false otherwise
/** Removes the specified client from the chunk; ignored if client not in chunk. */
void RemoveClient(cClientHandle * a_Client);
/** Returns true if the specified client is present in this chunk. */
bool HasClient(cClientHandle * a_Client);
/** Returns true if theres any client in the chunk; false otherwise */
bool HasAnyClients(void) const;
void AddEntity(cEntity * a_Entity);
void RemoveEntity(cEntity * a_Entity);
@ -390,6 +395,17 @@ public:
cBlockEntity * GetBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ);
cBlockEntity * GetBlockEntity(const Vector3i & a_BlockPos) { return GetBlockEntity(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z); }
/** Returns true if the chunk should be ticked in the tick-thread.
Checks if there are any clients and if the always-tick flag is set */
bool ShouldBeTicked(void) const;
/** Increments (a_AlwaysTicked == true) or decrements (false) the m_AlwaysTicked counter.
If the m_AlwaysTicked counter is greater than zero, the chunk is ticked in the tick-thread regardless of
whether it has any clients or not.
This function allows nesting and task-concurrency (multiple separate tasks can request ticking and as long
as at least one requests is active the chunk will be ticked). */
void SetAlwaysTicked(bool a_AlwaysTicked);
private:
@ -462,6 +478,12 @@ private:
/** Indicates if simulate-once blocks should be updated by the redstone simulator */
bool m_IsRedstoneDirty;
/** If greater than zero, the chunk is ticked even if it has no clients.
Manipulated by the SetAlwaysTicked() function, allows for nested calls of the function.
This is the support for plugin-accessible chunk tick forcing. */
int m_AlwaysTicked;
// Pick up a random block of this chunk
void getRandomBlockCoords(int& a_X, int& a_Y, int& a_Z);

View File

@ -2674,6 +2674,20 @@ void cChunkMap::QueueTickBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
void cChunkMap::SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicked)
{
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
if (Chunk != NULL)
{
Chunk->SetAlwaysTicked(a_AlwaysTicked);
}
}
////////////////////////////////////////////////////////////////////////////////
// cChunkMap::cChunkLayer:
@ -2788,12 +2802,14 @@ void cChunkMap::cChunkLayer::SpawnMobs(cMobSpawner& a_MobSpawner)
void cChunkMap::cChunkLayer::Tick(float a_Dt)
{
for (size_t i = 0; i < ARRAYCOUNT(m_Chunks); i++)
{
// Only tick chunks that are valid and have clients:
if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->HasAnyClients())
// Only tick chunks that are valid and should be ticked:
if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->ShouldBeTicked())
{
m_Chunks[i]->Tick(a_Dt);
}

View File

@ -339,6 +339,13 @@ public:
/** Returns the CS for locking the chunkmap; only cWorld::cLock may use this function! */
cCriticalSection & GetCS(void) { return m_CSLayers; }
/** Increments (a_AlwaysTicked == true) or decrements (false) the m_AlwaysTicked counter for the specified chunk.
If the m_AlwaysTicked counter is greater than zero, the chunk is ticked in the tick-thread regardless of
whether it has any clients or not.
This function allows nesting and task-concurrency (multiple separate tasks can request ticking and as long
as at least one requests is active the chunk will be ticked). */
void SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicked);
private:

View File

@ -3033,6 +3033,15 @@ void cWorld::TabCompleteUserName(const AString & a_Text, AStringVector & a_Resul
void cWorld::SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicked)
{
m_ChunkMap->SetChunkAlwaysTicked(a_ChunkX, a_ChunkZ, a_AlwaysTicked);
}
cRedstoneSimulator * cWorld::InitializeRedstoneSimulator(cIniFile & a_IniFile)
{
AString SimulatorName = a_IniFile.GetValueSet("Physics", "RedstoneSimulator", "");

View File

@ -772,6 +772,13 @@ public:
/** Get the current darkness level based on the time */
NIBBLETYPE GetSkyDarkness() { return m_SkyDarkness; }
/** Increments (a_AlwaysTicked == true) or decrements (false) the m_AlwaysTicked counter for the specified chunk.
If the m_AlwaysTicked counter is greater than zero, the chunk is ticked in the tick-thread regardless of
whether it has any clients or not.
This function allows nesting and task-concurrency (multiple separate tasks can request ticking and as long
as at least one requests is active the chunk will be ticked). */
void SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicked = true); // tolua_export
private: