1
0
Fork 0

Possibly decoupled IncrementalRedstoneSimulator from the rest of the server

THis wil hopefully allow for unit testing
This commit is contained in:
Tycho 2014-09-11 17:48:21 +01:00
parent c8b41e9b2b
commit 0b044e1c83
22 changed files with 2404 additions and 2340 deletions

View File

@ -10,7 +10,7 @@
#pragma once
#include "BlockEntity.h"
#include "RedstonePoweredEntity.h"
@ -27,7 +27,8 @@ namespace Json
// tolua_begin
class cCommandBlockEntity :
public cBlockEntity
public cBlockEntity,
public cRedstonePoweredEntity
{
typedef cBlockEntity super;
@ -52,7 +53,7 @@ public:
// tolua_begin
/// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate
void SetRedstonePower(bool a_IsPowered);
virtual void SetRedstonePower(bool a_IsPowered) override;
/// Sets the command block to execute a command in the next tick
void Activate(void);

View File

@ -6,7 +6,7 @@ class cRedstonePoweredEntity
{
public:
virtual ~cRedstonePoweredEntity() {};
virtual ~cRedstonePoweredEntity() {}
/// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate
virtual void SetRedstonePower(bool a_IsPowered) = 0;

View File

@ -0,0 +1,54 @@
#pragma once
class cBlockTorchHandler;
class cBlockLeverHandler;
class cBlockButtonHandler;
class cBlockTripwireHookHandler;
class cBlockDoorHandler;
class cBlockPistonHandler;
template<BLOCKTYPE T>
class GetHandlerCompileTime;
template<>
class GetHandlerCompileTime<E_BLOCK_TORCH>
{
public:
typedef cBlockTorchHandler type;
};
template<>
class GetHandlerCompileTime<E_BLOCK_LEVER>
{
public:
typedef cBlockLeverHandler type;
};
template<>
class GetHandlerCompileTime<E_BLOCK_STONE_BUTTON>
{
public:
typedef cBlockButtonHandler type;
};
template<>
class GetHandlerCompileTime<E_BLOCK_TRIPWIRE_HOOK>
{
public:
typedef cBlockTripwireHookHandler type;
};
template<>
class GetHandlerCompileTime<E_BLOCK_WOODEN_DOOR>
{
public:
typedef cBlockDoorHandler type;
};
template<>
class GetHandlerCompileTime<E_BLOCK_PISTON>
{
public:
typedef cBlockPistonHandler type;
};

View File

@ -1366,9 +1366,9 @@ void cChunk::CreateBlockEntities(void)
void cChunk::WakeUpSimulators(void)
{
cSimulator * WaterSimulator = m_World->GetWaterSimulator();
cSimulator * LavaSimulator = m_World->GetLavaSimulator();
cSimulator * RedstoneSimulator = m_World->GetRedstoneSimulator();
cSimulator<cChunk, cWorld> * WaterSimulator = m_World->GetWaterSimulator();
cSimulator<cChunk, cWorld> * LavaSimulator = m_World->GetLavaSimulator();
cSimulator<cChunk, cWorld> * RedstoneSimulator = m_World->GetRedstoneSimulator();
int BaseX = m_PosX * cChunkDef::Width;
int BaseZ = m_PosZ * cChunkDef::Width;
for (int x = 0; x < Width; x++)

View File

@ -9,6 +9,8 @@
#include "Simulator/SandSimulator.h"
#include "Simulator/IncrementalRedstoneSimulator.h"
#include "Blocks/GetHandlerCompileTimeTemplate.h"
@ -416,10 +418,10 @@ public:
cRedstoneSimulatorChunkData * GetRedstoneSimulatorData(void) { return &m_RedstoneSimulatorData; }
cRedstoneSimulatorChunkData * GetRedstoneSimulatorQueuedData(void) { return &m_RedstoneSimulatorQueuedData; }
cIncrementalRedstoneSimulator::PoweredBlocksList * GetRedstoneSimulatorPoweredBlocksList(void) { return &m_RedstoneSimulatorPoweredBlocksList; }
cIncrementalRedstoneSimulator::LinkedBlocksList * GetRedstoneSimulatorLinkedBlocksList(void) { return &m_RedstoneSimulatorLinkedBlocksList; }
cIncrementalRedstoneSimulator::SimulatedPlayerToggleableList * GetRedstoneSimulatorSimulatedPlayerToggleableList(void) { return &m_RedstoneSimulatorSimulatedPlayerToggleableList; }
cIncrementalRedstoneSimulator::RepeatersDelayList * GetRedstoneSimulatorRepeatersDelayList(void) { return &m_RedstoneSimulatorRepeatersDelayList; }
cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>::PoweredBlocksList * GetRedstoneSimulatorPoweredBlocksList(void) { return &m_RedstoneSimulatorPoweredBlocksList; }
cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>::LinkedBlocksList * GetRedstoneSimulatorLinkedBlocksList(void) { return &m_RedstoneSimulatorLinkedBlocksList; }
cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>::SimulatedPlayerToggleableList * GetRedstoneSimulatorSimulatedPlayerToggleableList(void) { return &m_RedstoneSimulatorSimulatedPlayerToggleableList; }
cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>::RepeatersDelayList * GetRedstoneSimulatorRepeatersDelayList(void) { return &m_RedstoneSimulatorRepeatersDelayList; }
bool IsRedstoneDirty(void) const { return m_IsRedstoneDirty; }
void SetIsRedstoneDirty(bool a_Flag) { m_IsRedstoneDirty = a_Flag; }
@ -506,10 +508,10 @@ private:
cRedstoneSimulatorChunkData m_RedstoneSimulatorData;
cRedstoneSimulatorChunkData m_RedstoneSimulatorQueuedData;
cIncrementalRedstoneSimulator::PoweredBlocksList m_RedstoneSimulatorPoweredBlocksList;
cIncrementalRedstoneSimulator::LinkedBlocksList m_RedstoneSimulatorLinkedBlocksList;
cIncrementalRedstoneSimulator::SimulatedPlayerToggleableList m_RedstoneSimulatorSimulatedPlayerToggleableList;
cIncrementalRedstoneSimulator::RepeatersDelayList m_RedstoneSimulatorRepeatersDelayList;
cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>::PoweredBlocksList m_RedstoneSimulatorPoweredBlocksList;
cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>::LinkedBlocksList m_RedstoneSimulatorLinkedBlocksList;
cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>::SimulatedPlayerToggleableList m_RedstoneSimulatorSimulatedPlayerToggleableList;
cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>::RepeatersDelayList m_RedstoneSimulatorRepeatersDelayList;
/** Indicates if simulate-once blocks should be updated by the redstone simulator */
bool m_IsRedstoneDirty;

View File

@ -10,7 +10,6 @@ SET (SRCS
FloodyFluidSimulator.cpp
FluidSimulator.cpp
IncrementalRedstoneSimulator.cpp
RedstoneSimulator.cpp
SandSimulator.cpp
Simulator.cpp
SimulatorManager.cpp

View File

@ -16,7 +16,7 @@ it progresses to the next step (blockmeta++). This value is updated if a neighbo
The simulator reads its parameters from the ini file given to the constructor.
*/
class cFireSimulator :
public cSimulator
public cSimulator<cChunk, cWorld>
{
public:
cFireSimulator(cWorld & a_World, cIniFile & a_IniFile);

View File

@ -4,7 +4,8 @@
#include "Simulator.h"
class cChunk;
class cWorld;
enum Direction
@ -36,9 +37,9 @@ public:
class cFluidSimulator :
public cSimulator
public cSimulator<cChunk, cWorld>
{
typedef cSimulator super;
typedef cSimulator<cChunk, cWorld> super;
public:
cFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid);

File diff suppressed because it is too large Load Diff

View File

@ -6,23 +6,25 @@
/// Per-chunk data for the simulator, specified individual chunks to simulate
typedef cCoordWithBlockAndBoolVector cRedstoneSimulatorChunkData;
class cRedstonePoweredEntity;
typedef cItemCallback<cRedstonePoweredEntity> cRedstonePoweredCallback;
template<class ChunkType, class WorldType, template <BLOCKTYPE block> class GetHandlerCompileTime, class ChestType>
class cIncrementalRedstoneSimulator :
public cRedstoneSimulator
public cRedstoneSimulator<ChunkType, WorldType>
{
typedef cRedstoneSimulator super;
typedef cRedstoneSimulator<ChunkType, WorldType> super;
public:
cIncrementalRedstoneSimulator(cWorld & a_World);
cIncrementalRedstoneSimulator(WorldType & a_World);
~cIncrementalRedstoneSimulator();
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used
virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, ChunkType * a_Chunk) override;
virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override { return IsRedstone(a_BlockType); }
virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override;
virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk) override;
enum eRedstoneDirection
{
@ -82,9 +84,9 @@ private:
SimulatedPlayerToggleableList * m_SimulatedPlayerToggleableBlocks;
RepeatersDelayList * m_RepeatersDelayList;
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override { RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); }
void RedstoneAddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk, cChunk * a_OtherChunk = NULL);
cChunk * m_Chunk;
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk) override { RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); }
void RedstoneAddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk, ChunkType * a_OtherChunk = NULL);
ChunkType * m_Chunk;
// We want a_MyState for devices needing a full FastSetBlock (as opposed to meta) because with our simulation model, we cannot keep setting the block if it is already set correctly
// In addition to being non-performant, it would stop the player from actually breaking said device
@ -159,12 +161,12 @@ private:
/** Removes a block from the Powered and LinkedPowered lists
Used for variable sources such as tripwire hooks, daylight sensors, and trapped chests
*/
void SetSourceUnpowered(int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, cChunk * a_Chunk, bool a_IsFirstCall = true);
void SetSourceUnpowered(int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, ChunkType * a_Chunk, bool a_IsFirstCall = true);
/** Returns if a coordinate is powered or linked powered */
bool AreCoordsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) { return AreCoordsDirectlyPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk) || AreCoordsLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); }
/** Returns if a coordinate is in the directly powered blocks list */
bool AreCoordsDirectlyPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, cChunk * a_Chunk);
bool AreCoordsDirectlyPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, ChunkType * a_Chunk);
/** Returns if a coordinate is in the indirectly powered blocks list */
bool AreCoordsLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Returns if a coordinate was marked as simulated (for blocks toggleable by players) */
@ -312,5 +314,7 @@ private:
};
#ifdef SELF_TEST
#include "IncrementalRedstoneSimulator.inc"
#endif

