summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTiger Wang <ziwei.tiger@outlook.com>2020-07-29 01:12:45 +0200
committerTiger Wang <ziwei.tiger@outlook.com>2020-08-02 16:52:06 +0200
commit99856df6869d32731e6fdcfeb1460297410f5820 (patch)
treec93afdb7dac377ff6c04732190a3efbe3a091c4b
parentDo not impose redstone wakup penalty for all blocks (diff)
downloadcuberite-99856df6869d32731e6fdcfeb1460297410f5820.tar
cuberite-99856df6869d32731e6fdcfeb1460297410f5820.tar.gz
cuberite-99856df6869d32731e6fdcfeb1460297410f5820.tar.bz2
cuberite-99856df6869d32731e6fdcfeb1460297410f5820.tar.lz
cuberite-99856df6869d32731e6fdcfeb1460297410f5820.tar.xz
cuberite-99856df6869d32731e6fdcfeb1460297410f5820.tar.zst
cuberite-99856df6869d32731e6fdcfeb1460297410f5820.zip
-rw-r--r--src/ChunkMap.cpp2
-rw-r--r--src/Protocol/ProtocolRecognizer.cpp1
-rw-r--r--src/Simulator/DelayedFluidSimulator.cpp24
-rw-r--r--src/Simulator/DelayedFluidSimulator.h3
-rw-r--r--src/Simulator/FireSimulator.cpp2
-rw-r--r--src/Simulator/FireSimulator.h3
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp93
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h6
-rw-r--r--src/Simulator/NoopFluidSimulator.h2
-rw-r--r--src/Simulator/NoopRedstoneSimulator.h2
-rw-r--r--src/Simulator/RedstoneSimulator.h5
-rw-r--r--src/Simulator/SandSimulator.cpp2
-rw-r--r--src/Simulator/SandSimulator.h4
-rw-r--r--src/Simulator/Simulator.cpp30
-rw-r--r--src/Simulator/Simulator.h44
-rw-r--r--src/Simulator/SimulatorManager.cpp17
-rw-r--r--src/Simulator/SimulatorManager.h14
-rw-r--r--src/Simulator/VaporizeFluidSimulator.cpp2
-rw-r--r--src/Simulator/VaporizeFluidSimulator.h2
-rw-r--r--src/World.cpp2
20 files changed, 140 insertions, 120 deletions
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<cRedstoneHandler> 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<cIncrementalRedstoneSimulatorChunkData *>(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<cIncrementalRedstoneSimulatorChunkData *>(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 <std::pair<cSimulator *, int> > 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);
}