Search in sources :

Example 1 with EntityUnsaveable

use of io.xol.chunkstories.api.entity.interfaces.EntityUnsaveable in project chunkstories by Hugobros3.

the class ChunkHolderImplementation method compressChunkData.

/**
 * This method is called assumming the chunk is well-locked
 */
private CompressedData compressChunkData(final CubicChunk chunk) {
    final int changesTakenIntoAccount = chunk.compr_uncomittedBlockModifications.get();
    // Stage 1: Compress the actual voxel data
    byte[] voxelCompressedData;
    if (!chunk.isAirChunk()) {
        // Heuristic value for the size of the buffer: fixed voxel size + factor of components & entities
        // + chunk.voxelComponents.size() * 1024 + chunk.localEntities.size() * 2048;
        int uncompressedStuffBufferSize = 32 * 32 * 32 * 4;
        ByteBuffer uncompressedStuff = MemoryUtil.memAlloc(uncompressedStuffBufferSize);
        uncompressedStuff.asIntBuffer().put(chunk.chunkVoxelData);
        // uncompressedStuff.flip();
        ByteBuffer compressedStuff = MemoryUtil.memAlloc(uncompressedStuffBufferSize + 2048);
        LZ4Compressor compressor = factory.fastCompressor();
        compressor.compress(uncompressedStuff, compressedStuff);
        // No longer need that buffer
        MemoryUtil.memFree(uncompressedStuff);
        // Make a Java byte[] array to put the final stuff in
        voxelCompressedData = new byte[compressedStuff.position()];
        compressedStuff.flip();
        compressedStuff.get(voxelCompressedData);
        // No longer need that buffer either
        MemoryUtil.memFree(compressedStuff);
    } else {
        // Just use a symbolic null here
        voxelCompressedData = null;
    }
    // Stage 2: Take care of the voxel components
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    DataOutputStream daos = new DataOutputStream(baos);
    // ByteBuffer smallBuffer = MemoryUtil.memAlloc(4096);
    // byte[] smallArray = new byte[4096];
    // ByteBufferOutputStream bbos = new ByteBufferOutputStream(smallBuffer);
    ByteArrayOutputStream bbos = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(bbos);
    try {
        // For all cells that have components
        for (CellComponentsHolder voxelComponents : chunk.allCellComponents.values()) {
            // Write a 1 then their in-chunk index
            daos.writeByte((byte) 0x01);
            daos.writeInt(voxelComponents.getIndex());
            // For all components in this cell
            for (Entry<String, VoxelComponent> entry : voxelComponents.all()) {
                // Write component name
                daos.writeUTF(entry.getKey());
                // Push the component in the temporary buffer
                entry.getValue().push(region.handler, dos);
                // smallBuffer.flip();
                byte[] bytesPushed = bbos.toByteArray();
                bbos.reset();
                // Write how many bytes the temporary buffer now contains
                // int bytesPushed = smallBuffer.limit();
                daos.writeShort(bytesPushed.length);
                // Get those bytes as an array then write it in the compressed stuff
                // smallBuffer.get(smallArray);
                daos.write(bytesPushed, 0, bytesPushed.length);
            // Reset the temporary buffer
            // smallBuffer.clear();
            }
            daos.writeUTF("\n");
        }
        // Write the final 00, so to be clear we are done with voxel components
        daos.writeByte((byte) 0x00);
    // Since we output to a local buffer, any failure is viewed as catastrophic
    } catch (IOException e) {
        assert false;
    }
    // Extract the byte array from the baos
    byte[] voxelComponentsData = baos.toByteArray();
    // MemoryUtil.memFree(smallBuffer);
    // Stage 3: Compress entities
    baos.reset();
    for (Entity entity : chunk.localEntities) {
        // Don't save controllable entities
        if (entity.exists() && !(entity instanceof EntityUnsaveable && !((EntityUnsaveable) entity).shouldSaveIntoRegion())) {
            EntitySerializer.writeEntityToStream(daos, region.handler, entity);
        }
    }
    EntitySerializer.writeEntityToStream(daos, region.handler, null);
    byte[] entityData = baos.toByteArray();
    // Remove whatever modifications existed when the method started, this is for avoiding concurrent modifications not being taken into account
    chunk.compr_uncomittedBlockModifications.addAndGet(-changesTakenIntoAccount);
    return new CompressedData(voxelCompressedData, voxelComponentsData, entityData);
}
Also used : EntityUnsaveable(io.xol.chunkstories.api.entity.interfaces.EntityUnsaveable) Entity(io.xol.chunkstories.api.entity.Entity) DataOutputStream(java.io.DataOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) CellComponentsHolder(io.xol.chunkstories.voxel.components.CellComponentsHolder) ByteBuffer(java.nio.ByteBuffer) LZ4Compressor(net.jpountz.lz4.LZ4Compressor) VoxelComponent(io.xol.chunkstories.api.voxel.components.VoxelComponent) PacketChunkCompressedData(io.xol.chunkstories.net.packets.PacketChunkCompressedData)

Aggregations

Entity (io.xol.chunkstories.api.entity.Entity)1 EntityUnsaveable (io.xol.chunkstories.api.entity.interfaces.EntityUnsaveable)1 VoxelComponent (io.xol.chunkstories.api.voxel.components.VoxelComponent)1 PacketChunkCompressedData (io.xol.chunkstories.net.packets.PacketChunkCompressedData)1 CellComponentsHolder (io.xol.chunkstories.voxel.components.CellComponentsHolder)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 DataOutputStream (java.io.DataOutputStream)1 IOException (java.io.IOException)1 ByteBuffer (java.nio.ByteBuffer)1 LZ4Compressor (net.jpountz.lz4.LZ4Compressor)1