File diff suppressed because it is too large Load Diff

View File

@ -8,9 +8,9 @@
class cRedstoneNoopSimulator :
public cRedstoneSimulator
public cRedstoneSimulator<cChunk, cWorld>
{
typedef cRedstoneSimulator super;
typedef cRedstoneSimulator<cChunk, cWorld> super;
public:
cRedstoneNoopSimulator(cWorld & a_World) :

View File

@ -1,19 +0,0 @@
#include "Globals.h"
#include "RedstoneSimulator.h"
#include "../World.h"
cRedstoneSimulator::cRedstoneSimulator(cWorld & a_World) :
super(a_World)
{
}

View File

@ -5,13 +5,16 @@
template <class ChunkType, class WorldType>
class cRedstoneSimulator :
public cSimulator
public cSimulator<ChunkType, WorldType>
{
typedef cSimulator super;
typedef cSimulator<ChunkType, WorldType> super;
public:
cRedstoneSimulator(cWorld & a_World);
cRedstoneSimulator(WorldType & a_World) :
super(a_World)
{
}
} ;

View File

@ -3,13 +3,15 @@
#include "Simulator.h"
/// Per-chunk data for the simulator, specified individual chunks to simulate; Data is not used
typedef cCoordWithIntList cSandSimulatorChunkData;
#include "Chunk.h"
/// Despite the class name, this simulator takes care of all blocks that fall when suspended in the air.
class cSandSimulator :
public cSimulator
public cSimulator<cChunk, cWorld>
{
public:
cSandSimulator(cWorld & a_World, cIniFile & a_IniFile);
@ -55,8 +57,7 @@ protected:
/// Per-chunk data for the simulator, specified individual chunks to simulate; Data is not used
typedef cCoordWithIntList cSandSimulatorChunkData;

View File

@ -1,50 +1,8 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "Simulator.h"
#include "../World.h"
#include "../BlockID.h"
#include "../Defines.h"
#include "../Chunk.h"
cSimulator::cSimulator(cWorld & a_World)
: m_World(a_World)
{
}
cSimulator::~cSimulator()
{
}
void cSimulator::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk)
{
AddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk);
AddBlock(a_BlockX - 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX - 1, a_BlockZ));
AddBlock(a_BlockX + 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX + 1, a_BlockZ));
AddBlock(a_BlockX, a_BlockY, a_BlockZ - 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ - 1));
AddBlock(a_BlockX, a_BlockY, a_BlockZ + 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ + 1));
if (a_BlockY > 0)
{
AddBlock(a_BlockX, a_BlockY - 1, a_BlockZ, a_Chunk);
}
if (a_BlockY < cChunkDef::Height - 1)
{
AddBlock(a_BlockX, a_BlockY + 1, a_BlockZ, a_Chunk);
}
}
#include "Globals.h"
#include "Simulator.inc"
#pragma clang diagnostic ignored "-Wweak-template-vtables"
template class cSimulator<cChunk, cWorld>;

