1
0

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
This commit is contained in:
Tiger Wang
2020-07-26 14:15:00 +01:00
parent de06ae7add
commit 4e5ab02a58
27 changed files with 785 additions and 847 deletions

View File

@@ -1,73 +1,132 @@
#pragma once
#include "RedstoneHandler.h"
#include <stack>
#include "../RedstoneSimulator.h"
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<int, bool> * GetMechanismDelayInfo(const Vector3i & a_Position)
std::pair<int, bool> * 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<Vector3i, VectorHasher<int>> AlwaysTickedPositions;
/** Structure storing position of mechanism + it's delay ticks (countdown) & if to power on */
std::unordered_map<Vector3i, std::pair<int, bool>, VectorHasher<int>> m_MechanismDelays;
private:
cVector3iArray m_ActiveBlocks;
std::stack<Vector3i, std::vector<Vector3i>> ActiveBlocks;
// TODO: map<Vector3i, int> -> Position of torch + it's heat level
std::unordered_map<Vector3i, cRedstoneHandler::PoweringData, VectorHasher<int>> m_CachedPowerLevels;
std::unordered_map<Vector3i, PoweringData, VectorHasher<int>> CachedPowerLevels;
friend class cRedstoneHandlerFactory;