remove concurrent datastructures
Some checks reported errors
studiorailgun/Renderer/pipeline/head Something is wrong with the build of this commit

This commit is contained in:
austin 2024-11-29 21:36:05 -05:00
parent dfc59e0ea6
commit 0f85b0ac92
7 changed files with 64 additions and 27 deletions

View File

@ -13,6 +13,7 @@ TODO(?):
- Network optimization
- Building cube voxels w/ LOD
- Tools to build voxels
- Audio Ray Tracing

View File

@ -1189,6 +1189,7 @@ Spawn characters from database
Fluid spawning item
Fix fluid shader
Re-enable fluid simulation
Remove concurrent datastructure usage in cell management
# TODO

View File

@ -6,7 +6,6 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
import io.github.studiorailgun.HashUtils;
@ -29,27 +28,27 @@ public class BlockChunkCache {
/**
* The map of full res chunk key -> chunk data
*/
Map<Long,BlockChunkData> cacheMapFullRes = new ConcurrentHashMap<Long,BlockChunkData>();
Map<Long,BlockChunkData> cacheMapFullRes = new HashMap<Long,BlockChunkData>();
/**
* The map of half res chunk key -> chunk data
*/
Map<Long,BlockChunkData> cacheMapHalfRes = new ConcurrentHashMap<Long,BlockChunkData>();
Map<Long,BlockChunkData> cacheMapHalfRes = new HashMap<Long,BlockChunkData>();
/**
* The map of quarter res chunk key -> chunk data
*/
Map<Long,BlockChunkData> cacheMapQuarterRes = new ConcurrentHashMap<Long,BlockChunkData>();
Map<Long,BlockChunkData> cacheMapQuarterRes = new HashMap<Long,BlockChunkData>();
/**
* The map of eighth res chunk key -> chunk data
*/
Map<Long,BlockChunkData> cacheMapEighthRes = new ConcurrentHashMap<Long,BlockChunkData>();
Map<Long,BlockChunkData> cacheMapEighthRes = new HashMap<Long,BlockChunkData>();
/**
* The map of sixteenth res chunk key -> chunk data
*/
Map<Long,BlockChunkData> cacheMapSixteenthRes = new ConcurrentHashMap<Long,BlockChunkData>();
Map<Long,BlockChunkData> cacheMapSixteenthRes = new HashMap<Long,BlockChunkData>();
/**
* Tracks how recently a chunk has been queries for (used for evicting old chunks from cache)

View File

@ -1,9 +1,9 @@
package electrosphere.client.fluid.cache;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
/**
@ -14,9 +14,9 @@ public class ClientFluidCache {
//cache capacity
int cacheSize;
//the map of chunk key -> chunk data
Map<String,FluidChunkData> cacheMap = new ConcurrentHashMap<String,FluidChunkData>();
Map<String,FluidChunkData> cacheMap = new HashMap<String,FluidChunkData>();
//the list of keys in the cache
List<String> cacheList = new CopyOnWriteArrayList<String>();
List<String> cacheList = new LinkedList<String>();
/**
* Constructor

View File

@ -5,7 +5,7 @@ import java.nio.FloatBuffer;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.locks.ReentrantLock;
import org.joml.Vector3i;
@ -27,7 +27,7 @@ import electrosphere.server.terrain.manager.ServerTerrainManager;
public class ClientFluidManager {
//queues messages from server
List<TerrainMessage> messageQueue = new CopyOnWriteArrayList<TerrainMessage>();
List<TerrainMessage> messageQueue = new LinkedList<TerrainMessage>();
//The interpolation ratio of fluid
public static final int INTERPOLATION_RATIO = ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO;
@ -42,7 +42,12 @@ public class ClientFluidManager {
ClientWorldData clientWorldData;
//The queue of fluid chunk data to be buffered to gpu
static List<FluidChunkGenQueueItem> fluidChunkGenerationQueue = new CopyOnWriteArrayList<FluidChunkGenQueueItem>();
static List<FluidChunkGenQueueItem> fluidChunkGenerationQueue = new LinkedList<FluidChunkGenQueueItem>();
/**
* Lock for thread-safeing the manager
*/
static ReentrantLock lock = new ReentrantLock();
/**
* Constructor
@ -53,9 +58,9 @@ public class ClientFluidManager {
public void handleMessages(){
lock.lock();
List<TerrainMessage> bouncedMessages = new LinkedList<TerrainMessage>();
for(TerrainMessage message : messageQueue){
messageQueue.remove(message);
switch(message.getMessageSubtype()){
case SENDFLUIDDATA: {
ByteBuffer buffer = ByteBuffer.wrap(message.getchunkData());
@ -81,13 +86,17 @@ public class ClientFluidManager {
break;
}
}
messageQueue.clear();
for(TerrainMessage message : bouncedMessages){
messageQueue.add(message);
}
lock.unlock();
}
public void attachFluidMessage(TerrainMessage message){
lock.lock();
messageQueue.add(message);
lock.unlock();
}
public boolean containsChunkDataAtWorldPoint(int worldX, int worldY, int worldZ){
@ -135,7 +144,9 @@ public class ClientFluidManager {
UUID newUUID = UUID.randomUUID();
promisedHash = newUUID.toString();
FluidChunkGenQueueItem queueItem = new FluidChunkGenQueueItem(data, promisedHash);
lock.lock();
fluidChunkGenerationQueue.add(queueItem);
lock.unlock();
return promisedHash;
}
@ -144,11 +155,13 @@ public class ClientFluidManager {
*/
public static void generateFluidChunkGeometry(){
Globals.profiler.beginCpuSample("generateFluidChunkGeometry");
lock.lock();
for(FluidChunkGenQueueItem queueItem : fluidChunkGenerationQueue){
Model fluidModel = FluidChunkModelGeneration.generateFluidModel(queueItem.getData());
Globals.assetManager.registerModelToSpecificString(fluidModel, queueItem.getPromisedHash());
}
fluidChunkGenerationQueue.clear();
lock.unlock();
Globals.profiler.endCpuSample();
}

View File

@ -11,12 +11,15 @@ import electrosphere.server.fluid.simulator.cellularautomata.FluidCellularAutoma
import electrosphere.server.terrain.manager.ServerTerrainChunk;
import electrosphere.server.terrain.manager.ServerTerrainManager;
import electrosphere.util.FileUtils;
import electrosphere.util.annotation.Exclude;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.locks.ReentrantLock;
import org.joml.Vector3i;
@ -37,28 +40,40 @@ public class ServerFluidManager {
//While we incur a penalty with converting ints -> string, think this will
//offset regenerating the array every time we want a new one
int cacheSize = 500;
@Exclude
Map<String, ServerFluidChunk> chunkCache;
@Exclude
List<String> chunkCacheContents;
//The map of chunk position <-> file on disk containing chunk data
FluidDiskMap chunkDiskMap = null;
@Exclude
//The generation algorithm for this fluid manager
FluidGenerator chunkGenerator;
@Exclude
//the fluid simulator
ServerFluidSimulator serverFluidSimulator;
@Exclude
//the terrain manager associated
ServerTerrainManager serverTerrainManager;
//controls whether fluid simulation should actually happen or not
boolean simulate = false;
@Exclude
/**
* The parent world data
*/
ServerWorldData parent;
@Exclude
/**
* Locks the fluid manager
*/
ReentrantLock lock = new ReentrantLock();
/**
@ -72,8 +87,8 @@ public class ServerFluidManager {
){
this.parent = parent;
this.serverTerrainManager = serverTerrainManager;
this.chunkCache = new ConcurrentHashMap<String, ServerFluidChunk>();
this.chunkCacheContents = new CopyOnWriteArrayList<String>();
this.chunkCache = new HashMap<String, ServerFluidChunk>();
this.chunkCacheContents = new LinkedList<String>();
this.seed = seed;
this.chunkGenerator = chunkGenerator;
this.serverFluidSimulator = new FluidCellularAutomataSimulator();
@ -94,6 +109,7 @@ public class ServerFluidManager {
* @param saveName The name of the save
*/
public void save(String saveName){
lock.lock();
if(model != null){
ByteBuffer buffer = ByteBuffer.allocate(model.getElevation().length * model.getElevation()[0].length * 4);
FloatBuffer floatView = buffer.asFloatBuffer();
@ -115,6 +131,7 @@ public class ServerFluidManager {
if(chunkDiskMap != null){
chunkDiskMap.save();
}
lock.unlock();
}
/**
@ -203,14 +220,14 @@ public class ServerFluidManager {
* @return The ServerFluidChunk
*/
public ServerFluidChunk getChunk(int worldX, int worldY, int worldZ){
ServerFluidChunk returnedChunk = null;
lock.lock();
//THIS FIRES IF THERE IS A MAIN GAME WORLD RUNNING
String key = getKey(worldX,worldY,worldZ);
ServerFluidChunk returnedChunk = null;
if(chunkCache.containsKey(key)){
chunkCacheContents.remove(key);
chunkCacheContents.add(0, key);
returnedChunk = chunkCache.get(key);
return returnedChunk;
} else {
if(chunkCacheContents.size() > cacheSize){
String oldChunk = chunkCacheContents.remove(chunkCacheContents.size() - 1);
@ -228,8 +245,9 @@ public class ServerFluidManager {
}
chunkCache.put(key, returnedChunk);
chunkCacheContents.add(key);
return returnedChunk;
}
lock.unlock();
return returnedChunk;
}
/**
@ -238,7 +256,9 @@ public class ServerFluidManager {
* @param position The position to save
*/
public void savePositionToDisk(Vector3i position){
lock.lock();
chunkDiskMap.saveToDisk(getChunk(position.x, position.y, position.z));
lock.unlock();
}
/**
@ -259,8 +279,10 @@ public class ServerFluidManager {
// ServerFluidChunk chunk = chunkCache.get(key);
// chunk.addModification(modification);
// }
lock.lock();
ServerFluidChunk fluidChunk = this.getChunk(worldPos.x, worldPos.y, worldPos.z);
fluidChunk.setWeight(voxelPos.x, voxelPos.y, voxelPos.z, weight);
lock.unlock();
}
/**
@ -269,6 +291,7 @@ public class ServerFluidManager {
public boolean simulate(int worldX, int worldY, int worldZ){
boolean rVal = false;
Globals.profiler.beginAggregateCpuSample("ServerFluidManager.simulate");
lock.lock();
if(simulate){
ServerFluidChunk fluidChunk = this.getChunk(worldX, worldY, worldZ);
ServerTerrainChunk terrainChunk = this.serverTerrainManager.getChunk(worldX, worldY, worldZ);
@ -276,6 +299,7 @@ public class ServerFluidManager {
rVal = this.serverFluidSimulator.simulate(fluidChunk,terrainChunk,worldX,worldY,worldZ);
}
}
lock.unlock();
Globals.profiler.endCpuSample();
return rVal;
}

View File

@ -6,7 +6,6 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Semaphore;
import io.github.studiorailgun.HashUtils;
@ -29,27 +28,27 @@ public class ServerChunkCache {
/**
* The map of full res chunk key -> chunk data
*/
Map<Long,ServerTerrainChunk> cacheMapFullRes = new ConcurrentHashMap<Long,ServerTerrainChunk>();
Map<Long,ServerTerrainChunk> cacheMapFullRes = new HashMap<Long,ServerTerrainChunk>();
/**
* The map of half res chunk key -> chunk data
*/
Map<Long,ServerTerrainChunk> cacheMapHalfRes = new ConcurrentHashMap<Long,ServerTerrainChunk>();
Map<Long,ServerTerrainChunk> cacheMapHalfRes = new HashMap<Long,ServerTerrainChunk>();
/**
* The map of quarter res chunk key -> chunk data
*/
Map<Long,ServerTerrainChunk> cacheMapQuarterRes = new ConcurrentHashMap<Long,ServerTerrainChunk>();
Map<Long,ServerTerrainChunk> cacheMapQuarterRes = new HashMap<Long,ServerTerrainChunk>();
/**
* The map of eighth res chunk key -> chunk data
*/
Map<Long,ServerTerrainChunk> cacheMapEighthRes = new ConcurrentHashMap<Long,ServerTerrainChunk>();
Map<Long,ServerTerrainChunk> cacheMapEighthRes = new HashMap<Long,ServerTerrainChunk>();
/**
* The map of sixteenth res chunk key -> chunk data
*/
Map<Long,ServerTerrainChunk> cacheMapSixteenthRes = new ConcurrentHashMap<Long,ServerTerrainChunk>();
Map<Long,ServerTerrainChunk> cacheMapSixteenthRes = new HashMap<Long,ServerTerrainChunk>();
/**
* Tracks how recently a chunk has been queries for (used for evicting old chunks from cache)