View File

@ -8,17 +8,12 @@
class cWorld;
class cChunk;
template <class ChunkType, class WorldType>
class cSimulator
{
public:
cSimulator(cWorld & a_World);
cSimulator(WorldType & a_World);
virtual ~cSimulator();
/// Called in each tick, a_Dt is the time passed since the last tick, in msec
@ -26,7 +21,7 @@ public:
/// 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
virtual void SimulateChunk(float a_Dt, int a_ChunkX,
int a_ChunkZ, cChunk * a_Chunk)
int a_ChunkZ, ChunkType * a_Chunk)
{
UNUSED(a_Dt);
UNUSED(a_ChunkX);
@ -35,7 +30,7 @@ public:
}
/// Called when a block changes
virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk);
virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk);
virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) = 0;
@ -43,9 +38,9 @@ protected:
friend class cChunk; // Calls AddBlock() in its WakeUpSimulators() function, to speed things up
/// Called to simulate a new block
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) = 0;
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk) = 0;
cWorld & m_World;
WorldType & m_World;
} ;

View File

@ -0,0 +1,49 @@
#include "Simulator.h"
#include "../World.h"
#include "../BlockID.h"
#include "../Defines.h"
#include "../Chunk.h"
template <class ChunkType, class WorldType>
cSimulator<ChunkType, WorldType>::cSimulator(WorldType & a_World)
: m_World(a_World)
{
}
template <class ChunkType, class WorldType>
cSimulator<ChunkType, WorldType>::~cSimulator()
{
}
template <class ChunkType, class WorldType>
void cSimulator<ChunkType, WorldType>::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk)
{
AddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk);
AddBlock(a_BlockX - 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX - 1, a_BlockZ));
AddBlock(a_BlockX + 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX + 1, a_BlockZ));
AddBlock(a_BlockX, a_BlockY, a_BlockZ - 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ - 1));
AddBlock(a_BlockX, a_BlockY, a_BlockZ + 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ + 1));
if (a_BlockY > 0)
{
AddBlock(a_BlockX, a_BlockY - 1, a_BlockZ, a_Chunk);
}
if (a_BlockY < cChunkDef::Height - 1)
{
AddBlock(a_BlockX, a_BlockY + 1, a_BlockZ, a_Chunk);
}
}

