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 --- .../RedstoneSimulatorChunkData.h | 105 ++++++++++++++++----- 1 file changed, 82 insertions(+), 23 deletions(-) (limited to 'src/Simulator/IncrementalRedstoneSimulator/RedstoneSimulatorChunkData.h') diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneSimulatorChunkData.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneSimulatorChunkData.h index a842770a5..71d43d00e 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneSimulatorChunkData.h +++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneSimulatorChunkData.h @@ -1,73 +1,132 @@ #pragma once -#include "RedstoneHandler.h" +#include + #include "../RedstoneSimulator.h" -class cIncrementalRedstoneSimulatorChunkData : public cRedstoneSimulatorChunkData +struct PoweringData { +public: + PoweringData(BLOCKTYPE a_PoweringBlock, unsigned char a_PowerLevel) : + PoweringBlock(a_PoweringBlock), + PowerLevel(a_PowerLevel) + { + } + + PoweringData(void) : + PoweringBlock(E_BLOCK_AIR), + PowerLevel(0) + { + } + BLOCKTYPE PoweringBlock; + unsigned char PowerLevel; + + inline friend bool operator < (const PoweringData & Lhs, const PoweringData & Rhs) + { + return ( + (Lhs.PowerLevel < Rhs.PowerLevel) || + ( + (Lhs.PowerLevel == Rhs.PowerLevel) && + ((Lhs.PoweringBlock == E_BLOCK_REDSTONE_WIRE) && (Rhs.PoweringBlock != E_BLOCK_REDSTONE_WIRE)) + ) + ); + } + + inline friend bool operator == (const PoweringData & Lhs, const PoweringData & Rhs) + { + return (Lhs.PowerLevel == Rhs.PowerLevel); + } + + inline friend bool operator != (const PoweringData & Lhs, const PoweringData & Rhs) + { + return !operator ==(Lhs, Rhs); + } +}; + + + + + +class cIncrementalRedstoneSimulatorChunkData : public cRedstoneSimulatorChunkData +{ public: + void WakeUp(const Vector3i & a_Position) { - m_ActiveBlocks.push_back(a_Position); + ActiveBlocks.push(a_Position); } - cVector3iArray & GetActiveBlocks() + auto & GetActiveBlocks() { - return m_ActiveBlocks; + return ActiveBlocks; } - const cRedstoneHandler::PoweringData GetCachedPowerData(const Vector3i & a_Position) const + const PoweringData GetCachedPowerData(const Vector3i Position) const { - auto Result = m_CachedPowerLevels.find(a_Position); - return (Result == m_CachedPowerLevels.end()) ? cRedstoneHandler::PoweringData() : Result->second; + auto Result = CachedPowerLevels.find(Position); + return (Result == CachedPowerLevels.end()) ? PoweringData() : Result->second; } - void SetCachedPowerData(const Vector3i & a_Position, cRedstoneHandler::PoweringData a_PoweringData) + void SetCachedPowerData(const Vector3i Position, PoweringData PoweringData) { - m_CachedPowerLevels[a_Position] = a_PoweringData; + CachedPowerLevels[Position] = PoweringData; } - std::pair * GetMechanismDelayInfo(const Vector3i & a_Position) + std::pair * GetMechanismDelayInfo(const Vector3i Position) { - auto Result = m_MechanismDelays.find(a_Position); + auto Result = m_MechanismDelays.find(Position); return (Result == m_MechanismDelays.end()) ? nullptr : &Result->second; } - /** Erase cached PowerData for position */ - void ErasePowerData(const Vector3i & a_Position) + /** Erase all cached redstone data for position. */ + void ErasePowerData(const Vector3i Position) { - m_CachedPowerLevels.erase(a_Position); - m_MechanismDelays.erase(a_Position); + CachedPowerLevels.erase(Position); + m_MechanismDelays.erase(Position); + AlwaysTickedPositions.erase(Position); } - cRedstoneHandler::PoweringData ExchangeUpdateOncePowerData(const Vector3i & a_Position, cRedstoneHandler::PoweringData a_PoweringData) + PoweringData ExchangeUpdateOncePowerData(const Vector3i & a_Position, PoweringData a_PoweringData) { - auto Result = m_CachedPowerLevels.find(a_Position); - if (Result == m_CachedPowerLevels.end()) + auto Result = CachedPowerLevels.find(a_Position); + if (Result == CachedPowerLevels.end()) { - m_CachedPowerLevels[a_Position] = a_PoweringData; - return cRedstoneHandler::PoweringData(); + CachedPowerLevels[a_Position] = a_PoweringData; + return PoweringData(); } std::swap(Result->second, a_PoweringData); return a_PoweringData; } + /** Adjust From-relative coordinates into To-relative coordinates. */ + inline static Vector3i RebaseRelativePosition(cChunk & From, cChunk & To, const Vector3i Position) + { + return + { + Position.x + (From.GetPosX() - To.GetPosX()) * cChunkDef::Width, + Position.y, + Position.z + (From.GetPosZ() - To.GetPosZ()) * cChunkDef::Width + }; + } + + std::unordered_set> AlwaysTickedPositions; + /** Structure storing position of mechanism + it's delay ticks (countdown) & if to power on */ std::unordered_map, VectorHasher> m_MechanismDelays; private: - cVector3iArray m_ActiveBlocks; + std::stack> ActiveBlocks; // TODO: map -> Position of torch + it's heat level - std::unordered_map> m_CachedPowerLevels; + std::unordered_map> CachedPowerLevels; friend class cRedstoneHandlerFactory; -- cgit v1.2.3