1
0

Merge pull request #3149 from LogicParrot/meta

Reduced unnecessary block updates and some code cleanup
This commit is contained in:
LogicParrot 2016-04-23 01:28:25 +03:00
commit 932c59ee38
16 changed files with 54 additions and 91 deletions

View File

@ -70,7 +70,7 @@ bool cChestEntity::UsedBy(cPlayer * a_Player)
// The few false positives aren't much to worry about
int ChunkX, ChunkZ;
cChunkDef::BlockToChunk(m_PosX, m_PosZ, ChunkX, ChunkZ);
m_World->MarkChunkDirty(ChunkX, ChunkZ, true);
m_World->MarkChunkDirty(ChunkX, ChunkZ);
return true;
}

View File

@ -67,7 +67,6 @@ private:
}
m_World->MarkChunkDirty(GetChunkX(), GetChunkZ());
m_World->MarkRedstoneDirty(GetChunkX(), GetChunkZ());
}
}

View File

@ -600,10 +600,6 @@ enum
E_META_LOG_BIRCH = 2,
E_META_LOG_JUNGLE = 3,
// E_BLOCK_NEW_LEAVES metas:
E_META_NEW_LEAVES_ACACIA_WOOD = 0,
E_META_NEW_LEAVES_DARK_OAK_WOOD = 1,
// E_BLOCK_NEW_LOG metas:
E_META_NEW_LOG_ACACIA_WOOD = 0,
E_META_NEW_LOG_DARK_OAK_WOOD = 1,

View File

@ -33,7 +33,7 @@ public:
// Set p the ON bit to on
Meta |= 0x08;
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta, false);
a_WorldInterface.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
a_WorldInterface.GetBroadcastManager().BroadcastSoundEffect("random.click", x, y, z, 0.5f, 0.6f);
@ -44,7 +44,7 @@ public:
if (a_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == m_BlockType)
{
// Block hasn't change in the meantime; set its meta
a_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x07);
a_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x07, false);
a_World.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
a_World.BroadcastSoundEffect("random.click", x, y, z, 0.5f, 0.5f);
}

View File

@ -75,11 +75,12 @@ public:
virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_WhichNeighbor) override
{
// Unset 0x8 bit so this block gets checked for decay:
NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
if ((Meta & 0x08) != 0)
// Set 0x8 bit so this block gets checked for decay:
if ((Meta & 0x08) == 0)
{
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta & 0x7, false, false);
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta | 0x8, true, false);
}
}
@ -92,7 +93,7 @@ public:
return;
}
if ((Meta & 0x8) != 0)
if ((Meta & 0x8) == 0)
{
// These leaves have been checked for decay lately and nothing around them changed
return;
@ -116,10 +117,8 @@ public:
if (HasNearLog(Area, BlockX, a_RelY, BlockZ))
{
// Wood found, the leaves stay; mark them as checked.
// There is no point in saving this to disk or informing the client
// So we use SetMetaQuiet
a_Chunk.SetMeta(a_RelX, a_RelY, a_RelZ, Meta | 0x8, false, false);
// Wood found, the leaves stay; unset the check bit
a_Chunk.SetMeta(a_RelX, a_RelY, a_RelZ, Meta ^ 0x8, true, false);
return;
}

View File

@ -95,7 +95,6 @@ cChunk::cChunk(
m_WaterSimulatorData(a_World->GetWaterSimulator()->CreateChunkData()),
m_LavaSimulatorData (a_World->GetLavaSimulator ()->CreateChunkData()),
m_RedstoneSimulatorData(a_World->GetRedstoneSimulator()->CreateChunkData()),
m_IsRedstoneDirty(false),
m_AlwaysTicked(0)
{
if (a_NeighborXM != nullptr)
@ -1536,8 +1535,17 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT
return;
}
MarkDirty();
m_IsRedstoneDirty = true;
bool ReplacingLiquids = (
((OldBlockType == E_BLOCK_STATIONARY_WATER) && (a_BlockType == E_BLOCK_WATER)) || // Replacing stationary water with water
((OldBlockType == E_BLOCK_WATER) && (a_BlockType == E_BLOCK_STATIONARY_WATER)) || // Replacing water with stationary water
((OldBlockType == E_BLOCK_STATIONARY_LAVA) && (a_BlockType == E_BLOCK_LAVA)) || // Replacing stationary lava with lava
((OldBlockType == E_BLOCK_LAVA) && (a_BlockType == E_BLOCK_STATIONARY_LAVA)) // Replacing lava with stationary lava
);
if (!ReplacingLiquids)
{
MarkDirty();
}
m_ChunkData.SetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType);
@ -1550,13 +1558,7 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT
((OldBlockType == E_BLOCK_NEW_LEAVES) && (a_BlockType == E_BLOCK_NEW_LEAVES))
) && // ... AND ...
(
(OldBlockMeta != a_BlockMeta) || // ... the meta value is different OR ...
!( // ... the old and new blocktypes AREN'T liquids (because client doesn't need to distinguish betwixt them):
((OldBlockType == E_BLOCK_STATIONARY_WATER) && (a_BlockType == E_BLOCK_WATER)) || // Replacing stationary water with water
((OldBlockType == E_BLOCK_WATER) && (a_BlockType == E_BLOCK_STATIONARY_WATER)) || // Replacing water with stationary water
((OldBlockType == E_BLOCK_STATIONARY_LAVA) && (a_BlockType == E_BLOCK_LAVA)) || // Replacing stationary water with water
((OldBlockType == E_BLOCK_LAVA) && (a_BlockType == E_BLOCK_STATIONARY_LAVA)) // Replacing water with stationary water
)
(OldBlockMeta != a_BlockMeta) || (!ReplacingLiquids)
)
)
)