View File

@ -70,7 +70,7 @@ void cSimulatorManager::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk
void cSimulatorManager::RegisterSimulator(cSimulator * a_Simulator, int a_Rate)
void cSimulatorManager::RegisterSimulator(cSimulator<cChunk, cWorld> * a_Simulator, int a_Rate)
{
m_Simulators.push_back(std::make_pair(a_Simulator, a_Rate));
}

View File

@ -37,10 +37,10 @@ public:
void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk);
void RegisterSimulator(cSimulator * a_Simulator, int a_Rate); // Takes ownership of the simulator object!
void RegisterSimulator(cSimulator<cChunk, cWorld> * a_Simulator, int a_Rate); // Takes ownership of the simulator object!
protected:
typedef std::vector <std::pair<cSimulator *, int> > cSimulators;
typedef std::vector <std::pair<cSimulator<cChunk, cWorld> *, int> > cSimulators;
cWorld & m_World;
cSimulators m_Simulators;

View File

@ -3258,7 +3258,7 @@ void cWorld::SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicke
cRedstoneSimulator * cWorld::InitializeRedstoneSimulator(cIniFile & a_IniFile)
cRedstoneSimulator<cChunk, cWorld> * cWorld::InitializeRedstoneSimulator(cIniFile & a_IniFile)
{
AString SimulatorName = a_IniFile.GetValueSet("Physics", "RedstoneSimulator", "Incremental");
@ -3268,11 +3268,11 @@ cRedstoneSimulator * cWorld::InitializeRedstoneSimulator(cIniFile & a_IniFile)
SimulatorName = "Incremental";
}
cRedstoneSimulator * res = NULL;
cRedstoneSimulator<cChunk, cWorld> * res = NULL;
if (NoCaseCompare(SimulatorName, "Incremental") == 0)
{
res = new cIncrementalRedstoneSimulator(*this);
res = new cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>(*this);
}
else if (NoCaseCompare(SimulatorName, "noop") == 0)
{

View File

@ -33,6 +33,7 @@
class cFireSimulator;
class cFluidSimulator;
class cSandSimulator;
template <class ChunkType, class WorldType>
class cRedstoneSimulator;
class cItem;
class cPlayer;
@ -502,7 +503,7 @@ public:
inline cFluidSimulator * GetWaterSimulator(void) { return m_WaterSimulator; }
inline cFluidSimulator * GetLavaSimulator (void) { return m_LavaSimulator; }
inline cRedstoneSimulator * GetRedstoneSimulator(void) { return m_RedstoneSimulator; }
inline cRedstoneSimulator<cChunk, cWorld> * GetRedstoneSimulator(void) { return m_RedstoneSimulator; }
/** Calls the callback for each block entity in the specified chunk; returns true if all block entities processed, false if the callback aborted by returning true */
bool ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback & a_Callback); // Exported in ManualBindings.cpp
@ -910,7 +911,7 @@ private:
cFluidSimulator * m_WaterSimulator;
cFluidSimulator * m_LavaSimulator;
cFireSimulator * m_FireSimulator;
cRedstoneSimulator * m_RedstoneSimulator;
cRedstoneSimulator<cChunk, cWorld> * m_RedstoneSimulator;
cCriticalSection m_CSPlayers;
cPlayerList m_Players;
@ -1051,7 +1052,7 @@ private:
cFluidSimulator * InitializeFluidSimulator(cIniFile & a_IniFile, const char * a_FluidName, BLOCKTYPE a_SimulateBlock, BLOCKTYPE a_StationaryBlock);
/** Creates a new redstone simulator.*/
cRedstoneSimulator * InitializeRedstoneSimulator(cIniFile & a_IniFile);
cRedstoneSimulator<cChunk, cWorld> * InitializeRedstoneSimulator(cIniFile & a_IniFile);
/** Adds the players queued in the m_PlayersToAdd queue into the m_Players list.
Assumes it is called from the Tick thread. */