fix block chunk data allocating on write to disk
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2025-05-03 19:02:35 -04:00
parent 4458c9e266
commit d7868d0ccc
7 changed files with 125 additions and 69 deletions

View File

@ -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,11 +217,13 @@ 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();
}
if(this.type != null){
this.type[x * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH + z * CHUNK_DATA_WIDTH + y] = type;
}
}
/**
* Sets a specific block's type
@ -228,11 +233,13 @@ 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();
}
if(this.type != null){
this.type[x * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH + z * CHUNK_DATA_WIDTH + y] = (short)type;
}
}
/**
* Sets a specific block's metadata
@ -242,11 +249,13 @@ 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();
}
if(this.metadata != null){
this.metadata[x * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH + z * CHUNK_DATA_WIDTH + y] = metadata;
}
}
/**
* Sets a specific block's metadata
@ -256,11 +265,13 @@ 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();
}
if(this.metadata != null){
this.metadata[x * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH + z * CHUNK_DATA_WIDTH + y] = (short)metadata;
}
}
/**
* Gets the metadata at a given position
@ -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();
}

View File

@ -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

View File

@ -214,9 +214,11 @@ public class TerrainProtocol implements ClientProtocolTemplate<TerrainMessage> {
message.getvoxelZ(),
message.getblockType()
);
if(data.getHomogenousValue() != message.getblockType()){
data.setHomogenousValue(BlockChunkData.NOT_HOMOGENOUS);
}
}
}
//
//mark all relevant drawcells as updateable
for(Vector3i worldPosToUpdate : positionsToUpdate){

View File

@ -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();
}
/**

View File

@ -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,6 +153,13 @@ public class ServerBlockChunkDiskMap {
//parse
if(rawData != null){
ByteBuffer buffer = ByteBuffer.wrap(rawData);
rVal = new BlockChunkData();
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];
@ -154,10 +176,19 @@ public class ServerBlockChunkDiskMap {
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);
} else {
//read a homogenous chunk
short homogenousValue = buffer.getShort();
rVal.setHomogenousValue(homogenousValue);
}
//set metadata
rVal.setWorldX(worldX);
rVal.setWorldY(worldY);
rVal.setWorldZ(worldZ);
@ -186,7 +217,20 @@ 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);
//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);
}
//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]);
@ -194,6 +238,12 @@ public class ServerBlockChunkDiskMap {
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();
DeflaterOutputStream deflaterInputStream = new DeflaterOutputStream(out);

View File

@ -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){

View File

@ -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);