diff --git a/assets/Data/game/recipes/voxelrecipes.json b/assets/Data/game/recipes/voxelrecipes.json index 14dd0550..f7307766 100644 --- a/assets/Data/game/recipes/voxelrecipes.json +++ b/assets/Data/game/recipes/voxelrecipes.json @@ -21,7 +21,7 @@ "craftingTag" : "HAND", "ingredients": [ { - "itemType": "mat:Log", + "itemType": "mat:Rock", "count": 1 } ], diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 76a0da2b..1c5022dc 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1646,6 +1646,7 @@ New AI behaviors - Stops targeting trees if they're dead Fix bug where sync messages eternally bounce if the entity was already deleted Fix blocks not saving to disk when being ejected from cache +Block chunk memory pooling diff --git a/src/main/java/electrosphere/client/block/BlockChunkCache.java b/src/main/java/electrosphere/client/block/BlockChunkCache.java index e8e850a1..1cfeb824 100644 --- a/src/main/java/electrosphere/client/block/BlockChunkCache.java +++ b/src/main/java/electrosphere/client/block/BlockChunkCache.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.locks.ReentrantLock; +import electrosphere.mem.BlockChunkPool; import electrosphere.server.physics.block.diskmap.ServerBlockChunkDiskMap; import electrosphere.util.math.HashUtils; @@ -142,11 +143,29 @@ public class BlockChunkCache { BlockChunkData fullRes = cacheMapFullRes.remove(oldKey); if(fullRes != null && this.chunkDiskMap != null){ this.chunkDiskMap.saveToDisk(fullRes); + BlockChunkPool.release(fullRes.getType()); + BlockChunkPool.release(fullRes.getMetadata()); + } + BlockChunkData halfRes = cacheMapHalfRes.remove(oldKey); + BlockChunkData quarterRes = cacheMapQuarterRes.remove(oldKey); + BlockChunkData eighthRes = cacheMapEighthRes.remove(oldKey); + BlockChunkData sixteenthRes = cacheMapSixteenthRes.remove(oldKey); + if(halfRes != null){ + BlockChunkPool.release(halfRes.getType()); + BlockChunkPool.release(halfRes.getMetadata()); + } + if(quarterRes != null){ + BlockChunkPool.release(quarterRes.getType()); + BlockChunkPool.release(quarterRes.getMetadata()); + } + if(eighthRes != null){ + BlockChunkPool.release(eighthRes.getType()); + BlockChunkPool.release(eighthRes.getMetadata()); + } + if(sixteenthRes != null){ + BlockChunkPool.release(sixteenthRes.getType()); + BlockChunkPool.release(sixteenthRes.getMetadata()); } - cacheMapHalfRes.remove(oldKey); - cacheMapQuarterRes.remove(oldKey); - cacheMapEighthRes.remove(oldKey); - cacheMapSixteenthRes.remove(oldKey); } lock.unlock(); } diff --git a/src/main/java/electrosphere/client/block/BlockChunkData.java b/src/main/java/electrosphere/client/block/BlockChunkData.java index cf62dfb1..de2bef7d 100644 --- a/src/main/java/electrosphere/client/block/BlockChunkData.java +++ b/src/main/java/electrosphere/client/block/BlockChunkData.java @@ -2,6 +2,7 @@ package electrosphere.client.block; import org.joml.Vector3i; +import electrosphere.mem.BlockChunkPool; import electrosphere.renderer.meshgen.BlockMeshgenData; import electrosphere.server.physics.terrain.manager.ServerTerrainChunk; @@ -129,8 +130,8 @@ public class BlockChunkData implements BlockMeshgenData { */ public static BlockChunkData allocate(){ BlockChunkData rVal = new BlockChunkData(); - rVal.setType(new short[CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH]); - rVal.setMetadata(new short[CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH]); + rVal.setType(BlockChunkPool.getShort()); + rVal.setMetadata(BlockChunkPool.getShort()); return rVal; } @@ -147,8 +148,8 @@ public class BlockChunkData implements BlockMeshgenData { * Allocates the arrays in a given homogenous data chunk */ private void allocateFromHomogenous(){ - this.setType(new short[CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH]); - this.setMetadata(new short[CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH]); + this.setType(BlockChunkPool.getShort()); + this.setMetadata(BlockChunkPool.getShort()); } /** diff --git a/src/main/java/electrosphere/mem/BlockChunkPool.java b/src/main/java/electrosphere/mem/BlockChunkPool.java new file mode 100644 index 00000000..7f67cae9 --- /dev/null +++ b/src/main/java/electrosphere/mem/BlockChunkPool.java @@ -0,0 +1,53 @@ +package electrosphere.mem; + +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.locks.ReentrantLock; + +import electrosphere.client.block.BlockChunkData; + +/** + * A pool for temporary vectors + */ +public class BlockChunkPool { + + /** + * Structure to store not-in-use objects + */ + static List shortPool = new LinkedList(); + + /** + * Lock for thread-safeing operations + */ + static ReentrantLock lock = new ReentrantLock(); + + /** + * Gets a short[] from the pool. Allocates if no free one is available. + * @param type The type of the message + * @return A short[] + */ + public static short[] getShort(){ + short[] rVal = null; + lock.lock(); + if(shortPool.size() > 0){ + rVal = shortPool.remove(0); + } else { + rVal = new short[BlockChunkData.CHUNK_DATA_WIDTH * BlockChunkData.CHUNK_DATA_WIDTH * BlockChunkData.CHUNK_DATA_WIDTH]; + } + lock.unlock(); + return rVal; + } + + /** + * Releases a Vector3f back into the pool + * @param data The object to release + */ + public static void release(short[] data){ + lock.lock(); + if(data != null){ + BlockChunkPool.shortPool.add(data); + } + lock.unlock(); + } + +} diff --git a/src/main/java/electrosphere/net/client/protocol/EntityProtocol.java b/src/main/java/electrosphere/net/client/protocol/EntityProtocol.java index e3ae8525..2c69aa03 100644 --- a/src/main/java/electrosphere/net/client/protocol/EntityProtocol.java +++ b/src/main/java/electrosphere/net/client/protocol/EntityProtocol.java @@ -49,6 +49,10 @@ public class EntityProtocol implements ClientProtocolTemplate { Globals.profiler.beginAggregateCpuSample("EntityProtocol.handleEntityMessage"); LoggerInterface.loggerNetworking.DEBUG_LOOP("Parse entity message of type " + message.getMessageSubtype()); + if(Globals.clientScene != null && Globals.clientSynchronizationManager.isDeleted(message.getentityID())){ + return; + } + //error check if(Globals.clientScene != null && Globals.clientSceneWrapper.getEntityFromServerId(message.getentityID()) == null && !idModifyingMessages.contains(message.getMessageSubtype())){ LoggerInterface.loggerNetworking.WARNING("Client received packet for entity that is not in the client scene!"); diff --git a/src/main/java/electrosphere/net/synchronization/client/ClientSynchronizationManager.java b/src/main/java/electrosphere/net/synchronization/client/ClientSynchronizationManager.java index 667dd22d..36a3a892 100644 --- a/src/main/java/electrosphere/net/synchronization/client/ClientSynchronizationManager.java +++ b/src/main/java/electrosphere/net/synchronization/client/ClientSynchronizationManager.java @@ -192,6 +192,15 @@ public class ClientSynchronizationManager { this.deletedEntityIds.add(id); } + /** + * Checks if an entity has been deleted by the server + * @param entityId The entity's id + * @return true if it has been deleted, false otherwise + */ + public boolean isDeleted(int entityId){ + return this.deletedEntityIds.contains(entityId); + } + /** *

Automatically generated

*