1
0

cBlockInfo static initialisation (#3832)

This commit is contained in:
peterbell10 2017-07-03 17:34:27 +01:00 committed by Lukas Pioch
parent bc861e5bb8
commit d838ef7ba4
6 changed files with 938 additions and 924 deletions

File diff suppressed because it is too large Load Diff

View File

@ -19,20 +19,8 @@ public:
/** Returns the associated BlockInfo structure for the specified block type. */ /** Returns the associated BlockInfo structure for the specified block type. */
/** This accessor makes sure that the cBlockInfo structures are properly initialized exactly once. /** This accessor makes sure that the cBlockInfo structures are properly initialized exactly once.
It does so by using the C++ singleton approximation - storing the actual singleton as the function's static variable. It does so by using the C++ singleton approximation - storing the actual singleton as the function's static variable. */
It works only if it is called for the first time before the app spawns other threads. */ static cBlockInfo & Get(BLOCKTYPE a_Type);
static cBlockInfo & Get(BLOCKTYPE a_Type)
{
static cBlockInfo ms_Info[256];
static bool IsBlockInfoInitialized = false;
if (!IsBlockInfoInitialized)
{
cBlockInfo::Initialize(ms_Info);
IsBlockInfoInitialized = true;
}
return ms_Info[a_Type];
}
/** How much light do the blocks emit on their own? */ /** How much light do the blocks emit on their own? */
NIBBLETYPE m_LightValue; NIBBLETYPE m_LightValue;
@ -75,8 +63,14 @@ public:
// tolua_end // tolua_end
/** Custom deleter allows cBlockHandler to be an incomplete type. */
struct sHandlerDeleter
{
void operator () (cBlockHandler * a_Handler);
};
/** Associated block handler. */ /** Associated block handler. */
cBlockHandler * m_Handler; std::unique_ptr<cBlockHandler, sHandlerDeleter> m_Handler;
// tolua_begin // tolua_begin
@ -96,11 +90,7 @@ public:
// tolua_end // tolua_end
inline static cBlockHandler * GetHandler (BLOCKTYPE a_Type) { return Get(a_Type).m_Handler; } inline static cBlockHandler * GetHandler (BLOCKTYPE a_Type) { return Get(a_Type).m_Handler.get(); }
protected:
/** Storage for all the BlockInfo structures. */
typedef cBlockInfo cBlockInfoArray[256];
/** Creates a default BlockInfo structure, initializes all values to their defaults */ /** Creates a default BlockInfo structure, initializes all values to their defaults */
cBlockInfo() cBlockInfo()
@ -115,26 +105,46 @@ protected:
, m_FullyOccupiesVoxel(false) , m_FullyOccupiesVoxel(false)
, m_CanBeTerraformed(false) , m_CanBeTerraformed(false)
, m_BlockHeight(1.0) , m_BlockHeight(1.0)
, m_PlaceSound("") , m_PlaceSound()
, m_Hardness(0.0f) , m_Hardness(0.0f)
, m_Handler(nullptr) , m_Handler()
{} {}
/** Cleans up the stored values */ private:
~cBlockInfo(); /** Storage for all the BlockInfo structures. */
class cBlockInfoArray;
/** Initializes the specified BlockInfo structures with block-specific values. */
static void Initialize(cBlockInfoArray & a_BlockInfos);
}; // tolua_export }; // tolua_export
class cBlockInfo::cBlockInfoArray:
public std::array<cBlockInfo, 256>
{
public:
/** Initializes the contained BlockInfo structures with block-specific values. */
cBlockInfoArray();
};
inline cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type)
{
static cBlockInfoArray ms_Info;
return ms_Info[a_Type];
}
// Shortcut to get the blockhandler for a specific block // Shortcut to get the blockhandler for a specific block
inline cBlockHandler * BlockHandler(BLOCKTYPE a_BlockType) inline cBlockHandler * BlockHandler(BLOCKTYPE a_BlockType)
{ {
return cBlockInfo::Get(a_BlockType).m_Handler; return cBlockInfo::Get(a_BlockType).m_Handler.get();
} }

View File