View File

@ -401,7 +401,6 @@ public:
bool hasChanged = m_ChunkData.SetMeta(a_RelX, a_RelY, a_RelZ, a_Meta);
if (hasChanged)
{
m_IsRedstoneDirty = true;
if (a_ShouldMarkDirty)
{
MarkDirty();
@ -462,8 +461,6 @@ public:
cRedstoneSimulatorChunkData * GetRedstoneSimulatorData(void) { return m_RedstoneSimulatorData; }
void SetRedstoneSimulatorData(cRedstoneSimulatorChunkData * a_Data) { m_RedstoneSimulatorData = a_Data; }
bool IsRedstoneDirty(void) const { return m_IsRedstoneDirty; }
void SetIsRedstoneDirty(bool a_Flag) { m_IsRedstoneDirty = a_Flag; }
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); }
@ -551,10 +548,6 @@ private:
cRedstoneSimulatorChunkData * m_RedstoneSimulatorData;
/** 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. */

View File

@ -859,22 +859,7 @@ void cChunkMap::WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_M
void cChunkMap::MarkRedstoneDirty(int a_ChunkX, int a_ChunkZ)
{
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ);
if ((Chunk == nullptr) || !Chunk->IsValid())
{
return;
}
Chunk->SetIsRedstoneDirty(true);
}
void cChunkMap::MarkChunkDirty(int a_ChunkX, int a_ChunkZ, bool a_MarkRedstoneDirty)
void cChunkMap::MarkChunkDirty(int a_ChunkX, int a_ChunkZ)
{
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ);
@ -883,10 +868,6 @@ void cChunkMap::MarkChunkDirty(int a_ChunkX, int a_ChunkZ, bool a_MarkRedstoneDi
return;
}
Chunk->MarkDirty();
if (a_MarkRedstoneDirty)
{
Chunk->SetIsRedstoneDirty(true);
}
}

View File

@ -116,8 +116,7 @@ public:
/** Wakes up the simulators for the specified area of blocks */
void WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ);
void MarkRedstoneDirty (int a_ChunkX, int a_ChunkZ);
void MarkChunkDirty (int a_ChunkX, int a_ChunkZ, bool a_MarkRedstoneDirty = false);
void MarkChunkDirty (int a_ChunkX, int a_ChunkZ);
void MarkChunkSaving (int a_ChunkX, int a_ChunkZ);
void MarkChunkSaved (int a_ChunkX, int a_ChunkZ);

