1
0

cBlockArea: use unique_ptr

This commit is contained in:
peterbell10 2017-09-06 18:40:04 +01:00 committed by Mattes D
parent 642fc239e2
commit 4a0355f065
3 changed files with 163 additions and 147 deletions

View File

@ -296,26 +296,7 @@ void MergeCombinatorMask(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cBlockArea: // cBlockArea:
cBlockArea::cBlockArea(void) : cBlockArea::cBlockArea(void) = default;
m_BlockTypes(nullptr),
m_BlockMetas(nullptr),
m_BlockLight(nullptr),
m_BlockSkyLight(nullptr)
{
}
cBlockArea::~cBlockArea()
{
Clear();
}
bool cBlockArea::IsValidDataTypeCombination(int a_DataTypes) bool cBlockArea::IsValidDataTypeCombination(int a_DataTypes)
{ {
@ -338,15 +319,10 @@ bool cBlockArea::IsValidDataTypeCombination(int a_DataTypes)
void cBlockArea::Clear(void) void cBlockArea::Clear(void)
{ {
delete[] m_BlockTypes; m_BlockTypes = nullptr; m_BlockTypes.reset();
delete[] m_BlockMetas; m_BlockMetas = nullptr; m_BlockMetas.reset();
delete[] m_BlockLight; m_BlockLight = nullptr; m_BlockLight.reset();
delete[] m_BlockSkyLight; m_BlockSkyLight = nullptr; m_BlockSkyLight.reset();
if (m_BlockEntities != nullptr)
{
ClearBlockEntities(*m_BlockEntities);
m_BlockEntities.reset();
}
m_BlockEntities.reset(); m_BlockEntities.reset();
m_Origin.Set(0, 0, 0); m_Origin.Set(0, 0, 0);
m_Size.Set(0, 0, 0); m_Size.Set(0, 0, 0);
@ -373,7 +349,7 @@ void cBlockArea::Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
int BlockCount = a_SizeX * a_SizeY * a_SizeZ; int BlockCount = a_SizeX * a_SizeY * a_SizeZ;
if ((a_DataTypes & baTypes) != 0) if ((a_DataTypes & baTypes) != 0)
{ {
m_BlockTypes = new BLOCKTYPE[BlockCount]; m_BlockTypes.reset(new BLOCKTYPE[BlockCount]);
for (int i = 0; i < BlockCount; i++) for (int i = 0; i < BlockCount; i++)
{ {
m_BlockTypes[i] = E_BLOCK_AIR; m_BlockTypes[i] = E_BLOCK_AIR;
@ -381,7 +357,7 @@ void cBlockArea::Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
} }
if ((a_DataTypes & baMetas) != 0) if ((a_DataTypes & baMetas) != 0)
{ {
m_BlockMetas = new NIBBLETYPE[BlockCount]; m_BlockMetas.reset(new NIBBLETYPE[BlockCount]);
for (int i = 0; i < BlockCount; i++) for (int i = 0; i < BlockCount; i++)
{ {
m_BlockMetas[i] = 0; m_BlockMetas[i] = 0;
@ -389,7 +365,7 @@ void cBlockArea::Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
} }
if ((a_DataTypes & baLight) != 0) if ((a_DataTypes & baLight) != 0)
{ {
m_BlockLight = new NIBBLETYPE[BlockCount]; m_BlockLight.reset(new NIBBLETYPE[BlockCount]);
for (int i = 0; i < BlockCount; i++) for (int i = 0; i < BlockCount; i++)
{ {
m_BlockLight[i] = 0; m_BlockLight[i] = 0;
@ -397,7 +373,7 @@ void cBlockArea::Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
} }
if ((a_DataTypes & baSkyLight) != 0) if ((a_DataTypes & baSkyLight) != 0)
{ {
m_BlockSkyLight = new NIBBLETYPE[BlockCount]; m_BlockSkyLight.reset(new NIBBLETYPE[BlockCount]);
for (int i = 0; i < BlockCount; i++) for (int i = 0; i < BlockCount; i++)
{ {
m_BlockSkyLight[i] = 0x0f; m_BlockSkyLight[i] = 0x0f;
@ -405,7 +381,7 @@ void cBlockArea::Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
} }
if ((a_DataTypes & baBlockEntities) != 0) if ((a_DataTypes & baBlockEntities) != 0)
{ {
m_BlockEntities = cpp14::make_unique<cBlockEntities>(); m_BlockEntities.reset(new cBlockEntities);
} }
m_Size.Set(a_SizeX, a_SizeY, a_SizeZ); m_Size.Set(a_SizeX, a_SizeY, a_SizeZ);
m_Origin.Set(0, 0, 0); m_Origin.Set(0, 0, 0);
@ -613,19 +589,19 @@ void cBlockArea::CopyTo(cBlockArea & a_Into) const
size_t BlockCount = GetBlockCount(); size_t BlockCount = GetBlockCount();
if (HasBlockTypes()) if (HasBlockTypes())
{ {
memcpy(a_Into.m_BlockTypes, m_BlockTypes, BlockCount * sizeof(BLOCKTYPE)); memcpy(a_Into.GetBlockTypes(), GetBlockTypes(), BlockCount * sizeof(BLOCKTYPE));
} }
if (HasBlockMetas()) if (HasBlockMetas())
{ {
memcpy(a_Into.m_BlockMetas, m_BlockMetas, BlockCount * sizeof(NIBBLETYPE)); memcpy(a_Into.GetBlockMetas(), GetBlockMetas(), BlockCount * sizeof(NIBBLETYPE));
} }
if (HasBlockLights()) if (HasBlockLights())
{ {
memcpy(a_Into.m_BlockLight, m_BlockLight, BlockCount * sizeof(NIBBLETYPE)); memcpy(a_Into.GetBlockLight(), GetBlockLight(), BlockCount * sizeof(NIBBLETYPE));
} }
if (HasBlockSkyLights()) if (HasBlockSkyLights())
{ {
memcpy(a_Into.m_BlockSkyLight, m_BlockSkyLight, BlockCount * sizeof(NIBBLETYPE)); memcpy(a_Into.GetBlockSkyLight(), GetBlockSkyLight(), BlockCount * sizeof(NIBBLETYPE));
} }
if (HasBlockEntities()) if (HasBlockEntities())
{ {
@ -670,19 +646,19 @@ void cBlockArea::DumpToRawFile(const AString & a_FileName)
size_t NumBlocks = GetBlockCount(); size_t NumBlocks = GetBlockCount();
if (HasBlockTypes()) if (HasBlockTypes())
{ {
f.Write(m_BlockTypes, NumBlocks * sizeof(BLOCKTYPE)); f.Write(GetBlockTypes(), NumBlocks * sizeof(BLOCKTYPE));
} }
if (HasBlockMetas()) if (HasBlockMetas())
{ {
f.Write(m_BlockMetas, NumBlocks); f.Write(GetBlockMetas(), NumBlocks);
} }
if (HasBlockLights()) if (HasBlockLights())
{ {
f.Write(m_BlockLight, NumBlocks); f.Write(GetBlockLight(), NumBlocks);
} }
if (HasBlockSkyLights()) if (HasBlockSkyLights())
{ {
f.Write(m_BlockSkyLight, NumBlocks); f.Write(GetBlockSkyLight(), NumBlocks);
} }
} }
@ -826,7 +802,7 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R
{ {
const NIBBLETYPE * SrcMetas = a_Src.GetBlockMetas(); const NIBBLETYPE * SrcMetas = a_Src.GetBlockMetas();
NIBBLETYPE * DstMetas = m_BlockMetas; NIBBLETYPE * DstMetas = GetBlockMetas();
bool IsDummyMetas = ((SrcMetas == nullptr) || (DstMetas == nullptr)); bool IsDummyMetas = ((SrcMetas == nullptr) || (DstMetas == nullptr));
@ -1123,8 +1099,8 @@ void cBlockArea::RotateCCW(void)
} }
// We are guaranteed that both blocktypes and blockmetas exist; rotate both at the same time: // We are guaranteed that both blocktypes and blockmetas exist; rotate both at the same time:
BLOCKTYPE * NewTypes = new BLOCKTYPE[GetBlockCount()]; BLOCKARRAY NewTypes{ new BLOCKTYPE[GetBlockCount()] };
NIBBLETYPE * NewMetas = new NIBBLETYPE[GetBlockCount()]; NIBBLEARRAY NewMetas{ new NIBBLETYPE[GetBlockCount()] };
for (int x = 0; x < m_Size.x; x++) for (int x = 0; x < m_Size.x; x++)
{ {
int NewZ = m_Size.x - x - 1; int NewZ = m_Size.x - x - 1;
@ -1140,10 +1116,8 @@ void cBlockArea::RotateCCW(void)
} // for y } // for y
} // for z } // for z
} // for x } // for x
std::swap(m_BlockTypes, NewTypes); m_BlockTypes = std::move(NewTypes);
std::swap(m_BlockMetas, NewMetas); m_BlockMetas = std::move(NewMetas);
delete[] NewTypes; NewTypes = nullptr;
delete[] NewMetas; NewMetas = nullptr;
// Rotate the BlockEntities: // Rotate the BlockEntities:
if (HasBlockEntities()) if (HasBlockEntities())
@ -1185,8 +1159,8 @@ void cBlockArea::RotateCW(void)
} }
// We are guaranteed that both blocktypes and blockmetas exist; rotate both at the same time: // We are guaranteed that both blocktypes and blockmetas exist; rotate both at the same time:
BLOCKTYPE * NewTypes = new BLOCKTYPE[GetBlockCount()]; BLOCKARRAY NewTypes{ new BLOCKTYPE[GetBlockCount()] };
NIBBLETYPE * NewMetas = new NIBBLETYPE[GetBlockCount()]; NIBBLEARRAY NewMetas{ new NIBBLETYPE[GetBlockCount()] };
for (int x = 0; x < m_Size.x; x++) for (int x = 0; x < m_Size.x; x++)
{ {
int NewZ = x; int NewZ = x;
@ -1202,10 +1176,8 @@ void cBlockArea::RotateCW(void)
} // for y } // for y
} // for z } // for z
} // for x } // for x
std::swap(m_BlockTypes, NewTypes); m_BlockTypes = std::move(NewTypes);
std::swap(m_BlockMetas, NewMetas); m_BlockMetas = std::move(NewMetas);
delete[] NewTypes; NewTypes = nullptr;
delete[] NewMetas; NewMetas = nullptr;
// Rotate the BlockEntities: // Rotate the BlockEntities:
if (HasBlockEntities()) if (HasBlockEntities())
@ -1406,7 +1378,7 @@ void cBlockArea::RotateCCWNoMeta(void)
{ {
if (HasBlockTypes()) if (HasBlockTypes())
{ {
BLOCKTYPE * NewTypes = new BLOCKTYPE[GetBlockCount()]; BLOCKARRAY NewTypes{ new BLOCKTYPE[GetBlockCount()] };
for (int x = 0; x < m_Size.x; x++) for (int x = 0; x < m_Size.x; x++)
{ {
int NewZ = m_Size.x - x - 1; int NewZ = m_Size.x - x - 1;
@ -1419,12 +1391,11 @@ void cBlockArea::RotateCCWNoMeta(void)
} // for y } // for y
} // for z } // for z
} // for x } // for x
std::swap(m_BlockTypes, NewTypes); m_BlockTypes = std::move(NewTypes);
delete[] NewTypes; NewTypes = nullptr;
} }
if (HasBlockMetas()) if (HasBlockMetas())
{ {
NIBBLETYPE * NewMetas = new NIBBLETYPE[GetBlockCount()]; NIBBLEARRAY NewMetas{ new NIBBLETYPE[GetBlockCount()] };
for (int x = 0; x < m_Size.x; x++) for (int x = 0; x < m_Size.x; x++)
{ {
int NewZ = m_Size.x - x - 1; int NewZ = m_Size.x - x - 1;
@ -1437,8 +1408,7 @@ void cBlockArea::RotateCCWNoMeta(void)
} // for y } // for y
} // for z } // for z
} // for x } // for x
std::swap(m_BlockMetas, NewMetas); m_BlockMetas = std::move(NewMetas);
delete[] NewMetas; NewMetas = nullptr;
} }
// Rotate the BlockEntities: // Rotate the BlockEntities:
@ -1469,7 +1439,7 @@ void cBlockArea::RotateCWNoMeta(void)
{ {
if (HasBlockTypes()) if (HasBlockTypes())
{ {
BLOCKTYPE * NewTypes = new BLOCKTYPE[GetBlockCount()]; BLOCKARRAY NewTypes{ new BLOCKTYPE[GetBlockCount()] };
for (int z = 0; z < m_Size.z; z++) for (int z = 0; z < m_Size.z; z++)
{ {
int NewX = m_Size.z - z - 1; int NewX = m_Size.z - z - 1;
@ -1482,12 +1452,11 @@ void cBlockArea::RotateCWNoMeta(void)
} // for y } // for y
} // for x } // for x
} // for z } // for z
std::swap(m_BlockTypes, NewTypes); m_BlockTypes = std::move(NewTypes);
delete[] NewTypes; NewTypes = nullptr;
} }
if (HasBlockMetas()) if (HasBlockMetas())
{ {
NIBBLETYPE * NewMetas = new NIBBLETYPE[GetBlockCount()]; NIBBLEARRAY NewMetas{ new NIBBLETYPE[GetBlockCount()] };
for (int z = 0; z < m_Size.z; z++) for (int z = 0; z < m_Size.z; z++)
{ {
int NewX = m_Size.z - z - 1; int NewX = m_Size.z - z - 1;
@ -1500,8 +1469,7 @@ void cBlockArea::RotateCWNoMeta(void)
} // for y } // for y
} // for x } // for x
} // for z } // for z
std::swap(m_BlockMetas, NewMetas); m_BlockMetas = std::move(NewMetas);
delete[] NewMetas; NewMetas = nullptr;
} }
// Rotate the BlockEntities: // Rotate the BlockEntities:
@ -1732,7 +1700,7 @@ void cBlockArea::SetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYP
void cBlockArea::SetRelBlockMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockMeta) void cBlockArea::SetRelBlockMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockMeta)
{ {
SetRelNibble(a_RelX, a_RelY, a_RelZ, a_BlockMeta, m_BlockMetas); SetRelNibble(a_RelX, a_RelY, a_RelZ, a_BlockMeta, GetBlockMetas());
} }
@ -1741,7 +1709,7 @@ void cBlockArea::SetRelBlockMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE
void cBlockArea::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockMeta) void cBlockArea::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockMeta)
{ {
SetNibble(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta, m_BlockMetas); SetNibble(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta, GetBlockMetas());
} }
@ -1750,7 +1718,7 @@ void cBlockArea::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETY
void cBlockArea::SetRelBlockLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockLight) void cBlockArea::SetRelBlockLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockLight)
{ {
SetRelNibble(a_RelX, a_RelY, a_RelZ, a_BlockLight, m_BlockLight); SetRelNibble(a_RelX, a_RelY, a_RelZ, a_BlockLight, GetBlockLight());
} }
@ -1759,7 +1727,7 @@ void cBlockArea::SetRelBlockLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE
void cBlockArea::SetBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockLight) void cBlockArea::SetBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockLight)
{ {
SetNibble(a_BlockX, a_BlockY, a_BlockZ, a_BlockLight, m_BlockLight); SetNibble(a_BlockX, a_BlockY, a_BlockZ, a_BlockLight, GetBlockLight());
} }
@ -1768,7 +1736,7 @@ void cBlockArea::SetBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLET
void cBlockArea::SetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockSkyLight) void cBlockArea::SetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockSkyLight)
{ {
SetRelNibble(a_RelX, a_RelY, a_RelZ, a_BlockSkyLight, m_BlockSkyLight); SetRelNibble(a_RelX, a_RelY, a_RelZ, a_BlockSkyLight, GetBlockSkyLight());
} }
@ -1777,7 +1745,7 @@ void cBlockArea::SetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLET
void cBlockArea::SetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockSkyLight) void cBlockArea::SetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockSkyLight)
{ {
SetNibble(a_BlockX, a_BlockY, a_BlockZ, a_BlockSkyLight, m_BlockSkyLight); SetNibble(a_BlockX, a_BlockY, a_BlockZ, a_BlockSkyLight, GetBlockSkyLight());
} }
@ -1809,7 +1777,7 @@ BLOCKTYPE cBlockArea::GetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ) con
NIBBLETYPE cBlockArea::GetRelBlockMeta(int a_RelX, int a_RelY, int a_RelZ) const NIBBLETYPE cBlockArea::GetRelBlockMeta(int a_RelX, int a_RelY, int a_RelZ) const
{ {
return GetRelNibble(a_RelX, a_RelY, a_RelZ, m_BlockMetas); return GetRelNibble(a_RelX, a_RelY, a_RelZ, GetBlockMetas());
} }
@ -1818,7 +1786,7 @@ NIBBLETYPE cBlockArea::GetRelBlockMeta(int a_RelX, int a_RelY, int a_RelZ) const
NIBBLETYPE cBlockArea::GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ) const NIBBLETYPE cBlockArea::GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ) const
{ {
return GetNibble(a_BlockX, a_BlockY, a_BlockZ, m_BlockMetas); return GetNibble(a_BlockX, a_BlockY, a_BlockZ, GetBlockMetas());
} }
@ -1827,7 +1795,7 @@ NIBBLETYPE cBlockArea::GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ) co
NIBBLETYPE cBlockArea::GetRelBlockLight(int a_RelX, int a_RelY, int a_RelZ) const NIBBLETYPE cBlockArea::GetRelBlockLight(int a_RelX, int a_RelY, int a_RelZ) const
{ {
return GetRelNibble(a_RelX, a_RelY, a_RelZ, m_BlockLight); return GetRelNibble(a_RelX, a_RelY, a_RelZ, GetBlockLight());
} }
@ -1836,7 +1804,7 @@ NIBBLETYPE cBlockArea::GetRelBlockLight(int a_RelX, int a_RelY, int a_RelZ) cons
NIBBLETYPE cBlockArea::GetBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ) const NIBBLETYPE cBlockArea::GetBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ) const
{ {
return GetNibble(a_BlockX, a_BlockY, a_BlockZ, m_BlockLight); return GetNibble(a_BlockX, a_BlockY, a_BlockZ, GetBlockLight());
} }
@ -1845,7 +1813,7 @@ NIBBLETYPE cBlockArea::GetBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ) c
NIBBLETYPE cBlockArea::GetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ) const NIBBLETYPE cBlockArea::GetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ) const
{ {
return GetRelNibble(a_RelX, a_RelY, a_RelZ, m_BlockSkyLight); return GetRelNibble(a_RelX, a_RelY, a_RelZ, GetBlockSkyLight());
} }
@ -1854,7 +1822,7 @@ NIBBLETYPE cBlockArea::GetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ) c
NIBBLETYPE cBlockArea::GetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ) const NIBBLETYPE cBlockArea::GetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ) const
{ {
return GetNibble(a_BlockX, a_BlockY, a_BlockZ, m_BlockSkyLight); return GetNibble(a_BlockX, a_BlockY, a_BlockZ, GetBlockSkyLight());
} }
@ -2152,69 +2120,62 @@ int cBlockArea::GetDataTypes(void) const
bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes) bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
{ {
ASSERT(m_BlockTypes == nullptr); // Has been cleared
ASSERT(IsValidDataTypeCombination(a_DataTypes)); ASSERT(IsValidDataTypeCombination(a_DataTypes));
BLOCKARRAY NewBlocks;
NIBBLEARRAY NewMetas;
NIBBLEARRAY NewLight;
NIBBLEARRAY NewSkyLight;
cBlockEntitiesPtr NewBlockEntities;
// Try to allocate the new storage
if ((a_DataTypes & baTypes) != 0) if ((a_DataTypes & baTypes) != 0)
{ {
m_BlockTypes = new BLOCKTYPE[a_SizeX * a_SizeY * a_SizeZ]; NewBlocks.reset(new BLOCKTYPE[a_SizeX * a_SizeY * a_SizeZ]);
if (m_BlockTypes == nullptr) if (NewBlocks == nullptr)
{ {
return false; return false;
} }
} }
if ((a_DataTypes & baMetas) != 0) if ((a_DataTypes & baMetas) != 0)
{ {
m_BlockMetas = new NIBBLETYPE[a_SizeX * a_SizeY * a_SizeZ]; NewMetas.reset(new NIBBLETYPE[a_SizeX * a_SizeY * a_SizeZ]);
if (m_BlockMetas == nullptr) if (NewMetas == nullptr)
{ {
delete[] m_BlockTypes;
m_BlockTypes = nullptr;
return false; return false;
} }
} }
if ((a_DataTypes & baLight) != 0) if ((a_DataTypes & baLight) != 0)
{ {
m_BlockLight = new NIBBLETYPE[a_SizeX * a_SizeY * a_SizeZ]; NewLight.reset(new NIBBLETYPE[a_SizeX * a_SizeY * a_SizeZ]);
if (m_BlockLight == nullptr) if (NewLight == nullptr)
{ {
delete[] m_BlockMetas;
m_BlockMetas = nullptr;
delete[] m_BlockTypes;
m_BlockTypes = nullptr;
return false; return false;
} }
} }
if ((a_DataTypes & baSkyLight) != 0) if ((a_DataTypes & baSkyLight) != 0)
{ {
m_BlockSkyLight = new NIBBLETYPE[a_SizeX * a_SizeY * a_SizeZ]; NewSkyLight.reset(new NIBBLETYPE[a_SizeX * a_SizeY * a_SizeZ]);
if (m_BlockSkyLight == nullptr) if (NewSkyLight == nullptr)
{ {
delete[] m_BlockLight;
m_BlockLight = nullptr;
delete[] m_BlockMetas;
m_BlockMetas = nullptr;
delete[] m_BlockTypes;
m_BlockTypes = nullptr;
return false; return false;
} }
} }
if ((a_DataTypes & baBlockEntities) != 0) if ((a_DataTypes & baBlockEntities) != 0)
{ {
m_BlockEntities = cpp14::make_unique<cBlockEntities>(); NewBlockEntities.reset(new cBlockEntities);
if (m_BlockEntities == nullptr) if (NewBlockEntities == nullptr)
{ {
delete[] m_BlockSkyLight;
m_BlockSkyLight = nullptr;
delete[] m_BlockLight;
m_BlockLight = nullptr;
delete[] m_BlockMetas;
m_BlockMetas = nullptr;
delete[] m_BlockTypes;
m_BlockTypes = nullptr;
return false; return false;
} }
} }
// Commit changes
m_BlockTypes = std::move(NewBlocks);
m_BlockMetas = std::move(NewMetas);
m_BlockLight = std::move(NewLight);
m_BlockSkyLight = std::move(NewSkyLight);
m_BlockEntities = std::move(NewBlockEntities);
m_Size.Set(a_SizeX, a_SizeY, a_SizeZ); m_Size.Set(a_SizeX, a_SizeY, a_SizeZ);
return true; return true;
} }
@ -2340,7 +2301,7 @@ void cBlockArea::CropBlockTypes(int a_AddMinX, int a_SubMaxX, int a_AddMinY, int
int NewSizeX = GetSizeX() - a_AddMinX - a_SubMaxX; int NewSizeX = GetSizeX() - a_AddMinX - a_SubMaxX;
int NewSizeY = GetSizeY() - a_AddMinY - a_SubMaxY; int NewSizeY = GetSizeY() - a_AddMinY - a_SubMaxY;
int NewSizeZ = GetSizeZ() - a_AddMinZ - a_SubMaxZ; int NewSizeZ = GetSizeZ() - a_AddMinZ - a_SubMaxZ;
BLOCKTYPE * NewBlockTypes = new BLOCKTYPE[NewSizeX * NewSizeY * NewSizeZ]; BLOCKARRAY NewBlockTypes{ new BLOCKTYPE[NewSizeX * NewSizeY * NewSizeZ] };
int idx = 0; int idx = 0;
for (int y = 0; y < NewSizeY; y++) for (int y = 0; y < NewSizeY; y++)
{ {
@ -2353,8 +2314,7 @@ void cBlockArea::CropBlockTypes(int a_AddMinX, int a_SubMaxX, int a_AddMinY, int
} // for x } // for x
} // for z } // for z
} // for y } // for y
delete m_BlockTypes; m_BlockTypes = std::move(NewBlockTypes);
m_BlockTypes = NewBlockTypes;
} }
@ -2366,7 +2326,7 @@ void cBlockArea::CropNibbles(NIBBLEARRAY & a_Array, int a_AddMinX, int a_SubMaxX
int NewSizeX = GetSizeX() - a_AddMinX - a_SubMaxX; int NewSizeX = GetSizeX() - a_AddMinX - a_SubMaxX;
int NewSizeY = GetSizeY() - a_AddMinY - a_SubMaxY; int NewSizeY = GetSizeY() - a_AddMinY - a_SubMaxY;
int NewSizeZ = GetSizeZ() - a_AddMinZ - a_SubMaxZ; int NewSizeZ = GetSizeZ() - a_AddMinZ - a_SubMaxZ;
NIBBLETYPE * NewNibbles = new NIBBLETYPE[NewSizeX * NewSizeY * NewSizeZ]; NIBBLEARRAY NewNibbles{ new NIBBLETYPE[NewSizeX * NewSizeY * NewSizeZ] };
int idx = 0; int idx = 0;
for (int y = 0; y < NewSizeY; y++) for (int y = 0; y < NewSizeY; y++)
{ {
@ -2378,8 +2338,7 @@ void cBlockArea::CropNibbles(NIBBLEARRAY & a_Array, int a_AddMinX, int a_SubMaxX
} // for x } // for x
} // for z } // for z
} // for y } // for y
delete a_Array; a_Array = std::move(NewNibbles);
a_Array = NewNibbles;
} }
@ -2392,8 +2351,8 @@ void cBlockArea::ExpandBlockTypes(int a_SubMinX, int a_AddMaxX, int a_SubMinY, i
int NewSizeY = m_Size.y + a_SubMinY + a_AddMaxY; int NewSizeY = m_Size.y + a_SubMinY + a_AddMaxY;
int NewSizeZ = m_Size.z + a_SubMinZ + a_AddMaxZ; int NewSizeZ = m_Size.z + a_SubMinZ + a_AddMaxZ;
size_t BlockCount = static_cast<size_t>(NewSizeX * NewSizeY * NewSizeZ); size_t BlockCount = static_cast<size_t>(NewSizeX * NewSizeY * NewSizeZ);
BLOCKTYPE * NewBlockTypes = new BLOCKTYPE[BlockCount]; BLOCKARRAY NewBlockTypes{ new BLOCKTYPE[BlockCount] };
memset(NewBlockTypes, 0, BlockCount * sizeof(BLOCKTYPE)); memset(NewBlockTypes.get(), 0, BlockCount * sizeof(BLOCKTYPE));
int OldIndex = 0; int OldIndex = 0;
for (int y = 0; y < m_Size.y; y++) for (int y = 0; y < m_Size.y; y++)
{ {
@ -2408,8 +2367,7 @@ void cBlockArea::ExpandBlockTypes(int a_SubMinX, int a_AddMaxX, int a_SubMinY, i
} // for x } // for x
} // for z } // for z
} // for y } // for y
delete m_BlockTypes; m_BlockTypes = std::move(NewBlockTypes);
m_BlockTypes = NewBlockTypes;
} }
@ -2422,8 +2380,8 @@ void cBlockArea::ExpandNibbles(NIBBLEARRAY & a_Array, int a_SubMinX, int a_AddMa
int NewSizeY = m_Size.y + a_SubMinY + a_AddMaxY; int NewSizeY = m_Size.y + a_SubMinY + a_AddMaxY;
int NewSizeZ = m_Size.z + a_SubMinZ + a_AddMaxZ; int NewSizeZ = m_Size.z + a_SubMinZ + a_AddMaxZ;
size_t BlockCount = static_cast<size_t>(NewSizeX * NewSizeY * NewSizeZ); size_t BlockCount = static_cast<size_t>(NewSizeX * NewSizeY * NewSizeZ);
NIBBLETYPE * NewNibbles = new NIBBLETYPE[BlockCount]; NIBBLEARRAY NewNibbles{ new NIBBLETYPE[BlockCount] };
memset(NewNibbles, 0, BlockCount * sizeof(NIBBLETYPE)); memset(NewNibbles.get(), 0, BlockCount * sizeof(NIBBLETYPE));
int OldIndex = 0; int OldIndex = 0;
for (int y = 0; y < m_Size.y; y++) for (int y = 0; y < m_Size.y; y++)
{ {
@ -2438,8 +2396,7 @@ void cBlockArea::ExpandNibbles(NIBBLEARRAY & a_Array, int a_SubMinX, int a_AddMa
} // for x } // for x
} // for z } // for z
} // for y } // for y
delete a_Array; a_Array = std::move(NewNibbles);
a_Array = NewNibbles;
} }
@ -2529,7 +2486,7 @@ void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_Rel
case cBlockArea::msOverwrite: case cBlockArea::msOverwrite:
{ {
InternalMergeBlocks<MetasValid, MergeCombinatorOverwrite<MetasValid> >( InternalMergeBlocks<MetasValid, MergeCombinatorOverwrite<MetasValid> >(
m_BlockTypes, a_Src.GetBlockTypes(), GetBlockTypes(), a_Src.GetBlockTypes(),
DstMetas, SrcMetas, DstMetas, SrcMetas,
SizeX, SizeY, SizeZ, SizeX, SizeY, SizeZ,
SrcOffX, SrcOffY, SrcOffZ, SrcOffX, SrcOffY, SrcOffZ,
@ -2543,7 +2500,7 @@ void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_Rel
case cBlockArea::msFillAir: case cBlockArea::msFillAir:
{ {
InternalMergeBlocks<MetasValid, MergeCombinatorFillAir<MetasValid> >( InternalMergeBlocks<MetasValid, MergeCombinatorFillAir<MetasValid> >(
m_BlockTypes, a_Src.GetBlockTypes(), GetBlockTypes(), a_Src.GetBlockTypes(),
DstMetas, SrcMetas, DstMetas, SrcMetas,
SizeX, SizeY, SizeZ, SizeX, SizeY, SizeZ,
SrcOffX, SrcOffY, SrcOffZ, SrcOffX, SrcOffY, SrcOffZ,
@ -2557,7 +2514,7 @@ void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_Rel
case cBlockArea::msImprint: case cBlockArea::msImprint:
{ {
InternalMergeBlocks<MetasValid, MergeCombinatorImprint<MetasValid> >( InternalMergeBlocks<MetasValid, MergeCombinatorImprint<MetasValid> >(
m_BlockTypes, a_Src.GetBlockTypes(), GetBlockTypes(), a_Src.GetBlockTypes(),
DstMetas, SrcMetas, DstMetas, SrcMetas,
SizeX, SizeY, SizeZ, SizeX, SizeY, SizeZ,
SrcOffX, SrcOffY, SrcOffZ, SrcOffX, SrcOffY, SrcOffZ,
@ -2571,7 +2528,7 @@ void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_Rel
case cBlockArea::msLake: case cBlockArea::msLake:
{ {
InternalMergeBlocks<MetasValid, MergeCombinatorLake<MetasValid> >( InternalMergeBlocks<MetasValid, MergeCombinatorLake<MetasValid> >(
m_BlockTypes, a_Src.GetBlockTypes(), GetBlockTypes(), a_Src.GetBlockTypes(),
DstMetas, SrcMetas, DstMetas, SrcMetas,
SizeX, SizeY, SizeZ, SizeX, SizeY, SizeZ,
SrcOffX, SrcOffY, SrcOffZ, SrcOffX, SrcOffY, SrcOffZ,
@ -2585,7 +2542,7 @@ void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_Rel
case cBlockArea::msSpongePrint: case cBlockArea::msSpongePrint:
{ {
InternalMergeBlocks<MetasValid, MergeCombinatorSpongePrint<MetasValid> >( InternalMergeBlocks<MetasValid, MergeCombinatorSpongePrint<MetasValid> >(
m_BlockTypes, a_Src.GetBlockTypes(), GetBlockTypes(), a_Src.GetBlockTypes(),
DstMetas, SrcMetas, DstMetas, SrcMetas,
SizeX, SizeY, SizeZ, SizeX, SizeY, SizeZ,
SrcOffX, SrcOffY, SrcOffZ, SrcOffX, SrcOffY, SrcOffZ,
@ -2599,7 +2556,7 @@ void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_Rel
case cBlockArea::msDifference: case cBlockArea::msDifference:
{ {
InternalMergeBlocks<MetasValid, MergeCombinatorDifference<MetasValid> >( InternalMergeBlocks<MetasValid, MergeCombinatorDifference<MetasValid> >(
m_BlockTypes, a_Src.GetBlockTypes(), GetBlockTypes(), a_Src.GetBlockTypes(),
DstMetas, SrcMetas, DstMetas, SrcMetas,
SizeX, SizeY, SizeZ, SizeX, SizeY, SizeZ,
SrcOffX, SrcOffY, SrcOffZ, SrcOffX, SrcOffY, SrcOffZ,
@ -2613,7 +2570,7 @@ void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_Rel
case cBlockArea::msSimpleCompare: case cBlockArea::msSimpleCompare:
{ {
InternalMergeBlocks<MetasValid, MergeCombinatorSimpleCompare<MetasValid> >( InternalMergeBlocks<MetasValid, MergeCombinatorSimpleCompare<MetasValid> >(
m_BlockTypes, a_Src.GetBlockTypes(), GetBlockTypes(), a_Src.GetBlockTypes(),
DstMetas, SrcMetas, DstMetas, SrcMetas,
SizeX, SizeY, SizeZ, SizeX, SizeY, SizeZ,
SrcOffX, SrcOffY, SrcOffZ, SrcOffX, SrcOffY, SrcOffZ,
@ -2627,7 +2584,7 @@ void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_Rel
case cBlockArea::msMask: case cBlockArea::msMask:
{ {
InternalMergeBlocks<MetasValid, MergeCombinatorMask<MetasValid> >( InternalMergeBlocks<MetasValid, MergeCombinatorMask<MetasValid> >(
m_BlockTypes, a_Src.GetBlockTypes(), GetBlockTypes(), a_Src.GetBlockTypes(),
DstMetas, SrcMetas, DstMetas, SrcMetas,
SizeX, SizeY, SizeZ, SizeX, SizeY, SizeZ,
SrcOffX, SrcOffY, SrcOffZ, SrcOffX, SrcOffY, SrcOffZ,
@ -2793,6 +2750,22 @@ void cBlockArea::RemoveNonMatchingBlockEntities(void)
////////////////////////////////////////////////////////////////////////////////
// cBlockArea::sBlockEntityDeleter:
void cBlockArea::sBlockEntitiesDeleter::operator () (cBlockEntities * a_BlockEntities)
{
if (a_BlockEntities != nullptr)
{
ClearBlockEntities(*a_BlockEntities);
delete a_BlockEntities;
}
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cBlockArea::cChunkReader: // cBlockArea::cChunkReader:

View File

@ -63,7 +63,6 @@ public:
} ; } ;
cBlockArea(void); cBlockArea(void);
~cBlockArea();
/** Returns true if the datatype combination is valid. /** Returns true if the datatype combination is valid.
Invalid combinations include BlockEntities without BlockTypes. */ Invalid combinations include BlockEntities without BlockTypes. */
@ -366,10 +365,10 @@ public:
// Clients can use these for faster access to all blocktypes. Be careful though! // Clients can use these for faster access to all blocktypes. Be careful though!
/** Returns the internal pointer to the block types */ /** Returns the internal pointer to the block types */
BLOCKTYPE * GetBlockTypes (void) const { return m_BlockTypes; } BLOCKTYPE * GetBlockTypes (void) const { return m_BlockTypes.get(); }
NIBBLETYPE * GetBlockMetas (void) const { return m_BlockMetas; } // NOTE: one byte per block! NIBBLETYPE * GetBlockMetas (void) const { return m_BlockMetas.get(); } // NOTE: one byte per block!
NIBBLETYPE * GetBlockLight (void) const { return m_BlockLight; } // NOTE: one byte per block! NIBBLETYPE * GetBlockLight (void) const { return m_BlockLight.get(); } // NOTE: one byte per block!
NIBBLETYPE * GetBlockSkyLight(void) const { return m_BlockSkyLight; } // NOTE: one byte per block! NIBBLETYPE * GetBlockSkyLight(void) const { return m_BlockSkyLight.get(); } // NOTE: one byte per block!
size_t GetBlockCount(void) const { return static_cast<size_t>(m_Size.x * m_Size.y * m_Size.z); } size_t GetBlockCount(void) const { return static_cast<size_t>(m_Size.x * m_Size.y * m_Size.z); }
int MakeIndex(int a_RelX, int a_RelY, int a_RelZ) const; int MakeIndex(int a_RelX, int a_RelY, int a_RelZ) const;
@ -419,7 +418,43 @@ protected:
virtual void BlockEntity(cBlockEntity * a_BlockEntity) override; virtual void BlockEntity(cBlockEntity * a_BlockEntity) override;
} ; } ;
typedef NIBBLETYPE * NIBBLEARRAY; template <typename T>
class cDynArray:
public std::unique_ptr<T[]>
{
using Super = std::unique_ptr<T[]>;
public:
// using Super::Super;
cDynArray() = default;
cDynArray(cDynArray && a_Other) : Super(std::move(a_Other)) {}
cDynArray & operator = (cDynArray && a_Other)
{
Super::operator = (std::move(a_Other));
return *this;
}
cDynArray(std::nullptr_t) {}
cDynArray(T * a_Ptr):
Super(a_Ptr)
{
}
// Allow indexing with signed types
T & operator [] (int a_Idx) const
{
ASSERT(a_Idx >= 0);
return (Super::get())[a_Idx];
}
T & operator [] (size_t a_Idx) const
{
return (Super::get())[a_Idx];
}
};
using NIBBLEARRAY = cDynArray<NIBBLETYPE>;
using BLOCKARRAY = cDynArray<BLOCKTYPE>;
Vector3i m_Origin; Vector3i m_Origin;
@ -429,15 +464,23 @@ protected:
cBlockArea doesn't use this value in any way. */ cBlockArea doesn't use this value in any way. */
Vector3i m_WEOffset; Vector3i m_WEOffset;
BLOCKTYPE * m_BlockTypes; BLOCKARRAY m_BlockTypes;
NIBBLETYPE * m_BlockMetas; // Each meta is stored as a separate byte for faster access NIBBLEARRAY m_BlockMetas; // Each meta is stored as a separate byte for faster access
NIBBLETYPE * m_BlockLight; // Each light value is stored as a separate byte for faster access NIBBLEARRAY m_BlockLight; // Each light value is stored as a separate byte for faster access
NIBBLETYPE * m_BlockSkyLight; // Each light value is stored as a separate byte for faster access NIBBLEARRAY m_BlockSkyLight; // Each light value is stored as a separate byte for faster access
/** Deleter to clear the block entities before deleting the container. */
struct sBlockEntitiesDeleter
{
void operator () (cBlockEntities * a_BlockEntities);
};
using cBlockEntitiesPtr = std::unique_ptr<cBlockEntities, sBlockEntitiesDeleter>;
/** The block entities contained within the area. /** The block entities contained within the area.
Only valid if the area was created / read with the baBlockEntities flag. Only valid if the area was created / read with the baBlockEntities flag.
The block entities are owned by this object. */ The block entities are owned by this object. */
std::unique_ptr<cBlockEntities> m_BlockEntities; cBlockEntitiesPtr m_BlockEntities;
/** Clears the data stored and prepares a fresh new block area with the specified dimensions */ /** Clears the data stored and prepares a fresh new block area with the specified dimensions */
bool SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes); bool SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes);

View File

@ -210,7 +210,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP
); );
NumTypeBytes = a_NBT.GetDataLength(TBlockTypes); NumTypeBytes = a_NBT.GetDataLength(TBlockTypes);
} }
memcpy(a_BlockArea.m_BlockTypes, a_NBT.GetData(TBlockTypes), NumTypeBytes); memcpy(a_BlockArea.GetBlockTypes(), a_NBT.GetData(TBlockTypes), NumTypeBytes);
if (AreMetasPresent) if (AreMetasPresent)
{ {
@ -222,7 +222,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP
); );
NumMetaBytes = a_NBT.GetDataLength(TBlockMetas); NumMetaBytes = a_NBT.GetDataLength(TBlockMetas);
} }
memcpy(a_BlockArea.m_BlockMetas, a_NBT.GetData(TBlockMetas), NumMetaBytes); memcpy(a_BlockArea.GetBlockMetas(), a_NBT.GetData(TBlockMetas), NumMetaBytes);
} }
return true; return true;
@ -241,7 +241,7 @@ AString cSchematicFileSerializer::SaveToSchematicNBT(const cBlockArea & a_BlockA
Writer.AddString("Materials", "Alpha"); Writer.AddString("Materials", "Alpha");
if (a_BlockArea.HasBlockTypes()) if (a_BlockArea.HasBlockTypes())
{ {
Writer.AddByteArray("Blocks", reinterpret_cast<const char *>(a_BlockArea.m_BlockTypes), a_BlockArea.GetBlockCount()); Writer.AddByteArray("Blocks", reinterpret_cast<const char *>(a_BlockArea.GetBlockTypes()), a_BlockArea.GetBlockCount());
} }
else else
{ {
@ -250,7 +250,7 @@ AString cSchematicFileSerializer::SaveToSchematicNBT(const cBlockArea & a_BlockA
} }
if (a_BlockArea.HasBlockMetas()) if (a_BlockArea.HasBlockMetas())
{ {
Writer.AddByteArray("Data", reinterpret_cast<const char *>(a_BlockArea.m_BlockMetas), a_BlockArea.GetBlockCount()); Writer.AddByteArray("Data", reinterpret_cast<const char *>(a_BlockArea.GetBlockMetas()), a_BlockArea.GetBlockCount());
} }
else else
{ {