summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Blocks/BlockComparator.h19
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/CommandBlockHandler.h42
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/DoorHandler.h52
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h49
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/HopperHandler.h46
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp142
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h19
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/NoteBlockHandler.h44
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/ObserverHandler.h44
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/PistonHandler.h54
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/PoweredRailHandler.h42
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/PressurePlateHandler.h132
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneBlockHandler.h27
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneComparatorHandler.h136
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.h137
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneLampHandler.h23
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneRepeaterHandler.h59
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneSimulatorChunkData.h105
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneToggleHandler.h23
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneTorchHandler.h45
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h152
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/SmallGateHandler.h37
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/SolidBlockHandler.h27
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/TNTHandler.h31
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/TrappedChestHandler.h35
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h70
-rw-r--r--src/Simulator/NoopRedstoneSimulator.h2
27 files changed, 766 insertions, 828 deletions
diff --git a/src/Blocks/BlockComparator.h b/src/Blocks/BlockComparator.h
index a2f2d430d..ba939b41f 100644
--- a/src/Blocks/BlockComparator.h
+++ b/src/Blocks/BlockComparator.h
@@ -34,10 +34,13 @@ public:
const Vector3i a_CursorPos
) override
{
+ const auto Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos);
+
// Toggle the 3rd bit (addition / subtraction):
- NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos);
- Meta ^= 0x04;
- a_ChunkInterface.SetBlockMeta(a_BlockPos, Meta);
+ a_ChunkInterface.SetBlockMeta(a_BlockPos, Meta ^ 0x04);
+
+ // Update simulators:
+ a_WorldInterface.WakeUpSimulators(a_BlockPos);
return true;
}
@@ -56,6 +59,7 @@ public:
UNUSED(a_ChunkInterface);
UNUSED(a_BlockFace);
+ a_WorldInterface.WakeUpSimulators(a_BlockPos);
a_WorldInterface.SendBlockTo(a_BlockPos, a_Player);
}
@@ -120,15 +124,6 @@ public:
- inline static bool IsOn(NIBBLETYPE a_Meta)
- {
- return ((a_Meta & 0x8) == 0x8);
- }
-
-
-
-
-
inline static Vector3i GetSideCoordinate(Vector3i a_Position, NIBBLETYPE a_Meta, bool a_bInverse)
{
if (!a_bInverse)
diff --git a/src/Simulator/IncrementalRedstoneSimulator/CommandBlockHandler.h b/src/Simulator/IncrementalRedstoneSimulator/CommandBlockHandler.h
index 6bdd580a9..31a34236c 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/CommandBlockHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/CommandBlockHandler.h
@@ -8,16 +8,13 @@
-class cCommandBlockHandler:
- public cRedstoneHandler
+class cCommandBlockHandler 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_World);
+ UNUSED(a_Chunk);
UNUSED(a_Position);
UNUSED(a_BlockType);
UNUSED(a_Meta);
@@ -26,40 +23,29 @@ public:
return 0;
}
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
- {
- UNUSED(a_World);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- return 0;
- }
-
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
+ virtual void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
// LOGD("Evaluating commander the cmdblck (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- auto Previous = static_cast<cIncrementalRedstoneSimulator *>(a_World.GetRedstoneSimulator())->GetChunkData()->ExchangeUpdateOncePowerData(a_Position, a_PoweringData);
+ auto Previous = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, a_PoweringData);
if ((Previous.PowerLevel != 0) || (a_PoweringData.PowerLevel == 0))
{
// If we're already powered or received an update of no power, don't activate
- return {};
+ return;
}
- a_World.DoWithCommandBlockAt(a_Position.x, a_Position.y, a_Position.z, [](cCommandBlockEntity & a_CommandBlock)
- {
- a_CommandBlock.Activate();
- return false;
- }
- );
- return {};
+ a_Chunk.DoWithCommandBlockAt(a_Position, [](cCommandBlockEntity & a_CommandBlock)
+ {
+ a_CommandBlock.Activate();
+ return false;
+ });
}
- 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_BlockType);
UNUSED(a_Meta);
- return GetAdjustedRelatives(a_Position, GetRelativeAdjacents());
+ InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
}
};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/DoorHandler.h b/src/Simulator/IncrementalRedstoneSimulator/DoorHandler.h
index a22a6ff50..c91886f4e 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/DoorHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/DoorHandler.h
@@ -8,16 +8,13 @@
-class cDoorHandler:
- public cRedstoneHandler
+class cDoorHandler 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_World);
+ UNUSED(a_Chunk);
UNUSED(a_Position);
UNUSED(a_BlockType);
UNUSED(a_Meta);
@@ -26,46 +23,27 @@ public:
return 0;
}
-
-
-
-
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
- {
- UNUSED(a_World);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- return 0;
- }
-
-
-
-
-
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
+ virtual void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
// LOGD("Evaluating dori the door (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- if (a_PoweringData != static_cast<cIncrementalRedstoneSimulator *>(a_World.GetRedstoneSimulator())->GetChunkData()->ExchangeUpdateOncePowerData(a_Position, a_PoweringData))
+ cChunkInterface ChunkInterface(a_Chunk.GetWorld()->GetChunkMap());
+ const bool ShouldBeOpen = a_PoweringData.PowerLevel != 0;
+ const auto AbsolutePosition = cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos());
+ const bool IsOpen = cBlockDoorHandler::IsOpen(ChunkInterface, AbsolutePosition);
+
+ if (ShouldBeOpen != IsOpen)
{
- cChunkInterface ChunkInterface(a_World.GetChunkMap());
- cBlockDoorHandler::SetOpen(ChunkInterface, a_Position, (a_PoweringData.PowerLevel != 0));
- a_World.BroadcastSoundParticleEffect(EffectID::SFX_RANDOM_WOODEN_DOOR_OPEN, a_Position, 0);
+ cBlockDoorHandler::SetOpen(ChunkInterface, AbsolutePosition, ShouldBeOpen);
+ a_Chunk.GetWorld()->BroadcastSoundParticleEffect(EffectID::SFX_RANDOM_WOODEN_DOOR_OPEN, AbsolutePosition, 0);
}
-
- return {};
}
-
-
-
-
- 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_BlockType);
UNUSED(a_Meta);
- return GetAdjustedRelatives(a_Position, GetRelativeAdjacents());
+ InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
}
};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h b/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h
index 131d2eb6c..cee8133d8 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h
@@ -8,17 +8,15 @@
-class cDropSpenserHandler:
- public cRedstoneHandler
+class cDropSpenserHandler final : public cRedstoneHandler
{
- using Super = cRedstoneHandler;
-
public:
inline static bool IsActivated(NIBBLETYPE a_Meta)
{
return (a_Meta & E_META_DROPSPENSER_ACTIVATED) != 0;
}
+
inline static NIBBLETYPE SetActivationState(NIBBLETYPE a_Meta, bool IsOn)
{
if (IsOn)
@@ -31,9 +29,9 @@ 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_World);
+ UNUSED(a_Chunk);
UNUSED(a_Position);
UNUSED(a_BlockType);
UNUSED(a_Meta);
@@ -42,45 +40,34 @@ public:
return 0;
}
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
- {
- UNUSED(a_World);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- return 0;
- }
-
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
+ virtual void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
// LOGD("Evaluating spencer the dropspenser (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- bool IsPoweredNow = (a_PoweringData.PowerLevel > 0);
- bool WasPoweredPreviously = IsActivated(a_Meta);
+
+ const bool IsPoweredNow = (a_PoweringData.PowerLevel > 0);
+ const bool WasPoweredPreviously = IsActivated(a_Meta);
+
if (IsPoweredNow && !WasPoweredPreviously)
{
- a_World.DoWithDropSpenserAt(a_Position.x, a_Position.y, a_Position.z, [](cDropSpenserEntity & a_DropSpenser)
- {
- a_DropSpenser.Activate();
- return false;
- }
- );
+ a_Chunk.DoWithDropSpenserAt(a_Position, [](cDropSpenserEntity & a_DropSpenser)
+ {
+ a_DropSpenser.Activate();
+ return false;
+ });
}
// Update the internal dropspenser state if necessary
if (IsPoweredNow != WasPoweredPreviously)
{
- a_World.SetBlockMeta(a_Position, SetActivationState(a_Meta, IsPoweredNow));
+ a_Chunk.SetMeta(a_Position, SetActivationState(a_Meta, IsPoweredNow));
}
-
- return {};
}
- 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_BlockType);
UNUSED(a_Meta);
-
- return GetAdjustedRelatives(a_Position, GetRelativeAdjacents());
+ InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
}
};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/HopperHandler.h b/src/Simulator/IncrementalRedstoneSimulator/HopperHandler.h
index 32b615ffa..2f2e5b129 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/HopperHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/HopperHandler.h
@@ -8,16 +8,13 @@
-class cHopperHandler:
- public cRedstoneHandler
+class cHopperHandler 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_World);
+ UNUSED(a_Chunk);
UNUSED(a_Position);
UNUSED(a_BlockType);
UNUSED(a_Meta);
@@ -26,39 +23,28 @@ public:
return 0;
}
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
+ virtual void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
- UNUSED(a_World);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- return 0;
- }
-
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
- {
- // LOGD("Evaluating commander the cmdblck (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
+ // LOGD("Evaluating holey the hopper (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- auto Previous = static_cast<cIncrementalRedstoneSimulator *>(a_World.GetRedstoneSimulator())->GetChunkData()->ExchangeUpdateOncePowerData(a_Position, a_PoweringData);
- if (Previous.PowerLevel != a_PoweringData.PowerLevel)
+ auto Previous = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, a_PoweringData);
+ if (Previous.PowerLevel == a_PoweringData.PowerLevel)
{
- return {};
+ return;
}
- a_World.DoWithHopperAt(a_Position.x, a_Position.y, a_Position.z, [a_PoweringData](cHopperEntity & a_Hopper)
- {
- a_Hopper.SetLocked(a_PoweringData.PowerLevel != 0);
- return false;
- }
- );
- return {};
+ a_Chunk.DoWithHopperAt(a_Position, [a_PoweringData](cHopperEntity & a_Hopper)
+ {
+ a_Hopper.SetLocked(a_PoweringData.PowerLevel != 0);
+ return false;
+ });
}
- 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_BlockType);
UNUSED(a_Meta);
- return GetAdjustedRelatives(a_Position, GetRelativeAdjacents());
+ InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
}
};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp
index 109ee4adc..2eb515604 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp
+++ b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp
@@ -7,7 +7,6 @@
#include "CommandBlockHandler.h"
#include "DoorHandler.h"
-#include "RedstoneHandler.h"
#include "RedstoneTorchHandler.h"
#include "RedstoneWireHandler.h"
#include "RedstoneRepeaterHandler.h"
@@ -31,9 +30,10 @@
+
const cRedstoneHandler * cIncrementalRedstoneSimulator::GetComponentHandler(BLOCKTYPE a_BlockType)
{
- struct sComponents:
+ struct sComponents :
public std::array<std::unique_ptr<cRedstoneHandler>, 256>
{
sComponents()
@@ -128,76 +128,98 @@ std::unique_ptr<cRedstoneHandler> cIncrementalRedstoneSimulator::CreateComponent
-void cIncrementalRedstoneSimulator::Simulate(float a_dt)
+void cIncrementalRedstoneSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
{
- for (auto & DelayInfo : m_Data.m_MechanismDelays)
+ auto & ChunkData = *static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_Chunk->GetRedstoneSimulatorData());
+ for (auto & DelayInfo : ChunkData.m_MechanismDelays)
{
if ((--DelayInfo.second.first) == 0)
{
- m_Data.GetActiveBlocks().emplace_back(DelayInfo.first);
+ ChunkData.WakeUp(DelayInfo.first);
}
}
// Build our work queue
- cVector3iArray WorkQueue;
- std::swap(WorkQueue, m_Data.GetActiveBlocks());
+ auto & WorkQueue = ChunkData.GetActiveBlocks();
// Process the work queue
while (!WorkQueue.empty())
{
// Grab the first element and remove it from the list
- Vector3i CurrentLocation = WorkQueue.back();
- WorkQueue.pop_back();
+ Vector3i CurrentLocation = WorkQueue.top();
+ WorkQueue.pop();
- BLOCKTYPE CurrentBlock;
- NIBBLETYPE CurrentMeta;
- if (!m_World.GetBlockTypeMeta(CurrentLocation.x, CurrentLocation.y, CurrentLocation.z, CurrentBlock, CurrentMeta))
+ const auto NeighbourChunk = a_Chunk->GetRelNeighborChunkAdjustCoords(CurrentLocation);
+ if ((NeighbourChunk == nullptr) || !NeighbourChunk->IsValid())
{
- continue;
+ return;
}
- auto CurrentHandler = GetComponentHandler(CurrentBlock);
- if (CurrentHandler == nullptr) // Block at CurrentPosition doesn't have a corresponding redstone handler
- {
- // Clean up cached PowerData for CurrentPosition
- GetChunkData()->ErasePowerData(CurrentLocation);
- continue;
- }
+ ProcessWorkItem(*NeighbourChunk, *a_Chunk, CurrentLocation);
+ }
+
+ for (const auto Position : ChunkData.AlwaysTickedPositions)
+ {
+ ChunkData.WakeUp(Position);
+ }
+}
+
- cRedstoneHandler::PoweringData Power;
- for (const auto & Location : CurrentHandler->GetValidSourcePositions(m_World, CurrentLocation, CurrentBlock, CurrentMeta))
- {
- if (!cChunk::IsValidHeight(Location.y))
- {
- continue;
- }
- BLOCKTYPE PotentialBlock;
- NIBBLETYPE PotentialMeta;
- if (!m_World.GetBlockTypeMeta(Location.x, Location.y, Location.z, PotentialBlock, PotentialMeta))
- {
- continue;
- }
- auto PotentialSourceHandler = GetComponentHandler(PotentialBlock);
- if (PotentialSourceHandler == nullptr)
- {
- continue;
- }
- decltype(Power) PotentialPower(PotentialBlock, PotentialSourceHandler->GetPowerDeliveredToPosition(m_World, Location, PotentialBlock, PotentialMeta, CurrentLocation, CurrentBlock));
- Power = std::max(Power, PotentialPower);
+void cIncrementalRedstoneSimulator::ProcessWorkItem(cChunk & Chunk, cChunk & TickingSource, const Vector3i Position)
+{
+ auto & ChunkData = *static_cast<cIncrementalRedstoneSimulatorChunkData *>(Chunk.GetRedstoneSimulatorData());
+
+ BLOCKTYPE CurrentBlock;
+ NIBBLETYPE CurrentMeta;
+ Chunk.GetBlockTypeMeta(Position, CurrentBlock, CurrentMeta);
+
+ auto CurrentHandler = GetComponentHandler(CurrentBlock);
+ if (CurrentHandler == nullptr) // Block at CurrentPosition doesn't have a corresponding redstone handler
+ {
+ // Clean up cached PowerData for CurrentPosition
+ ChunkData.ErasePowerData(Position);
+ return;
+ }
+
+ PoweringData Power;
+ CurrentHandler->ForValidSourcePositions(Chunk, Position, CurrentBlock, CurrentMeta, [&Chunk, Position, CurrentBlock, &Power](Vector3i Location)
+ {
+ if (!cChunk::IsValidHeight(Location.y))
+ {
+ return;
}
- // Inform the handler to update
- cVector3iArray Updates = CurrentHandler->Update(m_World, CurrentLocation, CurrentBlock, CurrentMeta, Power);
- WorkQueue.insert(WorkQueue.end(), Updates.begin(), Updates.end());
+ const auto NeighbourChunk = Chunk.GetRelNeighborChunkAdjustCoords(Location);
+ if ((NeighbourChunk == nullptr) || !NeighbourChunk->IsValid())
+ {
+ return;
+ }
- if (IsAlwaysTicked(CurrentBlock))
+ BLOCKTYPE PotentialBlock;
+ NIBBLETYPE PotentialMeta;
+ NeighbourChunk->GetBlockTypeMeta(Location, PotentialBlock, PotentialMeta);
+
+ auto PotentialSourceHandler = GetComponentHandler(PotentialBlock);
+ if (PotentialSourceHandler == nullptr)
{
- m_Data.GetActiveBlocks().emplace_back(CurrentLocation);
+ return;
}
- }
+
+ const PoweringData PotentialPower(
+ PotentialBlock,
+ PotentialSourceHandler->GetPowerDeliveredToPosition(
+ *NeighbourChunk, Location, PotentialBlock, PotentialMeta,
+ cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(Chunk, *NeighbourChunk, Position), CurrentBlock
+ )
+ );
+ Power = std::max(Power, PotentialPower);
+ });
+
+ // Inform the handler to update
+ CurrentHandler->Update(Chunk, TickingSource, Position, CurrentBlock, CurrentMeta, Power);
}
@@ -206,27 +228,31 @@ void cIncrementalRedstoneSimulator::Simulate(float a_dt)
void cIncrementalRedstoneSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk)
{
- // Can't inspect block, so queue update anyway
- if (a_Chunk == nullptr)
+ // Can't inspect block, ignore:
+ if ((a_Chunk == nullptr) || (!a_Chunk->IsValid()))
{
- m_Data.WakeUp(a_Block);
return;
}
- const auto RelPos = cChunkDef::AbsoluteToRelative(a_Block, a_Chunk->GetPos());
- const auto CurBlock = a_Chunk->GetBlock(RelPos);
+ auto & ChunkData = *static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_Chunk->GetRedstoneSimulatorData());
+ const auto Relative = cChunkDef::AbsoluteToRelative(a_Block, a_Chunk->GetPos());
+ const auto CurrentBlock = a_Chunk->GetBlock(Relative);
// Always update redstone devices
- if (IsRedstone(CurBlock))
+ if (IsRedstone(CurrentBlock))
{
- m_Data.WakeUp(a_Block);
+ if (IsAlwaysTicked(CurrentBlock))
+ {
+ ChunkData.AlwaysTickedPositions.emplace(Relative);
+ }
+ ChunkData.WakeUp(Relative);
return;
}
// Never update blocks without a handler
- if (GetComponentHandler(CurBlock) == nullptr)
+ if (GetComponentHandler(CurrentBlock) == nullptr)
{
- GetChunkData()->ErasePowerData(a_Block);
+ ChunkData.ErasePowerData(Relative);
return;
}
@@ -235,14 +261,14 @@ void cIncrementalRedstoneSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk)
{
for (int y = -1; y < 2; ++y)
{
- if (!cChunkDef::IsValidHeight(RelPos.y + y))
+ if (!cChunkDef::IsValidHeight(Relative.y + y))
{
continue;
}
for (int z = -1; z < 2; ++z)
{
- auto CheckPos = RelPos + Vector3i{x, y, z};
+ auto CheckPos = Relative + Vector3i{x, y, z};
BLOCKTYPE Block;
NIBBLETYPE Meta;
@@ -252,7 +278,7 @@ void cIncrementalRedstoneSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk)
IsRedstone(Block)
)
{
- m_Data.WakeUp(a_Block);
+ ChunkData.WakeUp(Relative);
return;
}
}
diff --git a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h
index 8213eddae..3523463bd 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h
@@ -2,26 +2,29 @@
#pragma once
#include "../RedstoneSimulator.h"
+#include "RedstoneHandler.h"
#include "RedstoneSimulatorChunkData.h"
-class cIncrementalRedstoneSimulator:
+class cIncrementalRedstoneSimulator final :
public cRedstoneSimulator
{
using Super = cRedstoneSimulator;
public:
- cIncrementalRedstoneSimulator(cWorld & a_World):
+ cIncrementalRedstoneSimulator(cWorld & a_World) :
Super(a_World)
{
}
- virtual void Simulate(float a_dt) override;
- virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override {}
+ virtual void Simulate(float Dt) override {};
+ virtual void SimulateChunk(std::chrono::milliseconds Dt, int ChunkX, int ChunkZ, cChunk * Chunk) override;
+
+ void ProcessWorkItem(cChunk & Chunk, cChunk & TickingSource, const Vector3i Position);
virtual cIncrementalRedstoneSimulatorChunkData * CreateChunkData() override
{
@@ -36,8 +39,7 @@ public:
virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override;
/** Returns if a block is a mechanism (something that accepts power and does something)
- Used by torches to determine if they will power a block
- */
+ Used by torches to determine if they will power a block */
inline static bool IsMechanism(BLOCKTYPE Block)
{
switch (Block)
@@ -158,14 +160,9 @@ public:
}
}
- cIncrementalRedstoneSimulatorChunkData * GetChunkData() { return &m_Data; }
-
static const cRedstoneHandler * GetComponentHandler(BLOCKTYPE a_BlockType);
private:
static std::unique_ptr<cRedstoneHandler> CreateComponent(BLOCKTYPE a_BlockType);
-
- // oh yea its crazy time
- cIncrementalRedstoneSimulatorChunkData m_Data;
} ;
diff --git a/src/Simulator/IncrementalRedstoneSimulator/NoteBlockHandler.h b/src/Simulator/IncrementalRedstoneSimulator/NoteBlockHandler.h
index f6dfc7c97..7d3ec2f30 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/NoteBlockHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/NoteBlockHandler.h
@@ -8,17 +8,13 @@
-class cNoteBlockHandler:
- public cRedstoneHandler
+class cNoteBlockHandler: 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_World);
- UNUSED(a_World);
+ UNUSED(a_Chunk);
UNUSED(a_Position);
UNUSED(a_BlockType);
UNUSED(a_Meta);
@@ -27,41 +23,29 @@ public:
return 0;
}
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
- {
- UNUSED(a_World);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- return 0;
- }
-
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
+ virtual void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
// LOGD("Evaluating sparky the magical note block (%d %d %d) %i", a_Position.x, a_Position.y, a_Position.z, a_PoweringData.PowerLevel);
- auto Previous = static_cast<cIncrementalRedstoneSimulator *>(a_World.GetRedstoneSimulator())->GetChunkData()->ExchangeUpdateOncePowerData(a_Position, a_PoweringData);
+ auto Previous = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, a_PoweringData);
if ((Previous.PowerLevel != 0) || (a_PoweringData.PowerLevel == 0))
{
// If we're already powered or received an update of no power, don't make a sound
- return {};
+ return;
}
- a_World.DoWithNoteBlockAt(a_Position.x, a_Position.y, a_Position.z, [](cNoteEntity & a_NoteBlock)
- {
- a_NoteBlock.MakeSound();
- return false;
- }
- );
-
- return {};
+ a_Chunk.DoWithNoteBlockAt(a_Position, [](cNoteEntity & a_NoteBlock)
+ {
+ a_NoteBlock.MakeSound();
+ return false;
+ });
}
- 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_BlockType);
UNUSED(a_Meta);
- return GetAdjustedRelatives(a_Position, GetRelativeAdjacents());
+ InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
}
};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/ObserverHandler.h b/src/Simulator/IncrementalRedstoneSimulator/ObserverHandler.h
index b4af66aff..a3c055844 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/ObserverHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/ObserverHandler.h
@@ -8,7 +8,7 @@
-class cObserverHandler : public cRedstoneHandler
+class cObserverHandler final : public cRedstoneHandler
{
public:
@@ -17,24 +17,24 @@ public:
return (a_Meta & 0x8) == 0x8;
}
- static bool ShouldPowerOn(cWorld & a_World, const Vector3i a_Position, NIBBLETYPE a_Meta, cIncrementalRedstoneSimulatorChunkData * a_Data)
+ static bool ShouldPowerOn(cChunk & Chunk, const Vector3i a_Position, NIBBLETYPE a_Meta, cIncrementalRedstoneSimulatorChunkData & a_Data)
{
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
- if (!a_World.GetBlockTypeMeta(a_Position + cBlockObserverHandler::GetObservingFaceOffset(a_Meta), BlockType, BlockMeta))
+ if (!Chunk.UnboundedRelGetBlock(a_Position + cBlockObserverHandler::GetObservingFaceOffset(a_Meta), BlockType, BlockMeta))
{
return false;
}
// Cache the last seen block type and meta in the power data for this position
auto Observed = PoweringData(BlockType, BlockMeta);
- auto Previous = a_Data->ExchangeUpdateOncePowerData(a_Position, Observed);
+ auto Previous = a_Data.ExchangeUpdateOncePowerData(a_Position, Observed);
// Determine if to signal an update based on the block previously observed changed
return (Previous.PoweringBlock != Observed.PoweringBlock) || (Previous.PowerLevel != Observed.PowerLevel);
}
- 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
{
if (IsOn(a_Meta) && (a_QueryPosition == (a_Position + cBlockObserverHandler::GetSignalOutputOffset(a_Meta))))
{
@@ -44,30 +44,25 @@ public:
return 0;
}
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
- {
- return IsOn(a_BlockType) ? 15 : 0;
- }
-
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
+ virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
// LOGD("Evaluating Lenny the observer (%i %i %i)", a_Position.x, a_Position.y, a_Position.z);
- auto Data = static_cast<cIncrementalRedstoneSimulator *>(a_World.GetRedstoneSimulator())->GetChunkData();
- auto DelayInfo = Data->GetMechanismDelayInfo(a_Position);
+ auto & Data = DataForChunk(a_Chunk);
+ auto DelayInfo = Data.GetMechanismDelayInfo(a_Position);
if (DelayInfo == nullptr)
{
- if (!ShouldPowerOn(a_World, a_Position, a_Meta, Data))
+ if (!ShouldPowerOn(a_Chunk, a_Position, a_Meta, Data))
{
- return {};
+ return;
}
// From rest, we've determined there was a block update
// Schedule power-on 1 tick in the future
- Data->m_MechanismDelays[a_Position] = std::make_pair(1, true);
+ Data.m_MechanismDelays[a_Position] = std::make_pair(1, true);
- return {};
+ return;
}
int DelayTicks;
@@ -76,31 +71,30 @@ public:
if (DelayTicks != 0)
{
- return {};
+ return;
}
if (ShouldPowerOn)
{
// Remain on for 1 tick before resetting
*DelayInfo = std::make_pair(1, false);
- a_World.SetBlockMeta(a_Position, a_Meta | 0x8);
+ a_Chunk.SetMeta(a_Position, a_Meta | 0x8);
}
else
{
// We've reset. Erase delay data in preparation for detecting further updates
- Data->m_MechanismDelays.erase(a_Position);
- a_World.SetBlockMeta(a_Position, a_Meta & ~0x8);
+ Data.m_MechanismDelays.erase(a_Position);
+ a_Chunk.SetMeta(a_Position, a_Meta & ~0x8);
}
- return { a_Position + cBlockObserverHandler::GetSignalOutputOffset(a_Meta) };
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position + cBlockObserverHandler::GetSignalOutputOffset(a_Meta));
}
- 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_BlockType);
- return {};
}
};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/PistonHandler.h b/src/Simulator/IncrementalRedstoneSimulator/PistonHandler.h
index 0929951d5..b3860a778 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/PistonHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/PistonHandler.h
@@ -8,16 +8,13 @@
-class cPistonHandler:
- public cRedstoneHandler
+class cPistonHandler 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_World);
+ UNUSED(a_Chunk);
UNUSED(a_Position);
UNUSED(a_BlockType);
UNUSED(a_Meta);
@@ -26,52 +23,45 @@ public:
return 0;
}
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
- {
- UNUSED(a_World);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- return 0;
- }
-
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
+ virtual void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
// LOGD("Evaluating pisty the piston (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- bool ShouldBeExtended = (a_PoweringData.PowerLevel != 0);
+ const bool ShouldBeExtended = a_PoweringData.PowerLevel != 0;
if (ShouldBeExtended == cBlockPistonHandler::IsExtended(a_Meta))
{
- return {};
+ return;
}
+ a_Position = cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos());
+
if (ShouldBeExtended)
{
- cBlockPistonHandler::ExtendPiston(a_Position, a_World);
+ cBlockPistonHandler::ExtendPiston(a_Position, *a_Chunk.GetWorld());
}
else
{
- cBlockPistonHandler::RetractPiston(a_Position, a_World);
+ cBlockPistonHandler::RetractPiston(a_Position, *a_Chunk.GetWorld());
}
// It is necessary to delay after a signal to prevent an infinite loop (#3168)
- // However, that is present as a side effect of the implementation of piston animation in Blocks\BlockPiston.cpp
-
- return {};
+ // However, this delay is already present: as a side effect of the implementation of piston animation in Blocks\BlockPiston.cpp
}
- 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_BlockType);
- auto PositionsOffset = GetRelativeAdjacents();
- auto Face = cBlockPistonHandler::MetaDataToDirection(a_Meta);
- int OffsetX = 0, OffsetY = 0, OffsetZ = 0;
+ const auto Face = cBlockPistonHandler::MetaDataToDirection(a_Meta);
+ const auto FrontOffset = AddFaceDirection(Vector3i(), Face);
- AddFaceDirection(OffsetX, OffsetY, OffsetZ, Face);
- PositionsOffset.erase(std::remove(PositionsOffset.begin(), PositionsOffset.end(), Vector3i(OffsetX, OffsetY, OffsetZ)), PositionsOffset.end());
-
- return GetAdjustedRelatives(a_Position, PositionsOffset);
+ for (const auto Offset : RelativeAdjacents)
+ {
+ if (Offset != FrontOffset)
+ {
+ Callback(a_Position + Offset);
+ }
+ }
}
};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/PoweredRailHandler.h b/src/Simulator/IncrementalRedstoneSimulator/PoweredRailHandler.h
index d1d44a270..38fbf8d98 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/PoweredRailHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/PoweredRailHandler.h
@@ -7,11 +7,8 @@
-class cPoweredRailHandler:
- public cRedstoneHandler
+class cPoweredRailHandler final : public cRedstoneHandler
{
- using Super = cRedstoneHandler;
-
public:
static Vector3i GetPoweredRailAdjacentXZCoordinateOffset(NIBBLETYPE a_Meta) // Not in cBlockRailHandler since specific to powered rails
@@ -32,27 +29,20 @@ 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_QueryBlockType);
auto Offset = GetPoweredRailAdjacentXZCoordinateOffset(a_Meta);
if (((Offset + a_Position) == a_QueryPosition) || ((-Offset + a_Position) == a_QueryPosition))
{
- auto Power = GetPowerLevel(a_World, a_Position, a_BlockType, a_Meta);
+ auto Power = DataForChunk(a_Chunk).GetCachedPowerData(a_Position).PowerLevel;
return (Power <= 7) ? 0 : --Power;
}
return 0;
}
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
- {
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- return static_cast<cIncrementalRedstoneSimulator *>(a_World.GetRedstoneSimulator())->GetChunkData()->GetCachedPowerData(a_Position).PowerLevel;
- }
-
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
+ virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTickingChunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
// LOGD("Evaluating tracky the rail (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
@@ -66,33 +56,37 @@ public:
SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_MyType);
}
*/
- return {};
+ return;
}
case E_BLOCK_ACTIVATOR_RAIL:
case E_BLOCK_POWERED_RAIL:
{
auto Offset = GetPoweredRailAdjacentXZCoordinateOffset(a_Meta);
- if (a_PoweringData != static_cast<cIncrementalRedstoneSimulator *>(a_World.GetRedstoneSimulator())->GetChunkData()->ExchangeUpdateOncePowerData(a_Position, a_PoweringData))
+ if (a_PoweringData != DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, a_PoweringData))
{
- a_World.SetBlockMeta(a_Position, (a_PoweringData.PowerLevel == 0) ? (a_Meta & 0x07) : (a_Meta | 0x08));
- return cVector3iArray{ { Offset + a_Position }, { -Offset + a_Position } };
+ a_Chunk.SetMeta(a_Position, (a_PoweringData.PowerLevel == 0) ? (a_Meta & 0x07) : (a_Meta | 0x08));
+
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTickingChunk, a_Position + Offset);
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTickingChunk, a_Position + -Offset);
}
- return {};
+ return;
}
default:
{
ASSERT(!"Unhandled type of rail in passed to rail handler!");
- return {};
}
}
}
- 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_BlockType);
+ UNUSED(a_Chunk);
UNUSED(a_Meta);
- return GetAdjustedRelatives(a_Position, GetRelativeAdjacents());
+
+ if ((a_BlockType == E_BLOCK_POWERED_RAIL) || (a_BlockType == E_BLOCK_ACTIVATOR_RAIL))
+ {
+ InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
+ }
}
};
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<cIncrementalRedstoneSimulator *>(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<cPickup &>(a_Entity).GetItem().m_ItemCount;
- return false;
- }
- NumberOfEntities++;
+ FoundPlayer = true;
+ }
+
+ if (Entity.IsPickup())
+ {
+ NumberOfEntities += static_cast<cPickup &>(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<cIncrementalRedstoneSimulator *>(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!");
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneBlockHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneBlockHandler.h
index 98d373002..150723944 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneBlockHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneBlockHandler.h
@@ -7,16 +7,13 @@
-class cRedstoneBlockHandler:
- public cRedstoneHandler
+class cRedstoneBlockHandler 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_World);
+ UNUSED(a_Chunk);
UNUSED(a_Position);
UNUSED(a_BlockType);
UNUSED(a_Meta);
@@ -24,27 +21,17 @@ public:
return cIncrementalRedstoneSimulator::IsMechanism(a_QueryBlockType) ? 15 : 0;
}
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
- {
- UNUSED(a_World);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- return 15;
- }
-
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
+ virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
// LOGD("Evaluating crimson the redstone block (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- return {};
}
- 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);
}
};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneComparatorHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneComparatorHandler.h
index 3c5dae98f..5827c806b 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneComparatorHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneComparatorHandler.h
@@ -8,14 +8,11 @@
-class cRedstoneComparatorHandler:
- public cRedstoneHandler
+class cRedstoneComparatorHandler : public cRedstoneHandler
{
- using Super = cRedstoneHandler;
-
public:
- unsigned char GetFrontPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, unsigned char a_HighestSidePowerLevel, unsigned char a_HighestRearPowerLevel) const
+ static unsigned char GetFrontPowerLevel(NIBBLETYPE a_Meta, unsigned char a_HighestSidePowerLevel, unsigned char a_HighestRearPowerLevel)
{
if (cBlockComparatorHandler::IsInSubtractionMode(a_Meta))
{
@@ -29,107 +26,120 @@ 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_QueryPosition);
UNUSED(a_QueryBlockType);
- auto ChunkData = static_cast<cIncrementalRedstoneSimulator *>(a_World.GetRedstoneSimulator())->GetChunkData();
return (
(cBlockComparatorHandler::GetFrontCoordinate(a_Position, a_Meta & 0x3) == a_QueryPosition) ?
- ChunkData->GetCachedPowerData(a_Position).PowerLevel : 0
+ DataForChunk(a_Chunk).GetCachedPowerData(a_Position).PowerLevel : 0
);
}
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
+ static unsigned char GetPowerLevel(cChunk & a_Chunk, Vector3i Position, BLOCKTYPE BlockType, NIBBLETYPE Meta)
{
- UNUSED(a_Position);
- UNUSED(a_BlockType);
-
UInt8 SignalStrength = 0;
- auto RearCoordinate = cBlockComparatorHandler::GetRearCoordinate(a_Position, a_Meta & 0x3);
- a_World.DoWithBlockEntityAt(RearCoordinate.x, RearCoordinate.y, RearCoordinate.z, [&](cBlockEntity & a_BlockEntity)
+ auto RearCoordinate = cBlockComparatorHandler::GetRearCoordinate(Position, Meta & 0x3);
+
+ auto RearChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(RearCoordinate);
+ if ((RearChunk == nullptr) || !RearChunk->IsValid())
+ {
+ return SignalStrength;
+ }
+
+ RearChunk->DoWithBlockEntityAt(RearCoordinate, [&](cBlockEntity & a_BlockEntity)
+ {
+ // Skip BlockEntities that don't have slots
+ auto BlockEntityWithItems = dynamic_cast<cBlockEntityWithItems *>(&a_BlockEntity);
+ if (BlockEntityWithItems == nullptr)
{
- // Skip BlockEntities that don't have slots
- auto BlockEntityWithItems = dynamic_cast<cBlockEntityWithItems *>(&a_BlockEntity);
- if (BlockEntityWithItems == nullptr)
- {
- return false;
- }
-
- auto & Contents = BlockEntityWithItems->GetContents();
- float Fullness = 0; // Is a floating-point type to allow later calculation to produce a non-truncated value
-
- for (int Slot = 0; Slot != Contents.GetNumSlots(); ++Slot)
- {
- Fullness += static_cast<float>(Contents.GetSlot(Slot).m_ItemCount) / Contents.GetSlot(Slot).GetMaxStackSize();
- }
-
- SignalStrength = (Fullness < 0.001 /* container empty? */) ? 0 : static_cast<UInt8>(1 + (Fullness / Contents.GetNumSlots()) * 14);
return false;
}
- );
- auto RearPower = SignalStrength;
- auto RearType = a_World.GetBlock(RearCoordinate);
+
+ // TODO: handle double chests
+
+ auto & Contents = BlockEntityWithItems->GetContents();
+ float Fullness = 0; // Is a floating-point type to allow later calculation to produce a non-truncated value
+
+ for (int Slot = 0; Slot != Contents.GetNumSlots(); ++Slot)
+ {
+ Fullness += static_cast<float>(Contents.GetSlot(Slot).m_ItemCount) / Contents.GetSlot(Slot).GetMaxStackSize();
+ }
+
+ SignalStrength = (Fullness < 0.001 /* container empty? */) ? 0 : static_cast<UInt8>(1 + (Fullness / Contents.GetNumSlots()) * 14);
+ return false;
+ });
+
+ BLOCKTYPE RearType;
+ NIBBLETYPE RearMeta;
+ RearChunk->GetBlockTypeMeta(RearCoordinate, RearType, RearMeta);
auto PotentialSourceHandler = cIncrementalRedstoneSimulator::GetComponentHandler(RearType);
- if (PotentialSourceHandler != nullptr)
+ if (PotentialSourceHandler == nullptr)
{
- NIBBLETYPE RearMeta = a_World.GetBlockMeta(RearCoordinate);
- RearPower = std::max(SignalStrength, PotentialSourceHandler->GetPowerDeliveredToPosition(a_World, RearCoordinate, RearType, RearMeta, a_Position, a_BlockType));
+ return SignalStrength;
}
- return RearPower;
+ return std::max(
+ SignalStrength,
+ PotentialSourceHandler->GetPowerDeliveredToPosition(
+ *RearChunk, RearCoordinate, RearType, RearMeta,
+ cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(a_Chunk, *RearChunk, Position), BlockType
+ )
+ );
}
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
+ virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
// Note that a_PoweringData here contains the maximum * side * power level, as specified by GetValidSourcePositions
// LOGD("Evaluating ALU the comparator (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- auto Data = static_cast<cIncrementalRedstoneSimulator *>(a_World.GetRedstoneSimulator())->GetChunkData();
- auto DelayInfo = Data->GetMechanismDelayInfo(a_Position);
+
+ auto & Data = DataForChunk(a_Chunk);
+ auto DelayInfo = Data.GetMechanismDelayInfo(a_Position);
// Delay is used here to prevent an infinite loop (#3168)
if (DelayInfo == nullptr)
{
- auto RearPower = GetPowerLevel(a_World, a_Position, a_BlockType, a_Meta);
- auto FrontPower = GetFrontPowerLevel(a_World, a_Position, a_BlockType, a_Meta, a_PoweringData.PowerLevel, RearPower);
- auto PreviousFrontPower = Data->ExchangeUpdateOncePowerData(a_Position, PoweringData(a_PoweringData.PoweringBlock, FrontPower));
+ const auto RearPower = GetPowerLevel(a_Chunk, a_Position, a_BlockType, a_Meta);
+ const auto FrontPower = GetFrontPowerLevel(a_Meta, a_PoweringData.PowerLevel, RearPower);
+ const auto PreviousFrontPower = Data.GetCachedPowerData(a_Position);
+ const bool ShouldUpdate = (FrontPower != PreviousFrontPower.PowerLevel); // "Business logic" (:P) - determined by side and rear power levels
- bool ShouldBeOn = (RearPower > 0); // Provide visual indication by examining * rear * power level
- bool ShouldUpdate = (FrontPower != PreviousFrontPower.PowerLevel); // "Business logic" (:P) - determine by examining *side* power levels
-
- if (ShouldUpdate || (ShouldBeOn != cBlockComparatorHandler::IsOn(a_Meta)))
+ if (ShouldUpdate)
{
- Data->m_MechanismDelays[a_Position] = std::make_pair(1, ShouldBeOn);
+ Data.m_MechanismDelays[a_Position] = std::make_pair(1, bool());
}
}
else
{
int DelayTicks;
- bool ShouldPowerOn;
- std::tie(DelayTicks, ShouldPowerOn) = *DelayInfo;
+ std::tie(DelayTicks, std::ignore) = *DelayInfo;
if (DelayTicks == 0)
{
- a_World.SetBlockMeta(a_Position, ShouldPowerOn ? (a_Meta | 0x8) : (a_Meta & 0x7));
- Data->m_MechanismDelays.erase(a_Position);
-
- // Assume that an update (to front power) is needed.
- // Note: potential inconsistencies will arise as power data is updated before-delay due to limitations of the power data caching functionality (only stores one bool)
- // This means that other mechanisms like wires may get our new power data before our delay has finished
- // This also means that we have to manually update ourselves to be aware of any changes that happened in the previous redstone tick
- return StaticAppend(GetAdjustedRelatives(a_Position, GetRelativeLaterals()), cVector3iArray{ a_Position });
+ const auto RearPower = GetPowerLevel(a_Chunk, a_Position, a_BlockType, a_Meta);
+ const auto FrontPower = GetFrontPowerLevel(a_Meta, a_PoweringData.PowerLevel, RearPower);
+ const auto NewMeta = (FrontPower > 0) ? (a_Meta | 0x8) : (a_Meta & 0x7);
+
+ // Don't care about the previous power level so return value ignored
+ Data.ExchangeUpdateOncePowerData(a_Position, PoweringData(a_PoweringData.PoweringBlock, FrontPower));
+
+ a_Chunk.SetMeta(a_Position, NewMeta);
+ Data.m_MechanismDelays.erase(a_Position);
+
+ // Assume that an update (to front power) is needed:
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, cBlockComparatorHandler::GetFrontCoordinate(a_Position, a_Meta & 0x3));
}
}
-
- return {};
}
- 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_BlockType);
- return cVector3iArray {cBlockComparatorHandler::GetSideCoordinate(a_Position, a_Meta & 0x3, false), cBlockComparatorHandler::GetSideCoordinate(a_Position, a_Meta & 0x3, true)};
+
+ Callback(cBlockComparatorHandler::GetSideCoordinate(a_Position, a_Meta & 0x3, false));
+ Callback(cBlockComparatorHandler::GetSideCoordinate(a_Position, a_Meta & 0x3, true));
}
};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.h
index 2d0ac97b9..fec38b14d 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.h
@@ -1,7 +1,8 @@
#pragma once
-#include "../../World.h"
+#include "../../Chunk.h"
+#include "RedstoneSimulatorChunkData.h"
@@ -14,50 +15,11 @@ public:
cRedstoneHandler() = default;
DISALLOW_COPY_AND_ASSIGN(cRedstoneHandler);
- 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 & a_Lhs, const PoweringData & a_Rhs)
- {
- return (
- (a_Lhs.PowerLevel < a_Rhs.PowerLevel) ||
- (
- (a_Lhs.PowerLevel == a_Rhs.PowerLevel) &&
- ((a_Lhs.PoweringBlock == E_BLOCK_REDSTONE_WIRE) && (a_Rhs.PoweringBlock != E_BLOCK_REDSTONE_WIRE))
- )
- );
- }
-
- inline friend bool operator == (const PoweringData & a_Lhs, const PoweringData & a_Rhs)
- {
- return (a_Lhs.PowerLevel == a_Rhs.PowerLevel);
- }
-
- inline friend bool operator != (const PoweringData & a_Lhs, const PoweringData & a_Rhs)
- {
- return !operator ==(a_Lhs, a_Rhs);
- }
- };
+ using SourceCallback = cFunctionRef<void(Vector3i)>;
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const = 0;
- virtual unsigned char GetPowerDeliveredToPosition(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType) const = 0;
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const = 0;
- virtual cVector3iArray GetValidSourcePositions(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const = 0;
+ virtual unsigned char GetPowerDeliveredToPosition(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType) const = 0;
+ virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const = 0;
+ virtual void ForValidSourcePositions(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const = 0;
// Force a virtual destructor
virtual ~cRedstoneHandler() {}
@@ -72,15 +34,9 @@ protected:
return ToReturn;
}
- inline static Vector3i OffsetYP()
- {
- return Vector3i(0, 1, 0);
- }
+ inline static Vector3i OffsetYP{ 0, 1, 0 };
- inline static Vector3i OffsetYM()
- {
- return Vector3i(0, -1, 0);
- }
+ inline static Vector3i OffsetYM{ 0, -1, 0 };
static cVector3iArray GetAdjustedRelatives(Vector3i a_Position, cVector3iArray a_Relatives)
{
@@ -91,31 +47,68 @@ protected:
return a_Relatives;
}
- inline static cVector3iArray GetRelativeAdjacents()
+ inline static cIncrementalRedstoneSimulatorChunkData & DataForChunk(cChunk & a_Chunk)
+ {
+ return *static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_Chunk.GetRedstoneSimulatorData());
+ }
+
+ template <typename... ArrayTypes>
+ static void UpdateAdjustedRelatives(cChunk & From, cChunk & To, const Vector3i Position)
{
- return
+ DataForChunk(To).WakeUp(cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(From, To, Position));
+ }
+
+ template <typename ArrayType, typename... ArrayTypes>
+ static void UpdateAdjustedRelatives(cChunk & From, cChunk & To, const Vector3i Position, const ArrayType & Relative, const ArrayTypes &... Relatives)
+ {
+ for (const auto Offset : Relative)
+ {
+ DataForChunk(To).GetActiveBlocks().push(cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(From, To, Position + Offset));
+ }
+
+ UpdateAdjustedRelatives(From, To, Position, Relatives...);
+ }
+
+ template <typename ArrayType, typename... ArrayTypes>
+ static void InvokeForAdjustedRelatives(SourceCallback Callback, Vector3i Position, const ArrayType & Relative, const ArrayTypes &... Relatives)
+ {
+ for (const auto Offset : Relative)
{
- {
- { 1, 0, 0 },
- { -1, 0, 0 },
- { 0, 1, 0 },
- { 0, -1, 0 },
- { 0, 0, 1 },
- { 0, 0, -1 },
- }
- };
+ Callback(Position + Offset);
+ }
+
+ InvokeForAdjustedRelatives(Callback, Position, Relatives...);
}
- inline static cVector3iArray GetRelativeLaterals()
+ inline static std::array<Vector3i, 6> RelativeAdjacents
+ {
+ {
+ { 1, 0, 0 },
+ { -1, 0, 0 },
+ { 0, 1, 0 },
+ { 0, -1, 0 },
+ { 0, 0, 1 },
+ { 0, 0, -1 },
+ }
+ };
+
+ inline static std::array<Vector3i, 4> RelativeLaterals
{
- return
{
- {
- { 1, 0, 0 },
- { -1, 0, 0 },
- { 0, 0, 1 },
- { 0, 0, -1 },
- }
- };
+ { 1, 0, 0 },
+ { -1, 0, 0 },
+ { 0, 0, 1 },
+ { 0, 0, -1 },
+ }
+ };
+
+private:
+
+ static void UpdateAdjustedRelatives(cVector3iArray &, Vector3i)
+ {
+ }
+
+ static void InvokeForAdjustedRelatives(SourceCallback, Vector3i)
+ {
}
};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneLampHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneLampHandler.h
index 7c967af9c..85aa1d743 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneLampHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneLampHandler.h
@@ -5,7 +5,7 @@
-class cRedstoneLampHandler : public cRedstoneHandler
+class cRedstoneLampHandler final : public cRedstoneHandler
{
public:
@@ -14,17 +14,12 @@ public:
return (a_BlockType == E_BLOCK_REDSTONE_LAMP_ON);
}
- 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
{
return 0;
}
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
- {
- return 0;
- }
-
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
+ virtual void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
// LOGD("Evaluating lamp (%i %i %i)", a_Position.x, a_Position.y, a_Position.z);
@@ -32,25 +27,23 @@ public:
{
if (!IsOn(a_BlockType))
{
- a_World.SetBlock(a_Position.x, a_Position.y, a_Position.z, E_BLOCK_REDSTONE_LAMP_ON, 0);
+ a_Chunk.FastSetBlock(a_Position, E_BLOCK_REDSTONE_LAMP_ON, 0);
}
}
else
{
if (IsOn(a_BlockType))
{
- a_World.SetBlock(a_Position.x, a_Position.y, a_Position.z, E_BLOCK_REDSTONE_LAMP_OFF, 0);
+ a_Chunk.FastSetBlock(a_Position, E_BLOCK_REDSTONE_LAMP_OFF, 0);
}
}
-
- return {};
}
- 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_Meta);
UNUSED(a_BlockType);
- return GetAdjustedRelatives(a_Position, GetRelativeAdjacents());
+ InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
}
};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneRepeaterHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneRepeaterHandler.h
index 0cd65be53..4174ac930 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneRepeaterHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneRepeaterHandler.h
@@ -15,37 +15,27 @@ class cRedstoneRepeaterHandler:
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
{
- return (
- (a_QueryPosition == (a_Position + cBlockRedstoneRepeaterHandler::GetFrontCoordinateOffset(a_Meta))) ?
- GetPowerLevel(a_World, a_Position, a_BlockType, a_Meta) : 0
- );
+ return ((a_QueryPosition == (a_Position + cBlockRedstoneRepeaterHandler::GetFrontCoordinateOffset(a_Meta))) && IsOn(a_BlockType)) ? 15 : 0;
}
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
- {
- UNUSED(a_World);
- UNUSED(a_Position);
- UNUSED(a_Meta);
- return IsOn(a_BlockType) ? 15 : 0;
- }
-
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
+ virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
// LOGD("Evaluating loopy the repeater (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- auto Data = static_cast<cIncrementalRedstoneSimulator *>(a_World.GetRedstoneSimulator())->GetChunkData();
- auto DelayInfo = Data->GetMechanismDelayInfo(a_Position);
+
+ auto & Data = DataForChunk(a_Chunk);
+ const auto DelayInfo = Data.GetMechanismDelayInfo(a_Position);
// If the repeater is locked by another, ignore and forget all power changes:
- if (IsLocked(a_World, a_Position, a_Meta))
+ if (IsLocked(a_Chunk, a_Position, a_Meta))
{
if (DelayInfo != nullptr)
{
- Data->m_MechanismDelays.erase(a_Position);
+ Data.m_MechanismDelays.erase(a_Position);
}
- return {};
+ return;
}
if (DelayInfo == nullptr)
@@ -53,7 +43,7 @@ public:
bool ShouldBeOn = (a_PoweringData.PowerLevel != 0);
if (ShouldBeOn != IsOn(a_BlockType))
{
- Data->m_MechanismDelays[a_Position] = std::make_pair((((a_Meta & 0xC) >> 0x2) + 1), ShouldBeOn);
+ Data.m_MechanismDelays[a_Position] = std::make_pair((((a_Meta & 0xC) >> 0x2) + 1), ShouldBeOn);
}
}
else
@@ -64,18 +54,23 @@ public:
if (DelayTicks == 0)
{
- a_World.SetBlock(a_Position.x, a_Position.y, a_Position.z, ShouldPowerOn ? E_BLOCK_REDSTONE_REPEATER_ON : E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta);
- Data->m_MechanismDelays.erase(a_Position);
- return cVector3iArray{ cBlockRedstoneRepeaterHandler::GetFrontCoordinateOffset(a_Meta) + a_Position };
+ const auto NewType = ShouldPowerOn ? E_BLOCK_REDSTONE_REPEATER_ON : E_BLOCK_REDSTONE_REPEATER_OFF;
+ a_Chunk.FastSetBlock(a_Position, NewType, a_Meta);
+ Data.m_MechanismDelays.erase(a_Position);
+
+ // While sleeping, we ignore any power changes and apply our saved ShouldBeOn when sleep expires
+ // Now, we need to recalculate to be aware of any new changes that may e.g. cause a new output change
+ // FastSetBlock doesn't wake simulators, so manually update ourselves:
+ Update(a_Chunk, CurrentlyTicking, a_Position, NewType, a_Meta, a_PoweringData);
+
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position + cBlockRedstoneRepeaterHandler::GetFrontCoordinateOffset(a_Meta));
}
}
-
- return {};
}
- 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
{
- return { cBlockRedstoneRepeaterHandler::GetRearCoordinateOffset(a_Meta) + a_Position };
+ Callback(cBlockRedstoneRepeaterHandler::GetRearCoordinateOffset(a_Meta) + a_Position);
}
private:
@@ -87,12 +82,12 @@ private:
/** Returns a pair with first element indicating if the block at the given position is an activated repeater.
If it is activated, the second element is the repeater metadata. */
- static std::pair<bool, NIBBLETYPE> IsOnRepeater(cWorld & a_World, const Vector3i a_Position)
+ static std::pair<bool, NIBBLETYPE> IsOnRepeater(cChunk & Chunk, const Vector3i a_Position)
{
BLOCKTYPE Type;
NIBBLETYPE Meta;
- if (!a_World.GetBlockTypeMeta(a_Position, Type, Meta))
+ if (!Chunk.UnboundedRelGetBlock(a_Position, Type, Meta))
{
return std::make_pair(false, 0);
}
@@ -103,20 +98,20 @@ private:
/** Determine if a repeater is locked.
A locked repeater is one with another powered repeater facing them, to their immediate left or right sides.
"Left" is relative to the direction the repeater output faces, naturally. */
- inline static bool IsLocked(cWorld & a_World, const Vector3i a_Position, const NIBBLETYPE a_Meta)
+ inline static bool IsLocked(cChunk & Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta)
{
// The left hand side offset. Will be negated to get the rhs offset
const auto LhsOffset = cBlockRedstoneRepeaterHandler::GetLeftCoordinateOffset(a_Meta);
// Test the block to the left of us
- const auto Lhs = IsOnRepeater(a_World, LhsOffset + a_Position);
+ const auto Lhs = IsOnRepeater(Chunk, LhsOffset + a_Position);
if (Lhs.first && DoesLhsLockMe(Lhs.second, a_Meta))
{
return true;
}
// Test the right side, flipping the argument order to DoesLhsLockMe
- const auto Rhs = IsOnRepeater(a_World, -LhsOffset + a_Position);
+ const auto Rhs = IsOnRepeater(Chunk, -LhsOffset + a_Position);
return Rhs.first && DoesLhsLockMe(a_Meta, Rhs.second);
}
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 <stack>
+
#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<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;
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneToggleHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneToggleHandler.h
index c56b09c7b..bf9c639b1 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneToggleHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneToggleHandler.h
@@ -9,11 +9,8 @@
-class cRedstoneToggleHandler:
- public cRedstoneHandler
+class cRedstoneToggleHandler final : public cRedstoneHandler
{
- using Super = cRedstoneHandler;
-
public:
inline static Vector3i GetPositionAttachedTo(Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
@@ -65,21 +62,18 @@ 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_QueryBlockType);
if ((GetPositionAttachedTo(a_Position, a_BlockType, a_Meta) == a_QueryPosition) || cIncrementalRedstoneSimulator::IsMechanism(a_QueryBlockType))
{
- return GetPowerLevel(a_World, a_Position, a_BlockType, a_Meta);
+ return GetPowerLevel(a_BlockType, a_Meta);
}
return 0;
}
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
+ static unsigned char GetPowerLevel(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
{
- UNUSED(a_World);
- UNUSED(a_Position);
-
switch (a_BlockType)
{
case E_BLOCK_LEVER: return cBlockLeverHandler::IsLeverOn(a_Meta) ? 15 : 0;
@@ -93,18 +87,17 @@ public:
}
}
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
+ virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
// LOGD("Evaluating templatio<> the lever/button (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- return {};
}
- 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);
}
};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneTorchHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneTorchHandler.h
index 16f060939..c935e1f1b 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneTorchHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneTorchHandler.h
@@ -7,7 +7,7 @@
-class cRedstoneTorchHandler : public cRedstoneHandler
+class cRedstoneTorchHandler final : public cRedstoneHandler
{
public:
@@ -33,12 +33,12 @@ 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
{
if (
IsOn(a_BlockType) &&
(a_QueryPosition != (a_Position + GetOffsetAttachedTo(a_Position, a_Meta))) &&
- (cIncrementalRedstoneSimulator::IsMechanism(a_QueryBlockType) || (cBlockInfo::FullyOccupiesVoxel(a_QueryBlockType) && (a_QueryPosition == (a_Position + OffsetYP()))))
+ (cIncrementalRedstoneSimulator::IsMechanism(a_QueryBlockType) || (cBlockInfo::FullyOccupiesVoxel(a_QueryBlockType) && (a_QueryPosition == (a_Position + OffsetYP))))
)
{
return 15;
@@ -46,24 +46,19 @@ public:
return 0;
}
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
- {
- return IsOn(a_BlockType) ? 15 : 0;
- }
-
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
+ virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
// LOGD("Evaluating torchy the redstone torch (%i %i %i)", a_Position.x, a_Position.y, a_Position.z);
- auto Data = static_cast<cIncrementalRedstoneSimulator *>(a_World.GetRedstoneSimulator())->GetChunkData();
- auto DelayInfo = Data->GetMechanismDelayInfo(a_Position);
+ auto & Data = DataForChunk(a_Chunk);
+ auto DelayInfo = Data.GetMechanismDelayInfo(a_Position);
if (DelayInfo == nullptr)
{
bool ShouldBeOn = (a_PoweringData.PowerLevel == 0);
if (ShouldBeOn != IsOn(a_BlockType))
{
- Data->m_MechanismDelays[a_Position] = std::make_pair(1, ShouldBeOn);
+ Data.m_MechanismDelays[a_Position] = std::make_pair(1, ShouldBeOn);
}
}
else
@@ -72,24 +67,28 @@ public:
bool ShouldPowerOn;
std::tie(DelayTicks, ShouldPowerOn) = *DelayInfo;
- if (DelayTicks == 0)
+ if (DelayTicks != 0)
{
- a_World.SetBlock(a_Position.x, a_Position.y, a_Position.z, ShouldPowerOn ? E_BLOCK_REDSTONE_TORCH_ON : E_BLOCK_REDSTONE_TORCH_OFF, a_Meta);
- Data->m_MechanismDelays.erase(a_Position);
+ return;
+ }
- cVector3iArray RelativePositions = GetRelativeAdjacents();
- RelativePositions.erase(std::remove(RelativePositions.begin(), RelativePositions.end(), GetOffsetAttachedTo(a_Position, a_Meta)), RelativePositions.end());
- return GetAdjustedRelatives(a_Position, RelativePositions);
+ a_Chunk.SetBlock(a_Position, ShouldPowerOn ? E_BLOCK_REDSTONE_TORCH_ON : E_BLOCK_REDSTONE_TORCH_OFF, a_Meta);
+ Data.m_MechanismDelays.erase(a_Position);
+
+ for (const auto Adjacent : RelativeAdjacents)
+ {
+ if (Adjacent != GetOffsetAttachedTo(a_Position, a_Meta))
+ {
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position + Adjacent);
+ }
}
}
-
- return {};
}
- 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_BlockType);
- return { (a_Position + GetOffsetAttachedTo(a_Position, a_Meta)) };
+ Callback(a_Position + GetOffsetAttachedTo(a_Position, a_Meta));
}
};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h
index e7666f560..3a782d1d3 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h
@@ -7,11 +7,8 @@
-class cRedstoneWireHandler:
- public cRedstoneHandler
+class cRedstoneWireHandler final : public cRedstoneHandler
{
- using Super = cRedstoneHandler;
-
public:
inline static bool IsDirectlyConnectingMechanism(BLOCKTYPE a_Block, NIBBLETYPE a_BlockMeta, const Vector3i a_Offset)
@@ -40,133 +37,170 @@ public:
}
}
- cVector3iArray GetTerracingConnectionOffsets(cWorld & a_World, const Vector3i a_Position) const
+ template <class OffsetCallback>
+ static bool ForTerracingConnectionOffsets(cChunk & a_Chunk, const Vector3i a_Position, OffsetCallback Callback)
{
- auto RelativePositions = GetRelativeLaterals();
- const auto YPTerraceBlock = a_World.GetBlock(a_Position + OffsetYP());
+ const auto YPTerraceBlock = a_Chunk.GetBlock(a_Position + OffsetYP);
const bool IsYPTerracingBlocked = cBlockInfo::IsSolid(YPTerraceBlock) && !cBlockInfo::IsTransparent(YPTerraceBlock);
- for (const auto & Adjacent : GetRelativeLaterals())
+ for (const auto Adjacent : RelativeLaterals)
{
+ // All laterals are counted as terracing, duh
+ if (Callback(Adjacent))
+ {
+ return true;
+ }
+
if (
+ BLOCKTYPE YPBlock;
+
// A block above us blocks all YP terracing, so the check is static in the loop
!IsYPTerracingBlocked &&
- (a_World.GetBlock(a_Position + Adjacent + OffsetYP()) == E_BLOCK_REDSTONE_WIRE)
+ a_Chunk.UnboundedRelGetBlockType(a_Position + Adjacent + OffsetYP, YPBlock) &&
+ (YPBlock == E_BLOCK_REDSTONE_WIRE)
)
{
- RelativePositions.emplace_back(Adjacent + OffsetYP());
+ if (Callback(Adjacent + OffsetYP))
+ {
+ return true;
+ }
}
- const auto YMTerraceBlock = a_World.GetBlock(a_Position + Adjacent);
if (
+ BLOCKTYPE YMTerraceBlock, YMDiagonalBlock;
+
// IsYMTerracingBlocked (i.e. check block above lower terracing position, a.k.a. just the plain adjacent)
+ a_Chunk.UnboundedRelGetBlockType(a_Position + Adjacent, YMTerraceBlock) &&
(!cBlockInfo::IsSolid(YMTerraceBlock) || cBlockInfo::IsTransparent(YMTerraceBlock)) &&
- (a_World.GetBlock(a_Position + Adjacent + OffsetYM()) == E_BLOCK_REDSTONE_WIRE)
+
+ a_Chunk.UnboundedRelGetBlockType(a_Position + Adjacent + OffsetYM, YMDiagonalBlock) &&
+ (YMDiagonalBlock == E_BLOCK_REDSTONE_WIRE)
)
{
- RelativePositions.emplace_back(Adjacent + OffsetYM());
+ if (Callback(Adjacent + OffsetYM))
+ {
+ return true;
+ }
}
}
- return RelativePositions;
+ return false;
}
- 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
{
- if (a_QueryPosition == (a_Position + OffsetYP()))
+ if (a_QueryPosition == (a_Position + OffsetYP))
{
// Wires do not power things above them
return 0;
}
- if (a_QueryBlockType != E_BLOCK_REDSTONE_WIRE)
+ if (a_QueryBlockType == E_BLOCK_REDSTONE_WIRE)
{
// For mechanisms, wire of power one will still power them
- a_Meta++;
+ // But for wire-to-wire connections, power level decreases by 1
+ return (a_Meta != 0) ? --a_Meta : a_Meta;
}
// Wires always deliver power to the block underneath, and any directly connecting mechanisms
if (
- (a_QueryPosition != (a_Position + OffsetYM())) &&
- !IsDirectlyConnectingMechanism(a_QueryBlockType, a_World.GetBlockMeta(a_QueryPosition), a_QueryPosition - a_Position)
+ NIBBLETYPE QueryMeta;
+
+ (a_QueryPosition == (a_Position + OffsetYM)) ||
+ (a_Chunk.UnboundedRelGetBlockMeta(a_QueryPosition, QueryMeta) && IsDirectlyConnectingMechanism(a_QueryBlockType, QueryMeta, a_QueryPosition - a_Position))
)
{
- /*
- Okay, we do not directly connect to the wire.
- If there are no DC mechanisms at all, the wire powers all laterals. Great, we fall out the loop.
- If there is one DC mechanism, the wire "goes straight" along the axis of the wire and mechanism.
- The only possible way for us to be powered is for us to be on the opposite end, with the wire pointing towards us.
- If there is more than one DC, no non-DCs are powered.
- */
-
- Vector3i PotentialOffset;
- bool FoundOneBorderingMechanism = false;
-
- for (const auto & Offset : GetTerracingConnectionOffsets(a_World, a_Position))
+ return a_Meta;
+ }
+
+ /*
+ Okay, we do not directly connect to the wire.
+ If there are no DC mechanisms at all, the wire powers all laterals. Great, we fall out the loop.
+ If there is one DC mechanism, the wire "goes straight" along the axis of the wire and mechanism.
+ The only possible way for us to be powered is for us to be on the opposite end, with the wire pointing towards us.
+ If there is more than one DC, no non-DCs are powered.
+ */
+
+ Vector3i PotentialOffset;
+ bool FoundOneBorderingMechanism = false;
+
+ if (
+ ForTerracingConnectionOffsets(a_Chunk, a_Position, [&a_Chunk, a_Position, &FoundOneBorderingMechanism, &PotentialOffset](const Vector3i Offset)
{
BLOCKTYPE Block;
NIBBLETYPE Meta;
if (
- !a_World.GetBlockTypeMeta(Offset + a_Position, Block, Meta) ||
+ !a_Chunk.UnboundedRelGetBlock(Offset + a_Position, Block, Meta) ||
!IsDirectlyConnectingMechanism(Block, Meta, Offset)
)
{
- continue;
+ return false;
}
if (FoundOneBorderingMechanism)
{
// Case 3
- return 0;
+ return true;
}
// Potential case 2
FoundOneBorderingMechanism = true;
PotentialOffset = { -Offset.x, 0, -Offset.z };
- }
- if (FoundOneBorderingMechanism && (a_QueryPosition != (a_Position + PotentialOffset)))
- {
- // Case 2 fail
- return 0;
- }
+ return false;
+ })
+ )
+ {
+ // Case 3
+ return 0;
+ }
- // Case 1
- // Case 2 success
+ if (FoundOneBorderingMechanism && (a_QueryPosition != (a_Position + PotentialOffset)))
+ {
+ // Case 2 fail
+ return 0;
}
- return (a_Meta != 0) ? --a_Meta : a_Meta;
- }
+ // Case 1
+ // Case 2 success
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
- {
- UNUSED(a_World);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
return a_Meta;
}
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
+ virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
- UNUSED(a_BlockType);
// LOGD("Evaluating dusty the wire (%d %d %d) %i", a_Position.x, a_Position.y, a_Position.z, a_PoweringData.PowerLevel);
if (a_Meta != a_PoweringData.PowerLevel)
{
- a_World.SetBlockMeta(a_Position, a_PoweringData.PowerLevel);
- return GetAdjustedRelatives(a_Position, StaticAppend(StaticAppend(GetRelativeLaterals(), GetTerracingConnectionOffsets(a_World, a_Position)), cVector3iArray{ OffsetYM() }));
- }
+ a_Chunk.SetMeta(a_Position, a_PoweringData.PowerLevel);
+
+ // Notify block below us to update:
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position + OffsetYM);
- return {};
+ // Notify all terracing positions:
+ ForTerracingConnectionOffsets(a_Chunk, a_Position, [&a_Chunk, &CurrentlyTicking, a_Position](const Vector3i Offset)
+ {
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position + Offset);
+ return false;
+ });
+ }
}
- 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_BlockType);
UNUSED(a_Meta);
- return GetAdjustedRelatives(a_Position, StaticAppend(GetRelativeAdjacents(), GetTerracingConnectionOffsets(a_World, a_Position)));
+ Callback(a_Position + OffsetYP);
+ Callback(a_Position + OffsetYM);
+
+ ForTerracingConnectionOffsets(a_Chunk, a_Position, [&Callback, a_Position](const Vector3i Offset)
+ {
+ Callback(a_Position + Offset);
+ return false;
+ });
}
};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/SmallGateHandler.h b/src/Simulator/IncrementalRedstoneSimulator/SmallGateHandler.h
index 48238f4eb..0bf2faacd 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/SmallGateHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/SmallGateHandler.h
@@ -7,16 +7,13 @@
-class cSmallGateHandler:
- public cRedstoneHandler
+class cSmallGateHandler 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_World);
+ UNUSED(a_Chunk);
UNUSED(a_Position);
UNUSED(a_BlockType);
UNUSED(a_Meta);
@@ -25,32 +22,24 @@ public:
return 0;
}
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
- {
- UNUSED(a_World);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- return 0;
- }
-
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
+ virtual void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
// LOGD("Evaluating gateydory the fence gate/trapdoor (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- auto Data = static_cast<cIncrementalRedstoneSimulator *>(a_World.GetRedstoneSimulator())->GetChunkData();
- if (a_PoweringData != Data->ExchangeUpdateOncePowerData(a_Position, a_PoweringData))
+
+ const bool ShouldBeOpen = a_PoweringData.PowerLevel != 0;
+ const bool IsOpen = (a_Meta & 0x4) == 0x4;
+
+ if (ShouldBeOpen != IsOpen)
{
- a_World.SetBlockMeta(a_Position, (a_PoweringData.PowerLevel > 0) ? (a_Meta | 0x4) : (a_Meta & ~0x04));
+ a_Chunk.SetMeta(a_Position, ShouldBeOpen ? (a_Meta | 0x4) : (a_Meta & ~0x04));
}
-
- return {};
}
- 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_BlockType);
UNUSED(a_Meta);
- return GetAdjustedRelatives(a_Position, GetRelativeAdjacents());
+ InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
}
};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/SolidBlockHandler.h b/src/Simulator/IncrementalRedstoneSimulator/SolidBlockHandler.h
index 5b6bafaa3..abf8dc63b 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/SolidBlockHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/SolidBlockHandler.h
@@ -14,41 +14,34 @@ class cSolidBlockHandler:
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
{
- // TODO: wire isn't linked powered only if the source was a wire, not just because it is a wire
+ const auto SolidBlock = DataForChunk(a_Chunk).GetCachedPowerData(a_Position);
return (
!cIncrementalRedstoneSimulator::IsRedstone(a_QueryBlockType) ||
(
(a_QueryBlockType == E_BLOCK_REDSTONE_WIRE) &&
- (static_cast<cIncrementalRedstoneSimulator *>(a_World.GetRedstoneSimulator())->GetChunkData()->GetCachedPowerData(a_Position).PoweringBlock == E_BLOCK_REDSTONE_WIRE)
+ (SolidBlock.PoweringBlock == E_BLOCK_REDSTONE_WIRE)
)
- ) ? 0 : GetPowerLevel(a_World, a_Position, a_BlockType, a_Meta);
+ ) ? 0 : SolidBlock.PowerLevel;
}
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
- {
- return static_cast<cIncrementalRedstoneSimulator *>(a_World.GetRedstoneSimulator())->GetChunkData()->GetCachedPowerData(a_Position).PowerLevel;
- }
-
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
+ virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
UNUSED(a_BlockType);
UNUSED(a_Meta);
// LOGD("Evaluating blocky the generic block (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- auto PreviousPower = static_cast<cIncrementalRedstoneSimulator *>(a_World.GetRedstoneSimulator())->GetChunkData()->ExchangeUpdateOncePowerData(a_Position, a_PoweringData);
+ auto PreviousPower = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, a_PoweringData);
if ((a_PoweringData != PreviousPower) || (a_PoweringData.PoweringBlock != PreviousPower.PoweringBlock))
{
- return GetAdjustedRelatives(a_Position, GetRelativeAdjacents());
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
}
-
- return {};
}
- 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_BlockType);
UNUSED(a_Meta);
@@ -64,6 +57,6 @@ public:
}
}
*/
- return GetAdjustedRelatives(a_Position, GetRelativeAdjacents());
+ InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
}
};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/TNTHandler.h b/src/Simulator/IncrementalRedstoneSimulator/TNTHandler.h
index 1ded2a733..4b048e5c2 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/TNTHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/TNTHandler.h
@@ -7,16 +7,13 @@
-class cTNTHandler:
- public cRedstoneHandler
+class cTNTHandler 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_World);
+ UNUSED(a_Chunk);
UNUSED(a_Position);
UNUSED(a_BlockType);
UNUSED(a_Meta);
@@ -25,31 +22,21 @@ public:
return 0;
}
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
- {
- UNUSED(a_World);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- return 0;
- }
-
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
+ virtual void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
// LOGD("Evaluating explodinator the trinitrotoluene (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
if (a_PoweringData.PowerLevel != 0)
{
- a_World.SetBlock(a_Position.x, a_Position.y, a_Position.z, E_BLOCK_AIR, 0);
- a_World.SpawnPrimedTNT(Vector3d(a_Position) + Vector3d(0.5, 0.5, 0.5)); // 80 ticks to boom
+ a_Chunk.SetBlock(a_Position, E_BLOCK_AIR, 0);
+ a_Chunk.GetWorld()->SpawnPrimedTNT(Vector3d(0.5, 0.5, 0.5) + cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos())); // 80 ticks to boom
}
- return {};
}
- 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_BlockType);
UNUSED(a_Meta);
- return GetAdjustedRelatives(a_Position, GetRelativeAdjacents());
+ InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
}
};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/TrappedChestHandler.h b/src/Simulator/IncrementalRedstoneSimulator/TrappedChestHandler.h
index e8483a73a..707c239e9 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/TrappedChestHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/TrappedChestHandler.h
@@ -15,54 +15,51 @@ class cTrappedChestHandler:
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<cIncrementalRedstoneSimulator *>(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 & a_Chunk, Vector3i a_Position)
{
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
-
int NumberOfPlayers = 0;
- VERIFY(!a_World.DoWithChestAt(a_Position.x, a_Position.y, a_Position.z, [&](cChestEntity & a_Chest)
+ VERIFY(
+ !a_Chunk.DoWithChestAt(a_Position, [&](cChestEntity & a_Chest)
{
ASSERT(a_Chest.GetBlockType() == E_BLOCK_TRAPPED_CHEST);
NumberOfPlayers = a_Chest.GetNumberOfPlayers();
return true;
- }
- ));
+ })
+ );
+
return static_cast<unsigned char>(std::min(NumberOfPlayers, 15));
}
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
+ virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
// LOGD("Evaluating tricky the trapped chest (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- auto Power = GetPowerLevel(a_World, a_Position, a_BlockType, a_Meta);
- auto PreviousPower = static_cast<cIncrementalRedstoneSimulator *>(a_World.GetRedstoneSimulator())->GetChunkData()->ExchangeUpdateOncePowerData(a_Position, PoweringData(a_BlockType, Power));
+ const auto Power = GetPowerLevel(a_Chunk, a_Position);
+ const auto PreviousPower = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, PoweringData(a_BlockType, Power));
if (Power != PreviousPower.PowerLevel)
{
- return GetAdjustedRelatives(a_Position, StaticAppend(GetRelativeLaterals(), cVector3iArray{ OffsetYM() }));
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, OffsetYM);
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeLaterals);
}
-
- return {};
}
- 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);
}
};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h b/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h
index 6a857cd7c..7c00c4e2f 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h
@@ -8,43 +8,53 @@
-class cTripwireHookHandler:
- public cRedstoneHandler
+class cTripwireHookHandler 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_QueryBlockType);
UNUSED(a_QueryPosition);
- return (GetPowerLevel(a_World, a_Position, a_BlockType, a_Meta) == 15) ? 15 : 0;
+ return (GetPowerLevel(a_Chunk, a_Position, a_Meta) == 15) ? 15 : 0;
}
- virtual unsigned char GetPowerLevel(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
+ static unsigned char GetPowerLevel(cChunk & a_Chunk, Vector3i a_Position, NIBBLETYPE a_Meta)
{
- UNUSED(a_BlockType);
-
bool FoundActivated = false;
- auto Position = a_Position;
- eBlockFace FaceToGoTowards = cBlockTripwireHookHandler::MetadataToDirection(a_Meta);
+ const auto FaceToGoTowards = cBlockTripwireHookHandler::MetadataToDirection(a_Meta);
for (int i = 0; i < 40; ++i) // Tripwires can be connected up to 40 blocks
{
BLOCKTYPE Type;
NIBBLETYPE Meta;
- AddFaceDirection(Position.x, Position.y, Position.z, FaceToGoTowards);
- a_World.GetBlockTypeMeta(Position.x, Position.y, Position.z, Type, Meta);
+ a_Position = AddFaceDirection(a_Position, FaceToGoTowards);
+ if (!a_Chunk.UnboundedRelGetBlock(a_Position, Type, Meta))
+ {
+ return 0;
+ }
if (Type == E_BLOCK_TRIPWIRE)
{
- if (!a_World.ForEachEntityInBox(cBoundingBox(Vector3d(0.5, 0, 0.5) + Position, 0.5, 0.5), [](cEntity &) { return true; }))
+ if (FoundActivated)
+ {
+ continue;
+ }
+
+ if (
+ !a_Chunk.ForEachEntityInBox(
+ cBoundingBox(Vector3d(0.5, 0, 0.5) + cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos()), 0.5, 0.5),
+ [](cEntity &) { return true; }
+ )
+ )
{
FoundActivated = true;
}
+
+ continue;
}
else if (Type == E_BLOCK_TRIPWIRE_HOOK)
{
@@ -53,27 +63,20 @@ public:
// Other hook facing in opposite direction - circuit completed!
return FoundActivated ? 15 : 1;
}
- else
- {
- // Tripwire hook not connected at all
- return 0;
- }
- }
- else
- {
- // Tripwire hook not connected at all
- return 0;
}
+
+ // Tripwire hook not connected at all
+ return 0;
}
return 0;
}
- virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
+ virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
// LOGD("Evaluating hooky the tripwire hook (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- auto Power = GetPowerLevel(a_World, a_Position, a_BlockType, a_Meta);
+ const auto Power = GetPowerLevel(a_Chunk, a_Position, a_Meta);
NIBBLETYPE Meta;
if (Power == 0)
{
@@ -91,25 +94,22 @@ public:
}
else
{
- ASSERT(!"Unexpected tripwire hook power level!");
- return {};
+ UNREACHABLE("Unexpected tripwire hook power level!");
}
if (Meta != a_Meta)
{
- a_World.SetBlockMeta(a_Position, Meta);
- return GetAdjustedRelatives(a_Position, GetRelativeAdjacents());
+ a_Chunk.SetMeta(a_Position, Meta);
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
}
-
- return {};
}
- 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_BlockType);
UNUSED(a_Meta);
UNUSED(a_Position);
- return {};
+ UNUSED(Callback);
}
};
diff --git a/src/Simulator/NoopRedstoneSimulator.h b/src/Simulator/NoopRedstoneSimulator.h
index 4959882fa..91436ce7e 100644
--- a/src/Simulator/NoopRedstoneSimulator.h
+++ b/src/Simulator/NoopRedstoneSimulator.h
@@ -7,7 +7,7 @@
-class cRedstoneNoopSimulator:
+class cRedstoneNoopSimulator final :
public cRedstoneSimulator
{
using Super = cRedstoneSimulator;