View File

@ -86,8 +86,8 @@ void cBioGenCache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a
{
if (((m_NumHits + m_NumMisses) % 1024) == 10)
{
LOGD("BioGenCache: %u hits, %u misses, saved %.2f %%", static_cast<unsigned>(m_NumHits), static_cast<unsigned>(m_NumMisses), 100.0 * m_NumHits / (m_NumHits + m_NumMisses));
LOGD("BioGenCache: Avg cache chain length: %.2f", static_cast<double>(m_TotalChain) / m_NumHits);
// LOGD("BioGenCache: %u hits, %u misses, saved %.2f %%", static_cast<unsigned>(m_NumHits), static_cast<unsigned>(m_NumMisses), 100.0 * m_NumHits / (m_NumHits + m_NumMisses));
// LOGD("BioGenCache: Avg cache chain length: %.2f", static_cast<double>(m_TotalChain) / m_NumHits);
}
for (size_t i = 0; i < m_CacheSize; i++)

View File

@ -209,10 +209,10 @@ void cChunkGenerator::Execute(void)
{
if ((NumChunksGenerated > 16) && (clock() - LastReportTick > CLOCKS_PER_SEC))
{
LOG("Chunk generator performance: %.2f ch / sec (%d ch total)",
/* LOG("Chunk generator performance: %.2f ch / sec (%d ch total)",
static_cast<double>(NumChunksGenerated) * CLOCKS_PER_SEC/ (clock() - GenerationStart),
NumChunksGenerated
);
); */
}
cCSUnlock Unlock(Lock);
m_Event.Wait();
@ -239,7 +239,7 @@ void cChunkGenerator::Execute(void)
m_evtRemoved.Set();
// Display perf info once in a while:
if ((NumChunksGenerated > 16) && (clock() - LastReportTick > 2 * CLOCKS_PER_SEC))
if ((NumChunksGenerated > 512) && (clock() - LastReportTick > 2 * CLOCKS_PER_SEC))
{
LOG("Chunk generator performance: %.2f ch / sec (%d ch total)",
static_cast<double>(NumChunksGenerated) * CLOCKS_PER_SEC / (clock() - GenerationStart),
@ -271,7 +271,7 @@ void cChunkGenerator::Execute(void)
}
// Generate the chunk:
LOGD("Generating chunk [%d, %d]", item.m_ChunkX, item.m_ChunkZ);
// LOGD("Generating chunk [%d, %d]", item.m_ChunkX, item.m_ChunkZ);
DoGenerate(item.m_ChunkX, item.m_ChunkZ);
if (item.m_Callback != nullptr)
{

View File

@ -376,8 +376,8 @@ void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::
#ifdef _DEBUG
if (((m_NumHits + m_NumMisses) % 1024) == 10)
{
LOGD("CompoGenCache: %d hits, %d misses, saved %.2f %%", m_NumHits, m_NumMisses, 100.0 * m_NumHits / (m_NumHits + m_NumMisses));
LOGD("CompoGenCache: Avg cache chain length: %.2f", static_cast<float>(m_TotalChain) / m_NumHits);
// LOGD("CompoGenCache: %d hits, %d misses, saved %.2f %%", m_NumHits, m_NumMisses, 100.0 * m_NumHits / (m_NumHits + m_NumMisses));
// LOGD("CompoGenCache: Avg cache chain length: %.2f", static_cast<float>(m_TotalChain) / m_NumHits);
}
#endif // _DEBUG

View File

@ -183,6 +183,14 @@ void cStructGenTrees::ApplyTreeImage(
CASE_TREE_OVERWRITTEN_BLOCKS:
{
a_ChunkDesc.SetBlockTypeMeta(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta);
// If grass is below our tree, turn it to dirt
if (
(cBlockInfo::IsSolid(itr->m_BlockType)) &&
(a_ChunkDesc.GetBlockType(itr->m_RelX, itr->m_RelY - 1, itr->m_RelZ) == E_BLOCK_GRASS)
)
{
a_ChunkDesc.SetBlockType(itr->m_RelX, itr->m_RelY - 1, itr->m_RelZ, E_BLOCK_DIRT);
}
break;
}

View File

@ -551,9 +551,9 @@ void GetAcaciaTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noi
}
// Add the leaves to the top of the branch
PushCoordBlocks(BranchPos.x, BranchPos.y, BranchPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD);
PushCoordBlocks(BranchPos.x, BranchPos.y + 1, BranchPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD);
a_OtherBlocks.push_back(sSetBlock(BranchPos.x, BranchPos.y + 1, BranchPos.z, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD));
PushCoordBlocks(BranchPos.x, BranchPos.y, BranchPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_ACACIA);
PushCoordBlocks(BranchPos.x, BranchPos.y + 1, BranchPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_ACACIA);
a_OtherBlocks.push_back(sSetBlock(BranchPos.x, BranchPos.y + 1, BranchPos.z, E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_ACACIA));
// Choose if we have to add another branch
bool TwoTop = (a_Noise.IntNoise3D(a_BlockX, a_BlockY, a_BlockZ) < 0 ? true : false);
@ -579,9 +579,9 @@ void GetAcaciaTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noi
}
// And add the leaves ontop of the second branch
PushCoordBlocks(BranchPos.x, BranchPos.y, BranchPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD);
PushCoordBlocks(BranchPos.x, BranchPos.y + 1, BranchPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD);
a_OtherBlocks.push_back(sSetBlock(BranchPos.x, BranchPos.y + 1, BranchPos.z, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD));
PushCoordBlocks(BranchPos.x, BranchPos.y, BranchPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_ACACIA);
PushCoordBlocks(BranchPos.x, BranchPos.y + 1, BranchPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_ACACIA);
a_OtherBlocks.push_back(sSetBlock(BranchPos.x, BranchPos.y + 1, BranchPos.z, E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_ACACIA));
}
@ -635,15 +635,15 @@ void GetDarkoakTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No
// The lower two leaves layers are BigO4 with log in the middle and possibly corners:
for (int i = 0; i < 2; i++)
{
PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO4, ARRAYCOUNT(BigO4), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD);
PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD);
PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO4, ARRAYCOUNT(BigO4), E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_DARK_OAK);
PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_DARK_OAK);
hei++;
} // for i < 2
// The top leaves layer is a BigO3 with leaves in the middle and possibly corners:
PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD);
PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD);
a_OtherBlocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD));
PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_DARK_OAK);
PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_DARK_OAK);
a_OtherBlocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_DARK_OAK));
}
@ -1125,7 +1125,3 @@ bool GetLargeTreeAdjustment(cWorld & a_World, int & a_X, int & a_Y, int & a_Z, N
return IsLarge;
}

