1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Start every block as monoblock, and set m_is_mono_block in reallocate

This commit is contained in:
Lars 2025-06-12 23:26:32 -07:00
parent 5967457be0
commit 46044e6d77
3 changed files with 27 additions and 25 deletions

View file

@ -101,11 +101,12 @@ static const char *modified_reason_strings[] = {
*/
MapBlock::MapBlock(v3s16 pos, IGameDef *gamedef):
m_is_mono_block(true),
m_pos(pos),
m_pos_relative(pos * MAP_BLOCKSIZE),
m_gamedef(gamedef)
{
reallocate(nodecount, MapNode(CONTENT_IGNORE));
reallocate(1, MapNode(CONTENT_IGNORE));
}
MapBlock::~MapBlock()
@ -222,25 +223,27 @@ void MapBlock::copyFrom(const VoxelManipulator &src)
v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE);
VoxelArea data_area(v3s16(0,0,0), data_size - v3s16(1,1,1));
deconvertMonoblock();
expandNodesIfNeeded();
// Copy from VoxelManipulator to data
src.copyTo(data, data_area, v3s16(0,0,0),
getPosRelative(), data_size);
tryConvertToMonoblock();
tryShrinkNodes();
}
void MapBlock::reallocate(u32 c, MapNode n)
{
delete[] data;
if (c == 1)
if (!m_is_mono_block && c == 1)
porting::TrackFreedMemory(sizeof(MapNode) * nodecount);
data = new MapNode[c];
for (u32 i = 0; i < c; i++)
data[i] = n;
m_is_mono_block = (c == 1);
}
void MapBlock::tryConvertToMonoblock()
void MapBlock::tryShrinkNodes()
{
if (m_is_mono_block)
return;
@ -255,7 +258,6 @@ void MapBlock::tryConvertToMonoblock()
}
if (is_mono_block) {
m_is_mono_block = true;
reallocate(1, n);
if (n.getContent() == CONTENT_AIR) {
m_is_air = true;
@ -264,11 +266,10 @@ void MapBlock::tryConvertToMonoblock()
}
}
void MapBlock::deconvertMonoblock()
void MapBlock::expandNodesIfNeeded()
{
if (m_is_mono_block) {
reallocate(nodecount, data[0]);
m_is_mono_block = false;
}
}
@ -513,6 +514,7 @@ void MapBlock::deSerialize(std::istream &in_compressed, u8 version, bool disk)
TRACESTREAM(<<"MapBlock::deSerialize "<<getPos()<<std::endl);
m_is_air_expired = true;
expandNodesIfNeeded();
if(version <= 21)
{
@ -642,7 +644,7 @@ void MapBlock::deSerialize(std::istream &in_compressed, u8 version, bool disk)
}
if (nimap.size() == 1) {
tryConvertToMonoblock();
tryShrinkNodes();
u16 dummy;
if (nimap.getId("air", dummy)) {
m_is_air = true;

View file

@ -76,7 +76,7 @@ public:
MapNode* getData()
{
deconvertMonoblock();
expandNodesIfNeeded();
return data;
}
@ -250,7 +250,7 @@ public:
if (!isValidPosition(x, y, z))
throw InvalidPositionException();
deconvertMonoblock();
expandNodesIfNeeded();
data[z * zstride + y * ystride + x] = n;
raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_SET_NODE);
}
@ -276,7 +276,7 @@ public:
inline void setNodeNoCheck(s16 x, s16 y, s16 z, MapNode n)
{
deconvertMonoblock();
expandNodesIfNeeded();
data[z * zstride + y * ystride + x] = n;
raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_SET_NODE);
}
@ -441,9 +441,9 @@ private:
void deSerialize_pre22(std::istream &is, u8 version, bool disk);
// check if all nodes are identical, if so store them as a single node
void tryConvertToMonoblock();
void tryShrinkNodes();
// if only a single node is stored, expand storage back to the full array
void deconvertMonoblock();
void expandNodesIfNeeded();
void reallocate(u32 c, MapNode n);
/*
@ -464,7 +464,7 @@ public:
private:
// see isOrphan()
bool m_orphan = false;
bool m_is_mono_block = false;
bool m_is_mono_block;
// Position in blocks on parent
v3s16 m_pos;

View file

@ -63,7 +63,7 @@ void TestMapBlock::testMonoblock(IGameDef *gamedef)
block.data[i] = MapNode(CONTENT_AIR);
}
// covert to monoblock
block.tryConvertToMonoblock();
block.tryShrinkNodes();
UASSERT(block.m_is_mono_block);
UASSERT(block.data[0].param0 == CONTENT_AIR);
UASSERT(block.data != t);
@ -76,17 +76,17 @@ void TestMapBlock::testMonoblock(IGameDef *gamedef)
UASSERT(block.data == d1);
// covert back to mono block
block.tryConvertToMonoblock();
block.tryShrinkNodes();
UASSERT(block.m_is_mono_block);
t = block.data;
// deconvert explicitly
block.deconvertMonoblock();
block.expandNodesIfNeeded();
UASSERT(!block.m_is_mono_block);
UASSERT(block.data != t);
// covert back to mono block
block.tryConvertToMonoblock();
block.tryShrinkNodes();
UASSERT(block.m_is_mono_block);
t = block.data;
@ -97,7 +97,7 @@ void TestMapBlock::testMonoblock(IGameDef *gamedef)
t = block.data;
// cannot covert to mono block
block.tryConvertToMonoblock();
block.tryShrinkNodes();
UASSERT(!block.m_is_mono_block);
UASSERT(block.data == t);
@ -107,7 +107,7 @@ void TestMapBlock::testMonoblock(IGameDef *gamedef)
}
// can covert to mono block
block.tryConvertToMonoblock();
block.tryShrinkNodes();
UASSERT(block.m_is_mono_block);
UASSERT(block.data[0].param0 == 42);
UASSERT(block.data != t);
@ -143,19 +143,19 @@ void TestMapBlock::testMonoblock(IGameDef *gamedef)
UASSERT(block.m_is_mono_block);
block.setNode(5,5,5,MapNode(23));
block.tryConvertToMonoblock();
block.tryShrinkNodes();
UASSERT(!block.m_is_mono_block);
block.setNode(5,5,5,MapNode(42, 1, 0));
block.tryConvertToMonoblock();
block.tryShrinkNodes();
UASSERT(!block.m_is_mono_block);
block.setNode(5,5,5,MapNode(42, 0, 1));
block.tryConvertToMonoblock();
block.tryShrinkNodes();
UASSERT(!block.m_is_mono_block);
block.setNode(5,5,5,MapNode(42));
block.tryConvertToMonoblock();
block.tryShrinkNodes();
UASSERT(block.m_is_mono_block);
}