fix world.set_chunk_data & rid of extra memory allocations in world.get_chunk_data

This commit is contained in:
MihailRis 2025-01-11 18:50:45 +03:00
parent 807abef2c4
commit 7b962841d6

View File

@ -7,6 +7,7 @@
#include "coders/compression.hpp" #include "coders/compression.hpp"
#include "coders/gzip.hpp" #include "coders/gzip.hpp"
#include "coders/json.hpp" #include "coders/json.hpp"
#include "coders/rle.hpp"
#include "engine/Engine.hpp" #include "engine/Engine.hpp"
#include "files/engine_paths.hpp" #include "files/engine_paths.hpp"
#include "files/files.hpp" #include "files/files.hpp"
@ -123,45 +124,44 @@ static int l_get_generator(lua::State* L) {
} }
static int l_get_chunk_data(lua::State* L) { static int l_get_chunk_data(lua::State* L) {
int x = (int)lua::tointeger(L, 1); int x = static_cast<int>(lua::tointeger(L, 1));
int y = (int)lua::tointeger(L, 2); int y = static_cast<int>(lua::tointeger(L, 2));
const auto& chunk = level->chunks->getChunk(x, y); const auto& chunk = level->chunks->getChunk(x, y);
if (chunk == nullptr) { if (chunk == nullptr) {
lua::pushnil(L); lua::pushnil(L);
return 0; return 0;
} }
bool compress = false; bool compress = true;
if (lua::gettop(L) >= 3) { if (lua::gettop(L) >= 3) {
compress = lua::toboolean(L, 3); compress = lua::toboolean(L, 3);
} }
std::vector<ubyte> chunk_data; std::vector<ubyte> chunk_data;
if (compress) { if (compress) {
size_t rle_compressed_size; // world.get_chunk_data is only available in the main Lua state
size_t gzip_compressed_size; static util::Buffer<ubyte> rlebuffer;
if (rlebuffer.size() < CHUNK_DATA_LEN * 2) {
rlebuffer = util::Buffer<ubyte>(CHUNK_DATA_LEN * 2);
}
const auto& data_ptr = chunk->encode(); const auto& data_ptr = chunk->encode();
ubyte* data = data_ptr.get(); ubyte* data = data_ptr.get();
const auto& rle_compressed_data_ptr = compression::compress(
data, size_t rle_compressed_size =
CHUNK_DATA_LEN, extrle::encode16(data, CHUNK_DATA_LEN, rlebuffer.data());
rle_compressed_size,
compression::Method::EXTRLE16 const auto gzip_compressed_data = gzip::compress(
); rlebuffer.data(), rle_compressed_size
const auto& gzip_compressed_data = compression::compress(
rle_compressed_data_ptr.get(),
rle_compressed_size,
gzip_compressed_size,
compression::Method::GZIP
); );
auto tmp = dataio::h2le(rle_compressed_size); auto tmp = dataio::h2le(rle_compressed_size);
chunk_data.reserve(gzip_compressed_size + sizeof(tmp)); chunk_data.reserve(gzip_compressed_data.size() + sizeof(tmp));
chunk_data.insert( chunk_data.insert(
chunk_data.begin() + 0, (char*)&tmp, ((char*)&tmp) + sizeof(tmp) chunk_data.begin() + 0, (char*)&tmp, ((char*)&tmp) + sizeof(tmp)
); );
chunk_data.insert( chunk_data.insert(
chunk_data.begin() + sizeof(tmp), chunk_data.begin() + sizeof(tmp),
gzip_compressed_data.get(), gzip_compressed_data.data(),
gzip_compressed_data.get() + gzip_compressed_size gzip_compressed_data.data() + gzip_compressed_data.size()
); );
} else { } else {
const auto& data = chunk->encode(); const auto& data = chunk->encode();
@ -174,10 +174,10 @@ static int l_get_chunk_data(lua::State* L) {
} }
static int l_set_chunk_data(lua::State* L) { static int l_set_chunk_data(lua::State* L) {
int x = (int)lua::tointeger(L, 1); int x = static_cast<int>(lua::tointeger(L, 1));
int y = (int)lua::tointeger(L, 2); int y = static_cast<int>(lua::tointeger(L, 2));
auto buffer = lua::touserdata<lua::LuaBytearray>(L, 3); auto buffer = lua::touserdata<lua::LuaBytearray>(L, 3);
bool is_compressed = false; bool is_compressed = true;
if (lua::gettop(L) >= 4) { if (lua::gettop(L) >= 4) {
is_compressed = lua::toboolean(L, 4); is_compressed = lua::toboolean(L, 4);
} }
@ -207,38 +207,32 @@ static int l_set_chunk_data(lua::State* L) {
} }
auto chunksController = controller->getChunksController(); auto chunksController = controller->getChunksController();
if (chunksController == nullptr) { if (chunksController->lighting == nullptr) {
return 1; return lua::pushboolean(L, true);
} }
Lighting& lighting = *chunksController->lighting; Lighting& lighting = *chunksController->lighting;
chunk->updateHeights(); chunk->updateHeights();
lighting.buildSkyLight(x, y); chunk->flags.loadedLights = false;
chunk->flags.modified = true; chunk->flags.lighted = false;
chunk->setModifiedAndUnsaved();
Lighting::prebuildSkyLight(*chunk, *indices);
lighting.onChunkLoaded(x, y, true); lighting.onChunkLoaded(x, y, true);
chunk = level->chunks->getChunk(x - 1, y); for (int lz = -1; lz <= 1; lz++) {
if (chunk != nullptr) { for (int lx = -1; lx <= 1; lx++) {
chunk->flags.modified = true; if (std::abs(lx) + std::abs(lz) != 1) {
lighting.onChunkLoaded(x - 1, y, true); continue;
} }
chunk = level->chunks->getChunk(x + 1, y); chunk = level->chunks->getChunk(x + lx, y + lz);
if (chunk != nullptr) { if (chunk != nullptr) {
chunk->flags.modified = true; chunk->setModifiedAndUnsaved();
lighting.onChunkLoaded(x + 1, y, true); lighting.onChunkLoaded(x - 1, y, true);
} }
chunk = level->chunks->getChunk(x, y - 1); }
if (chunk != nullptr) {
chunk->flags.modified = true;
lighting.onChunkLoaded(x, y - 1, true);
}
chunk = level->chunks->getChunk(x, y + 1);
if (chunk != nullptr) {
chunk->flags.modified = true;
lighting.onChunkLoaded(x, y + 1, true);
} }
return 1; return lua::pushboolean(L, true);
} }
static int l_count_chunks(lua::State* L) { static int l_count_chunks(lua::State* L) {