From 99856df6869d32731e6fdcfeb1460297410f5820 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 29 Jul 2020 00:12:45 +0100 Subject: Add WakeUp/AddBlock distinction * WakeUp is for singular changes (block breaking for example). The simulator should check blocks around the position and discover other affected blocks as it sees fit * AddBlock is for when you know a whole area is to be updated; chunk loading, or area wakeups for example + Prepares for correct handling of destroyed blocks after removal of SolidBlockHandler in the redstone simulator --- src/ChunkMap.cpp | 2 +- src/Protocol/ProtocolRecognizer.cpp | 1 - src/Simulator/DelayedFluidSimulator.cpp | 24 +++--- src/Simulator/DelayedFluidSimulator.h | 3 +- src/Simulator/FireSimulator.cpp | 2 +- src/Simulator/FireSimulator.h | 3 +- .../IncrementalRedstoneSimulator.cpp | 93 ++++++++++++---------- .../IncrementalRedstoneSimulator.h | 6 +- src/Simulator/NoopFluidSimulator.h | 2 +- src/Simulator/NoopRedstoneSimulator.h | 2 +- src/Simulator/RedstoneSimulator.h | 5 -- src/Simulator/SandSimulator.cpp | 2 +- src/Simulator/SandSimulator.h | 4 +- src/Simulator/Simulator.cpp | 30 +++---- src/Simulator/Simulator.h | 44 +++++----- src/Simulator/SimulatorManager.cpp | 17 ++-- src/Simulator/SimulatorManager.h | 14 ++-- src/Simulator/VaporizeFluidSimulator.cpp | 2 +- src/Simulator/VaporizeFluidSimulator.h | 2 +- src/World.cpp | 2 +- 20 files changed, 140 insertions(+), 120 deletions(-) (limited to 'src') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index e548a02e8..43253a91d 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1330,7 +1330,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ ); // Wake up all simulators for the area, so that water and lava flows and sand falls into the blasted holes (FS #391): - m_World->GetSimulatorManager()->WakeUpArea(cCuboid( + m_World->GetSimulatorManager()->WakeUp(cCuboid( {bx - ExplosionSizeInt - 1, MinY, bz - ExplosionSizeInt - 1}, {bx + ExplosionSizeInt + 1, MaxY, bz + ExplosionSizeInt + 1} )); diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 813791485..81570ccd4 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -111,7 +111,6 @@ void cMultiVersionProtocol::HandleIncomingDataInRecognitionStage(cClientHandle & // The protocol recogniser succesfully identified, switch mode: HandleIncomingData = [this](cClientHandle &, const std::string_view a_In) { - // TODO: make it take our a_ReceivedData m_Protocol->DataReceived(m_Buffer, a_In.data(), a_In.size()); }; } diff --git a/src/Simulator/DelayedFluidSimulator.cpp b/src/Simulator/DelayedFluidSimulator.cpp index d4537656d..af9007548 100644 --- a/src/Simulator/DelayedFluidSimulator.cpp +++ b/src/Simulator/DelayedFluidSimulator.cpp @@ -78,19 +78,8 @@ cDelayedFluidSimulator::cDelayedFluidSimulator(cWorld & a_World, BLOCKTYPE a_Flu -void cDelayedFluidSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk) +void cDelayedFluidSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) { - if ((a_Block.y < 0) || (a_Block.y >= cChunkDef::Height)) - { - // Not inside the world (may happen when rclk with a full bucket - the client sends Y = -1) - return; - } - - if ((a_Chunk == nullptr) || !a_Chunk->IsValid()) - { - return; - } - int RelX = a_Block.x - a_Chunk->GetPosX() * cChunkDef::Width; int RelZ = a_Block.z - a_Chunk->GetPosZ() * cChunkDef::Width; BLOCKTYPE BlockType = a_Chunk->GetBlock(RelX, a_Block.y, RelZ); @@ -156,3 +145,14 @@ void cDelayedFluidSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a + +void cDelayedFluidSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) +{ + if (!cChunkDef::IsValidHeight(a_Position.y)) + { + // Not inside the world (may happen when rclk with a full bucket - the client sends Y = -1) + return; + } + + Super::WakeUp(a_Chunk, a_Position, a_Block); +} diff --git a/src/Simulator/DelayedFluidSimulator.h b/src/Simulator/DelayedFluidSimulator.h index 4627cdce2..b3158efec 100644 --- a/src/Simulator/DelayedFluidSimulator.h +++ b/src/Simulator/DelayedFluidSimulator.h @@ -55,7 +55,8 @@ public: cDelayedFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, int a_TickDelay); // cSimulator overrides: - virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override; + virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override; + virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override; 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 cFluidSimulatorData * CreateChunkData(void) override { return new cDelayedFluidSimulatorChunkData(m_TickDelay); } diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index 3b53d5545..1f212e2a5 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -239,7 +239,7 @@ bool cFireSimulator::DoesBurnForever(BLOCKTYPE a_BlockType) -void cFireSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk) +void cFireSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) { if ((a_Chunk == nullptr) || !a_Chunk->IsValid()) { diff --git a/src/Simulator/FireSimulator.h b/src/Simulator/FireSimulator.h index f36407584..1bc6e7c0b 100644 --- a/src/Simulator/FireSimulator.h +++ b/src/Simulator/FireSimulator.h @@ -43,8 +43,7 @@ protected: /** Chance [0..100000] of a fuel burning out being replaced by a new fire block instead of an air block */ int m_ReplaceFuelChance; - - virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override; + virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override; /** Returns the time [msec] after which the specified fire block is stepped again; based on surrounding fuels */ int GetBurnStepTime(cChunk * a_Chunk, Vector3i a_RelPos); diff --git a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp index fdcd69069..33c0f9523 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp @@ -128,6 +128,53 @@ std::unique_ptr cIncrementalRedstoneSimulator::CreateComponent +void cIncrementalRedstoneSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) +{ + Super::WakeUp(a_Chunk, a_Position, a_Block); + + auto & ChunkData = *static_cast(a_Chunk.GetRedstoneSimulatorData()); + + // Never update blocks without a handler: + if (GetComponentHandler(a_Block) == nullptr) + { + ChunkData.ErasePowerData(a_Position); + return; + } + + // Only update others if there is a redstone device nearby + for (int x = -1; x < 2; ++x) + { + for (int y = -1; y < 2; ++y) + { + if (!cChunkDef::IsValidHeight(a_Position.y + y)) + { + continue; + } + + for (int z = -1; z < 2; ++z) + { + auto CheckPos = a_Position + Vector3i{ x, y, z }; + BLOCKTYPE Block; + NIBBLETYPE Meta; + + // If we can't read the block, assume it is a mechanism + if ( + !a_Chunk.UnboundedRelGetBlock(CheckPos, Block, Meta) || + IsRedstone(Block) + ) + { + ChunkData.WakeUp(a_Position); + return; + } + } + } + } +} + + + + + void cIncrementalRedstoneSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) { auto & ChunkData = *static_cast(a_Chunk->GetRedstoneSimulatorData()); @@ -224,7 +271,7 @@ void cIncrementalRedstoneSimulator::ProcessWorkItem(cChunk & Chunk, cChunk & Tic -void cIncrementalRedstoneSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk) +void cIncrementalRedstoneSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) { // Can't inspect block, ignore: if ((a_Chunk == nullptr) || !a_Chunk->IsValid()) @@ -236,50 +283,16 @@ void cIncrementalRedstoneSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk) const auto Relative = cChunkDef::AbsoluteToRelative(a_Block, a_Chunk->GetPos()); const auto CurrentBlock = a_Chunk->GetBlock(Relative); - // Always update redstone devices - if (IsRedstone(CurrentBlock)) + if (!IsRedstone(CurrentBlock)) { - if (IsAlwaysTicked(CurrentBlock)) - { - ChunkData.AlwaysTickedPositions.emplace(Relative); - } - ChunkData.WakeUp(Relative); return; } - // Never update blocks without a handler - if (GetComponentHandler(CurrentBlock) == nullptr) + if (IsAlwaysTicked(CurrentBlock)) { - ChunkData.ErasePowerData(Relative); - return; + ChunkData.AlwaysTickedPositions.emplace(Relative); } - // Only update others if there is a redstone device nearby - for (int x = -1; x < 2; ++x) - { - for (int y = -1; y < 2; ++y) - { - if (!cChunkDef::IsValidHeight(Relative.y + y)) - { - continue; - } - - for (int z = -1; z < 2; ++z) - { - auto CheckPos = Relative + Vector3i{x, y, z}; - BLOCKTYPE Block; - NIBBLETYPE Meta; - - // If we can't read the block, assume it is a mechanism - if ( - !a_Chunk->UnboundedRelGetBlock(CheckPos, Block, Meta) || - IsRedstone(Block) - ) - { - ChunkData.WakeUp(Relative); - return; - } - } - } - } + // Always update redstone devices: + ChunkData.WakeUp(Relative); } diff --git a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h index 3523463bd..7f1a6a9cf 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h +++ b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h @@ -21,6 +21,10 @@ public: { } +private: + + virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override; + virtual void Simulate(float Dt) override {}; virtual void SimulateChunk(std::chrono::milliseconds Dt, int ChunkX, int ChunkZ, cChunk * Chunk) override; @@ -36,7 +40,7 @@ public: return IsRedstone(a_BlockType); } - virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override; + virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) 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 */ diff --git a/src/Simulator/NoopFluidSimulator.h b/src/Simulator/NoopFluidSimulator.h index 6fc8b3689..71c37d92d 100644 --- a/src/Simulator/NoopFluidSimulator.h +++ b/src/Simulator/NoopFluidSimulator.h @@ -28,7 +28,7 @@ public: } // cSimulator overrides: - virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override + virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override { UNUSED(a_Block); UNUSED(a_Chunk); diff --git a/src/Simulator/NoopRedstoneSimulator.h b/src/Simulator/NoopRedstoneSimulator.h index 91436ce7e..8d47ceccf 100644 --- a/src/Simulator/NoopRedstoneSimulator.h +++ b/src/Simulator/NoopRedstoneSimulator.h @@ -28,7 +28,7 @@ public: UNUSED(a_Chunk); } virtual bool IsAllowedBlock( BLOCKTYPE a_BlockType) override { return false; } - virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override + virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override { UNUSED(a_Block); UNUSED(a_Chunk); diff --git a/src/Simulator/RedstoneSimulator.h b/src/Simulator/RedstoneSimulator.h index f90026374..6d60b91a2 100644 --- a/src/Simulator/RedstoneSimulator.h +++ b/src/Simulator/RedstoneSimulator.h @@ -31,11 +31,6 @@ public: { } - virtual void Simulate(float a_Dt) = 0; - virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) = 0; - virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) = 0; - virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) = 0; - virtual cRedstoneSimulatorChunkData * CreateChunkData() = 0; }; diff --git a/src/Simulator/SandSimulator.cpp b/src/Simulator/SandSimulator.cpp index ee2c45520..ef02339bc 100644 --- a/src/Simulator/SandSimulator.cpp +++ b/src/Simulator/SandSimulator.cpp @@ -97,7 +97,7 @@ bool cSandSimulator::IsAllowedBlock(BLOCKTYPE a_BlockType) -void cSandSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk) +void cSandSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) { if ((a_Chunk == nullptr) || !a_Chunk->IsValid()) { diff --git a/src/Simulator/SandSimulator.h b/src/Simulator/SandSimulator.h index d7a27edd4..665208fbe 100644 --- a/src/Simulator/SandSimulator.h +++ b/src/Simulator/SandSimulator.h @@ -27,6 +27,7 @@ class cSandSimulator : public cSimulator { public: + cSandSimulator(cWorld & a_World, cIniFile & a_IniFile); // cSimulator overrides: @@ -56,11 +57,12 @@ public: ); protected: + bool m_IsInstantFall; // If set to true, blocks don't fall using cFallingBlock entity, but instantly instead int m_TotalBlocks; // Total number of blocks currently in the queue for simulating - virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override; + virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override; /** Performs the instant fall of the block - removes it from top, Finishes it at the bottom */ void DoInstantFall(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ); diff --git a/src/Simulator/Simulator.cpp b/src/Simulator/Simulator.cpp index ac2e757e4..e55b77f0f 100644 --- a/src/Simulator/Simulator.cpp +++ b/src/Simulator/Simulator.cpp @@ -1,33 +1,38 @@ #include "Globals.h" -#include "../World.h" -#include "../Defines.h" +#include "Simulator.h" #include "../Chunk.h" #include "../Cuboid.h" +#include "../World.h" -#ifdef __clang__ - #pragma clang diagnostic ignored "-Wweak-template-vtables" -#endif // __clang__ -#include "Simulator.h" +void cSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) +{ + ASSERT(a_Chunk.IsValid()); + + AddBlock(a_Chunk, a_Position, a_Block); +} -void cSimulator::WakeUp(Vector3i a_Block, cChunk * a_Chunk) + +void cSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position, Vector3i a_Offset, BLOCKTYPE a_Block) { - AddBlock(a_Block, a_Chunk); + ASSERT(a_Chunk.IsValid()); + + WakeUp(a_Chunk, a_Position, a_Block); } -void cSimulator::WakeUpArea(const cCuboid & a_Area) +void cSimulator::WakeUp(const cCuboid & a_Area) { cCuboid area(a_Area); area.Sort(); @@ -60,7 +65,8 @@ void cSimulator::WakeUpArea(const cCuboid & a_Area) { for (int x = startX; x <= endX; ++x) { - AddBlock({x, y, z}, &a_CBChunk); + const auto Position = cChunkDef::AbsoluteToRelative({ x, y, z }); + AddBlock(a_CBChunk, Position, a_CBChunk.GetBlock(Position)); } // for x } // for z } // for y @@ -70,7 +76,3 @@ void cSimulator::WakeUpArea(const cCuboid & a_Area) } // for cx } // for cz } - - - - diff --git a/src/Simulator/Simulator.h b/src/Simulator/Simulator.h index 669680693..5bd5d8f30 100644 --- a/src/Simulator/Simulator.h +++ b/src/Simulator/Simulator.h @@ -19,6 +19,7 @@ may update its internal state based on this call. */ class cSimulator { public: + cSimulator(cWorld & a_World) : m_World(a_World) { @@ -26,10 +27,13 @@ public: virtual ~cSimulator() {} - /** Called in each tick, a_Dt is the time passed since the last tick, in msec */ - virtual void Simulate(float a_Dt) = 0; + virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block); - /** Called in each tick for each chunk, a_Dt is the time passed since the last tick, in msec; direct access to chunk data available */ +protected: + + friend class cChunk; // Calls AddBlock() in its WakeUpSimulators() function, to speed things up + + virtual void Simulate(float a_Dt) = 0; virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) { UNUSED(a_Dt); @@ -38,28 +42,26 @@ public: UNUSED(a_Chunk); } - /** Called when a block changes */ - void WakeUp(Vector3i a_Block, cChunk * a_Chunk); - - /** Does the same processing as WakeUp, but for all blocks within the specified area. - Has better performance than calling WakeUp for each block individually, due to neighbor-checking. - All chunks intersected by the area should be valid (outputs a warning if not). - Note that, unlike WakeUp(), this call adds blocks not only face-neighboring, but also edge-neighboring and - corner-neighboring the specified area. So far none of the simulators care about that. */ - void WakeUpArea(const cCuboid & a_Area); - /** Returns true if the specified block type is "interesting" for this simulator. */ virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) = 0; -protected: - friend class cChunk; // Calls AddBlock() in its WakeUpSimulators() function, to speed things up - - /** Called to simulate a new block */ - virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) = 0; - - cWorld & m_World; -} ; + /** Called to simulate a new block. Unlike WakeUp this function will perform minimal checking. + It queues the block to be simulated as fast as possible, only making sure that the block type IsAllowedBlock. */ + virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) = 0; + /** Called to simulate a single new block, typically as a result of a single block break or change. + The simulator implementation may decide to perform additional checks or maintain consistency of internal state + before the block is added to the simulate queue. */ + virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block); + /** Called to simulate a single block, synthesised by the simulator manager. + The position represents the adjacents of the block that was actually changed, with the offset used given. + Simulators may use this information to update additional blocks that were affected by the change, or queue + farther, extra-adjacents blocks to be updated. The simulator manager calls this overload after the 3-argument WakeUp. */ + virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, Vector3i a_Offset, BLOCKTYPE a_Block); + /** Called to simulate an area by the manager, delegated to cSimulator to avoid virtual calls in tight loops. */ + void WakeUp(const cCuboid & a_Area); + cWorld & m_World; +} ; diff --git a/src/Simulator/SimulatorManager.cpp b/src/Simulator/SimulatorManager.cpp index a2740f707..f10c285e0 100644 --- a/src/Simulator/SimulatorManager.cpp +++ b/src/Simulator/SimulatorManager.cpp @@ -2,6 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "SimulatorManager.h" +#include "../Chunk.h" #include "../World.h" @@ -58,11 +59,13 @@ void cSimulatorManager::SimulateChunk(std::chrono::milliseconds a_Dt, int a_Chun -void cSimulatorManager::WakeUp(Vector3i a_Block, cChunk * a_Chunk) +void cSimulatorManager::WakeUp(cChunk & a_Chunk, Vector3i a_Position) { + ASSERT(a_Chunk.IsValid()); + for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr) { - itr->first->WakeUp(a_Block, a_Chunk); + itr->first->WakeUp(a_Chunk, a_Position, a_Chunk.GetBlock(a_Position)); } } @@ -70,11 +73,11 @@ void cSimulatorManager::WakeUp(Vector3i a_Block, cChunk * a_Chunk) -void cSimulatorManager::WakeUpArea(const cCuboid & a_Area) +void cSimulatorManager::WakeUp(const cCuboid & a_Area) { - for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr) + for (const auto Item : m_Simulators) { - itr->first->WakeUpArea(a_Area); + Item.first->WakeUp(a_Area); } } @@ -86,7 +89,3 @@ void cSimulatorManager::RegisterSimulator(cSimulator * a_Simulator, int a_Rate) { m_Simulators.push_back(std::make_pair(a_Simulator, a_Rate)); } - - - - diff --git a/src/Simulator/SimulatorManager.h b/src/Simulator/SimulatorManager.h index 98a60b4ee..b5f54381c 100644 --- a/src/Simulator/SimulatorManager.h +++ b/src/Simulator/SimulatorManager.h @@ -28,26 +28,30 @@ class cWorld; class cSimulatorManager { public: + cSimulatorManager(cWorld & a_World); ~cSimulatorManager(); + /** Called in each tick, a_Dt is the time passed since the last tick, in msec. */ void Simulate(float a_Dt); + /** Called in each tick for each chunk, a_Dt is the time passed since the last tick, in msec; direct access to chunk data available. */ void SimulateChunk(std::chrono::milliseconds a_DT, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk); - /* Called when a single block changes, wakes all simulators up for the block and its face-neighbors. */ - void WakeUp(Vector3i a_Block, cChunk * a_Chunk); + /* Called when a single block changes, wakes all simulators up for the block. + The simulator implementation may also decide to wake the block's face-neighbors or blocks farther away. */ + void WakeUp(cChunk & a_Chunk, Vector3i a_Position); /** Does the same processing as WakeUp, but for all blocks within the specified area. Has better performance than calling WakeUp for each block individually, due to neighbor-checking. All chunks intersected by the area should be valid (outputs a warning if not). - Note that, unlike WakeUp(), this call adds blocks not only face-neighboring, but also edge-neighboring and - corner-neighboring the specified area. So far none of the simulators care about that. */ - void WakeUpArea(const cCuboid & a_Area); + Note that, unlike WakeUp(), this call adds blocks not only face-neighboring, but also edge-neighboring and corner-neighboring the specified area. */ + void WakeUp(const cCuboid & a_Area); void RegisterSimulator(cSimulator * a_Simulator, int a_Rate); // Takes ownership of the simulator object! protected: + typedef std::vector > cSimulators; cWorld & m_World; diff --git a/src/Simulator/VaporizeFluidSimulator.cpp b/src/Simulator/VaporizeFluidSimulator.cpp index d0c590d16..8063a0706 100644 --- a/src/Simulator/VaporizeFluidSimulator.cpp +++ b/src/Simulator/VaporizeFluidSimulator.cpp @@ -22,7 +22,7 @@ cVaporizeFluidSimulator::cVaporizeFluidSimulator(cWorld & a_World, BLOCKTYPE a_F -void cVaporizeFluidSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk) +void cVaporizeFluidSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) { if (a_Chunk == nullptr) { diff --git a/src/Simulator/VaporizeFluidSimulator.h b/src/Simulator/VaporizeFluidSimulator.h index d3ae28db3..2d259e56e 100644 --- a/src/Simulator/VaporizeFluidSimulator.h +++ b/src/Simulator/VaporizeFluidSimulator.h @@ -26,7 +26,7 @@ public: cVaporizeFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid); // cSimulator overrides: - virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override; + virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override; virtual void Simulate(float a_Dt) override; } ; diff --git a/src/World.cpp b/src/World.cpp index d13081fb0..4de325d6e 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1327,7 +1327,7 @@ void cWorld::WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_MinB void cWorld::WakeUpSimulatorsInArea(const cCuboid & a_Area) { - m_SimulatorManager->WakeUpArea(a_Area); + m_SimulatorManager->WakeUp(a_Area); } -- cgit v1.2.3