View File

@ -2706,18 +2706,9 @@ void cWorld::SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClientHa
void cWorld::MarkRedstoneDirty(int a_ChunkX, int a_ChunkZ)
void cWorld::MarkChunkDirty(int a_ChunkX, int a_ChunkZ)
{
m_ChunkMap->MarkRedstoneDirty(a_ChunkX, a_ChunkZ);
}
void cWorld::MarkChunkDirty(int a_ChunkX, int a_ChunkZ, bool a_MarkRedstoneDirty)
{
m_ChunkMap->MarkChunkDirty(a_ChunkX, a_ChunkZ, a_MarkRedstoneDirty);
m_ChunkMap->MarkChunkDirty(a_ChunkX, a_ChunkZ);
}

View File

@ -227,8 +227,7 @@ public:
/** If there is a block entity at the specified coords, sends it to the client specified */
void SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle & a_Client);
void MarkRedstoneDirty(int a_ChunkX, int a_ChunkZ);
void MarkChunkDirty (int a_ChunkX, int a_ChunkZ, bool a_MarkRedstoneDirty = false);
void MarkChunkDirty (int a_ChunkX, int a_ChunkZ);
void MarkChunkSaving(int a_ChunkX, int a_ChunkZ);
void MarkChunkSaved (int a_ChunkX, int a_ChunkZ);