diff options
author | Tiger Wang <ziwei.tiger@outlook.com> | 2020-08-19 22:14:40 +0200 |
---|---|---|
committer | Tiger Wang <ziwei.tiger@outlook.com> | 2020-08-21 01:50:09 +0200 |
commit | 3143d6ce679f322ee73d3d70e2d843e9c98cc043 (patch) | |
tree | 8ccc3b6d2a22a848e0c01c667aa10b25c3a5684e /src/Simulator | |
parent | Minor typo fixes (diff) | |
download | cuberite-3143d6ce679f322ee73d3d70e2d843e9c98cc043.tar cuberite-3143d6ce679f322ee73d3d70e2d843e9c98cc043.tar.gz cuberite-3143d6ce679f322ee73d3d70e2d843e9c98cc043.tar.bz2 cuberite-3143d6ce679f322ee73d3d70e2d843e9c98cc043.tar.lz cuberite-3143d6ce679f322ee73d3d70e2d843e9c98cc043.tar.xz cuberite-3143d6ce679f322ee73d3d70e2d843e9c98cc043.tar.zst cuberite-3143d6ce679f322ee73d3d70e2d843e9c98cc043.zip |
Diffstat (limited to 'src/Simulator')
28 files changed, 494 insertions, 545 deletions
diff --git a/src/Simulator/IncrementalRedstoneSimulator/CMakeLists.txt b/src/Simulator/IncrementalRedstoneSimulator/CMakeLists.txt index 3f64d6e4e..2a9b2894b 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/CMakeLists.txt +++ b/src/Simulator/IncrementalRedstoneSimulator/CMakeLists.txt @@ -3,6 +3,7 @@ target_sources( ForEachSourceCallback.cpp IncrementalRedstoneSimulator.cpp + RedstoneHandler.cpp CommandBlockHandler.h DoorHandler.h @@ -13,6 +14,7 @@ target_sources( RedstoneHandler.h RedstoneSimulatorChunkData.h RedstoneComparatorHandler.h + RedstoneDataHelper.h RedstoneRepeaterHandler.h RedstoneBlockHandler.h RedstoneTorchHandler.h diff --git a/src/Simulator/IncrementalRedstoneSimulator/CommandBlockHandler.h b/src/Simulator/IncrementalRedstoneSimulator/CommandBlockHandler.h index 89dc55ecd..72871b12d 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/CommandBlockHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/CommandBlockHandler.h @@ -1,16 +1,15 @@ #pragma once -#include "RedstoneHandler.h" #include "../../BlockEntities/CommandBlockEntity.h" -class cCommandBlockHandler final : public cRedstoneHandler +namespace CommandBlockHandler { - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) { UNUSED(a_Chunk); UNUSED(a_Position); @@ -21,7 +20,7 @@ class cCommandBlockHandler final : public cRedstoneHandler return 0; } - virtual void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // LOGD("Evaluating commander the cmdblck (%d %d %d)", a_Position.x, a_Position.y, a_Position.z); @@ -39,7 +38,7 @@ class cCommandBlockHandler final : public cRedstoneHandler }); } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { UNUSED(a_Chunk); UNUSED(a_BlockType); diff --git a/src/Simulator/IncrementalRedstoneSimulator/DoorHandler.h b/src/Simulator/IncrementalRedstoneSimulator/DoorHandler.h index 7011b852b..4806a0367 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/DoorHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/DoorHandler.h @@ -1,18 +1,17 @@ #pragma once -#include "RedstoneHandler.h" #include "../../Blocks/BlockDoor.h" -class cDoorHandler final : public cRedstoneHandler +namespace DoorHandler { // "Doormammu, I've come to bargain" - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) { UNUSED(a_Chunk); UNUSED(a_Position); @@ -23,7 +22,7 @@ class cDoorHandler final : public cRedstoneHandler return 0; } - virtual void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // LOGD("Evaluating dori the door (%d %d %d)", a_Position.x, a_Position.y, a_Position.z); @@ -35,7 +34,7 @@ class cDoorHandler final : public cRedstoneHandler const auto TopPosition = a_Position + OffsetYP; ForEachSourceCallback Callback(a_Chunk, TopPosition, a_BlockType); - ForValidSourcePositions(a_Chunk, TopPosition, a_BlockType, a_Meta, Callback); + RedstoneHandler::ForValidSourcePositions(a_Chunk, TopPosition, a_BlockType, a_Meta, Callback); // Factor in what the upper half is getting: a_PoweringData = std::max(a_PoweringData, Callback.Power); @@ -52,7 +51,7 @@ class cDoorHandler final : public cRedstoneHandler } } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { UNUSED(a_Chunk); UNUSED(a_BlockType); diff --git a/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h b/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h index d953be8c0..76cc5893a 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h @@ -1,21 +1,20 @@ #pragma once -#include "RedstoneHandler.h" #include "../../BlockEntities/DropSpenserEntity.h" -class cDropSpenserHandler final : public cRedstoneHandler +namespace DropSpenserHandler { - inline static bool IsActivated(NIBBLETYPE a_Meta) + inline bool IsActivated(NIBBLETYPE a_Meta) { return (a_Meta & E_META_DROPSPENSER_ACTIVATED) != 0; } - inline static NIBBLETYPE SetActivationState(NIBBLETYPE a_Meta, bool IsOn) + inline NIBBLETYPE SetActivationState(NIBBLETYPE a_Meta, bool IsOn) { if (IsOn) { @@ -27,7 +26,7 @@ class cDropSpenserHandler final : public cRedstoneHandler } } - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) { UNUSED(a_Chunk); UNUSED(a_Position); @@ -38,7 +37,7 @@ class cDropSpenserHandler final : public cRedstoneHandler return 0; } - virtual void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // LOGD("Evaluating spencer the dropspenser (%d %d %d)", a_Position.x, a_Position.y, a_Position.z); @@ -61,7 +60,7 @@ class cDropSpenserHandler final : public cRedstoneHandler } } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { UNUSED(a_Chunk); UNUSED(a_BlockType); diff --git a/src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.cpp b/src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.cpp index 3bf0fc371..a0dd8fe94 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.cpp @@ -2,9 +2,10 @@ #include "Globals.h" #include "ForEachSourceCallback.h" -#include "IncrementalRedstoneSimulator.h" #include "../../BlockInfo.h" #include "../../Chunk.h" +#include "IncrementalRedstoneSimulator.h" +#include "RedstoneHandler.h" @@ -67,16 +68,10 @@ void ForEachSourceCallback::operator()(Vector3i Location) PoweringData ForEachSourceCallback::QueryPower(const cChunk & Chunk, const Vector3i SourcePosition, const BLOCKTYPE SourceBlock, const Vector3i QueryPosition, const BLOCKTYPE QueryBlock, const bool IsLinked) { - const auto PotentialSourceHandler = cIncrementalRedstoneSimulator::GetComponentHandler(SourceBlock); - if (PotentialSourceHandler == nullptr) - { - return {}; - } - return { SourceBlock, - PotentialSourceHandler->GetPowerDeliveredToPosition( + RedstoneHandler::GetPowerDeliveredToPosition( Chunk, SourcePosition, SourceBlock, QueryPosition, QueryBlock, IsLinked ) diff --git a/src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.h b/src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.h index 4ab3866d3..daf1ef363 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.h +++ b/src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.h @@ -1,7 +1,6 @@ #pragma once -#include "ForEachSourceCallback.h" #include "RedstoneSimulatorChunkData.h" class ForEachSourceCallback diff --git a/src/Simulator/IncrementalRedstoneSimulator/HopperHandler.h b/src/Simulator/IncrementalRedstoneSimulator/HopperHandler.h index 24685e287..32b948553 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/HopperHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/HopperHandler.h @@ -1,16 +1,15 @@ #pragma once -#include "RedstoneHandler.h" #include "../../BlockEntities/HopperEntity.h" -class cHopperHandler final : public cRedstoneHandler +namespace HopperHandler { - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) { UNUSED(a_Chunk); UNUSED(a_Position); @@ -21,7 +20,7 @@ class cHopperHandler final : public cRedstoneHandler return 0; } - virtual void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // LOGD("Evaluating holey the hopper (%d %d %d)", a_Position.x, a_Position.y, a_Position.z); @@ -38,7 +37,7 @@ class cHopperHandler final : public cRedstoneHandler }); } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { UNUSED(a_Chunk); UNUSED(a_BlockType); diff --git a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp index 056bfb368..d9e4aa961 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp @@ -2,122 +2,9 @@ #include "Globals.h" #include "IncrementalRedstoneSimulator.h" +#include "RedstoneHandler.h" #include "ForEachSourceCallback.h" -#include "CommandBlockHandler.h" -#include "DoorHandler.h" -#include "RedstoneTorchHandler.h" -#include "RedstoneWireHandler.h" -#include "RedstoneRepeaterHandler.h" -#include "RedstoneToggleHandler.h" -#include "RedstoneLampHandler.h" -#include "RedstoneBlockHandler.h" -#include "PistonHandler.h" -#include "SmallGateHandler.h" -#include "NoteBlockHandler.h" -#include "ObserverHandler.h" -#include "TNTHandler.h" -#include "PoweredRailHandler.h" -#include "PressurePlateHandler.h" -#include "TripwireHookHandler.h" -#include "DropSpenserHandler.h" -#include "RedstoneComparatorHandler.h" -#include "TrappedChestHandler.h" -#include "HopperHandler.h" - - - - - -const cRedstoneHandler * cIncrementalRedstoneSimulator::GetComponentHandler(BLOCKTYPE a_BlockType) -{ - struct sComponents : - public std::array<std::unique_ptr<cRedstoneHandler>, 256> - { - sComponents() - { - for (size_t i = 0; i != 256; ++i) - { - (*this)[i] = cIncrementalRedstoneSimulator::CreateComponent(static_cast<BLOCKTYPE>(i)); - } - } - }; - - - static sComponents Components; - return Components[a_BlockType].get(); -} - - - - - -std::unique_ptr<cRedstoneHandler> cIncrementalRedstoneSimulator::CreateComponent(BLOCKTYPE a_BlockType) -{ - switch (a_BlockType) - { - case E_BLOCK_ACTIVATOR_RAIL: - case E_BLOCK_DETECTOR_RAIL: - case E_BLOCK_POWERED_RAIL: return std::make_unique<cPoweredRailHandler>(); - - case E_BLOCK_ACTIVE_COMPARATOR: - case E_BLOCK_INACTIVE_COMPARATOR: return std::make_unique<cRedstoneComparatorHandler>(); - - case E_BLOCK_DISPENSER: - case E_BLOCK_DROPPER: return std::make_unique<cDropSpenserHandler>(); - - case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: - case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: - case E_BLOCK_STONE_PRESSURE_PLATE: - case E_BLOCK_WOODEN_PRESSURE_PLATE: return std::make_unique<cPressurePlateHandler>(); - - case E_BLOCK_ACACIA_FENCE_GATE: - case E_BLOCK_BIRCH_FENCE_GATE: - case E_BLOCK_DARK_OAK_FENCE_GATE: - case E_BLOCK_FENCE_GATE: - case E_BLOCK_IRON_TRAPDOOR: - case E_BLOCK_JUNGLE_FENCE_GATE: - case E_BLOCK_SPRUCE_FENCE_GATE: - case E_BLOCK_TRAPDOOR: return std::make_unique<cSmallGateHandler>(); - - case E_BLOCK_REDSTONE_LAMP_OFF: - case E_BLOCK_REDSTONE_LAMP_ON: return std::make_unique<cRedstoneLampHandler>(); - - case E_BLOCK_REDSTONE_REPEATER_OFF: - case E_BLOCK_REDSTONE_REPEATER_ON: return std::make_unique<cRedstoneRepeaterHandler>(); - - case E_BLOCK_REDSTONE_TORCH_OFF: - case E_BLOCK_REDSTONE_TORCH_ON: return std::make_unique<cRedstoneTorchHandler>(); - - case E_BLOCK_OBSERVER: return std::make_unique<cObserverHandler>(); - - case E_BLOCK_PISTON: - case E_BLOCK_STICKY_PISTON: return std::make_unique<cPistonHandler>(); - - case E_BLOCK_LEVER: - case E_BLOCK_STONE_BUTTON: - case E_BLOCK_WOODEN_BUTTON: return std::make_unique<cRedstoneToggleHandler>(); - - case E_BLOCK_BLOCK_OF_REDSTONE: return std::make_unique<cRedstoneBlockHandler>(); - case E_BLOCK_COMMAND_BLOCK: return std::make_unique<cCommandBlockHandler>(); - case E_BLOCK_HOPPER: return std::make_unique<cHopperHandler>(); - case E_BLOCK_NOTE_BLOCK: return std::make_unique<cNoteBlockHandler>(); - case E_BLOCK_REDSTONE_WIRE: return std::make_unique<cRedstoneWireHandler>(); - case E_BLOCK_TNT: return std::make_unique<cTNTHandler>(); - case E_BLOCK_TRAPPED_CHEST: return std::make_unique<cTrappedChestHandler>(); - case E_BLOCK_TRIPWIRE_HOOK: return std::make_unique<cTripwireHookHandler>(); - default: - { - if (cBlockDoorHandler::IsDoorBlockType(a_BlockType)) - { - return std::make_unique<cDoorHandler>(); - } - - return nullptr; - } - } -} - @@ -168,19 +55,11 @@ void cIncrementalRedstoneSimulator::ProcessWorkItem(cChunk & Chunk, cChunk & Tic NIBBLETYPE CurrentMeta; Chunk.GetBlockTypeMeta(Position, CurrentBlock, CurrentMeta); - auto CurrentHandler = GetComponentHandler(CurrentBlock); - if (CurrentHandler == nullptr) - { - // Block at Position doesn't have a corresponding redstone handler - // ErasePowerData will have been called in AddBlock - return; - } - ForEachSourceCallback Callback(Chunk, Position, CurrentBlock); - CurrentHandler->ForValidSourcePositions(Chunk, Position, CurrentBlock, CurrentMeta, Callback); + RedstoneHandler::ForValidSourcePositions(Chunk, Position, CurrentBlock, CurrentMeta, Callback); // Inform the handler to update - CurrentHandler->Update(Chunk, TickingSource, Position, CurrentBlock, CurrentMeta, Callback.Power); + RedstoneHandler::Update(Chunk, TickingSource, Position, CurrentBlock, CurrentMeta, Callback.Power); } @@ -189,14 +68,12 @@ void cIncrementalRedstoneSimulator::ProcessWorkItem(cChunk & Chunk, cChunk & Tic void cIncrementalRedstoneSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) { + // Never update blocks without a handler: if (!IsRedstone(a_Block)) { return; } - // Never update blocks without a handler: - ASSERT(GetComponentHandler(a_Block) != nullptr); - auto & ChunkData = *static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_Chunk.GetRedstoneSimulatorData()); if (IsAlwaysTicked(a_Block)) @@ -207,7 +84,7 @@ void cIncrementalRedstoneSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Positi // Temporary: in the absence of block state support calculate our own: if (a_Block == E_BLOCK_REDSTONE_WIRE) { - static_cast<const cRedstoneWireHandler *>(GetComponentHandler(a_Block))->SetWireState(a_Chunk, a_Position); + RedstoneHandler::SetWireState(a_Chunk, a_Position); } // Always update redstone devices: diff --git a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h index a940b8920..dc00f73c7 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h +++ b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h @@ -2,7 +2,6 @@ #pragma once #include "../RedstoneSimulator.h" -#include "RedstoneHandler.h" #include "RedstoneSimulatorChunkData.h" @@ -18,8 +17,6 @@ public: using Super::cRedstoneSimulator; - static const cRedstoneHandler * GetComponentHandler(BLOCKTYPE a_BlockType); - private: /** Returns if a redstone device is always ticked due to influence by its environment */ @@ -110,8 +107,4 @@ private: virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override; virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override; virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, Vector3i a_Offset, BLOCKTYPE a_Block) override; - -private: - - static std::unique_ptr<cRedstoneHandler> CreateComponent(BLOCKTYPE a_BlockType); } ; diff --git a/src/Simulator/IncrementalRedstoneSimulator/NoteBlockHandler.h b/src/Simulator/IncrementalRedstoneSimulator/NoteBlockHandler.h index e610e6bdf..366129f31 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/NoteBlockHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/NoteBlockHandler.h @@ -1,16 +1,15 @@ #pragma once -#include "RedstoneHandler.h" #include "../../BlockEntities/NoteEntity.h" -class cNoteBlockHandler: public cRedstoneHandler +namespace NoteBlockHandler { - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) { UNUSED(a_Chunk); UNUSED(a_Position); @@ -21,7 +20,7 @@ class cNoteBlockHandler: public cRedstoneHandler return 0; } - virtual void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // LOGD("Evaluating sparky the magical note block (%d %d %d) %i", a_Position.x, a_Position.y, a_Position.z, a_PoweringData.PowerLevel); @@ -39,7 +38,7 @@ class cNoteBlockHandler: public cRedstoneHandler }); } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { UNUSED(a_Chunk); UNUSED(a_BlockType); diff --git a/src/Simulator/IncrementalRedstoneSimulator/ObserverHandler.h b/src/Simulator/IncrementalRedstoneSimulator/ObserverHandler.h index c0866824b..926b3ab51 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/ObserverHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/ObserverHandler.h @@ -1,21 +1,20 @@ #pragma once -#include "RedstoneHandler.h" #include "../../Blocks/BlockObserver.h" -class cObserverHandler final : public cRedstoneHandler +namespace ObserverHandler { - inline static bool IsOn(NIBBLETYPE a_Meta) + inline bool IsOn(NIBBLETYPE a_Meta) { return (a_Meta & 0x8) == 0x8; } - static bool ShouldPowerOn(cChunk & Chunk, const Vector3i a_Position, NIBBLETYPE a_Meta, cIncrementalRedstoneSimulatorChunkData & a_Data) + inline bool ShouldPowerOn(cChunk & Chunk, const Vector3i a_Position, NIBBLETYPE a_Meta, cIncrementalRedstoneSimulatorChunkData & a_Data) { BLOCKTYPE BlockType; NIBBLETYPE BlockMeta; @@ -32,13 +31,13 @@ class cObserverHandler final : public cRedstoneHandler return (Previous.PoweringBlock != Observed.PoweringBlock) || (Previous.PowerLevel != Observed.PowerLevel); } - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) { const auto Meta = a_Chunk.GetMeta(a_Position); return (IsOn(Meta) && (a_QueryPosition == (a_Position + cBlockObserverHandler::GetSignalOutputOffset(Meta)))) ? 15 : 0; } - virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // LOGD("Evaluating Lenny the observer (%i %i %i)", a_Position.x, a_Position.y, a_Position.z); @@ -84,7 +83,7 @@ class cObserverHandler final : public cRedstoneHandler UpdateAdjustedRelative(a_Chunk, CurrentlyTicking, a_Position, cBlockObserverHandler::GetSignalOutputOffset(a_Meta)); } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { UNUSED(a_Chunk); UNUSED(a_Position); diff --git a/src/Simulator/IncrementalRedstoneSimulator/PistonHandler.h b/src/Simulator/IncrementalRedstoneSimulator/PistonHandler.h index 14932b95b..81b19688e 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/PistonHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/PistonHandler.h @@ -1,16 +1,15 @@ #pragma once -#include "RedstoneHandler.h" #include "../../Blocks/BlockPiston.h" -class cPistonHandler final: public cRedstoneHandler +namespace PistonHandler { - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) { UNUSED(a_Chunk); UNUSED(a_Position); @@ -21,7 +20,7 @@ class cPistonHandler final: public cRedstoneHandler return 0; } - virtual void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // LOGD("Evaluating pisty the piston (%d %d %d)", a_Position.x, a_Position.y, a_Position.z); @@ -46,7 +45,7 @@ class cPistonHandler final: public cRedstoneHandler // However, this delay is already present: as a side effect of the implementation of piston animation in Blocks\BlockPiston.cpp } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { UNUSED(a_Chunk); UNUSED(a_BlockType); diff --git a/src/Simulator/IncrementalRedstoneSimulator/PoweredRailHandler.h b/src/Simulator/IncrementalRedstoneSimulator/PoweredRailHandler.h index 6f8dbc196..c420251b1 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/PoweredRailHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/PoweredRailHandler.h @@ -1,15 +1,13 @@ #pragma once -#include "RedstoneHandler.h" - -class cPoweredRailHandler final : public cRedstoneHandler +namespace PoweredRailHandler { - static Vector3i GetPoweredRailAdjacentXZCoordinateOffset(NIBBLETYPE a_Meta) // Not in cBlockRailHandler since specific to powered rails + Vector3i GetPoweredRailAdjacentXZCoordinateOffset(NIBBLETYPE a_Meta) // Not in cBlockRailHandler since specific to powered rails { switch (a_Meta & 0x7) { @@ -27,7 +25,7 @@ class cPoweredRailHandler final : public cRedstoneHandler } } - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) { UNUSED(a_QueryBlockType); @@ -41,7 +39,7 @@ class cPoweredRailHandler final : public cRedstoneHandler return 0; } - virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTickingChunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTickingChunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // LOGD("Evaluating tracky the rail (%d %d %d)", a_Position.x, a_Position.y, a_Position.z); @@ -78,7 +76,7 @@ class cPoweredRailHandler final : public cRedstoneHandler } } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { UNUSED(a_Chunk); UNUSED(a_Meta); diff --git a/src/Simulator/IncrementalRedstoneSimulator/PressurePlateHandler.h b/src/Simulator/IncrementalRedstoneSimulator/PressurePlateHandler.h index 979d1ef96..61450278f 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/PressurePlateHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/PressurePlateHandler.h @@ -1,7 +1,6 @@ #pragma once -#include "RedstoneHandler.h" #include "../../BoundingBox.h" #include "../../Entities/Pickup.h" @@ -9,20 +8,9 @@ -class cPressurePlateHandler final : public cRedstoneHandler +namespace PressurePlateHandler { - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override - { - UNUSED(a_BlockType); - UNUSED(a_QueryPosition); - UNUSED(a_QueryBlockType); - - // Plates only link power blocks below - // Retrieve and return the cached power calculated by Update for performance: - return (IsLinked && (a_QueryPosition != (a_Position + OffsetYM))) ? 0 : DataForChunk(a_Chunk).GetCachedPowerData(a_Position).PowerLevel; - } - - static unsigned char GetPowerLevel(const cChunk & Chunk, const Vector3i Position, const BLOCKTYPE BlockType) + inline unsigned char GetPowerLevel(const cChunk & Chunk, const Vector3i Position, const BLOCKTYPE BlockType) { unsigned NumberOfEntities = 0; bool FoundPlayer = false; @@ -69,7 +57,52 @@ class cPressurePlateHandler final : public cRedstoneHandler } } - virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline 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_HEAVY_WEIGHTED_PRESSURE_PLATE: + case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: return "block.metal_pressureplate.click_on"; + default: + { + ASSERT(!"No on sound for this one!"); + return ""; + } + } + } + + inline 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_HEAVY_WEIGHTED_PRESSURE_PLATE: + case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: return "block.metal_pressureplate.click_off"; + default: + { + ASSERT(!"No off sound for this one!"); + return ""; + } + } + } + + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) + { + UNUSED(a_BlockType); + UNUSED(a_QueryPosition); + UNUSED(a_QueryBlockType); + + // Plates only link power blocks below + // Retrieve and return the cached power calculated by Update for performance: + return (IsLinked && (a_QueryPosition != (a_Position + OffsetYM))) ? 0 : DataForChunk(a_Chunk).GetCachedPowerData(a_Position).PowerLevel; + } + + inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // LOGD("Evaluating clicky the pressure plate (%d %d %d)", a_Position.x, a_Position.y, a_Position.z); @@ -171,7 +204,7 @@ class cPressurePlateHandler final : public cRedstoneHandler UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents); } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { UNUSED(a_Chunk); UNUSED(a_Position); @@ -179,40 +212,4 @@ class cPressurePlateHandler final : public cRedstoneHandler UNUSED(a_Meta); UNUSED(Callback); } - -private: - - 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_HEAVY_WEIGHTED_PRESSURE_PLATE: - case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: return "block.metal_pressureplate.click_on"; - default: - { - ASSERT(!"No on sound for this one!"); - return ""; - } - } - } - - 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_HEAVY_WEIGHTED_PRESSURE_PLATE: - case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: return "block.metal_pressureplate.click_off"; - default: - { - ASSERT(!"No off sound for this one!"); - return ""; - } - } - } }; diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneBlockHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneBlockHandler.h index 51e2162d1..630cb6a3a 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneBlockHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneBlockHandler.h @@ -1,17 +1,13 @@ #pragma once -#include "RedstoneHandler.h" - -class cRedstoneBlockHandler final : public cRedstoneHandler +namespace RedstoneBlockHandler { -public: - - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) { UNUSED(a_Chunk); UNUSED(a_Position); @@ -21,12 +17,12 @@ public: return IsLinked ? 0 : 15; } - virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // LOGD("Evaluating crimson the redstone block (%d %d %d)", a_Position.x, a_Position.y, a_Position.z); } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { UNUSED(a_Chunk); UNUSED(a_Position); diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneComparatorHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneComparatorHandler.h index bf781eb7a..7200eede0 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneComparatorHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneComparatorHandler.h @@ -1,16 +1,15 @@ #pragma once -#include "RedstoneHandler.h" #include "../../Blocks/BlockComparator.h" -class cRedstoneComparatorHandler : public cRedstoneHandler +namespace RedstoneComparatorHandler { - static unsigned char GetFrontPowerLevel(NIBBLETYPE a_Meta, unsigned char a_HighestSidePowerLevel, unsigned char a_HighestRearPowerLevel) + inline unsigned char GetFrontPowerLevel(NIBBLETYPE a_Meta, unsigned char a_HighestSidePowerLevel, unsigned char a_HighestRearPowerLevel) { if (cBlockComparatorHandler::IsInSubtractionMode(a_Meta)) { @@ -24,7 +23,7 @@ class cRedstoneComparatorHandler : public cRedstoneHandler } } - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) { UNUSED(a_QueryPosition); UNUSED(a_QueryBlockType); @@ -36,7 +35,7 @@ class cRedstoneComparatorHandler : public cRedstoneHandler ); } - static unsigned char GetPowerLevel(cChunk & a_Chunk, Vector3i Position, BLOCKTYPE BlockType, NIBBLETYPE Meta) + inline unsigned char GetPowerLevel(cChunk & a_Chunk, Vector3i Position, BLOCKTYPE BlockType, NIBBLETYPE Meta) { UInt8 SignalStrength = 0; auto RearCoordinate = cBlockComparatorHandler::GetRearCoordinate(Position, Meta & 0x3); @@ -71,22 +70,16 @@ class cRedstoneComparatorHandler : public cRedstoneHandler }); const auto RearType = RearChunk->GetBlock(RearCoordinate); - const auto PotentialSourceHandler = cIncrementalRedstoneSimulator::GetComponentHandler(RearType); - if (PotentialSourceHandler == nullptr) - { - return SignalStrength; - } - return std::max( SignalStrength, - PotentialSourceHandler->GetPowerDeliveredToPosition( + RedstoneHandler::GetPowerDeliveredToPosition( *RearChunk, RearCoordinate, RearType, cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(a_Chunk, *RearChunk, Position), BlockType, false ) ); } - virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // 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); @@ -132,7 +125,7 @@ class cRedstoneComparatorHandler : public cRedstoneHandler UpdateAdjustedRelative(a_Chunk, CurrentlyTicking, a_Position, cBlockComparatorHandler::GetFrontCoordinate(a_Position, a_Meta & 0x3) - a_Position); } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { UNUSED(a_Chunk); UNUSED(a_BlockType); diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneDataHelper.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneDataHelper.h new file mode 100644 index 000000000..16d6924b1 --- /dev/null +++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneDataHelper.h @@ -0,0 +1,63 @@ +#pragma once + +#include "../../Chunk.h" + +inline auto & DataForChunk(const cChunk & a_Chunk) +{ + return *static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_Chunk.GetRedstoneSimulatorData()); +} + +template <typename... ArrayTypes> +inline void UpdateAdjustedRelative(const cChunk & From, const cChunk & To, const Vector3i Position, const Vector3i Offset) +{ + DataForChunk(To).WakeUp(cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(From, To, Position + Offset)); + + for (const auto LinkedOffset : cSimulator::GetLinkedOffsets(Offset)) + { + DataForChunk(To).WakeUp(cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(From, To, Position + LinkedOffset)); + } +} + +template <typename ArrayType> +inline void UpdateAdjustedRelatives(const cChunk & From, const cChunk & To, const Vector3i Position, const ArrayType & Relative) +{ + for (const auto Offset : Relative) + { + UpdateAdjustedRelative(From, To, Position, Offset); + } +} + +template <typename ArrayType> +inline void InvokeForAdjustedRelatives(ForEachSourceCallback & Callback, const Vector3i Position, const ArrayType & Relative) +{ + for (const auto Offset : Relative) + { + Callback(Position + Offset); + } +} + +inline constexpr Vector3i OffsetYP{ 0, 1, 0 }; + +inline constexpr Vector3i OffsetYM{ 0, -1, 0 }; + +inline constexpr std::array<Vector3i, 6> RelativeAdjacents +{ + { + { 1, 0, 0 }, + { -1, 0, 0 }, + { 0, 1, 0 }, + { 0, -1, 0 }, + { 0, 0, 1 }, + { 0, 0, -1 }, + } +}; + +inline constexpr std::array<Vector3i, 4> RelativeLaterals +{ + { + { 1, 0, 0 }, + { -1, 0, 0 }, + { 0, 0, 1 }, + { 0, 0, -1 }, + } +}; diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.cpp b/src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.cpp new file mode 100644 index 000000000..c5457e302 --- /dev/null +++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.cpp @@ -0,0 +1,128 @@ + +#include "Globals.h" + +#include "RedstoneHandler.h" +#include "RedstoneDataHelper.h" +#include "ForEachSourceCallback.h" + +#include "CommandBlockHandler.h" +#include "DoorHandler.h" +#include "RedstoneTorchHandler.h" +#include "RedstoneWireHandler.h" +#include "RedstoneRepeaterHandler.h" +#include "RedstoneToggleHandler.h" +#include "RedstoneLampHandler.h" +#include "RedstoneBlockHandler.h" +#include "PistonHandler.h" +#include "SmallGateHandler.h" +#include "NoteBlockHandler.h" +#include "ObserverHandler.h" +#include "TNTHandler.h" +#include "PoweredRailHandler.h" +#include "PressurePlateHandler.h" +#include "TripwireHookHandler.h" +#include "DropSpenserHandler.h" +#include "RedstoneComparatorHandler.h" +#include "TrappedChestHandler.h" +#include "HopperHandler.h" + + + + + +#define INVOKE_FOR_HANDLERS(Callback) \ + switch (BlockType) \ + { \ + case E_BLOCK_ACTIVATOR_RAIL: \ + case E_BLOCK_DETECTOR_RAIL: \ + case E_BLOCK_POWERED_RAIL: return PoweredRailHandler::Callback; \ + case E_BLOCK_ACTIVE_COMPARATOR: \ + case E_BLOCK_INACTIVE_COMPARATOR: return RedstoneComparatorHandler::Callback; \ + case E_BLOCK_DISPENSER: \ + case E_BLOCK_DROPPER: return DropSpenserHandler::Callback; \ + case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: \ + case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: \ + case E_BLOCK_STONE_PRESSURE_PLATE: \ + case E_BLOCK_WOODEN_PRESSURE_PLATE: return PressurePlateHandler::Callback; \ + case E_BLOCK_ACACIA_FENCE_GATE: \ + case E_BLOCK_BIRCH_FENCE_GATE: \ + case E_BLOCK_DARK_OAK_FENCE_GATE: \ + case E_BLOCK_FENCE_GATE: \ + case E_BLOCK_IRON_TRAPDOOR: \ + case E_BLOCK_JUNGLE_FENCE_GATE: \ + case E_BLOCK_SPRUCE_FENCE_GATE: \ + case E_BLOCK_TRAPDOOR: return SmallGateHandler::Callback; \ + case E_BLOCK_REDSTONE_LAMP_OFF: \ + case E_BLOCK_REDSTONE_LAMP_ON: return RedstoneLampHandler::Callback; \ + case E_BLOCK_REDSTONE_REPEATER_OFF: \ + case E_BLOCK_REDSTONE_REPEATER_ON: return RedstoneRepeaterHandler::Callback; \ + case E_BLOCK_REDSTONE_TORCH_OFF: \ + case E_BLOCK_REDSTONE_TORCH_ON: return RedstoneTorchHandler::Callback; \ + case E_BLOCK_OBSERVER: return ObserverHandler::Callback; \ + case E_BLOCK_PISTON: \ + case E_BLOCK_STICKY_PISTON: return PistonHandler::Callback; \ + case E_BLOCK_LEVER: \ + case E_BLOCK_STONE_BUTTON: \ + case E_BLOCK_WOODEN_BUTTON: return RedstoneToggleHandler::Callback; \ + case E_BLOCK_BLOCK_OF_REDSTONE: return RedstoneBlockHandler::Callback; \ + case E_BLOCK_COMMAND_BLOCK: return CommandBlockHandler::Callback; \ + case E_BLOCK_HOPPER: return HopperHandler::Callback; \ + case E_BLOCK_NOTE_BLOCK: return NoteBlockHandler::Callback; \ + case E_BLOCK_REDSTONE_WIRE: return RedstoneWireHandler::Callback; \ + case E_BLOCK_TNT: return TNTHandler::Callback; \ + case E_BLOCK_TRAPPED_CHEST: return TrappedChestHandler::Callback; \ + case E_BLOCK_TRIPWIRE_HOOK: return TripwireHookHandler::Callback; \ + default: \ + { \ + if (cBlockDoorHandler::IsDoorBlockType(BlockType)) \ + { \ + return DoorHandler::Callback; \ + } \ + } \ + } + + + + + +namespace RedstoneHandler +{ + unsigned char GetPowerDeliveredToPosition(const cChunk & Chunk, const Vector3i Position, const BLOCKTYPE BlockType, const Vector3i QueryPosition, const BLOCKTYPE QueryBlockType, const bool IsLinked) + { + INVOKE_FOR_HANDLERS(GetPowerDeliveredToPosition(Chunk, Position, BlockType, QueryPosition, QueryBlockType, IsLinked)); + + // Fell through the switch statement + // Block at Position doesn't have a corresponding redstone handler + // ErasePowerData will have been called in AddBlock + + // Default: + return 0; + } + + + + + + void Update(cChunk & Chunk, cChunk & CurrentlyTicking, const Vector3i Position, const BLOCKTYPE BlockType, const NIBBLETYPE Meta, const PoweringData PoweringData) + { + INVOKE_FOR_HANDLERS(Update(Chunk, CurrentlyTicking, Position, BlockType, Meta, PoweringData)); + } + + + + + + void ForValidSourcePositions(const cChunk & Chunk, const Vector3i Position, const BLOCKTYPE BlockType, const NIBBLETYPE Meta, ForEachSourceCallback & Callback) + { + INVOKE_FOR_HANDLERS(ForValidSourcePositions(Chunk, Position, BlockType, Meta, Callback)); + } + + + + + + void SetWireState(const cChunk & Chunk, const Vector3i Position) + { + RedstoneWireHandler::SetWireState(Chunk, Position); + } +} diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.h index 9b131ece2..5b3dcdeac 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.h @@ -1,89 +1,18 @@ #pragma once -#include "../../Chunk.h" -#include "ForEachSourceCallback.h" #include "RedstoneSimulatorChunkData.h" +class cChunk; +class ForEachSourceCallback; - - - -class cRedstoneHandler +namespace RedstoneHandler { -public: - - cRedstoneHandler() = default; - DISALLOW_COPY_AND_ASSIGN(cRedstoneHandler); - - using SourceCallback = ForEachSourceCallback &; - - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) 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(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const = 0; - - // Force a virtual destructor - virtual ~cRedstoneHandler() {} - -protected: - - inline static auto & DataForChunk(const cChunk & a_Chunk) - { - return *static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_Chunk.GetRedstoneSimulatorData()); - } - - template <typename... ArrayTypes> - static void UpdateAdjustedRelative(const cChunk & From, const cChunk & To, const Vector3i Position, const Vector3i Offset) - { - DataForChunk(To).WakeUp(cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(From, To, Position + Offset)); - - for (const auto LinkedOffset : cSimulator::GetLinkedOffsets(Offset)) - { - DataForChunk(To).WakeUp(cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(From, To, Position + LinkedOffset)); - } - } - - template <typename ArrayType> - static void UpdateAdjustedRelatives(const cChunk & From, const cChunk & To, const Vector3i Position, const ArrayType & Relative) - { - for (const auto Offset : Relative) - { - UpdateAdjustedRelative(From, To, Position, Offset); - } - } - - template <typename ArrayType> - static void InvokeForAdjustedRelatives(SourceCallback Callback, const Vector3i Position, const ArrayType & Relative) - { - for (const auto Offset : Relative) - { - Callback(Position + Offset); - } - } - - inline static Vector3i OffsetYP{ 0, 1, 0 }; + unsigned char GetPowerDeliveredToPosition(const cChunk & Chunk, Vector3i Position, BLOCKTYPE BlockType, Vector3i QueryPosition, BLOCKTYPE QueryBlockType, bool IsLinked); - inline static Vector3i OffsetYM{ 0, -1, 0 }; + void Update(cChunk & Chunk, cChunk & CurrentlyTicking, Vector3i Position, BLOCKTYPE BlockType, NIBBLETYPE Meta, PoweringData PoweringData); - 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 }, - } - }; + void ForValidSourcePositions(const cChunk & Chunk, Vector3i Position, BLOCKTYPE BlockType, NIBBLETYPE Meta, ForEachSourceCallback & Callback); - inline static std::array<Vector3i, 4> RelativeLaterals - { - { - { 1, 0, 0 }, - { -1, 0, 0 }, - { 0, 0, 1 }, - { 0, 0, -1 }, - } - }; -}; + void SetWireState(const cChunk & Chunk, Vector3i Position); +} diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneLampHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneLampHandler.h index eb47e2367..a7f5bd332 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneLampHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneLampHandler.h @@ -5,19 +5,19 @@ -class cRedstoneLampHandler final : public cRedstoneHandler +namespace RedstoneLampHandler { - inline static bool IsOn(BLOCKTYPE a_BlockType) + inline bool IsOn(BLOCKTYPE a_BlockType) { return (a_BlockType == E_BLOCK_REDSTONE_LAMP_ON); } - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) { return 0; } - virtual void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // LOGD("Evaluating lamp (%i %i %i)", a_Position.x, a_Position.y, a_Position.z); @@ -37,7 +37,7 @@ class cRedstoneLampHandler final : public cRedstoneHandler } } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { UNUSED(a_Chunk); UNUSED(a_Meta); diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneRepeaterHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneRepeaterHandler.h index ce42e0163..ed890a8bb 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneRepeaterHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneRepeaterHandler.h @@ -1,16 +1,87 @@ #pragma once -#include "RedstoneHandler.h" #include "../../Blocks/BlockRedstoneRepeater.h" -class cRedstoneRepeaterHandler final : public cRedstoneHandler +namespace RedstoneRepeaterHandler { - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override + inline bool IsOn(BLOCKTYPE a_Block) + { + return (a_Block == E_BLOCK_REDSTONE_REPEATER_ON); + } + + /** 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. */ + inline std::pair<bool, NIBBLETYPE> IsOnRepeater(cChunk & Chunk, const Vector3i a_Position) + { + BLOCKTYPE Type; + NIBBLETYPE Meta; + + if (!Chunk.UnboundedRelGetBlock(a_Position, Type, Meta)) + { + return std::make_pair(false, 0); + } + + return std::make_pair(IsOn(Type), Meta); + } + + /** Determine, from the metadata of a repeater on our left side, if they lock us. + To test a repeater on our right, simply invert the order of arguments provided. + "Left" is relative to the direction the repeater output faces, naturally. */ + inline bool DoesLhsLockMe(NIBBLETYPE a_MetaLhs, NIBBLETYPE a_MyMeta) + { + // Get the direction bits + a_MetaLhs &= E_META_REDSTONE_REPEATER_FACING_MASK; + a_MyMeta &= E_META_REDSTONE_REPEATER_FACING_MASK; + + /* + Check for a valid locking configuration, where they are perpendicular and one snuggles into the other. + + Order of comparisons: + XP >^ ZM + ZP |_ XP + XM <| ZP + ZP ^< xM + + Key: + ^ Facing up + _ Facing right + | Facing down + < Facing left + */ + return + ((a_MetaLhs == E_META_REDSTONE_REPEATER_FACING_XP) && (a_MyMeta == E_META_REDSTONE_REPEATER_FACING_ZM)) || + ((a_MetaLhs == E_META_REDSTONE_REPEATER_FACING_ZP) && (a_MyMeta == E_META_REDSTONE_REPEATER_FACING_XP)) || + ((a_MetaLhs == E_META_REDSTONE_REPEATER_FACING_XM) && (a_MyMeta == E_META_REDSTONE_REPEATER_FACING_ZP)) || + ((a_MetaLhs == E_META_REDSTONE_REPEATER_FACING_ZM) && (a_MyMeta == E_META_REDSTONE_REPEATER_FACING_XM)) + ; + } + + /** 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 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(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(Chunk, -LhsOffset + a_Position); + return Rhs.first && DoesLhsLockMe(a_Meta, Rhs.second); + } + + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) { if (!IsOn(a_BlockType)) { @@ -27,7 +98,7 @@ class cRedstoneRepeaterHandler final : public cRedstoneHandler return 0; } - virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // LOGD("Evaluating loopy the repeater (%d %d %d)", a_Position.x, a_Position.y, a_Position.z); @@ -77,80 +148,8 @@ class cRedstoneRepeaterHandler final : public cRedstoneHandler UpdateAdjustedRelative(a_Chunk, CurrentlyTicking, a_Position, cBlockRedstoneRepeaterHandler::GetFrontCoordinateOffset(a_Meta)); } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { Callback(cBlockRedstoneRepeaterHandler::GetRearCoordinateOffset(a_Meta) + a_Position); } - - inline static bool IsOn(BLOCKTYPE a_Block) - { - return (a_Block == E_BLOCK_REDSTONE_REPEATER_ON); - } - - /** 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(cChunk & Chunk, const Vector3i a_Position) - { - BLOCKTYPE Type; - NIBBLETYPE Meta; - - if (!Chunk.UnboundedRelGetBlock(a_Position, Type, Meta)) - { - return std::make_pair(false, 0); - } - - return std::make_pair(IsOn(Type), Meta); - } - - /** 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(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(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(Chunk, -LhsOffset + a_Position); - return Rhs.first && DoesLhsLockMe(a_Meta, Rhs.second); - } - - /** Determine, from the metadata of a repeater on our left side, if they lock us. - To test a repeater on our right, simply invert the order of arguments provided. - "Left" is relative to the direction the repeater output faces, naturally. */ - static bool DoesLhsLockMe(NIBBLETYPE a_MetaLhs, NIBBLETYPE a_MyMeta) - { - // Get the direction bits - a_MetaLhs &= E_META_REDSTONE_REPEATER_FACING_MASK; - a_MyMeta &= E_META_REDSTONE_REPEATER_FACING_MASK; - - /* - Check for a valid locking configuration, where they are perpendicular and one snuggles into the other. - - Order of comparisons: - XP >^ ZM - ZP |_ XP - XM <| ZP - ZP ^< xM - - Key: - ^ Facing up - _ Facing right - | Facing down - < Facing left - */ - return - ((a_MetaLhs == E_META_REDSTONE_REPEATER_FACING_XP) && (a_MyMeta == E_META_REDSTONE_REPEATER_FACING_ZM)) || - ((a_MetaLhs == E_META_REDSTONE_REPEATER_FACING_ZP) && (a_MyMeta == E_META_REDSTONE_REPEATER_FACING_XP)) || - ((a_MetaLhs == E_META_REDSTONE_REPEATER_FACING_XM) && (a_MyMeta == E_META_REDSTONE_REPEATER_FACING_ZP)) || - ((a_MetaLhs == E_META_REDSTONE_REPEATER_FACING_ZM) && (a_MyMeta == E_META_REDSTONE_REPEATER_FACING_XM)) - ; - } }; diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneToggleHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneToggleHandler.h index b66ce47fd..b8f910d5f 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneToggleHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneToggleHandler.h @@ -1,7 +1,6 @@ #pragma once -#include "RedstoneHandler.h" #include "../../Blocks/BlockButton.h" #include "../../Blocks/BlockLever.h" @@ -9,9 +8,9 @@ -class cRedstoneToggleHandler final : public cRedstoneHandler +namespace RedstoneToggleHandler { - inline static Vector3i GetOffsetAttachedTo(Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) + inline Vector3i GetOffsetAttachedTo(Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) { switch (a_BlockType) { @@ -60,22 +59,7 @@ class cRedstoneToggleHandler final : public cRedstoneHandler } } - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override - { - UNUSED(a_QueryBlockType); - - const auto Meta = a_Chunk.GetMeta(a_Position); - const auto QueryOffset = a_QueryPosition - a_Position; - - if (IsLinked && (QueryOffset != GetOffsetAttachedTo(a_Position, a_BlockType, Meta))) - { - return 0; - } - - return GetPowerLevel(a_BlockType, Meta); - } - - static unsigned char GetPowerLevel(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) + inline unsigned char GetPowerLevel(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) { switch (a_BlockType) { @@ -90,12 +74,27 @@ class cRedstoneToggleHandler final : public cRedstoneHandler } } - virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) + { + UNUSED(a_QueryBlockType); + + const auto Meta = a_Chunk.GetMeta(a_Position); + const auto QueryOffset = a_QueryPosition - a_Position; + + if (IsLinked && (QueryOffset != GetOffsetAttachedTo(a_Position, a_BlockType, Meta))) + { + return 0; + } + + return GetPowerLevel(a_BlockType, Meta); + } + + inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // LOGD("Evaluating templatio<> the lever/button (%d %d %d)", a_Position.x, a_Position.y, a_Position.z); } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { UNUSED(a_Chunk); UNUSED(a_Position); diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneTorchHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneTorchHandler.h index 77c889aa9..e7f5bf6f1 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneTorchHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneTorchHandler.h @@ -1,20 +1,18 @@ #pragma once -#include "RedstoneHandler.h" - -class cRedstoneTorchHandler final : public cRedstoneHandler +namespace RedstoneTorchHandler { - inline static bool IsOn(BLOCKTYPE a_Block) + inline bool IsOn(BLOCKTYPE a_Block) { return (a_Block == E_BLOCK_REDSTONE_TORCH_ON); } - inline static Vector3i GetOffsetAttachedTo(const NIBBLETYPE a_Meta) + inline Vector3i GetOffsetAttachedTo(const NIBBLETYPE a_Meta) { switch (a_Meta) { @@ -31,7 +29,7 @@ class cRedstoneTorchHandler final : public cRedstoneHandler } } - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) { const auto QueryOffset = a_QueryPosition - a_Position; @@ -47,7 +45,7 @@ class cRedstoneTorchHandler final : public cRedstoneHandler return 15; } - virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // LOGD("Evaluating torchy the redstone torch (%i %i %i)", a_Position.x, a_Position.y, a_Position.z); @@ -88,7 +86,7 @@ class cRedstoneTorchHandler final : public cRedstoneHandler } } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { UNUSED(a_Chunk); UNUSED(a_BlockType); diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h index 2772441bd..bbc1c212d 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h @@ -8,7 +8,7 @@ -class cRedstoneWireHandler final : public cRedstoneHandler +namespace RedstoneWireHandler { /** A unified representation of wire direction. */ enum class TemporaryDirection @@ -17,32 +17,10 @@ class cRedstoneWireHandler final : public cRedstoneHandler Side }; - /** Adjusts a given wire block so that the direction represented by Offset has state Direction. */ - inline static void SetDirectionState(const Vector3i Offset, short & Block, TemporaryDirection Direction) - { - Block = DoWithDirectionState(Offset, Block, [Direction](auto, auto & Front, auto) - { - using FrontState = std::remove_reference_t<decltype(Front)>; - switch (Direction) - { - case TemporaryDirection::Up: - { - Front = FrontState::Up; - return; - } - case TemporaryDirection::Side: - { - Front = FrontState::Side; - return; - } - } - }); - } - /** Invokes Callback with the wire's left, front, and right direction state corresponding to Offset. Returns a new block constructed from the directions that the callback may have modified. */ template <class OffsetCallback> - inline static short DoWithDirectionState(const Vector3i Offset, short Block, OffsetCallback Callback) + inline short DoWithDirectionState(const Vector3i Offset, short Block, OffsetCallback Callback) { auto North = Block::RedstoneWire::North(Block); auto South = Block::RedstoneWire::South(Block); @@ -70,11 +48,58 @@ class cRedstoneWireHandler final : public cRedstoneHandler return Block::RedstoneWire::RedstoneWire(East, North, 0, South, West); } -public: + /** Adjusts a given wire block so that the direction represented by Offset has state Direction. */ + inline void SetDirectionState(const Vector3i Offset, short & Block, TemporaryDirection Direction) + { + Block = DoWithDirectionState(Offset, Block, [Direction](auto, auto & Front, auto) + { + using FrontState = std::remove_reference_t<decltype(Front)>; + switch (Direction) + { + case TemporaryDirection::Up: + { + Front = FrontState::Up; + return; + } + case TemporaryDirection::Side: + { + Front = FrontState::Side; + return; + } + } + }); + } + + inline bool IsDirectlyConnectingMechanism(BLOCKTYPE a_Block, NIBBLETYPE a_BlockMeta, const Vector3i a_Offset) + { + switch (a_Block) + { + case E_BLOCK_REDSTONE_REPEATER_ON: + case E_BLOCK_REDSTONE_REPEATER_OFF: + { + a_BlockMeta &= E_META_REDSTONE_REPEATER_FACING_MASK; + if ((a_BlockMeta == E_META_REDSTONE_REPEATER_FACING_XP) || (a_BlockMeta == E_META_REDSTONE_REPEATER_FACING_XM)) + { + // Wire connects to repeater if repeater is aligned along X + // and wire is in front or behind it (#4639) + return a_Offset.x != 0; + } + + return a_Offset.z != 0; + } + case E_BLOCK_ACTIVE_COMPARATOR: + case E_BLOCK_INACTIVE_COMPARATOR: + case E_BLOCK_BLOCK_OF_REDSTONE: + case E_BLOCK_REDSTONE_TORCH_OFF: + case E_BLOCK_REDSTONE_TORCH_ON: + case E_BLOCK_REDSTONE_WIRE: return true; + default: return false; + } + } /** Temporary. Discovers a wire's connection state, including terracing, storing the block inside redstone chunk data. TODO: once the server supports block states this should go in the block handler, with data saved in the world. */ - void SetWireState(const cChunk & Chunk, const Vector3i Position) const + inline void SetWireState(const cChunk & Chunk, const Vector3i Position) { auto Block = Block::RedstoneWire::RedstoneWire(); const auto YPTerraceBlock = Chunk.GetBlock(Position + OffsetYP); @@ -164,36 +189,7 @@ public: DataForChunk(Chunk).WireStates[Position] = Block; } -private: - - inline static bool IsDirectlyConnectingMechanism(BLOCKTYPE a_Block, NIBBLETYPE a_BlockMeta, const Vector3i a_Offset) - { - switch (a_Block) - { - case E_BLOCK_REDSTONE_REPEATER_ON: - case E_BLOCK_REDSTONE_REPEATER_OFF: - { - a_BlockMeta &= E_META_REDSTONE_REPEATER_FACING_MASK; - if ((a_BlockMeta == E_META_REDSTONE_REPEATER_FACING_XP) || (a_BlockMeta == E_META_REDSTONE_REPEATER_FACING_XM)) - { - // Wire connects to repeater if repeater is aligned along X - // and wire is in front or behind it (#4639) - return a_Offset.x != 0; - } - - return a_Offset.z != 0; - } - case E_BLOCK_ACTIVE_COMPARATOR: - case E_BLOCK_INACTIVE_COMPARATOR: - case E_BLOCK_BLOCK_OF_REDSTONE: - case E_BLOCK_REDSTONE_TORCH_OFF: - case E_BLOCK_REDSTONE_TORCH_ON: - case E_BLOCK_REDSTONE_WIRE: return true; - default: return false; - } - } - - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) { // Starts off as the wire's meta value, modified appropriately and returned auto Power = a_Chunk.GetMeta(a_Position); @@ -257,7 +253,7 @@ private: return Power; } - virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // LOGD("Evaluating dusty the wire (%d %d %d) %i", a_Position.x, a_Position.y, a_Position.z, a_PoweringData.PowerLevel); @@ -280,7 +276,7 @@ private: } } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { UNUSED(a_BlockType); UNUSED(a_Meta); diff --git a/src/Simulator/IncrementalRedstoneSimulator/SmallGateHandler.h b/src/Simulator/IncrementalRedstoneSimulator/SmallGateHandler.h index 68727284d..64d9ecf12 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/SmallGateHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/SmallGateHandler.h @@ -1,15 +1,13 @@ #pragma once -#include "RedstoneHandler.h" - -class cSmallGateHandler final : public cRedstoneHandler +namespace SmallGateHandler { - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) { UNUSED(a_Chunk); UNUSED(a_Position); @@ -20,7 +18,7 @@ class cSmallGateHandler final : public cRedstoneHandler return 0; } - virtual void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // LOGD("Evaluating gateydory the fence gate/trapdoor (%d %d %d)", a_Position.x, a_Position.y, a_Position.z); @@ -33,7 +31,7 @@ class cSmallGateHandler final : public cRedstoneHandler } } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { UNUSED(a_Chunk); UNUSED(a_BlockType); diff --git a/src/Simulator/IncrementalRedstoneSimulator/TNTHandler.h b/src/Simulator/IncrementalRedstoneSimulator/TNTHandler.h index 2396660a8..f8f9241b2 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/TNTHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/TNTHandler.h @@ -1,15 +1,13 @@ #pragma once -#include "RedstoneHandler.h" - -class cTNTHandler final : public cRedstoneHandler +namespace TNTHandler { - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) { UNUSED(a_Chunk); UNUSED(a_Position); @@ -20,7 +18,7 @@ class cTNTHandler final : public cRedstoneHandler return 0; } - virtual void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // LOGD("Evaluating explodinator the trinitrotoluene (%d %d %d)", a_Position.x, a_Position.y, a_Position.z); if (a_PoweringData.PowerLevel != 0) @@ -30,7 +28,7 @@ class cTNTHandler final : public cRedstoneHandler } } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { UNUSED(a_Chunk); UNUSED(a_BlockType); diff --git a/src/Simulator/IncrementalRedstoneSimulator/TrappedChestHandler.h b/src/Simulator/IncrementalRedstoneSimulator/TrappedChestHandler.h index 45014d637..94a3c3b07 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/TrappedChestHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/TrappedChestHandler.h @@ -1,16 +1,15 @@ #pragma once -#include "RedstoneHandler.h" #include "../../BlockEntities/ChestEntity.h" -class cTrappedChestHandler final : public cRedstoneHandler +namespace TrappedChestHandler { - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) { UNUSED(a_BlockType); UNUSED(a_QueryPosition); @@ -20,7 +19,7 @@ class cTrappedChestHandler final : public cRedstoneHandler return DataForChunk(a_Chunk).GetCachedPowerData(a_Position).PowerLevel; } - static unsigned char GetPowerLevel(cChunk & a_Chunk, Vector3i a_Position) + inline unsigned char GetPowerLevel(cChunk & a_Chunk, Vector3i a_Position) { int NumberOfPlayers = 0; VERIFY( @@ -35,7 +34,7 @@ class cTrappedChestHandler final : public cRedstoneHandler return static_cast<unsigned char>(std::min(NumberOfPlayers, 15)); } - virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // LOGD("Evaluating tricky the trapped chest (%d %d %d)", a_Position.x, a_Position.y, a_Position.z); @@ -48,7 +47,7 @@ class cTrappedChestHandler final : public cRedstoneHandler } } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { UNUSED(a_Chunk); UNUSED(a_Position); diff --git a/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h b/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h index 6ae3c2e3c..87853b254 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h @@ -1,25 +1,15 @@ #pragma once -#include "RedstoneHandler.h" #include "../../Blocks/BlockTripwireHook.h" -class cTripwireHookHandler final : public cRedstoneHandler +namespace TripwireHookHandler { - virtual unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) const override - { - UNUSED(a_BlockType); - UNUSED(a_QueryBlockType); - UNUSED(a_QueryPosition); - - return (GetPowerLevel(a_Chunk, a_Position, a_Chunk.GetMeta(a_Position)) == 15) ? 15 : 0; - } - - static unsigned char GetPowerLevel(const cChunk & a_Chunk, Vector3i a_Position, NIBBLETYPE a_Meta) + inline unsigned char GetPowerLevel(const cChunk & a_Chunk, Vector3i a_Position, NIBBLETYPE a_Meta) { bool FoundActivated = false; const auto FaceToGoTowards = cBlockTripwireHookHandler::MetadataToDirection(a_Meta); @@ -70,7 +60,16 @@ class cTripwireHookHandler final : public cRedstoneHandler return 0; } - virtual void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override + inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked) + { + UNUSED(a_BlockType); + UNUSED(a_QueryBlockType); + UNUSED(a_QueryPosition); + + return (GetPowerLevel(a_Chunk, a_Position, a_Chunk.GetMeta(a_Position)) == 15) ? 15 : 0; + } + + inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) { // LOGD("Evaluating hooky the tripwire hook (%d %d %d)", a_Position.x, a_Position.y, a_Position.z); @@ -102,7 +101,7 @@ class cTripwireHookHandler final : public cRedstoneHandler } } - virtual void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, SourceCallback Callback) const override + inline void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback) { UNUSED(a_Chunk); UNUSED(a_BlockType); |