Archived
0

More compact serialization

This commit is contained in:
Forwolk
2018-08-02 11:41:09 +03:00
parent 476b3624fe
commit a9e6378101
9 changed files with 46 additions and 39 deletions

View File

@@ -45,7 +45,6 @@ public interface Chunk extends Serializable{
int getY(); int getY();
int getZ(); int getZ();
Block[] getModifiedBlocks();
void setBlock (int x, int y, int z, Block block); void setBlock (int x, int y, int z, Block block);
Block getBlock (int x, int y, int z); Block getBlock (int x, int y, int z);
} }

View File

@@ -14,10 +14,10 @@ import java.io.Serializable;
* +-------------+----------------+------------+ * +-------------+----------------+------------+
* | param | range | bits | * | param | range | bits |
* +-------------+----------------+------------+ * +-------------+----------------+------------+
* | biome_map | 256x256 0-32 | 2097152 | * | biome_map | 256x256 0-128 | 524288 |
* +-------------+----------------+------------+ * +-------------+----------------+------------+
* *
* Total: 2097152 bits (256 Kb) * Total: 524288 bits (64 Kb)
* *
*/ */
public interface Region extends Serializable{ public interface Region extends Serializable{

View File

@@ -90,11 +90,6 @@ public class SimpleChunk implements Chunk {
return 0; return 0;
} }
@Override
public Block[] getModifiedBlocks() {
return new Block[0];
}
@Override @Override
public void setBlock(int x, int y, int z, Block block) { public void setBlock(int x, int y, int z, Block block) {

View File

@@ -3,13 +3,11 @@ package mc.world.generated_world.chunk;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import mc.core.block.Block; import mc.core.block.Block;
import mc.core.block.BlockType;
import mc.core.world.Biome; import mc.core.world.Biome;
import mc.core.world.Chunk; import mc.core.world.Chunk;
import mc.core.world.Region; import mc.core.world.Region;
import java.util.LinkedList;
import java.util.List;
import static mc.world.generated_world.WorldConstants.WORLD_CHUNK_SIZE; import static mc.world.generated_world.WorldConstants.WORLD_CHUNK_SIZE;
@RequiredArgsConstructor @RequiredArgsConstructor
@@ -21,7 +19,6 @@ public class ChunkImpl implements Chunk{
@Getter @Getter
private final int z; private final int z;
private final Block[][][] blocks = new Block[WORLD_CHUNK_SIZE][WORLD_CHUNK_SIZE][WORLD_CHUNK_SIZE]; private final Block[][][] blocks = new Block[WORLD_CHUNK_SIZE][WORLD_CHUNK_SIZE][WORLD_CHUNK_SIZE];
private final transient List<Block> modifiedBlocks = new LinkedList<>();
private final transient Region region; private final transient Region region;
@Override @Override
@@ -84,15 +81,12 @@ public class ChunkImpl implements Chunk{
region.setBiome(x + this.x * WORLD_CHUNK_SIZE,z + this.z * WORLD_CHUNK_SIZE, biome); region.setBiome(x + this.x * WORLD_CHUNK_SIZE,z + this.z * WORLD_CHUNK_SIZE, biome);
} }
@Override
public Block[] getModifiedBlocks() {
return modifiedBlocks.toArray(new Block[modifiedBlocks.size()]);
}
@Override @Override
public void setBlock(int x, int y, int z, Block block) { public void setBlock(int x, int y, int z, Block block) {
if (block.getBlockType() == BlockType.AIR) {
blocks[x][y][z] = null;
}
blocks[x][y][z] = block; blocks[x][y][z] = block;
modifiedBlocks.add(block);
} }
@Override @Override

View File

@@ -118,12 +118,6 @@ public class ChunkProxy implements Chunk {
return chunk.getZ(); return chunk.getZ();
} }
@Override
public Block[] getModifiedBlocks() {
use();
return chunk.getModifiedBlocks();
}
@Override @Override
public void setBlock(int x, int y, int z, Block block) { public void setBlock(int x, int y, int z, Block block) {
use(); use();

View File

@@ -6,6 +6,8 @@ import mc.core.block.BlockFactory;
import mc.core.block.BlockType; import mc.core.block.BlockType;
import mc.core.world.*; import mc.core.world.*;
import mc.world.generated_world.region.RegionImpl; import mc.world.generated_world.region.RegionImpl;
import mc.world.generated_world.serialization.ChunkSerializer;
import mc.world.generated_world.serialization.RegionReaderWriter;
import mc.world.generated_world.world.CubicWorld; import mc.world.generated_world.world.CubicWorld;
import mc.world.generated_world.world.Temperature; import mc.world.generated_world.world.Temperature;
import mc.world.generated_world.world.Wetness; import mc.world.generated_world.world.Wetness;
@@ -24,8 +26,8 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
WorldGenerator worldGenerator = new SeedBasedWorldGenerator(); WorldGenerator worldGenerator = new SeedBasedWorldGenerator();
World world = new CubicWorld(UUID.fromString("00000000-0000-0000-C000-000000000046"), 2626949); World world = new CubicWorld(UUID.fromString("00000000-0000-0000-C000-000000000046"), 2626949);
Region region = worldGenerator.generateRegion(0, 0, world); Region region = worldGenerator.generateRegion(0, 0, world);
//region.save(new ChunkSerializer(), new RegionSerializerDeserializer()); region.save(new ChunkSerializer(), new RegionReaderWriter(new File("worlds", world.getWorldId().toString())));
worldGenerator.generateRegion(1, 0, world); /*worldGenerator.generateRegion(1, 0, world);
worldGenerator.generateRegion(-1, 0, world); worldGenerator.generateRegion(-1, 0, world);
worldGenerator.generateRegion(0, 1, world); worldGenerator.generateRegion(0, 1, world);
worldGenerator.generateRegion(0, -1, world); worldGenerator.generateRegion(0, -1, world);
@@ -127,7 +129,7 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
image.setRGB(tx, ty, currentImage.getRGB(x, y)); image.setRGB(tx, ty, currentImage.getRGB(x, y));
} }
} }
ImageIO.write(image, "png", new File("out", "merged.png")); ImageIO.write(image, "png", new File("out", "merged.png"));*/
} }
@Override @Override

View File

@@ -84,8 +84,10 @@ public class RegionImpl implements Region{
for (int x = 0; x < WORLD_CHUNK_SIZE; x ++) { for (int x = 0; x < WORLD_CHUNK_SIZE; x ++) {
for (int z = 0; z < WORLD_CHUNK_SIZE; z ++) { for (int z = 0; z < WORLD_CHUNK_SIZE; z ++) {
for (int y = 0; y < WORLD_CHUNK_SIZE; y++) { for (int y = 0; y < WORLD_CHUNK_SIZE; y++) {
Chunk chunk = this.getChunkAt(x, y, z);
byte[] chunkBytes = chunkSerializer.serialize(chunk);
if (chunkBytes.length > 0) {
File chunkFile = new File(regionFile, MessageFormat.format(CHUNK_FILE_NAME_TEMPLATE, x, y, z)); File chunkFile = new File(regionFile, MessageFormat.format(CHUNK_FILE_NAME_TEMPLATE, x, y, z));
byte[] chunkBytes = chunkSerializer.serialize(this.getChunkAt(x, y, z));
try (FileOutputStream fileOutputStream = new FileOutputStream(chunkFile)) { try (FileOutputStream fileOutputStream = new FileOutputStream(chunkFile)) {
fileOutputStream.write(chunkBytes); fileOutputStream.write(chunkBytes);
} }
@@ -94,3 +96,4 @@ public class RegionImpl implements Region{
} }
} }
} }
}

View File

@@ -1,10 +1,19 @@
package mc.world.generated_world.serialization; package mc.world.generated_world.serialization;
import lombok.extern.slf4j.Slf4j;
import mc.core.block.Block; import mc.core.block.Block;
import mc.core.block.BlockFactory;
import mc.core.block.BlockType;
import mc.core.serialization.Serializer; import mc.core.serialization.Serializer;
import mc.core.world.Chunk; import mc.core.world.Chunk;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import static mc.world.generated_world.WorldConstants.WORLD_CHUNK_SIZE;
@Slf4j
public class ChunkSerializer implements Serializer<Chunk> { public class ChunkSerializer implements Serializer<Chunk> {
@Autowired @Autowired
@@ -12,15 +21,23 @@ public class ChunkSerializer implements Serializer<Chunk> {
@Override @Override
public byte[] serialize(Chunk chunk) { public byte[] serialize(Chunk chunk) {
int blocks = chunk.getModifiedBlocks().length; Serializer<Block> blockSerializer = new BlockSerializerDeserializer(new BlockFactory(), chunk);
byte[] bytes = new byte[3 * blocks]; ByteArrayOutputStream baos = new ByteArrayOutputStream();
Block current;
for (int i = 0; i < blocks; i ++) { for (int x = 0; x < WORLD_CHUNK_SIZE; x ++) {
byte[] blockSerialized = blockSerializer.serialize(chunk.getModifiedBlocks()[i]); for (int y = 0; y < WORLD_CHUNK_SIZE; y ++) {
for (int j = 0; j < 3; j ++) { for (int z = 0; z < WORLD_CHUNK_SIZE; z ++) {
bytes[i * 3 + j] = blockSerialized[j]; current = chunk.getBlock(x, y, z);
if (current != null && current.getBlockType() != BlockType.AIR) {
try {
baos.write(blockSerializer.serialize(current));
} catch (IOException e) {
log.error("Error occurred while writing serialized block to byte array", e);
} }
} }
return bytes; }
}
}
return baos.toByteArray();
} }
} }

View File

@@ -39,6 +39,9 @@ public class RegionReaderWriter implements IRegionReaderWriter {
@Override @Override
public void write (Region region) throws IOException{ public void write (Region region) throws IOException{
File regionFolder = new File(worldFolder, MessageFormat.format(REGION_FILE_NAME_TEMPLATE, region.getX(), region.getZ())); File regionFolder = new File(worldFolder, MessageFormat.format(REGION_FILE_NAME_TEMPLATE, region.getX(), region.getZ()));
if (!regionFolder.exists()) {
regionFolder.mkdirs();
}
File biomesFile = new File(regionFolder, BIOME_FILE_NAME_TEMPLATE); File biomesFile = new File(regionFolder, BIOME_FILE_NAME_TEMPLATE);
byte[] biomesBytes = new byte[WORLD_REGION_SIZE * WORLD_REGION_SIZE]; byte[] biomesBytes = new byte[WORLD_REGION_SIZE * WORLD_REGION_SIZE];
for (int x = 0; x < WORLD_REGION_SIZE; x ++) { for (int x = 0; x < WORLD_REGION_SIZE; x ++) {