fix block chunk data allocating on write to disk
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
This commit is contained in:
parent
4458c9e266
commit
d7868d0ccc
@ -200,6 +200,9 @@ public class BlockChunkData implements BlockMeshgenData {
|
||||
* @return The type at that position
|
||||
*/
|
||||
public short getType(int x, int y, int z){
|
||||
if(this.homogenousValue != BlockChunkData.NOT_HOMOGENOUS){
|
||||
return this.homogenousValue;
|
||||
}
|
||||
if(this.type == null){
|
||||
this.allocateFromHomogenous();
|
||||
}
|
||||
@ -214,10 +217,12 @@ public class BlockChunkData implements BlockMeshgenData {
|
||||
* @param type The type
|
||||
*/
|
||||
public void setType(int x, int y, int z, short type){
|
||||
if(this.type == null){
|
||||
if(this.type == null && this.homogenousValue != type){
|
||||
this.allocateFromHomogenous();
|
||||
}
|
||||
this.type[x * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH + z * CHUNK_DATA_WIDTH + y] = type;
|
||||
if(this.type != null){
|
||||
this.type[x * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH + z * CHUNK_DATA_WIDTH + y] = type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -228,10 +233,12 @@ public class BlockChunkData implements BlockMeshgenData {
|
||||
* @param type The type
|
||||
*/
|
||||
public void setType(int x, int y, int z, int type){
|
||||
if(this.type == null){
|
||||
if(this.type == null && this.homogenousValue != type){
|
||||
this.allocateFromHomogenous();
|
||||
}
|
||||
this.type[x * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH + z * CHUNK_DATA_WIDTH + y] = (short)type;
|
||||
if(this.type != null){
|
||||
this.type[x * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH + z * CHUNK_DATA_WIDTH + y] = (short)type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -242,10 +249,12 @@ public class BlockChunkData implements BlockMeshgenData {
|
||||
* @param metadata The metadata
|
||||
*/
|
||||
public void setMetadata(int x, int y, int z, short metadata){
|
||||
if(this.metadata == null){
|
||||
if(this.metadata == null && metadata != 0){
|
||||
this.allocateFromHomogenous();
|
||||
}
|
||||
this.metadata[x * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH + z * CHUNK_DATA_WIDTH + y] = metadata;
|
||||
if(this.metadata != null){
|
||||
this.metadata[x * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH + z * CHUNK_DATA_WIDTH + y] = metadata;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -256,10 +265,12 @@ public class BlockChunkData implements BlockMeshgenData {
|
||||
* @param metadata The metadata
|
||||
*/
|
||||
public void setMetadata(int x, int y, int z, int metadata){
|
||||
if(this.metadata == null){
|
||||
if(this.metadata == null && metadata != 0){
|
||||
this.allocateFromHomogenous();
|
||||
}
|
||||
this.metadata[x * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH + z * CHUNK_DATA_WIDTH + y] = (short)metadata;
|
||||
if(this.metadata != null){
|
||||
this.metadata[x * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH + z * CHUNK_DATA_WIDTH + y] = (short)metadata;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -270,6 +281,9 @@ public class BlockChunkData implements BlockMeshgenData {
|
||||
* @return The metadata at that position
|
||||
*/
|
||||
public short getMetadata(int x, int y, int z){
|
||||
if(this.homogenousValue != BlockChunkData.NOT_HOMOGENOUS){
|
||||
return 0;
|
||||
}
|
||||
if(this.metadata == null){
|
||||
this.allocateFromHomogenous();
|
||||
}
|
||||
|
||||
@ -29,7 +29,9 @@ import electrosphere.util.math.HashUtils;
|
||||
*/
|
||||
public class ClientBlockManager {
|
||||
|
||||
//queues messages from server
|
||||
/**
|
||||
* queues messages from server
|
||||
*/
|
||||
List<TerrainMessage> messageQueue = new LinkedList<TerrainMessage>();
|
||||
|
||||
/**
|
||||
@ -47,10 +49,14 @@ public class ClientBlockManager {
|
||||
*/
|
||||
public static final int FAILED_REQUEST_THRESHOLD = 500;
|
||||
|
||||
//The interpolation ratio of block
|
||||
/**
|
||||
* The interpolation ratio of block
|
||||
*/
|
||||
public static final int INTERPOLATION_RATIO = ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO;
|
||||
|
||||
//caches chunks from server
|
||||
/**
|
||||
* caches chunks from server
|
||||
*/
|
||||
static final int CACHE_SIZE = 2500 + (int)(ClientDrawCellManager.FULL_RES_DIST * 10) + (int)(ClientDrawCellManager.HALF_RES_DIST * 10);
|
||||
|
||||
/**
|
||||
@ -63,7 +69,9 @@ public class ClientBlockManager {
|
||||
*/
|
||||
BlockChunkCache blockCache;
|
||||
|
||||
//The world data for the client
|
||||
/**
|
||||
* The world data for the client
|
||||
*/
|
||||
ClientWorldData clientWorldData;
|
||||
|
||||
//The queue of block chunk data to be buffered to gpu
|
||||
|
||||
@ -214,7 +214,9 @@ public class TerrainProtocol implements ClientProtocolTemplate<TerrainMessage> {
|
||||
message.getvoxelZ(),
|
||||
message.getblockType()
|
||||
);
|
||||
data.setHomogenousValue(BlockChunkData.NOT_HOMOGENOUS);
|
||||
if(data.getHomogenousValue() != message.getblockType()){
|
||||
data.setHomogenousValue(BlockChunkData.NOT_HOMOGENOUS);
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
@ -6,9 +6,8 @@ import io.github.studiorailgun.CircularByteBuffer;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* The main message parser. This is used to serialize/deserialize messages to/from the provided streams.
|
||||
@ -38,12 +37,12 @@ public class NetworkParser {
|
||||
/**
|
||||
* The queue of incoming messages that have been parsed
|
||||
*/
|
||||
LinkedList<NetworkMessage> incomingMessageQueue = new LinkedList<NetworkMessage>();
|
||||
CopyOnWriteArrayList<NetworkMessage> incomingMessageQueue = new CopyOnWriteArrayList<NetworkMessage>();
|
||||
|
||||
/**
|
||||
* The queue of outgoing messages that have yet to be sent
|
||||
*/
|
||||
LinkedList<NetworkMessage> outgoingMessageQueue = new LinkedList<NetworkMessage>();
|
||||
CopyOnWriteArrayList<NetworkMessage> outgoingMessageQueue = new CopyOnWriteArrayList<NetworkMessage>();
|
||||
|
||||
/**
|
||||
* Message object pool
|
||||
@ -60,6 +59,11 @@ public class NetworkParser {
|
||||
*/
|
||||
byte[] readBuffer = new byte[READ_BLOCK_SIZE];
|
||||
|
||||
/**
|
||||
* The outgoing byte buffer
|
||||
*/
|
||||
CopyOnWriteArrayList<Byte> outgoingByteQueue = new CopyOnWriteArrayList<Byte>();
|
||||
|
||||
/**
|
||||
* The number of bytes read
|
||||
*/
|
||||
@ -71,11 +75,6 @@ public class NetworkParser {
|
||||
*/
|
||||
boolean releaseOnSend = true;
|
||||
|
||||
/**
|
||||
* Lock for thread-safing the parser
|
||||
*/
|
||||
ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -104,11 +103,9 @@ public class NetworkParser {
|
||||
//parse byte queue for messages
|
||||
//for each message, append to clientIncomingMessageQueue
|
||||
NetworkMessage newMessage;
|
||||
lock.lock();
|
||||
while((newMessage = NetworkMessage.parseBytestreamForMessage(incomingByteBuffer,this.pool))!=null){
|
||||
incomingMessageQueue.add(newMessage);
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -116,15 +113,13 @@ public class NetworkParser {
|
||||
* @throws IOException Thrown if a message fails to serialize or the output stream fails to write
|
||||
*/
|
||||
public void pushMessagesOut() throws IOException {
|
||||
lock.lock();
|
||||
for(NetworkMessage message : outgoingMessageQueue){
|
||||
outgoingMessageQueue.remove(message);
|
||||
outgoingStream.write(message.getRawBytes());
|
||||
if(this.releaseOnSend){
|
||||
this.pool.release(message);
|
||||
}
|
||||
}
|
||||
outgoingMessageQueue.clear();
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -132,10 +127,7 @@ public class NetworkParser {
|
||||
* @return true if there is message in the queue, false otherwise
|
||||
*/
|
||||
public boolean hasIncomingMessaage(){
|
||||
lock.lock();
|
||||
boolean rVal = incomingMessageQueue.size() > 0;
|
||||
lock.unlock();
|
||||
return rVal;
|
||||
return incomingMessageQueue.size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -143,10 +135,7 @@ public class NetworkParser {
|
||||
* @return The message
|
||||
*/
|
||||
public NetworkMessage popIncomingMessage(){
|
||||
lock.lock();
|
||||
NetworkMessage rVal = incomingMessageQueue.remove(0);
|
||||
lock.unlock();
|
||||
return rVal;
|
||||
return incomingMessageQueue.remove(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -154,9 +143,7 @@ public class NetworkParser {
|
||||
* @param message The message
|
||||
*/
|
||||
public void addOutgoingMessage(NetworkMessage message){
|
||||
lock.lock();
|
||||
outgoingMessageQueue.add(message);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,9 +151,7 @@ public class NetworkParser {
|
||||
* @param messages The list to copy the incoming messages to
|
||||
*/
|
||||
public void copyIncomingMessages(List<NetworkMessage> messages){
|
||||
lock.lock();
|
||||
messages.addAll(incomingMessageQueue);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -174,9 +159,7 @@ public class NetworkParser {
|
||||
* @param messages The list to copy the outgoing messages to
|
||||
*/
|
||||
public void copyOutgoingMessages(List<NetworkMessage> messages){
|
||||
lock.lock();
|
||||
messages.addAll(outgoingMessageQueue);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -32,6 +32,21 @@ public class ServerBlockChunkDiskMap {
|
||||
*/
|
||||
static final String BLOCK_DATA_DIR = "/block/";
|
||||
|
||||
/**
|
||||
* 1 x 4 int that stores whether it is a homogenous chunk or not
|
||||
*/
|
||||
static final int FILE_HEADER = 4;
|
||||
|
||||
/**
|
||||
* Header value for it being a non-homogenous chunk
|
||||
*/
|
||||
static final int HEADER_NON_HOMOGENOUS = 0;
|
||||
|
||||
/**
|
||||
* Header value for it being a homogenous chunk
|
||||
*/
|
||||
static final int HEADER_HOMOGENOUS = 1;
|
||||
|
||||
/**
|
||||
* The map of world position+chunk type to the file that actually houses that information
|
||||
*/
|
||||
@ -138,26 +153,42 @@ public class ServerBlockChunkDiskMap {
|
||||
//parse
|
||||
if(rawData != null){
|
||||
ByteBuffer buffer = ByteBuffer.wrap(rawData);
|
||||
ShortBuffer shortView = buffer.asShortBuffer();
|
||||
short[] type = new short[BlockChunkData.TOTAL_DATA_WIDTH];
|
||||
short[] metadata = new short[BlockChunkData.TOTAL_DATA_WIDTH];
|
||||
short firstType = -1;
|
||||
boolean homogenous = true;
|
||||
for(int i = 0; i < BlockChunkData.TOTAL_DATA_WIDTH; i++){
|
||||
type[i] = shortView.get();
|
||||
if(firstType == -1){
|
||||
firstType = type[i];
|
||||
} else if(homogenous && firstType == type[i]){
|
||||
homogenous = false;
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < BlockChunkData.TOTAL_DATA_WIDTH; i++){
|
||||
metadata[i] = shortView.get();
|
||||
}
|
||||
rVal = new BlockChunkData();
|
||||
rVal.setType(type);
|
||||
rVal.setMetadata(metadata);
|
||||
rVal.setHomogenousValue(homogenous ? firstType : BlockChunkData.NOT_HOMOGENOUS);
|
||||
|
||||
|
||||
int headerHomogenousType = buffer.getInt();
|
||||
if(headerHomogenousType == HEADER_NON_HOMOGENOUS){
|
||||
|
||||
//read a non-homogenous chunk
|
||||
ShortBuffer shortView = buffer.asShortBuffer();
|
||||
short[] type = new short[BlockChunkData.TOTAL_DATA_WIDTH];
|
||||
short[] metadata = new short[BlockChunkData.TOTAL_DATA_WIDTH];
|
||||
short firstType = -1;
|
||||
boolean homogenous = true;
|
||||
for(int i = 0; i < BlockChunkData.TOTAL_DATA_WIDTH; i++){
|
||||
type[i] = shortView.get();
|
||||
if(firstType == -1){
|
||||
firstType = type[i];
|
||||
} else if(homogenous && firstType == type[i]){
|
||||
homogenous = false;
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < BlockChunkData.TOTAL_DATA_WIDTH; i++){
|
||||
metadata[i] = shortView.get();
|
||||
}
|
||||
|
||||
|
||||
rVal.setType(type);
|
||||
rVal.setMetadata(metadata);
|
||||
rVal.setHomogenousValue(homogenous ? firstType : BlockChunkData.NOT_HOMOGENOUS);
|
||||
} else {
|
||||
|
||||
//read a homogenous chunk
|
||||
short homogenousValue = buffer.getShort();
|
||||
rVal.setHomogenousValue(homogenousValue);
|
||||
}
|
||||
|
||||
//set metadata
|
||||
rVal.setWorldX(worldX);
|
||||
rVal.setWorldY(worldY);
|
||||
rVal.setWorldZ(worldZ);
|
||||
@ -186,13 +217,32 @@ public class ServerBlockChunkDiskMap {
|
||||
//generate binary for the file
|
||||
short[] type = chunkData.getType();
|
||||
short[] metadata = chunkData.getMetadata();
|
||||
ByteBuffer buffer = ByteBuffer.allocate(BlockChunkData.TOTAL_DATA_WIDTH * 2 * 2);
|
||||
ShortBuffer shortView = buffer.asShortBuffer();
|
||||
for(int i = 0; i < BlockChunkData.TOTAL_DATA_WIDTH; i++){
|
||||
shortView.put(type[i]);
|
||||
|
||||
//allocate buffer
|
||||
ByteBuffer buffer = null;
|
||||
if(chunkData.getHomogenousValue() == BlockChunkData.NOT_HOMOGENOUS){
|
||||
buffer = ByteBuffer.allocate(ServerBlockChunkDiskMap.FILE_HEADER + BlockChunkData.TOTAL_DATA_WIDTH * 2 * 2);
|
||||
} else {
|
||||
buffer = ByteBuffer.allocate(ServerBlockChunkDiskMap.FILE_HEADER + 2);
|
||||
}
|
||||
for(int i = 0; i < BlockChunkData.TOTAL_DATA_WIDTH; i++){
|
||||
shortView.put(metadata[i]);
|
||||
|
||||
//push data
|
||||
if(chunkData.getHomogenousValue() == BlockChunkData.NOT_HOMOGENOUS){
|
||||
//put header
|
||||
buffer.putInt(HEADER_NON_HOMOGENOUS);
|
||||
//put data
|
||||
ShortBuffer shortView = buffer.asShortBuffer();
|
||||
for(int i = 0; i < BlockChunkData.TOTAL_DATA_WIDTH; i++){
|
||||
shortView.put(type[i]);
|
||||
}
|
||||
for(int i = 0; i < BlockChunkData.TOTAL_DATA_WIDTH; i++){
|
||||
shortView.put(metadata[i]);
|
||||
}
|
||||
} else {
|
||||
//put header
|
||||
buffer.putInt(HEADER_HOMOGENOUS);
|
||||
//put data
|
||||
buffer.putShort(chunkData.getHomogenousValue());
|
||||
}
|
||||
//compress
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
|
||||
@ -119,11 +119,10 @@ public class ServerBlockChunkGenerationThread implements Runnable {
|
||||
}
|
||||
//generate if it does not exist
|
||||
if(chunk == null){
|
||||
chunk = BlockChunkData.allocate();
|
||||
chunk = new BlockChunkData();
|
||||
chunk.setWorldX(worldX);
|
||||
chunk.setWorldY(worldY);
|
||||
chunk.setWorldZ(worldZ);
|
||||
|
||||
ServerBlockChunkGenerationThread.generate(chunk, macroData, worldX, worldY, worldZ);
|
||||
}
|
||||
if(chunk != null){
|
||||
|
||||
@ -125,7 +125,7 @@ public class ServerBlockManager {
|
||||
}
|
||||
//generate if it does not exist
|
||||
if(returnedChunk == null){
|
||||
returnedChunk = BlockChunkData.allocate();
|
||||
returnedChunk = new BlockChunkData();
|
||||
returnedChunk.setWorldX(worldX);
|
||||
returnedChunk.setWorldY(worldY);
|
||||
returnedChunk.setWorldZ(worldZ);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user