@ -101,7 +101,7 @@ protected:
// If the chunk we are trying to get the block information from is loaded // If the chunk we are trying to get the block information from is loaded
if (a_Chunk.UnboundedRelGetBlock(a_RelX + x, a_RelY, a_RelZ + z, Block, Meta)) if (a_Chunk.UnboundedRelGetBlock(a_RelX + x, a_RelY, a_RelZ + z, Block, Meta))
{ {
cBlockHandler * Handler = cBlockInfo::Get(Block).m_Handler; cBlockHandler * Handler = BlockHandler(Block);
// If the block affects growth, add to the adjustment // If the block affects growth, add to the adjustment
if (Handler->CanSustainPlant(m_BlockType)) if (Handler->CanSustainPlant(m_BlockType))

View File

@ -85,21 +85,23 @@ extern "C" int luaopen_lxp(lua_State * a_LuaState)
cBlockInfo::~cBlockInfo() void cBlockInfo::sHandlerDeleter::operator () (cBlockHandler * a_Handler)
{ {
delete a_Handler;
} }
void cBlockInfo::Initialize(cBlockInfo::cBlockInfoArray & a_BlockInfos) cBlockInfo::cBlockInfoArray::cBlockInfoArray()
{ {
cBlockInfoArray & BlockInfos = *this;
// The piece-loading code uses the handlers for rotations, so we need valid handlers // The piece-loading code uses the handlers for rotations, so we need valid handlers
// Insert dummy handlers: // Insert dummy handlers:
for (size_t i = 0; i < ARRAYCOUNT(a_BlockInfos); i++) for (size_t i = 0; i < BlockInfos.size(); i++)
{ {
a_BlockInfos[i].m_Handler = new cBlockHandler(static_cast<BLOCKTYPE>(i)); BlockInfos[i].m_Handler.reset(new cBlockHandler(static_cast<BLOCKTYPE>(i)));
} }
} }

View File

@ -85,21 +85,23 @@ extern "C" int luaopen_lxp(lua_State * a_LuaState)
cBlockInfo::~cBlockInfo() void cBlockInfo::sHandlerDeleter::operator () (cBlockHandler * a_Handler)
{ {
delete a_Handler;
} }
void cBlockInfo::Initialize(cBlockInfo::cBlockInfoArray & a_BlockInfos) cBlockInfo::cBlockInfoArray::cBlockInfoArray()
{ {
cBlockInfoArray & BlockInfos = *this;
// The piece-loading code uses the handlers for rotations, so we need valid handlers // The piece-loading code uses the handlers for rotations, so we need valid handlers
// Insert dummy handlers: // Insert dummy handlers:
for (size_t i = 0; i < ARRAYCOUNT(a_BlockInfos); i++) for (size_t i = 0; i < BlockInfos.size(); i++)
{ {
a_BlockInfos[i].m_Handler = new cBlockHandler(static_cast<BLOCKTYPE>(i)); BlockInfos[i].m_Handler.reset(new cBlockHandler(static_cast<BLOCKTYPE>(i)));
} }
} }

View File

@ -13,21 +13,23 @@
cBlockInfo::~cBlockInfo() void cBlockInfo::sHandlerDeleter::operator () (cBlockHandler * a_Handler)
{ {
delete a_Handler;
} }
void cBlockInfo::Initialize(cBlockInfo::cBlockInfoArray & a_BlockInfos) cBlockInfo::cBlockInfoArray::cBlockInfoArray()
{ {
cBlockInfoArray & BlockInfos = *this;
// The piece-loading code uses the handlers for rotations, so we need valid handlers // The piece-loading code uses the handlers for rotations, so we need valid handlers
// Insert dummy handlers: // Insert dummy handlers:
for (size_t i = 0; i < ARRAYCOUNT(a_BlockInfos); i++) for (size_t i = 0; i < BlockInfos.size(); i++)
{ {
a_BlockInfos[i].m_Handler = new cBlockHandler(static_cast<BLOCKTYPE>(i)); BlockInfos[i].m_Handler.reset(new cBlockHandler(static_cast<BLOCKTYPE>(i)));
} }
} }