/* * Copyright 2013 MovingBlocks * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.terasology.world.chunks.blockdata; import com.google.common.base.Preconditions; import org.terasology.world.chunks.deflate.TeraVisitingDeflator; import java.nio.ByteBuffer; import java.nio.ShortBuffer; /** * TeraDenseArray16Bit implements a dense array with elements of 16 bit size. * Its elements are in the range -32'768 through +32'767 and it internally uses the short type to store its elements. * */ public class TeraDenseArray16Bit extends TeraDenseArray { protected short[] data; public TeraDenseArray16Bit() { super(); } public TeraDenseArray16Bit(int sizeX, int sizeY, int sizeZ) { super(sizeX, sizeY, sizeZ, true); } public TeraDenseArray16Bit(int sizeX, int sizeY, int sizeZ, short[] data) { super(sizeX, sizeY, sizeZ, false); this.data = Preconditions.checkNotNull(data); Preconditions.checkArgument(data.length == getSizeXYZ(), "The length of parameter 'data' has to be " + getSizeXYZ() + " but is " + data.length); } public TeraDenseArray16Bit(TeraArray in) { super(in); } @Override protected void initialize() { this.data = new short[getSizeXYZ()]; } @Override public TeraArray copy() { short[] tmp = new short[getSizeXYZ()]; System.arraycopy(data, 0, tmp, 0, getSizeXYZ()); return new TeraDenseArray16Bit(getSizeX(), getSizeY(), getSizeZ(), tmp); } @Override public TeraArray deflate(TeraVisitingDeflator deflator) { return Preconditions.checkNotNull(deflator).deflateDenseArray16Bit(data, getSizeXZ(), getSizeX(), getSizeY(), getSizeZ()); } @Override public int getEstimatedMemoryConsumptionInBytes() { if (data == null) { return 4; } else { return 16 + data.length * 2; } } @Override public int getElementSizeInBits() { return 16; } @Override public int get(int x, int y, int z) { return data[pos(x, y, z)]; } @Override public int set(int x, int y, int z, int value) { int pos = pos(x, y, z); int old = data[pos]; data[pos] = (short) value; return old; } @Override public boolean set(int x, int y, int z, int value, int expected) { int pos = pos(x, y, z); int old = data[pos]; if (old == expected) { data[pos] = (short) value; return true; } return false; } public static class SerializationHandler extends TeraArray.BasicSerializationHandler<TeraDenseArray16Bit> { @Override public boolean canHandle(Class<?> clazz) { return TeraDenseArray16Bit.class.equals(clazz); } @Override protected int internalComputeMinimumBufferSize(TeraDenseArray16Bit array) { final short[] data = array.data; if (data == null) { return 4; } else { return 4 + data.length * 2; } } @Override protected void internalSerialize(TeraDenseArray16Bit array, ByteBuffer buffer) { final short[] data = array.data; if (data == null) { buffer.putInt(0); } else { buffer.putInt(data.length); final ShortBuffer sbuffer = buffer.asShortBuffer(); sbuffer.put(data); buffer.position(buffer.position() + data.length * 2); } } @Override protected TeraDenseArray16Bit internalDeserialize(int sizeX, int sizeY, int sizeZ, ByteBuffer buffer) { final int length = buffer.getInt(); if (length > 0) { final short[] data = new short[length]; final ShortBuffer sbuffer = buffer.asShortBuffer(); sbuffer.get(data, 0, length); buffer.position(buffer.position() + length * 2); return new TeraDenseArray16Bit(sizeX, sizeY, sizeZ, data); } return new TeraDenseArray16Bit(sizeX, sizeY, sizeZ); } } public static class Factory implements TeraArray.Factory<TeraDenseArray16Bit> { @Override public Class<TeraDenseArray16Bit> getArrayClass() { return TeraDenseArray16Bit.class; } @Override public SerializationHandler createSerializationHandler() { return new SerializationHandler(); } @Override public TeraDenseArray16Bit create() { return new TeraDenseArray16Bit(); } @Override public TeraDenseArray16Bit create(int sizeX, int sizeY, int sizeZ) { return new TeraDenseArray16Bit(sizeX, sizeY, sizeZ); } } }