From 4e5ab02a589582e2fa908909e3ee30360dd08be5 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 26 Jul 2020 14:15:00 +0100 Subject: Use SimulateChunk in redstone simulator + Improved performance, reduces bottleneck in chunkmap lookup * Stop allocating and throwing away lots of small vectors in Update/GetValidSourcePositions return values - Remove unused GetPowerLevel virtual --- .../PressurePlateHandler.h | 132 ++++++++++----------- 1 file changed, 62 insertions(+), 70 deletions(-) (limited to 'src/Simulator/IncrementalRedstoneSimulator/PressurePlateHandler.h') diff --git a/src/Simulator/IncrementalRedstoneSimulator/PressurePlateHandler.h b/src/Simulator/IncrementalRedstoneSimulator/PressurePlateHandler.h index 9f490b458..c2791e45c 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/PressurePlateHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/PressurePlateHandler.h @@ -9,47 +9,42 @@ -class cPressurePlateHandler: - public cRedstoneHandler +class cPressurePlateHandler final : public cRedstoneHandler { - using Super = cRedstoneHandler; - public: - virtual unsigned char GetPowerDeliveredToPosition(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType) const override + virtual unsigned char GetPowerDeliveredToPosition(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType) const override { UNUSED(a_BlockType); UNUSED(a_Meta); UNUSED(a_QueryPosition); UNUSED(a_QueryBlockType); - return static_cast(a_World.GetRedstoneSimulator())->GetChunkData()->GetCachedPowerData(a_Position).PowerLevel; + return DataForChunk(a_Chunk).GetCachedPowerData(a_Position).PowerLevel; } - virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override + static unsigned char GetPowerLevel(cChunk & Chunk, const Vector3i Position, const BLOCKTYPE BlockType) { - UNUSED(a_Meta); - - int NumberOfEntities = 0; + unsigned NumberOfEntities = 0; bool FoundPlayer = false; - a_World.ForEachEntityInBox(cBoundingBox(Vector3d(0.5, 0, 0.5) + a_Position, 0.5, 0.5), [&](cEntity & a_Entity) + + Chunk.ForEachEntityInBox(cBoundingBox(Vector3d(0.5, 0, 0.5) + Position, 0.5, 0.5), [&](cEntity & Entity) + { + if (Entity.IsPlayer()) { - if (a_Entity.IsPlayer()) - { - FoundPlayer = true; - } - - if (a_Entity.IsPickup()) - { - NumberOfEntities += static_cast(a_Entity).GetItem().m_ItemCount; - return false; - } - NumberOfEntities++; + FoundPlayer = true; + } + + if (Entity.IsPickup()) + { + NumberOfEntities += static_cast(Entity).GetItem().m_ItemCount; return false; } - ); + NumberOfEntities++; + return false; + }); - switch (a_BlockType) + switch (BlockType) { case E_BLOCK_STONE_PRESSURE_PLATE: { @@ -75,18 +70,22 @@ public: } } - virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + static void UpdatePlate(cChunk & Chunk, cChunk & CurrentlyTicking, Vector3i Position) { - UNUSED(a_PoweringData.PowerLevel); - // LOGD("Evaluating clicky the pressure plate (%d %d %d)", a_Position.x, a_Position.y, a_Position.z); + UpdateAdjustedRelatives(Chunk, CurrentlyTicking, Position, RelativeLaterals); + UpdateAdjustedRelatives(Chunk, CurrentlyTicking, Position + OffsetYM); + } - auto ChunkData = static_cast(a_World.GetRedstoneSimulator())->GetChunkData(); + virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + { + // LOGD("Evaluating clicky the pressure plate (%d %d %d)", a_Position.x, a_Position.y, a_Position.z); - const auto PreviousPower = ChunkData->GetCachedPowerData(a_Position); - auto Power = GetPowerLevel(a_World, a_Position, a_BlockType, a_Meta); // Get the current power of the platey + auto & ChunkData = DataForChunk(a_Chunk); - const auto PlateUpdates = GetAdjustedRelatives(a_Position, StaticAppend(GetRelativeLaterals(), cVector3iArray{ OffsetYM() })); - auto DelayInfo = ChunkData->GetMechanismDelayInfo(a_Position); + const auto PreviousPower = ChunkData.GetCachedPowerData(a_Position); + const auto Absolute = cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos()); + const auto Power = GetPowerLevel(a_Chunk, Absolute, a_BlockType); // Get the current power of the platey + const auto DelayInfo = ChunkData.GetMechanismDelayInfo(a_Position); // Resting state? if (DelayInfo == nullptr) @@ -94,22 +93,21 @@ public: if (Power == 0) { // Nothing happened, back to rest - return {}; + return; } // From rest, a player stepped on us // Schedule a minimum 0.5 second delay before even thinking about releasing - ChunkData->m_MechanismDelays[a_Position] = std::make_pair(5, true); + ChunkData.m_MechanismDelays[a_Position] = std::make_pair(5, true); - auto soundToPlay = GetClickOnSound(a_BlockType); - a_World.BroadcastSoundEffect(soundToPlay, a_Position, 0.5f, 0.6f); + a_Chunk.GetWorld()->BroadcastSoundEffect(GetClickOnSound(a_BlockType), Absolute, 0.5f, 0.6f); // Update power - ChunkData->SetCachedPowerData(a_Position, PoweringData(a_BlockType, Power)); + ChunkData.SetCachedPowerData(a_Position, PoweringData(a_BlockType, Power)); // Immediately depress plate - a_World.SetBlockMeta(a_Position, E_META_PRESSURE_PLATE_DEPRESSED); - return PlateUpdates; + a_Chunk.SetMeta(a_Position, E_META_PRESSURE_PLATE_DEPRESSED); + return UpdatePlate(a_Chunk, CurrentlyTicking, a_Position); } // Not a resting state @@ -124,7 +122,7 @@ public: // Nothing changes, if there is nothing on it anymore, because the state is locked. if (Power == 0) { - return {}; + return; } // Yes. Are we waiting to release, and found that the player stepped on it again? @@ -138,11 +136,11 @@ public: if (Power != PreviousPower.PowerLevel) { // Yes. Update power - ChunkData->SetCachedPowerData(a_Position, PoweringData(a_BlockType, Power)); - return PlateUpdates; + ChunkData.SetCachedPowerData(a_Position, PoweringData(a_BlockType, Power)); + return UpdatePlate(a_Chunk, CurrentlyTicking, a_Position); } - return {}; + return; } // Not waiting for anything. Has the initial delay elapsed? @@ -153,54 +151,51 @@ public: { // Yes. Go into subsequent release delay, for a further 0.5 seconds *DelayInfo = std::make_pair(5, false); - return {}; + return; } // Did the power level change and is still above zero? if (Power != PreviousPower.PowerLevel) { // Yes. Update power - ChunkData->SetCachedPowerData(a_Position, PoweringData(a_BlockType, Power)); - return PlateUpdates; + ChunkData.SetCachedPowerData(a_Position, PoweringData(a_BlockType, Power)); + return UpdatePlate(a_Chunk, CurrentlyTicking, a_Position); } // Yes, but player's still on the plate, do nothing - return {}; + return; } // Just got out of the subsequent release phase, reset everything and raise the plate - ChunkData->m_MechanismDelays.erase(a_Position); + ChunkData.m_MechanismDelays.erase(a_Position); - auto soundToPlay = GetClickOffSound(a_BlockType); - a_World.BroadcastSoundEffect(soundToPlay, a_Position, 0.5f, 0.5f); - ChunkData->SetCachedPowerData(a_Position, PoweringData(a_BlockType, Power)); + a_Chunk.GetWorld()->BroadcastSoundEffect(GetClickOffSound(a_BlockType), Absolute, 0.5f, 0.5f); + ChunkData.SetCachedPowerData(a_Position, PoweringData(a_BlockType, Power)); - a_World.SetBlockMeta(a_Position, E_META_PRESSURE_PLATE_RAISED); - return PlateUpdates; + a_Chunk.SetMeta(a_Position, E_META_PRESSURE_PLATE_RAISED); + return UpdatePlate(a_Chunk, CurrentlyTicking, a_Position); } - virtual cVector3iArray GetValidSourcePositions(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override + virtual void ForValidSourcePositions(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override { - UNUSED(a_World); + UNUSED(a_Chunk); UNUSED(a_Position); UNUSED(a_BlockType); UNUSED(a_Meta); - return {}; + UNUSED(Callback); } private: - static AString GetClickOnSound(BLOCKTYPE a_BlockType) + + static const char * GetClickOnSound(BLOCKTYPE a_BlockType) { // manage on-sound switch (a_BlockType) { - case E_BLOCK_STONE_PRESSURE_PLATE: - return "block.stone_pressureplate.click_on"; - case E_BLOCK_WOODEN_PRESSURE_PLATE: - return "block.wood_pressureplate.click_on"; + case E_BLOCK_STONE_PRESSURE_PLATE: return "block.stone_pressureplate.click_on"; + case E_BLOCK_WOODEN_PRESSURE_PLATE: return "block.wood_pressureplate.click_on"; case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: - case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: - return "block.metal_pressureplate.click_on"; + case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: return "block.metal_pressureplate.click_on"; default: { ASSERT(!"No on sound for this one!"); @@ -209,18 +204,15 @@ private: } } - static AString GetClickOffSound(BLOCKTYPE a_BlockType) + static const char * GetClickOffSound(BLOCKTYPE a_BlockType) { // manage off-sound switch (a_BlockType) { - case E_BLOCK_STONE_PRESSURE_PLATE: - return "block.stone_pressureplate.click_off"; - case E_BLOCK_WOODEN_PRESSURE_PLATE: - return "block.wood_pressureplate.click_off"; + case E_BLOCK_STONE_PRESSURE_PLATE: return "block.stone_pressureplate.click_off"; + case E_BLOCK_WOODEN_PRESSURE_PLATE: return "block.wood_pressureplate.click_off"; case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: - case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: - return "block.metal_pressureplate.click_off"; + case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: return "block.metal_pressureplate.click_off"; default: { ASSERT(!"No off sound for this one!"); -- cgit v1.2.3