From 99856df6869d32731e6fdcfeb1460297410f5820 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 29 Jul 2020 00:12:45 +0100 Subject: Add WakeUp/AddBlock distinction * WakeUp is for singular changes (block breaking for example). The simulator should check blocks around the position and discover other affected blocks as it sees fit * AddBlock is for when you know a whole area is to be updated; chunk loading, or area wakeups for example + Prepares for correct handling of destroyed blocks after removal of SolidBlockHandler in the redstone simulator --- .../IncrementalRedstoneSimulator.cpp | 93 ++++++++++++---------- 1 file changed, 53 insertions(+), 40 deletions(-) (limited to 'src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp') diff --git a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp index fdcd69069..33c0f9523 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp @@ -128,6 +128,53 @@ std::unique_ptr cIncrementalRedstoneSimulator::CreateComponent +void cIncrementalRedstoneSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) +{ + Super::WakeUp(a_Chunk, a_Position, a_Block); + + auto & ChunkData = *static_cast(a_Chunk.GetRedstoneSimulatorData()); + + // Never update blocks without a handler: + if (GetComponentHandler(a_Block) == nullptr) + { + ChunkData.ErasePowerData(a_Position); + return; + } + + // Only update others if there is a redstone device nearby + for (int x = -1; x < 2; ++x) + { + for (int y = -1; y < 2; ++y) + { + if (!cChunkDef::IsValidHeight(a_Position.y + y)) + { + continue; + } + + for (int z = -1; z < 2; ++z) + { + auto CheckPos = a_Position + Vector3i{ x, y, z }; + BLOCKTYPE Block; + NIBBLETYPE Meta; + + // If we can't read the block, assume it is a mechanism + if ( + !a_Chunk.UnboundedRelGetBlock(CheckPos, Block, Meta) || + IsRedstone(Block) + ) + { + ChunkData.WakeUp(a_Position); + return; + } + } + } + } +} + + + + + void cIncrementalRedstoneSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) { auto & ChunkData = *static_cast(a_Chunk->GetRedstoneSimulatorData()); @@ -224,7 +271,7 @@ void cIncrementalRedstoneSimulator::ProcessWorkItem(cChunk & Chunk, cChunk & Tic -void cIncrementalRedstoneSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk) +void cIncrementalRedstoneSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) { // Can't inspect block, ignore: if ((a_Chunk == nullptr) || !a_Chunk->IsValid()) @@ -236,50 +283,16 @@ void cIncrementalRedstoneSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk) const auto Relative = cChunkDef::AbsoluteToRelative(a_Block, a_Chunk->GetPos()); const auto CurrentBlock = a_Chunk->GetBlock(Relative); - // Always update redstone devices - if (IsRedstone(CurrentBlock)) + if (!IsRedstone(CurrentBlock)) { - if (IsAlwaysTicked(CurrentBlock)) - { - ChunkData.AlwaysTickedPositions.emplace(Relative); - } - ChunkData.WakeUp(Relative); return; } - // Never update blocks without a handler - if (GetComponentHandler(CurrentBlock) == nullptr) + if (IsAlwaysTicked(CurrentBlock)) { - ChunkData.ErasePowerData(Relative); - return; + ChunkData.AlwaysTickedPositions.emplace(Relative); } - // Only update others if there is a redstone device nearby - for (int x = -1; x < 2; ++x) - { - for (int y = -1; y < 2; ++y) - { - if (!cChunkDef::IsValidHeight(Relative.y + y)) - { - continue; - } - - for (int z = -1; z < 2; ++z) - { - auto CheckPos = Relative + Vector3i{x, y, z}; - BLOCKTYPE Block; - NIBBLETYPE Meta; - - // If we can't read the block, assume it is a mechanism - if ( - !a_Chunk->UnboundedRelGetBlock(CheckPos, Block, Meta) || - IsRedstone(Block) - ) - { - ChunkData.WakeUp(Relative); - return; - } - } - } - } + // Always update redstone devices: + ChunkData.WakeUp(Relative); } -- cgit v1.2.3