remove several usages of concurrent datastructures
	
		
			
	
		
	
	
		
	
		
			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
							
								
									68294ab636
								
							
						
					
					
						commit
						4458c9e266
					
				| @ -1654,6 +1654,7 @@ Refactor recast pathfinding classes | ||||
| 
 | ||||
| (05/03/2025) | ||||
| Fix voxel pathfinding logic | ||||
| Remove several usages of concurrent datastructures | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -1,7 +1,8 @@ | ||||
| package electrosphere.client.scene; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| import java.util.concurrent.locks.ReentrantLock; | ||||
| 
 | ||||
| import org.joml.Vector3d; | ||||
| import org.ode4j.ode.DContactGeom; | ||||
| @ -24,11 +25,11 @@ import electrosphere.logger.LoggerInterface; | ||||
| public class ClientSceneWrapper { | ||||
|      | ||||
|     //entity id translation between server/client | ||||
|     Map<Integer,Integer> clientToServerIdMap = new ConcurrentHashMap<Integer,Integer>(); | ||||
|     Map<Integer,Integer> serverToClientIdMap = new ConcurrentHashMap<Integer,Integer>(); | ||||
|     Map<Integer,Integer> clientToServerIdMap = new HashMap<Integer,Integer>(); | ||||
|     Map<Integer,Integer> serverToClientIdMap = new HashMap<Integer,Integer>(); | ||||
| 
 | ||||
|     //The list of server IDs that have been deleted | ||||
|     Map<Integer,Boolean> deletedServerIds = new ConcurrentHashMap<Integer,Boolean>(); | ||||
|     Map<Integer,Boolean> deletedServerIds = new HashMap<Integer,Boolean>(); | ||||
| 
 | ||||
|     //The scene backing the wrapper | ||||
|     Scene scene; | ||||
| @ -49,6 +50,11 @@ public class ClientSceneWrapper { | ||||
|     //The hitbox manager | ||||
|     HitboxManager hitboxManager; | ||||
| 
 | ||||
|     /** | ||||
|      * Lock for threadsafing the scene wrapper | ||||
|      */ | ||||
|     ReentrantLock lock = new ReentrantLock(); | ||||
| 
 | ||||
|     /** | ||||
|      * Constructor | ||||
|      * @param scene The scene | ||||
| @ -71,8 +77,10 @@ public class ClientSceneWrapper { | ||||
|      */ | ||||
|     public void mapIdToId(int clientId, int serverId){ | ||||
|         LoggerInterface.loggerNetworking.DEBUG("[CLIENT] MapID: " + clientId + " <===> " + serverId); | ||||
|         lock.lock(); | ||||
|         clientToServerIdMap.put(clientId, serverId); | ||||
|         serverToClientIdMap.put(serverId, clientId); | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -81,11 +89,15 @@ public class ClientSceneWrapper { | ||||
|      * @return The equivalent id on the server, or -1 if no equivalent is found | ||||
|      */ | ||||
|     public int mapClientToServerId(int clientId){ | ||||
|         lock.lock(); | ||||
|         if(clientToServerIdMap.get(clientId) == null){ | ||||
|             LoggerInterface.loggerNetworking.ERROR(new Error("Failed to map client entity " + clientId + " to server entity!")); | ||||
|             lock.unlock(); | ||||
|             return -1; | ||||
|         } | ||||
|         return clientToServerIdMap.get(clientId); | ||||
|         int rVal = clientToServerIdMap.get(clientId); | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -94,7 +106,10 @@ public class ClientSceneWrapper { | ||||
|      * @return The equivalent id on the client | ||||
|      */ | ||||
|     public int mapServerToClientId(int serverId){ | ||||
|         return serverToClientIdMap.get(serverId); | ||||
|         lock.lock(); | ||||
|         int rVal = serverToClientIdMap.get(serverId); | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -103,7 +118,10 @@ public class ClientSceneWrapper { | ||||
|      * @return true if the map contains that id, false otherwise | ||||
|      */ | ||||
|     public boolean containsServerId(int serverId){ | ||||
|         return serverToClientIdMap.containsKey(serverId); | ||||
|         lock.lock(); | ||||
|         boolean rVal = serverToClientIdMap.containsKey(serverId); | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| @ -113,7 +131,10 @@ public class ClientSceneWrapper { | ||||
|      * @return True if the server->client map contains the provided id | ||||
|      */ | ||||
|     public boolean serverToClientMapContainsId(int id){ | ||||
|         return serverToClientIdMap.containsKey(id); | ||||
|         lock.lock(); | ||||
|         boolean rVal = serverToClientIdMap.containsKey(id); | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -122,7 +143,10 @@ public class ClientSceneWrapper { | ||||
|      * @return true if there's a corresponding server id, false otherwise | ||||
|      */ | ||||
|     public boolean clientToServerMapContainsId(int id){ | ||||
|         return clientToServerIdMap.containsKey(id); | ||||
|         lock.lock(); | ||||
|         boolean rVal = clientToServerIdMap.containsKey(id); | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -130,6 +154,7 @@ public class ClientSceneWrapper { | ||||
|      * @param clientEntity The client entity | ||||
|      */ | ||||
|     public void deregisterTranslationMapping(Entity clientEntity){ | ||||
|         lock.lock(); | ||||
|         if(this.clientToServerMapContainsId(clientEntity.getId())){ | ||||
|             //remove from client->server map | ||||
|             int serverId = clientToServerIdMap.remove(clientEntity.getId()); | ||||
| @ -138,6 +163,7 @@ public class ClientSceneWrapper { | ||||
|             deletedServerIds.put(serverId,true); | ||||
|             LoggerInterface.loggerNetworking.DEBUG("[CLIENT] Remove scene from client<->server translation layer: " + clientEntity.getId() + "<->" + serverId); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -146,7 +172,10 @@ public class ClientSceneWrapper { | ||||
|      * @return true if it was registered at one point and has since been deleted, false otherwise | ||||
|      */ | ||||
|     public boolean hasBeenDeleted(int serverId){ | ||||
|         return deletedServerIds.containsKey(serverId); | ||||
|         lock.lock(); | ||||
|         boolean rVal = deletedServerIds.containsKey(serverId); | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| @ -156,22 +185,26 @@ public class ClientSceneWrapper { | ||||
|      * @return The entity in question | ||||
|      */ | ||||
|     public Entity getEntityFromServerId(int id){ | ||||
|         Entity rVal = null; | ||||
|         lock.lock(); | ||||
|         if(serverToClientIdMap.containsKey(id)){ | ||||
|             int clientId = mapServerToClientId(id); | ||||
|             return scene.getEntityFromId(clientId); | ||||
|         } else { | ||||
|             return null; | ||||
|             rVal = scene.getEntityFromId(clientId); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Dumps the status of the network translation layer | ||||
|      */ | ||||
|     public void dumpTranslationLayerStatus(){ | ||||
|         lock.lock(); | ||||
|         LoggerInterface.loggerNetworking.WARNING("Client -> Server keys"); | ||||
|         LoggerInterface.loggerNetworking.WARNING(clientToServerIdMap.keySet() + ""); | ||||
|         LoggerInterface.loggerNetworking.WARNING("Server -> Client keys"); | ||||
|         LoggerInterface.loggerNetworking.WARNING(serverToClientIdMap.keySet() + ""); | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -179,6 +212,7 @@ public class ClientSceneWrapper { | ||||
|      * @param id The id | ||||
|      */ | ||||
|     public void dumpIdData(int id){ | ||||
|         lock.lock(); | ||||
|         LoggerInterface.loggerNetworking.WARNING("Offending ID " + id); | ||||
|         LoggerInterface.loggerNetworking.WARNING("Client->Server Map contains? " + clientToServerIdMap.containsKey(id)); | ||||
|         LoggerInterface.loggerNetworking.WARNING("Server->Client Map contains? " + serverToClientIdMap.containsKey(id)); | ||||
| @ -188,6 +222,7 @@ public class ClientSceneWrapper { | ||||
|         if(serverToClientIdMap.containsKey(id)){ | ||||
|             LoggerInterface.loggerNetworking.WARNING("Server->Client Map entity: " + serverToClientIdMap.get(id)); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -24,12 +24,11 @@ import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.util.Collection; | ||||
| import java.util.Collections; | ||||
| import java.util.HashMap; | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.UUID; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| import java.util.concurrent.CopyOnWriteArrayList; | ||||
| import java.util.concurrent.locks.ReentrantLock; | ||||
| 
 | ||||
| import org.lwjgl.assimp.AIScene; | ||||
| @ -39,44 +38,48 @@ import org.ode4j.ode.DBody; | ||||
|  * Manages all assets loaded into the engine including initially loading and destructing | ||||
|  */ | ||||
| public class AssetManager { | ||||
|      | ||||
|     Map<String,Model> modelsLoadedIntoMemory = new ConcurrentHashMap<String,Model>(); | ||||
|     List<String> modelsInQueue = new CopyOnWriteArrayList<String>(); | ||||
|     List<String> modelsInDeleteQueue = new CopyOnWriteArrayList<String>(); | ||||
|     List<MeshShaderOverride> shaderOverrides = new CopyOnWriteArrayList<MeshShaderOverride>(); | ||||
|      | ||||
|     Map<String,Texture> texturesLoadedIntoMemory = new ConcurrentHashMap<String,Texture>(); | ||||
|     List<String> texturesInQueue = new CopyOnWriteArrayList<String>(); | ||||
|     List<String> texturesInDeleteQueue = new CopyOnWriteArrayList<String>(); | ||||
|      | ||||
|     Map<String,AudioBuffer> audioLoadedIntoMemory = new ConcurrentHashMap<String,AudioBuffer>(); | ||||
|     List<String> audioInQueue = new CopyOnWriteArrayList<String>(); | ||||
| 
 | ||||
|     Map<String,VisualShader> shadersLoadedIntoMemory = new ConcurrentHashMap<String,VisualShader>(); | ||||
|     List<ActorShaderMask> shadersInQueue = new CopyOnWriteArrayList<ActorShaderMask>(); | ||||
|     /** | ||||
|      * Lock for thread-safing the work | ||||
|      */ | ||||
|     ReentrantLock lock = new ReentrantLock(); | ||||
|      | ||||
|     Map<String,Model> modelsLoadedIntoMemory = new HashMap<String,Model>(); | ||||
|     List<String> modelsInQueue = new LinkedList<String>(); | ||||
|     List<String> modelsInDeleteQueue = new LinkedList<String>(); | ||||
|     List<MeshShaderOverride> shaderOverrides = new LinkedList<MeshShaderOverride>(); | ||||
|      | ||||
|     Map<String,Texture> texturesLoadedIntoMemory = new HashMap<String,Texture>(); | ||||
|     List<String> texturesInQueue = new LinkedList<String>(); | ||||
|     List<String> texturesInDeleteQueue = new LinkedList<String>(); | ||||
|      | ||||
|     Map<String,AudioBuffer> audioLoadedIntoMemory = new HashMap<String,AudioBuffer>(); | ||||
|     List<String> audioInQueue = new LinkedList<String>(); | ||||
| 
 | ||||
|     Map<String,VisualShader> shadersLoadedIntoMemory = new HashMap<String,VisualShader>(); | ||||
|     List<ActorShaderMask> shadersInQueue = new LinkedList<ActorShaderMask>(); | ||||
| 
 | ||||
|     // | ||||
|     //Compute shader related | ||||
|     // | ||||
|     Map<String,ComputeShader> computeShadersLoadedIntoMemory = new ConcurrentHashMap<String,ComputeShader>(); | ||||
|     List<String> computeShadersInQueue = new CopyOnWriteArrayList<String>(); | ||||
|     Map<String,ComputeShader> computeShadersLoadedIntoMemory = new HashMap<String,ComputeShader>(); | ||||
|     List<String> computeShadersInQueue = new LinkedList<String>(); | ||||
| 
 | ||||
|     Map<String,DBody> physicsMeshesLoadedIntoMemory = new ConcurrentHashMap<String,DBody>(); | ||||
|     List<PhysicsMeshQueueItem> physicsMeshesToLoad = new CopyOnWriteArrayList<PhysicsMeshQueueItem>(); | ||||
|     Map<String,DBody> physicsMeshesLoadedIntoMemory = new HashMap<String,DBody>(); | ||||
|     List<PhysicsMeshQueueItem> physicsMeshesToLoad = new LinkedList<PhysicsMeshQueueItem>(); | ||||
| 
 | ||||
|     Map<String,PoseModel> poseModelsLoadedIntoMemory = new ConcurrentHashMap<String,PoseModel>(); | ||||
|     List<String> poseModelsInQueue = new CopyOnWriteArrayList<String>(); | ||||
|     List<String> poseModelsInDeleteQueue = new CopyOnWriteArrayList<String>(); | ||||
|     Map<String,PoseModel> poseModelsLoadedIntoMemory = new HashMap<String,PoseModel>(); | ||||
|     List<String> poseModelsInQueue = new LinkedList<String>(); | ||||
|     List<String> poseModelsInDeleteQueue = new LinkedList<String>(); | ||||
| 
 | ||||
|     //A queue of homogenous buffers to allocate this render frame | ||||
|     List<HomogenousUniformBuffer> homogenousBufferAllocationQueue = new CopyOnWriteArrayList<HomogenousUniformBuffer>(); | ||||
|     List<HomogenousUniformBuffer> homogenousBufferAllocationQueue = new LinkedList<HomogenousUniformBuffer>(); | ||||
| 
 | ||||
|     //A queue of homogenous buffers to allocate this render frame | ||||
|     List<HomogenousInstancedArray> instanceArrayBufferAllocationQueue = new CopyOnWriteArrayList<HomogenousInstancedArray>(); | ||||
|     List<HomogenousInstancedArray> instanceArrayBufferAllocationQueue = new LinkedList<HomogenousInstancedArray>(); | ||||
| 
 | ||||
| 
 | ||||
|     //assets queued to be loaded | ||||
|     ReentrantLock queuedAssetLock = new ReentrantLock(); | ||||
|     List<QueuedAsset<?>> queuedAssets = new LinkedList<QueuedAsset<?>>(); | ||||
| 
 | ||||
|     /** | ||||
| @ -98,8 +101,8 @@ public class AssetManager { | ||||
|         //models | ||||
|         LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Load models"); | ||||
|         Globals.profiler.beginCpuSample("AssetManager.loadAssetsInQueue - Load Models"); | ||||
|         lock.lock(); | ||||
|         for(String currentPath : modelsInQueue){ | ||||
|             modelsInQueue.remove(currentPath); | ||||
|             AIScene aiScene = ModelLoader.loadAIScene(currentPath); | ||||
|             TextureMap textureMap = null; | ||||
|             if(this.getLocalTextureMapPath(currentPath) != null){ | ||||
| @ -119,43 +122,43 @@ public class AssetManager { | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         modelsInQueue.clear(); | ||||
|         Globals.profiler.endCpuSample(); | ||||
|         //textures from disk to gpu | ||||
|         LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Load textures"); | ||||
|         Globals.profiler.beginCpuSample("AssetManager.loadAssetsInQueue - Load textures"); | ||||
|         for(String currentPath : texturesInQueue){ | ||||
|             texturesInQueue.remove(currentPath); | ||||
|             Texture tex = new Texture(Globals.renderingEngine.getOpenGLState(), currentPath); | ||||
|             texturesLoadedIntoMemory.put(currentPath, tex); | ||||
|         } | ||||
|         texturesInQueue.clear(); | ||||
|         Globals.profiler.endCpuSample(); | ||||
|         //audio from disk | ||||
|         LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Load audio"); | ||||
|         Globals.profiler.beginCpuSample("AssetManager.loadAssetsInQueue - Load audio"); | ||||
|         if(Globals.audioEngine != null && Globals.audioEngine.initialized()){ | ||||
|             for(String currentPath : audioInQueue){ | ||||
|                 audioInQueue.remove(currentPath); | ||||
|                 audioLoadedIntoMemory.put(currentPath, new AudioBuffer(currentPath)); | ||||
|             } | ||||
|             audioInQueue.clear(); | ||||
|         } | ||||
|         Globals.profiler.endCpuSample(); | ||||
|         //shaders | ||||
|         LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Load visual shaders"); | ||||
|         Globals.profiler.beginCpuSample("AssetManager.loadAssetsInQueue - Load visual shaders"); | ||||
|         for(ActorShaderMask currentShader : shadersInQueue){ | ||||
|             shadersInQueue.remove(currentShader); | ||||
|             String key = getShaderKey(currentShader.getVertexShaderPath(),currentShader.getFragmentShaderPath()); | ||||
|             shadersLoadedIntoMemory.put( | ||||
|                 key, | ||||
|                 VisualShader.loadSpecificShader(currentShader.getVertexShaderPath(),currentShader.getFragmentShaderPath()) | ||||
|             ); | ||||
|         } | ||||
|         shadersInQueue.clear(); | ||||
|         Globals.profiler.endCpuSample(); | ||||
|         //compute shaders | ||||
|         LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Load compute shaders"); | ||||
|         Globals.profiler.beginCpuSample("AssetManager.loadAssetsInQueue - Load compute shaders"); | ||||
|         for(String computePath : computeShadersInQueue){ | ||||
|             computeShadersInQueue.remove(computePath); | ||||
|             String key = getComputeShaderKey(computePath); | ||||
|             try { | ||||
|                 computeShadersLoadedIntoMemory.put( | ||||
| @ -166,20 +169,20 @@ public class AssetManager { | ||||
|                 e.printStackTrace(); | ||||
|             } | ||||
|         } | ||||
|         computeShadersInQueue.clear(); | ||||
|         Globals.profiler.endCpuSample(); | ||||
|         //pose models | ||||
|         LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Load pose models"); | ||||
|         Globals.profiler.beginCpuSample("AssetManager.loadAssetsInQueue - Load pose models"); | ||||
|         for(String currentPath: poseModelsInQueue){ | ||||
|             poseModelsInQueue.remove(currentPath); | ||||
|             AIScene scene = ModelLoader.loadAIScene(currentPath); | ||||
|             poseModelsLoadedIntoMemory.put(currentPath, new PoseModel(currentPath, scene)); | ||||
|         } | ||||
|         poseModelsInQueue.clear(); | ||||
|         Globals.profiler.endCpuSample(); | ||||
|         //queued assets | ||||
|         LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Load queued assets"); | ||||
|         Globals.profiler.beginCpuSample("AssetManager.loadAssetsInQueue - Load queued assets"); | ||||
|         queuedAssetLock.lock(); | ||||
|         if(queuedAssets.size() > MAX_ASSETS_PER_FRAME){ | ||||
|             for(int i = 0; i < MAX_ASSETS_PER_FRAME; i++){ | ||||
|                 QueuedAsset<?> queuedAsset = queuedAssets.remove(0); | ||||
| @ -201,7 +204,6 @@ public class AssetManager { | ||||
|             } | ||||
|             queuedAssets.clear(); | ||||
|         } | ||||
|         queuedAssetLock.unlock(); | ||||
|         Globals.profiler.endCpuSample(); | ||||
| 
 | ||||
|         //allocate homogenous buffers | ||||
| @ -219,6 +221,8 @@ public class AssetManager { | ||||
|         //override meshes | ||||
|         LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Override meshes"); | ||||
|         this.performMeshOverrides(); | ||||
| 
 | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| @ -228,6 +232,7 @@ public class AssetManager { | ||||
|     public void updateAsset(String path){ | ||||
|         LoggerInterface.loggerEngine.DEBUG("AssetManager - updateAsset"); | ||||
|         //models | ||||
|         lock.lock(); | ||||
|         if(modelsLoadedIntoMemory.containsKey(path)){ | ||||
|             this.queueModelForDeletion(path); | ||||
|             this.deleteModelsInDeleteQueue(); | ||||
| @ -254,15 +259,18 @@ public class AssetManager { | ||||
|         if(computeShadersLoadedIntoMemory.containsKey(path)){ | ||||
|             throw new Error("Unhandled asset type! (Shader - Compute)"); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Handles the delete queues | ||||
|      */ | ||||
|     public void handleDeleteQueue(){ | ||||
|         lock.lock(); | ||||
|         this.deleteModelsInDeleteQueue(); | ||||
|         this.deletePoseModelsInDeleteQueue(); | ||||
|         this.deleteTexturesInDeleteQueue(); | ||||
|         lock.unlock(); | ||||
|     } | ||||
|      | ||||
|      | ||||
| @ -277,16 +285,20 @@ public class AssetManager { | ||||
|     // | ||||
|      | ||||
|     public void addModelPathToQueue(String path){ | ||||
|         lock.lock(); | ||||
|         if(!modelsInQueue.contains(path) && !modelsLoadedIntoMemory.containsKey(path)){ | ||||
|             modelsInQueue.add(path); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|     } | ||||
|      | ||||
|     public Model fetchModel(String path){ | ||||
|         Model rVal = null; | ||||
|         lock.lock(); | ||||
|         if(modelsLoadedIntoMemory.containsKey(path)){ | ||||
|             rVal = modelsLoadedIntoMemory.get(path); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
| @ -295,7 +307,9 @@ public class AssetManager { | ||||
|      * @param modelPath The path to the model | ||||
|      */ | ||||
|     public void queueModelForDeletion(String modelPath){ | ||||
|         lock.lock(); | ||||
|         modelsInDeleteQueue.add(modelPath); | ||||
|         lock.unlock(); | ||||
|     } | ||||
|      | ||||
|     /** | ||||
| @ -306,7 +320,9 @@ public class AssetManager { | ||||
|         String rVal; | ||||
|         UUID newUUID = UUID.randomUUID(); | ||||
|         rVal = newUUID.toString(); | ||||
|         lock.lock(); | ||||
|         modelsLoadedIntoMemory.put(rVal,m); | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
| @ -317,20 +333,27 @@ public class AssetManager { | ||||
|      * @param path The path to register the model to | ||||
|      */ | ||||
|     public void registerModelWithPath(Model m, String path){ | ||||
|         lock.lock(); | ||||
|         modelsLoadedIntoMemory.put(path, m); | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     public void deregisterModelPath(String path){ | ||||
|         lock.lock(); | ||||
|         modelsLoadedIntoMemory.remove(path); | ||||
|         lock.unlock(); | ||||
|     } | ||||
|      | ||||
|     public void queueOverrideMeshShader(String modelName, String meshName, String vertPath, String fragPath){ | ||||
|         lock.lock(); | ||||
|         MeshShaderOverride override = new MeshShaderOverride(modelName,meshName,vertPath,fragPath); | ||||
|         shaderOverrides.add(override); | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     public void performMeshOverrides(){ | ||||
|         List<MeshShaderOverride> toRemove = new LinkedList<MeshShaderOverride>(); | ||||
|         lock.lock(); | ||||
|         for(MeshShaderOverride shaderOverride : shaderOverrides){ | ||||
|             Model model = null; | ||||
|             if((model = fetchModel(shaderOverride.modelName)) != null){ | ||||
| @ -345,25 +368,28 @@ public class AssetManager { | ||||
|         for(MeshShaderOverride shaderOverride : toRemove){ | ||||
|             shaderOverrides.remove(shaderOverride); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Nuclear function, reloads all shaders loaded into memory | ||||
|      */ | ||||
|     public void forceReloadAllModels(){ | ||||
|         lock.lock(); | ||||
|         for(String modelKey : modelsLoadedIntoMemory.keySet()){ | ||||
|             if(modelKey.contains("Models")){ | ||||
|                 modelsInQueue.add(modelKey); | ||||
|                 modelsLoadedIntoMemory.remove(modelKey); | ||||
|             } | ||||
|         } | ||||
|         // modelsLoadedIntoMemory.clear(); | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Deletes all models in the delete queue | ||||
|      */ | ||||
|     public void deleteModelsInDeleteQueue(){ | ||||
|         lock.lock(); | ||||
|         for(String modelPath : modelsInDeleteQueue){ | ||||
|             Model model = this.fetchModel(modelPath); | ||||
|             if(model != null){ | ||||
| @ -371,6 +397,7 @@ public class AssetManager { | ||||
|             } | ||||
|             this.modelsLoadedIntoMemory.remove(modelPath); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|      | ||||
| @ -388,9 +415,11 @@ public class AssetManager { | ||||
|      * @param path The path to load | ||||
|      */ | ||||
|     public void addPoseModelPathToQueue(String path){ | ||||
|         lock.lock(); | ||||
|         if(!poseModelsInQueue.contains(path) && !poseModelsLoadedIntoMemory.containsKey(path)){ | ||||
|             poseModelsInQueue.add(path); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|     } | ||||
|      | ||||
|     /** | ||||
| @ -400,9 +429,11 @@ public class AssetManager { | ||||
|      */ | ||||
|     public PoseModel fetchPoseModel(String path){ | ||||
|         PoseModel rVal = null; | ||||
|         lock.lock(); | ||||
|         if(poseModelsLoadedIntoMemory.containsKey(path)){ | ||||
|             rVal = poseModelsLoadedIntoMemory.get(path); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
| @ -413,7 +444,9 @@ public class AssetManager { | ||||
|      * @param path The path to register the pose model to | ||||
|      */ | ||||
|     public void registerPoseModelWithPath(PoseModel m, String path){ | ||||
|         lock.lock(); | ||||
|         poseModelsLoadedIntoMemory.put(path, m); | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -421,13 +454,16 @@ public class AssetManager { | ||||
|      * @param modelPath The path to the pose model | ||||
|      */ | ||||
|     public void queuePoseModelForDeletion(String modelPath){ | ||||
|         lock.lock(); | ||||
|         poseModelsInDeleteQueue.add(modelPath); | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Deletes all pose models in the delete queue | ||||
|      */ | ||||
|     public void deletePoseModelsInDeleteQueue(){ | ||||
|         lock.lock(); | ||||
|         for(String modelPath : poseModelsInDeleteQueue){ | ||||
|             PoseModel poseModel = this.fetchPoseModel(modelPath); | ||||
|             if(poseModel != null){ | ||||
| @ -435,6 +471,7 @@ public class AssetManager { | ||||
|             } | ||||
|             this.poseModelsLoadedIntoMemory.remove(modelPath); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|     } | ||||
|      | ||||
|      | ||||
| @ -451,9 +488,11 @@ public class AssetManager { | ||||
|      | ||||
|      | ||||
|     public void addTexturePathtoQueue(String path){ | ||||
|         lock.lock(); | ||||
|         if(!texturesInQueue.contains(path) && !texturesLoadedIntoMemory.containsKey(path)){ | ||||
|             texturesInQueue.add(path); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -461,14 +500,18 @@ public class AssetManager { | ||||
|      * @param texturePath The path to the texture | ||||
|      */ | ||||
|     public void queueTextureForDeletion(String texturePath){ | ||||
|         lock.lock(); | ||||
|         texturesInDeleteQueue.add(texturePath); | ||||
|         lock.unlock(); | ||||
|     } | ||||
|      | ||||
|     public Texture fetchTexture(String path){ | ||||
|         Texture rVal = null; | ||||
|         lock.lock(); | ||||
|         if(texturesLoadedIntoMemory.containsKey(path)){ | ||||
|             rVal = texturesLoadedIntoMemory.get(path); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
|      | ||||
| @ -476,7 +519,9 @@ public class AssetManager { | ||||
|         String rVal; | ||||
|         UUID newUUID = UUID.randomUUID(); | ||||
|         rVal = newUUID.toString(); | ||||
|         lock.lock(); | ||||
|         texturesLoadedIntoMemory.put(rVal,t); | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
| @ -486,11 +531,16 @@ public class AssetManager { | ||||
|      * @param path The path | ||||
|      */ | ||||
|     public void registerTextureToPath(Texture t, String path){ | ||||
|         lock.lock(); | ||||
|         texturesLoadedIntoMemory.put(path,t); | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     public boolean hasLoadedTexture(String path){ | ||||
|         return texturesLoadedIntoMemory.containsKey(path); | ||||
|         lock.lock(); | ||||
|         boolean rVal = texturesLoadedIntoMemory.containsKey(path); | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -498,6 +548,7 @@ public class AssetManager { | ||||
|      * @param modelPath The model's path | ||||
|      */ | ||||
|     private String getLocalTextureMapPath(String modelPath){ | ||||
|         lock.lock(); | ||||
|         File modelFile = FileUtils.getAssetFile(modelPath); | ||||
|         File containingDirectory = modelFile.getParentFile(); | ||||
|         File[] children = containingDirectory.listFiles(); | ||||
| @ -506,10 +557,12 @@ public class AssetManager { | ||||
|                 if(child.getName().equals("texturemap.json")){ | ||||
|                     String rVal = child.getPath(); | ||||
|                     String fixed = rVal.replace(".\\assets", "").replace("./assets", ""); | ||||
|                     lock.unlock(); | ||||
|                     return fixed; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         lock.unlock(); | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
| @ -517,6 +570,7 @@ public class AssetManager { | ||||
|      * Deletes all textures in the delete queue | ||||
|      */ | ||||
|     public void deleteTexturesInDeleteQueue(){ | ||||
|         lock.lock(); | ||||
|         for(String texturePath : texturesInDeleteQueue){ | ||||
|             Texture texture = this.fetchTexture(texturePath); | ||||
|             if(texture != null){ | ||||
| @ -524,6 +578,7 @@ public class AssetManager { | ||||
|             } | ||||
|             this.texturesLoadedIntoMemory.remove(texturePath); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|     } | ||||
|      | ||||
|      | ||||
| @ -539,13 +594,16 @@ public class AssetManager { | ||||
|     // | ||||
|      | ||||
|     public void addAudioPathToQueue(String path){ | ||||
|         lock.lock(); | ||||
|         String sanitizedPath = FileUtils.sanitizeFilePath(path); | ||||
|         if(!audioInQueue.contains(sanitizedPath) && !audioLoadedIntoMemory.containsKey(sanitizedPath)){ | ||||
|             audioInQueue.add(sanitizedPath); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|     } | ||||
|      | ||||
|     public AudioBuffer fetchAudio(String path){ | ||||
|         lock.lock(); | ||||
|         AudioBuffer rVal = null; | ||||
|         String sanitizedPath = FileUtils.sanitizeFilePath(path); | ||||
|         if(audioLoadedIntoMemory.containsKey(sanitizedPath)){ | ||||
| @ -553,6 +611,7 @@ public class AssetManager { | ||||
|         } else { | ||||
|             LoggerInterface.loggerAudio.WARNING("Failed to find audio " + sanitizedPath); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
| @ -561,7 +620,10 @@ public class AssetManager { | ||||
|      * @return The collection of all audio buffers | ||||
|      */ | ||||
|     public Collection<AudioBuffer> getAllAudio(){ | ||||
|         return Collections.unmodifiableCollection(this.audioLoadedIntoMemory.values()); | ||||
|         lock.lock(); | ||||
|         Collection<AudioBuffer> rVal = Collections.unmodifiableCollection(this.audioLoadedIntoMemory.values()); | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
|      | ||||
|      | ||||
| @ -575,15 +637,19 @@ public class AssetManager { | ||||
|     //SHADERS | ||||
|     // | ||||
|     public void addShaderToQueue(String vertexShader, String fragmentShader){ | ||||
|         lock.lock(); | ||||
|         shadersInQueue.add(new ActorShaderMask("","",vertexShader,fragmentShader)); | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     public VisualShader fetchShader(String vertexPath, String fragmentPath){ | ||||
|         lock.lock(); | ||||
|         String path = getShaderKey(vertexPath,fragmentPath); | ||||
|         VisualShader rVal = null; | ||||
|         if(shadersLoadedIntoMemory.containsKey(path)){ | ||||
|             rVal = shadersLoadedIntoMemory.get(path); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
| @ -595,11 +661,13 @@ public class AssetManager { | ||||
|      * Nuclear function, reloads all shaders loaded into memory | ||||
|      */ | ||||
|     public void forceReloadAllShaders(){ | ||||
|         lock.lock(); | ||||
|         for(String shaderKey : shadersLoadedIntoMemory.keySet()){ | ||||
|             String shaderPaths[] = shaderKey.split("-"); | ||||
|             shadersInQueue.add(new ActorShaderMask("","",shaderPaths[0],shaderPaths[1])); | ||||
|         } | ||||
|         shadersLoadedIntoMemory.clear(); | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     // | ||||
| @ -610,7 +678,9 @@ public class AssetManager { | ||||
|      * @param computePath The path to the source code for the shader | ||||
|      */ | ||||
|     public void addComputeShaderToQueue(String computePath){ | ||||
|         lock.lock(); | ||||
|         computeShadersInQueue.add(getComputeShaderKey(computePath)); | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -619,11 +689,13 @@ public class AssetManager { | ||||
|      * @return The compute shader if it exists, null otherwise | ||||
|      */ | ||||
|     public ComputeShader fetchComputeShader(String computePath){ | ||||
|         lock.lock(); | ||||
|         String key = getComputeShaderKey(computePath); | ||||
|         ComputeShader rVal = null; | ||||
|         if(computeShadersLoadedIntoMemory.containsKey(key)){ | ||||
|             rVal = computeShadersLoadedIntoMemory.get(key); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
| @ -643,6 +715,7 @@ public class AssetManager { | ||||
|     //COLLISION MESH | ||||
|     // | ||||
|     public void addCollisionMeshToQueue(PhysicsMeshQueueItem physicsMeshQueueItem){ | ||||
|         lock.lock(); | ||||
|         if( | ||||
|             !physicsMeshesToLoad.contains(physicsMeshQueueItem) &&  | ||||
|             !physicsMeshesLoadedIntoMemory.containsKey(getCollisionMeshMapKey( | ||||
| @ -651,10 +724,14 @@ public class AssetManager { | ||||
|         ))){ | ||||
|             physicsMeshesToLoad.add(physicsMeshQueueItem); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     public DBody fetchCollisionObject(CollisionEngine collisionEngine, String path){ | ||||
|         return physicsMeshesLoadedIntoMemory.get(getCollisionMeshMapKey(collisionEngine,path)); | ||||
|         lock.lock(); | ||||
|         DBody rVal = physicsMeshesLoadedIntoMemory.get(getCollisionMeshMapKey(collisionEngine,path)); | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -675,10 +752,12 @@ public class AssetManager { | ||||
|      * Allocates all uniform buffers in queue | ||||
|      */ | ||||
|     public void allocateHomogenousBuffers(){ | ||||
|         lock.lock(); | ||||
|         for(HomogenousUniformBuffer buffer : homogenousBufferAllocationQueue){ | ||||
|             buffer.allocate(); | ||||
|         } | ||||
|         homogenousBufferAllocationQueue.clear(); | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -686,7 +765,9 @@ public class AssetManager { | ||||
|      * @param buffer The buffer | ||||
|      */ | ||||
|     public void addHomogenousBufferToQueue(HomogenousUniformBuffer buffer){ | ||||
|         lock.lock(); | ||||
|         homogenousBufferAllocationQueue.add(buffer); | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| @ -697,10 +778,12 @@ public class AssetManager { | ||||
|      * Allocates all instance array buffers in queue | ||||
|      */ | ||||
|     public void allocateInstanceArrayBuffers(){ | ||||
|         lock.lock(); | ||||
|         for(HomogenousInstancedArray buffer : instanceArrayBufferAllocationQueue){ | ||||
|             buffer.allocate(); | ||||
|         } | ||||
|         instanceArrayBufferAllocationQueue.clear(); | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -708,7 +791,9 @@ public class AssetManager { | ||||
|      * @param buffer The buffer | ||||
|      */ | ||||
|     public void addInstanceArrayBufferToQueue(HomogenousInstancedArray buffer){ | ||||
|         lock.lock(); | ||||
|         instanceArrayBufferAllocationQueue.add(buffer); | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| @ -720,7 +805,7 @@ public class AssetManager { | ||||
|      * @param asset the asset | ||||
|      */ | ||||
|     public String queuedAsset(QueuedAsset<?> asset){ | ||||
|         queuedAssetLock.lock(); | ||||
|         lock.lock(); | ||||
|         this.queuedAssets.add(asset); | ||||
| 
 | ||||
|         //promise a specific string for this asset | ||||
| @ -740,7 +825,7 @@ public class AssetManager { | ||||
|             asset.setPromisedPath(promisedPath); | ||||
|         } | ||||
| 
 | ||||
|         queuedAssetLock.unlock(); | ||||
|         lock.unlock(); | ||||
| 
 | ||||
|         return promisedPath; | ||||
|     } | ||||
|  | ||||
| @ -1,10 +1,10 @@ | ||||
| package electrosphere.engine.signal; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.HashSet; | ||||
| import java.util.Map; | ||||
| import java.util.Set; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| import java.util.concurrent.Semaphore; | ||||
| import java.util.concurrent.locks.ReentrantLock; | ||||
| 
 | ||||
| import electrosphere.engine.service.Service; | ||||
| import electrosphere.engine.signal.Signal.SignalType; | ||||
| @ -21,16 +21,16 @@ public class SignalSystem implements Service { | ||||
|     Map<SignalType,Set<SignalService>> typeServiceMap; | ||||
| 
 | ||||
|     /** | ||||
|      * The semaphore for thread-safing the system | ||||
|      * The lock for thread-safing the system | ||||
|      */ | ||||
|     Semaphore systemLock; | ||||
|     ReentrantLock systemLock; | ||||
| 
 | ||||
|     /** | ||||
|      * Initializes the signal system | ||||
|      */ | ||||
|     public void init(){ | ||||
|         typeServiceMap = new ConcurrentHashMap<SignalType,Set<SignalService>>(); | ||||
|         systemLock = new Semaphore(1); | ||||
|         typeServiceMap = new HashMap<SignalType,Set<SignalService>>(); | ||||
|         systemLock = new ReentrantLock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -52,7 +52,7 @@ public class SignalSystem implements Service { | ||||
|      * @param service The service to associate with that signal type | ||||
|      */ | ||||
|     public void registerService(SignalService service){ | ||||
|         systemLock.acquireUninterruptibly(); | ||||
|         systemLock.lock(); | ||||
|         LoggerInterface.loggerEngine.DEBUG("[SignalSystem] Register signal service " + service.getName()); | ||||
|         for(SignalType signalType : service.getSubscriptionTargets()){ | ||||
|             if(typeServiceMap.containsKey(signalType)){ | ||||
| @ -66,7 +66,7 @@ public class SignalSystem implements Service { | ||||
|                 this.typeServiceMap.put(signalType, services); | ||||
|             } | ||||
|         } | ||||
|         systemLock.release(); | ||||
|         systemLock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -75,7 +75,7 @@ public class SignalSystem implements Service { | ||||
|      * @param service The service to associate with that signal type | ||||
|      */ | ||||
|     public void registerServiceToSignal(SignalType signalType, SignalService service){ | ||||
|         systemLock.acquireUninterruptibly(); | ||||
|         systemLock.lock(); | ||||
|         LoggerInterface.loggerEngine.DEBUG("[SignalSystem] Register signal service " + service.getName()); | ||||
|         if(typeServiceMap.containsKey(signalType)){ | ||||
|             Set<SignalService> services = this.typeServiceMap.get(signalType); | ||||
| @ -87,7 +87,7 @@ public class SignalSystem implements Service { | ||||
|             services.add(service); | ||||
|             this.typeServiceMap.put(signalType, services); | ||||
|         } | ||||
|         systemLock.release(); | ||||
|         systemLock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -96,7 +96,7 @@ public class SignalSystem implements Service { | ||||
|      * @param service The signal service to unassociate from that signal type | ||||
|      */ | ||||
|     public void deregisterServiceToSignal(SignalType signalType, SignalService service){ | ||||
|         systemLock.acquireUninterruptibly(); | ||||
|         systemLock.lock(); | ||||
|         LoggerInterface.loggerEngine.DEBUG("[SignalSystem] Deregister signal service " + service.getName()); | ||||
|         if(typeServiceMap.containsKey(signalType)){ | ||||
|             Set<SignalService> services = this.typeServiceMap.get(signalType); | ||||
| @ -104,7 +104,7 @@ public class SignalSystem implements Service { | ||||
|         } else { | ||||
|             //there are no services mapped to this signal type | ||||
|         } | ||||
|         systemLock.release(); | ||||
|         systemLock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -113,7 +113,7 @@ public class SignalSystem implements Service { | ||||
|      * @param data The data associated with the signal | ||||
|      */ | ||||
|     public void post(SignalType type, Object data){ | ||||
|         systemLock.acquireUninterruptibly(); | ||||
|         systemLock.lock(); | ||||
|         if(typeServiceMap.containsKey(type)){ | ||||
|             LoggerInterface.loggerEngine.DEBUG("[SignalSystem] Post signal " + type); | ||||
|             Signal signal = Signal.create(type, data); | ||||
| @ -124,7 +124,7 @@ public class SignalSystem implements Service { | ||||
|         } else { | ||||
|             //there are no services mapped to this signal type | ||||
|         } | ||||
|         systemLock.release(); | ||||
|         systemLock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -1,7 +1,6 @@ | ||||
| package electrosphere.net.client; | ||||
| 
 | ||||
| import java.util.List; | ||||
| import java.util.concurrent.CopyOnWriteArrayList; | ||||
| import java.util.LinkedList; | ||||
| import java.util.concurrent.Semaphore; | ||||
| 
 | ||||
| import electrosphere.engine.Globals; | ||||
| @ -41,7 +40,7 @@ public class MessageProtocol { | ||||
|     Semaphore synchronousMessageLock = new Semaphore(1); | ||||
| 
 | ||||
|     //the queue of synchonous network messages | ||||
|     List<NetworkMessage> synchronousMessageQueue = new CopyOnWriteArrayList<NetworkMessage>(); | ||||
|     LinkedList<NetworkMessage> synchronousMessageQueue = new LinkedList<NetworkMessage>(); | ||||
| 
 | ||||
| 
 | ||||
|     //The individual protocols | ||||
|  | ||||
| @ -1,13 +1,14 @@ | ||||
| package electrosphere.net.parser.net.raw; | ||||
| 
 | ||||
| import electrosphere.net.parser.net.message.MessagePool; | ||||
| import electrosphere.net.parser.net.message.NetworkMessage; | ||||
| package electrosphere.net.parser.net.raw; | ||||
| 
 | ||||
| import electrosphere.net.parser.net.message.MessagePool; | ||||
| import electrosphere.net.parser.net.message.NetworkMessage; | ||||
| 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.CopyOnWriteArrayList; | ||||
| import java.util.concurrent.locks.ReentrantLock; | ||||
| 
 | ||||
| /** | ||||
|  * The main message parser. This is used to serialize/deserialize messages to/from the provided streams. | ||||
| @ -37,12 +38,12 @@ public class NetworkParser { | ||||
|     /** | ||||
|      * The queue of incoming messages that have been parsed | ||||
|      */ | ||||
|     CopyOnWriteArrayList<NetworkMessage> incomingMessageQueue = new CopyOnWriteArrayList<NetworkMessage>(); | ||||
|     LinkedList<NetworkMessage> incomingMessageQueue = new LinkedList<NetworkMessage>(); | ||||
| 
 | ||||
|     /** | ||||
|      * The queue of outgoing messages that have yet to be sent | ||||
|      */ | ||||
|     CopyOnWriteArrayList<NetworkMessage> outgoingMessageQueue = new CopyOnWriteArrayList<NetworkMessage>(); | ||||
|     LinkedList<NetworkMessage> outgoingMessageQueue = new LinkedList<NetworkMessage>(); | ||||
| 
 | ||||
|     /** | ||||
|      * Message object pool | ||||
| @ -59,11 +60,6 @@ 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 | ||||
|      */ | ||||
| @ -74,6 +70,11 @@ public class NetworkParser { | ||||
|      * Otherwise, will not release when the message is sent. | ||||
|      */ | ||||
|     boolean releaseOnSend = true; | ||||
| 
 | ||||
|     /** | ||||
|      * Lock for thread-safing the parser | ||||
|      */ | ||||
|     ReentrantLock lock = new ReentrantLock(); | ||||
|      | ||||
|      | ||||
|     /** | ||||
| @ -103,9 +104,11 @@ 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(); | ||||
|     } | ||||
|      | ||||
|     /** | ||||
| @ -113,13 +116,15 @@ 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(); | ||||
|     } | ||||
|      | ||||
|     /** | ||||
| @ -127,7 +132,10 @@ public class NetworkParser { | ||||
|      * @return true if there is message in the queue, false otherwise | ||||
|      */ | ||||
|     public boolean hasIncomingMessaage(){ | ||||
|         return incomingMessageQueue.size() > 0; | ||||
|         lock.lock(); | ||||
|         boolean rVal = incomingMessageQueue.size() > 0; | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
|      | ||||
|     /** | ||||
| @ -135,7 +143,10 @@ public class NetworkParser { | ||||
|      * @return The message | ||||
|      */ | ||||
|     public NetworkMessage popIncomingMessage(){ | ||||
|         return incomingMessageQueue.remove(0); | ||||
|         lock.lock(); | ||||
|         NetworkMessage rVal = incomingMessageQueue.remove(0); | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
|      | ||||
|     /** | ||||
| @ -143,7 +154,9 @@ public class NetworkParser { | ||||
|      * @param message The message | ||||
|      */ | ||||
|     public void addOutgoingMessage(NetworkMessage message){ | ||||
|         lock.lock(); | ||||
|         outgoingMessageQueue.add(message); | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -151,7 +164,9 @@ 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(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -159,7 +174,9 @@ 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(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -1,7 +1,6 @@ | ||||
| package electrosphere.net.server; | ||||
| 
 | ||||
| import java.util.List; | ||||
| import java.util.concurrent.CopyOnWriteArrayList; | ||||
| import java.util.LinkedList; | ||||
| import java.util.concurrent.Semaphore; | ||||
| 
 | ||||
| import electrosphere.engine.Globals; | ||||
| @ -37,7 +36,7 @@ public class MessageProtocol { | ||||
|     Semaphore synchronousMessageLock = new Semaphore(1); | ||||
| 
 | ||||
|     //the queue of synchonous network messages | ||||
|     List<NetworkMessage> synchronousMessageQueue = new CopyOnWriteArrayList<NetworkMessage>(); | ||||
|     LinkedList<NetworkMessage> synchronousMessageQueue = new LinkedList<NetworkMessage>(); | ||||
| 
 | ||||
|     //The server connection handler | ||||
|     ServerConnectionHandler serverConnectionHandler; | ||||
|  | ||||
| @ -16,7 +16,6 @@ import java.net.Socket; | ||||
| import java.net.SocketException; | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| import java.util.concurrent.CopyOnWriteArrayList; | ||||
| import java.util.concurrent.Semaphore; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| @ -127,11 +126,6 @@ public class ServerConnectionHandler implements Runnable { | ||||
|      * the lock used for synchronizing the synchronous message queue | ||||
|      */ | ||||
|     Semaphore synchronousMessageLock = new Semaphore(1); | ||||
| 
 | ||||
|     /** | ||||
|      * the queue of synchonous network messages | ||||
|      */ | ||||
|     List<NetworkMessage> synchronousMessageQueue = new CopyOnWriteArrayList<NetworkMessage>(); | ||||
|      | ||||
|     /** | ||||
|      * Constructs a connection from a socket | ||||
|  | ||||
| @ -1,13 +1,13 @@ | ||||
| package electrosphere.renderer.ui; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| import java.util.ListIterator; | ||||
| import java.util.Map; | ||||
| import java.util.Set; | ||||
| import java.util.Stack; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| import java.util.concurrent.CopyOnWriteArrayList; | ||||
| import java.util.concurrent.locks.ReentrantLock; | ||||
| 
 | ||||
| import org.joml.Vector2i; | ||||
| 
 | ||||
| @ -51,13 +51,18 @@ public class ElementService extends SignalServiceImpl { | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     Map<String,Element> elementMap = new ConcurrentHashMap<String,Element>(); | ||||
|     List<Element> elementList = new CopyOnWriteArrayList<Element>(); | ||||
|     Map<String,Element> elementMap = new HashMap<String,Element>(); | ||||
|     List<Element> elementList = new LinkedList<Element>(); | ||||
|     FocusableElement currentFocusedElement = null; | ||||
|     DraggableElement currentDragElement = null; | ||||
| 
 | ||||
|     // the element currently hovered over | ||||
|     HoverableElement currentHoveredElement = null; | ||||
| 
 | ||||
|     /** | ||||
|      * Lock for thread-safing the structure | ||||
|      */ | ||||
|     ReentrantLock lock = new ReentrantLock(); | ||||
|      | ||||
|     /** | ||||
|      * Registers a window | ||||
| @ -65,6 +70,7 @@ public class ElementService extends SignalServiceImpl { | ||||
|      * @param w The window element | ||||
|      */ | ||||
|     public void registerWindow(String name, Element w){ | ||||
|         lock.lock(); | ||||
|         elementMap.put(name,w); | ||||
|         if(!elementList.contains(w)){ | ||||
|             elementList.add(w); | ||||
| @ -72,6 +78,7 @@ public class ElementService extends SignalServiceImpl { | ||||
|         if(elementList.size() < 2){ | ||||
|             focusFirstElement(); | ||||
|         } | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -80,7 +87,11 @@ public class ElementService extends SignalServiceImpl { | ||||
|      * @return The window element if it exists, null otherwise | ||||
|      */ | ||||
|     public Element getWindow(String name){ | ||||
|         return elementMap.get(name); | ||||
|         Element rVal = null; | ||||
|         lock.lock(); | ||||
|         rVal = elementMap.get(name); | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
|      | ||||
|     /** | ||||
| @ -88,7 +99,10 @@ public class ElementService extends SignalServiceImpl { | ||||
|      * @return The list of all registered windows | ||||
|      */ | ||||
|     public List<Element> getWindowList(){ | ||||
|         return elementList; | ||||
|         lock.lock(); | ||||
|         List<Element> rVal = new LinkedList<Element>(this.elementList); | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
|      | ||||
|     /** | ||||
| @ -96,6 +110,7 @@ public class ElementService extends SignalServiceImpl { | ||||
|      * @param name The window string | ||||
|      */ | ||||
|     public void unregisterWindow(String name){ | ||||
|         lock.lock(); | ||||
|         Element w = elementMap.remove(name); | ||||
|         while(elementList.contains(w)){ | ||||
|             elementList.remove(w); | ||||
| @ -105,15 +120,21 @@ public class ElementService extends SignalServiceImpl { | ||||
|         } else { | ||||
|             this.currentFocusedElement = null; | ||||
|         } | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     public boolean containsWindow(String name){ | ||||
|         return elementMap.containsKey(name); | ||||
|         lock.lock(); | ||||
|         boolean rVal = elementMap.containsKey(name); | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
|     public void pushWindowToFront(Window window){ | ||||
|         lock.lock(); | ||||
|         elementList.remove(window); | ||||
|         elementList.add(window); | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -121,7 +142,10 @@ public class ElementService extends SignalServiceImpl { | ||||
|      * @return The set of ids | ||||
|      */ | ||||
|     public Set<String> getCurrentWindowIds(){ | ||||
|         return elementMap.keySet(); | ||||
|         lock.lock(); | ||||
|         Set<String> rVal = elementMap.keySet(); | ||||
|         lock.unlock(); | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -159,6 +183,7 @@ public class ElementService extends SignalServiceImpl { | ||||
|     } | ||||
| 
 | ||||
|     public void focusFirstElement(){ | ||||
|         lock.lock(); | ||||
|         if(elementList.size() > 0){ | ||||
|             List<FocusableElement> focusables = getFocusableList(elementList.get(elementList.size() - 1),new LinkedList<FocusableElement>()); | ||||
|             if(focusables.size() > 0){ | ||||
| @ -174,10 +199,13 @@ public class ElementService extends SignalServiceImpl { | ||||
|                 currentFocusedElement = null; | ||||
|             } | ||||
|         } | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     public void focusNextElement(){ | ||||
|         lock.lock(); | ||||
|         List<FocusableElement> focusables = getFocusableList(elementList.get(elementList.size() - 1),new LinkedList<FocusableElement>()); | ||||
|         lock.unlock(); | ||||
|         if(focusables.contains(currentFocusedElement)){ | ||||
|             int index = focusables.indexOf(currentFocusedElement); | ||||
|             if(index + 1 >= focusables.size()){ | ||||
| @ -194,7 +222,9 @@ public class ElementService extends SignalServiceImpl { | ||||
|     } | ||||
| 
 | ||||
|     public void focusPreviousElement(){ | ||||
|         lock.lock(); | ||||
|         List<FocusableElement> focusables = getFocusableList(elementList.get(elementList.size() - 1),new LinkedList<FocusableElement>()); | ||||
|         lock.unlock(); | ||||
|         if(focusables.contains(currentFocusedElement)){ | ||||
|             int index = focusables.indexOf(currentFocusedElement); | ||||
|             if(index - 1 < 0){ | ||||
| @ -230,7 +260,9 @@ public class ElementService extends SignalServiceImpl { | ||||
|      */ | ||||
|     public void fireEvent(Event event, int x, int y){ | ||||
|         boolean propagate = true; | ||||
|         lock.lock(); | ||||
|         ListIterator<Element> windowIterator = elementList.listIterator(elementList.size()); | ||||
|         lock.unlock(); | ||||
|         while(windowIterator.hasPrevious()){ | ||||
|             Element currentWindow = windowIterator.previous(); | ||||
|             Stack<Element> elementStack = buildElementPositionalStack(new Stack<Element>(), currentWindow, x, y); | ||||
| @ -283,12 +315,14 @@ public class ElementService extends SignalServiceImpl { | ||||
|      */ | ||||
|     public void fireTopLevelEvent(Event event){ | ||||
|         boolean propagate = true; | ||||
|         lock.lock(); | ||||
|         for(Element topLevelEl : this.elementList){ | ||||
|             propagate = fireEventNoPosition(event, topLevelEl); | ||||
|             if(!propagate){ | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         lock.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -358,6 +392,7 @@ public class ElementService extends SignalServiceImpl { | ||||
|     } | ||||
| 
 | ||||
|     public Element resolveFirstDraggable(DragEvent event){ | ||||
|         lock.lock(); | ||||
|         ListIterator<Element> windowIterator = elementList.listIterator(elementList.size()); | ||||
|         while(windowIterator.hasPrevious()){ | ||||
|             Element currentWindow = windowIterator.previous(); | ||||
| @ -366,10 +401,12 @@ public class ElementService extends SignalServiceImpl { | ||||
|             while(elementStack.size() > 0){ | ||||
|                 currentElement = elementStack.pop(); | ||||
|                 if(currentElement instanceof DraggableElement){ | ||||
|                     lock.unlock(); | ||||
|                     return currentElement; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         lock.unlock(); | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
| @ -380,6 +417,7 @@ public class ElementService extends SignalServiceImpl { | ||||
|      * @return The first hoverable element if it exists, null otherwise | ||||
|      */ | ||||
|     public Element resolveFirstHoverable(int currentX, int currentY){ | ||||
|         lock.lock(); | ||||
|         ListIterator<Element> windowIterator = elementList.listIterator(elementList.size()); | ||||
|         while(windowIterator.hasPrevious()){ | ||||
|             Element currentWindow = windowIterator.previous(); | ||||
| @ -388,10 +426,12 @@ public class ElementService extends SignalServiceImpl { | ||||
|             while(elementStack.size() > 0){ | ||||
|                 currentElement = elementStack.pop(); | ||||
|                 if(currentElement instanceof HoverableElement){ | ||||
|                     lock.unlock(); | ||||
|                     return currentElement; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         lock.unlock(); | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
| @ -497,10 +537,13 @@ public class ElementService extends SignalServiceImpl { | ||||
|      */ | ||||
|     public void navigateBackwards(){ | ||||
|         NavigationEvent event = new NavigationEvent(NavigationEventType.BACKWARD); | ||||
|         lock.lock(); | ||||
|         int elListSize = this.elementList.size(); | ||||
|         lock.unlock(); | ||||
|         if(currentFocusedElement != null){ | ||||
|             //fires on the currently focused element | ||||
|             fireEventNoPosition(event, currentFocusedElement); | ||||
|         } else if(this.elementList.size() > 0){ | ||||
|         } else if(elListSize > 0){ | ||||
|             fireTopLevelEvent(event); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -1,8 +1,5 @@ | ||||
| package electrosphere.server.physics.terrain.generation; | ||||
| 
 | ||||
| import java.util.Map; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| 
 | ||||
| import electrosphere.client.terrain.cache.ChunkData; | ||||
| import electrosphere.server.physics.terrain.generation.interfaces.ChunkGenerator; | ||||
| import electrosphere.server.physics.terrain.manager.ServerTerrainChunk; | ||||
| @ -19,7 +16,7 @@ public class OverworldChunkGenerator implements ChunkGenerator { | ||||
|     //cache for the bicubic interpolated chunks | ||||
|     //don't need to interpolate each time a new chunk is created | ||||
|     //This should eventually be removed as terrain generation becomes more complicated than a heightmap | ||||
|     Map<String, float[][]> heightmapCache = new ConcurrentHashMap<String, float[][]>(); | ||||
|     // Map<String, float[][]> heightmapCache = new ConcurrentHashMap<String, float[][]>(); | ||||
| 
 | ||||
|     /** | ||||
|      * Constructor | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user