optimization work
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
5588827644
commit
c630a184aa
@ -1383,6 +1383,7 @@ Network message object pooling
|
||||
Threadsafe EntityDataCellMapper
|
||||
Code cleanup
|
||||
Small ServerAttackTree fix (for when not holding an item)
|
||||
Work on optimization
|
||||
|
||||
|
||||
|
||||
|
||||
@ -32,9 +32,14 @@ public class ChunkData {
|
||||
*/
|
||||
public static final int CHUNK_DATA_SIZE = ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE;
|
||||
|
||||
//What type of terrain is in this voxel, eg stone vs dirt vs grass, etc
|
||||
/**
|
||||
* What type of terrain is in this voxel, eg stone vs dirt vs grass, etc
|
||||
*/
|
||||
int[][][] voxelType;
|
||||
//How much of that terrain type is in this voxel
|
||||
|
||||
/**
|
||||
* How much of that terrain type is in this voxel
|
||||
*/
|
||||
float[][][] voxelWeight;
|
||||
|
||||
//the list of positions modified since the last call to resetModifiedPositions
|
||||
|
||||
@ -112,7 +112,6 @@ public class ClientTerrainManager {
|
||||
public void handleMessages(){
|
||||
Globals.profiler.beginCpuSample("ClientTerrainManager.handleMessages");
|
||||
lock.acquireUninterruptibly();
|
||||
List<TerrainMessage> bouncedMessages = new LinkedList<TerrainMessage>();
|
||||
for(TerrainMessage message : messageQueue){
|
||||
switch(message.getMessageSubtype()){
|
||||
case SENDCHUNKDATA: {
|
||||
@ -216,11 +215,9 @@ public class ClientTerrainManager {
|
||||
LoggerInterface.loggerEngine.WARNING("ClientTerrainManager: unhandled network message of type" + message.getMessageSubtype());
|
||||
break;
|
||||
}
|
||||
Globals.clientConnection.release(message);
|
||||
}
|
||||
messageQueue.clear();
|
||||
for(TerrainMessage message : bouncedMessages){
|
||||
messageQueue.add(message);
|
||||
}
|
||||
//evaluate if any terrain chunks have failed to request
|
||||
for(Long key : this.requestedMap.keySet()){
|
||||
int duration = this.requestedMap.get(key);
|
||||
|
||||
@ -4,8 +4,8 @@ import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.state.collidable.Impulse;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
|
||||
/**
|
||||
@ -22,7 +22,7 @@ public class Collidable {
|
||||
boolean parentTracksCollidable = true;
|
||||
|
||||
//The impulses to be applied to this collidable
|
||||
List<Impulse> impulses = new CopyOnWriteArrayList<Impulse>();
|
||||
List<Impulse> impulses = new LinkedList<Impulse>();
|
||||
|
||||
/**
|
||||
* The params for the surface of this collidable when a collision occurs
|
||||
|
||||
@ -47,10 +47,10 @@ public class EntityUtils {
|
||||
if(dataCell != null){
|
||||
dataCell.getScene().deregisterEntity(e);
|
||||
}
|
||||
Globals.entityDataCellMapper.ejectEntity(e);
|
||||
}
|
||||
Globals.realmManager.removeEntity(e);
|
||||
}
|
||||
Globals.entityDataCellMapper.ejectEntity(e);
|
||||
EntityLookupUtils.removeEntity(e);
|
||||
}
|
||||
|
||||
|
||||
@ -6,15 +6,17 @@ import electrosphere.entity.EntityTags;
|
||||
import electrosphere.entity.btree.BehaviorTree;
|
||||
import electrosphere.entity.state.attach.AttachUtils;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.util.annotation.Exclude;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* A game scene
|
||||
@ -35,33 +37,39 @@ public class Scene {
|
||||
* The list of behavior trees
|
||||
*/
|
||||
List<BehaviorTree> behaviorTreeList;
|
||||
|
||||
@Exclude
|
||||
/**
|
||||
* Lock for threadsafeing the scene
|
||||
*/
|
||||
ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public Scene(){
|
||||
entityIdMap = new ConcurrentHashMap<Integer,Entity>();
|
||||
tagEntityMap = new ConcurrentHashMap<String,Set<Entity>>();
|
||||
behaviorTreeList = new CopyOnWriteArrayList<BehaviorTree>();
|
||||
tagEntityMap.put(EntityTags.BONE_ATTACHED, new CopyOnWriteArraySet<Entity>());
|
||||
tagEntityMap.put(EntityTags.COLLIDABLE, new CopyOnWriteArraySet<Entity>());
|
||||
tagEntityMap.put(EntityTags.SPRINTABLE, new CopyOnWriteArraySet<Entity>());
|
||||
tagEntityMap.put(EntityTags.MOVEABLE, new CopyOnWriteArraySet<Entity>());
|
||||
tagEntityMap.put(EntityTags.ATTACKER, new CopyOnWriteArraySet<Entity>());
|
||||
tagEntityMap.put(EntityTags.TARGETABLE, new CopyOnWriteArraySet<Entity>());
|
||||
tagEntityMap.put(EntityTags.LIFE_STATE, new CopyOnWriteArraySet<Entity>());
|
||||
tagEntityMap.put(EntityTags.CREATURE, new CopyOnWriteArraySet<Entity>());
|
||||
tagEntityMap.put(EntityTags.UI, new CopyOnWriteArraySet<Entity>());
|
||||
tagEntityMap.put(EntityTags.DRAWABLE, new CopyOnWriteArraySet<Entity>());
|
||||
tagEntityMap.put(EntityTags.DRAW_INSTANCED, new CopyOnWriteArraySet<Entity>());
|
||||
tagEntityMap.put(EntityTags.DRAW_VOLUMETIC_SOLIDS_PASS, new CopyOnWriteArraySet<Entity>());
|
||||
tagEntityMap.put(EntityTags.DRAW_VOLUMETIC_DEPTH_PASS, new CopyOnWriteArraySet<Entity>());
|
||||
tagEntityMap.put(EntityTags.DRAW_CAST_SHADOW, new CopyOnWriteArraySet<Entity>());
|
||||
tagEntityMap.put(EntityTags.LIGHT, new CopyOnWriteArraySet<Entity>());
|
||||
tagEntityMap.put(EntityTags.ITEM, new CopyOnWriteArraySet<Entity>());
|
||||
tagEntityMap.put(EntityTags.GRAVITY, new CopyOnWriteArraySet<Entity>());
|
||||
tagEntityMap.put(EntityTags.PARTICLE, new CopyOnWriteArraySet<Entity>());
|
||||
tagEntityMap.put(EntityTags.TRANSFORM_ATTACHED, new CopyOnWriteArraySet<Entity>());
|
||||
entityIdMap = new HashMap<Integer,Entity>();
|
||||
tagEntityMap = new HashMap<String,Set<Entity>>();
|
||||
behaviorTreeList = new LinkedList<BehaviorTree>();
|
||||
tagEntityMap.put(EntityTags.BONE_ATTACHED, new HashSet<Entity>());
|
||||
tagEntityMap.put(EntityTags.COLLIDABLE, new HashSet<Entity>());
|
||||
tagEntityMap.put(EntityTags.SPRINTABLE, new HashSet<Entity>());
|
||||
tagEntityMap.put(EntityTags.MOVEABLE, new HashSet<Entity>());
|
||||
tagEntityMap.put(EntityTags.ATTACKER, new HashSet<Entity>());
|
||||
tagEntityMap.put(EntityTags.TARGETABLE, new HashSet<Entity>());
|
||||
tagEntityMap.put(EntityTags.LIFE_STATE, new HashSet<Entity>());
|
||||
tagEntityMap.put(EntityTags.CREATURE, new HashSet<Entity>());
|
||||
tagEntityMap.put(EntityTags.UI, new HashSet<Entity>());
|
||||
tagEntityMap.put(EntityTags.DRAWABLE, new HashSet<Entity>());
|
||||
tagEntityMap.put(EntityTags.DRAW_INSTANCED, new HashSet<Entity>());
|
||||
tagEntityMap.put(EntityTags.DRAW_VOLUMETIC_SOLIDS_PASS, new HashSet<Entity>());
|
||||
tagEntityMap.put(EntityTags.DRAW_VOLUMETIC_DEPTH_PASS, new HashSet<Entity>());
|
||||
tagEntityMap.put(EntityTags.DRAW_CAST_SHADOW, new HashSet<Entity>());
|
||||
tagEntityMap.put(EntityTags.LIGHT, new HashSet<Entity>());
|
||||
tagEntityMap.put(EntityTags.ITEM, new HashSet<Entity>());
|
||||
tagEntityMap.put(EntityTags.GRAVITY, new HashSet<Entity>());
|
||||
tagEntityMap.put(EntityTags.PARTICLE, new HashSet<Entity>());
|
||||
tagEntityMap.put(EntityTags.TRANSFORM_ATTACHED, new HashSet<Entity>());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,7 +77,9 @@ public class Scene {
|
||||
* @param e The entity to register
|
||||
*/
|
||||
public void registerEntity(Entity e){
|
||||
lock.lock();
|
||||
entityIdMap.put(e.getId(), e);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,13 +88,15 @@ public class Scene {
|
||||
* @param tag The tag
|
||||
*/
|
||||
public void registerEntityToTag(Entity e, String tag){
|
||||
lock.lock();
|
||||
if(tagEntityMap.containsKey(tag)){
|
||||
tagEntityMap.get(tag).add(e);
|
||||
} else {
|
||||
Set<Entity> newEntityList = new CopyOnWriteArraySet<Entity>();
|
||||
Set<Entity> newEntityList = new HashSet<Entity>();
|
||||
newEntityList.add(e);
|
||||
tagEntityMap.put(tag,newEntityList);
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -93,7 +105,13 @@ public class Scene {
|
||||
* @return A list of all entities with the tag, or null if no entities have been added to the tag yet
|
||||
*/
|
||||
public Set<Entity> getEntitiesWithTag(String tag){
|
||||
return tagEntityMap.get(tag);
|
||||
lock.lock();
|
||||
Set<Entity> rVal = null;
|
||||
if(tagEntityMap.containsKey(tag)){
|
||||
rVal = new HashSet<Entity>(tagEntityMap.get(tag));
|
||||
}
|
||||
lock.unlock();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -102,7 +120,9 @@ public class Scene {
|
||||
* @param tag The tag
|
||||
*/
|
||||
public void removeEntityFromTag(Entity e, String tag){
|
||||
lock.lock();
|
||||
tagEntityMap.get(tag).remove(e);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -110,10 +130,12 @@ public class Scene {
|
||||
* @param e
|
||||
*/
|
||||
public void deregisterEntity(Entity e){
|
||||
lock.lock();
|
||||
for(String key : tagEntityMap.keySet()){
|
||||
tagEntityMap.get(key).remove(e);
|
||||
}
|
||||
entityIdMap.remove(e.getId());
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,6 +143,7 @@ public class Scene {
|
||||
* @param target The top level entity to deregister
|
||||
*/
|
||||
public void recursiveDeregister(Entity target){
|
||||
lock.lock();
|
||||
if(AttachUtils.hasChildren(target)){
|
||||
List<Entity> childrenList = AttachUtils.getChildrenList(target);
|
||||
for(Entity currentChild : childrenList){
|
||||
@ -128,6 +151,7 @@ public class Scene {
|
||||
}
|
||||
}
|
||||
this.deregisterEntity(target);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -136,7 +160,10 @@ public class Scene {
|
||||
* @return The entity with that ID
|
||||
*/
|
||||
public Entity getEntityFromId(int id){
|
||||
return (Entity)entityIdMap.get(id);
|
||||
lock.lock();
|
||||
Entity rVal = (Entity)entityIdMap.get(id);
|
||||
lock.unlock();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,7 +172,10 @@ public class Scene {
|
||||
* @return true if the scene contains the entity, false otherwise
|
||||
*/
|
||||
public boolean containsEntity(Entity e){
|
||||
return entityIdMap.containsKey(e.getId());
|
||||
lock.lock();
|
||||
boolean rVal = entityIdMap.containsKey(e.getId());
|
||||
lock.unlock();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -153,7 +183,9 @@ public class Scene {
|
||||
* @param tree The behavior tree to register
|
||||
*/
|
||||
public void registerBehaviorTree(BehaviorTree tree){
|
||||
lock.lock();
|
||||
behaviorTreeList.add(tree);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -161,9 +193,11 @@ public class Scene {
|
||||
* @param task The task
|
||||
*/
|
||||
public void registerBehaviorTree(Runnable task){
|
||||
lock.lock();
|
||||
this.registerBehaviorTree(new BehaviorTree(){public void simulate(float deltaTime) {
|
||||
task.run();
|
||||
}});
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -171,20 +205,25 @@ public class Scene {
|
||||
* @param tree The behavior tree to deregister
|
||||
*/
|
||||
public void deregisterBehaviorTree(BehaviorTree tree){
|
||||
lock.lock();
|
||||
while(behaviorTreeList.contains(tree)){
|
||||
behaviorTreeList.remove(tree);
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulates all behavior trees stored in the entity manager
|
||||
*/
|
||||
public void simulateBehaviorTrees(float deltaTime){
|
||||
lock.lock();
|
||||
Globals.profiler.beginAggregateCpuSample("Scene.simulateBehaviorTrees");
|
||||
for(BehaviorTree tree : behaviorTreeList){
|
||||
List<BehaviorTree> trees = new LinkedList<BehaviorTree>(behaviorTreeList);
|
||||
for(BehaviorTree tree : trees){
|
||||
tree.simulate(deltaTime);
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -192,7 +231,10 @@ public class Scene {
|
||||
* @return The collection of all entities in the scene
|
||||
*/
|
||||
public Collection<Entity> getEntityList(){
|
||||
return this.entityIdMap.values();
|
||||
lock.lock();
|
||||
Collection<Entity> rVal = new LinkedList<Entity>(this.entityIdMap.values());
|
||||
lock.unlock();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -200,7 +242,10 @@ public class Scene {
|
||||
* @return The list of behavior trees attached to the scene
|
||||
*/
|
||||
public Collection<BehaviorTree> getBehaviorTrees(){
|
||||
return Collections.unmodifiableList(this.behaviorTreeList);
|
||||
lock.lock();
|
||||
Collection<BehaviorTree> rVal = new LinkedList<BehaviorTree>(this.behaviorTreeList);
|
||||
lock.unlock();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -41,7 +41,6 @@ import electrosphere.server.datacell.Realm;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Vector3d;
|
||||
@ -63,7 +62,7 @@ public class ServerAttackTree implements BehaviorTree {
|
||||
|
||||
Entity parent;
|
||||
|
||||
CopyOnWriteArrayList<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList<EntityMessage>();
|
||||
List<EntityMessage> networkMessageQueue = new LinkedList<EntityMessage>();
|
||||
|
||||
long lastUpdateTime = 0;
|
||||
|
||||
@ -370,10 +369,12 @@ public class ServerAttackTree implements BehaviorTree {
|
||||
this.stateTransitionUtil.simulate(AttackTreeState.ATTACK);
|
||||
//activate hitboxes
|
||||
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
||||
for(Entity currentAttached : attachedEntities){
|
||||
if(HitboxCollectionState.hasHitboxState(currentAttached)){
|
||||
HitboxCollectionState currentState = HitboxCollectionState.getHitboxState(currentAttached);
|
||||
currentState.setActive(true);
|
||||
if(attachedEntities != null){
|
||||
for(Entity currentAttached : attachedEntities){
|
||||
if(HitboxCollectionState.hasHitboxState(currentAttached)){
|
||||
HitboxCollectionState currentState = HitboxCollectionState.getHitboxState(currentAttached);
|
||||
currentState.setActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(firesProjectile && projectileToFire != null){
|
||||
|
||||
@ -23,7 +23,8 @@ import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
||||
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
|
||||
import electrosphere.server.poseactor.PoseActor;
|
||||
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@SynchronizedBehaviorTree(name = "serverIdle", isServer = true, correspondingTree = "idle")
|
||||
@ -40,7 +41,7 @@ public class ServerIdleTree implements BehaviorTree {
|
||||
//The idle data
|
||||
IdleData idleData;
|
||||
|
||||
CopyOnWriteArrayList<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList<EntityMessage>();
|
||||
List<EntityMessage> networkMessageQueue = new LinkedList<EntityMessage>();
|
||||
|
||||
/**
|
||||
* Creates a server idle tree
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package electrosphere.entity.state.inventory;
|
||||
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.btree.BehaviorTree;
|
||||
@ -19,7 +20,7 @@ public class ServerInventoryState implements BehaviorTree {
|
||||
/**
|
||||
* The queue of messages to handle
|
||||
*/
|
||||
CopyOnWriteArrayList<InventoryMessage> networkMessageQueue = new CopyOnWriteArrayList<InventoryMessage>();
|
||||
List<InventoryMessage> networkMessageQueue = new LinkedList<InventoryMessage>();
|
||||
|
||||
/**
|
||||
* The parent of the state
|
||||
|
||||
@ -31,7 +31,8 @@ import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
||||
import electrosphere.server.utils.ServerScriptUtils;
|
||||
import electrosphere.util.math.SpatialMathUtils;
|
||||
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Vector3d;
|
||||
@ -63,7 +64,7 @@ public class ServerEditorMovementTree implements BehaviorTree {
|
||||
|
||||
Entity parent;
|
||||
|
||||
CopyOnWriteArrayList<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList<EntityMessage>();
|
||||
List<EntityMessage> networkMessageQueue = new LinkedList<EntityMessage>();
|
||||
|
||||
long lastUpdateTime = 0;
|
||||
|
||||
|
||||
@ -35,7 +35,8 @@ import electrosphere.server.poseactor.PoseActor;
|
||||
import electrosphere.server.utils.ServerScriptUtils;
|
||||
import electrosphere.util.math.SpatialMathUtils;
|
||||
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Vector3d;
|
||||
@ -71,7 +72,7 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
||||
|
||||
Collidable collidable;
|
||||
|
||||
CopyOnWriteArrayList<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList<EntityMessage>();
|
||||
List<EntityMessage> networkMessageQueue = new LinkedList<EntityMessage>();
|
||||
|
||||
long lastUpdateTime = 0;
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
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;
|
||||
@ -68,6 +68,12 @@ public class NetworkParser {
|
||||
* The number of bytes read
|
||||
*/
|
||||
long totalBytesRead = 0;
|
||||
|
||||
/**
|
||||
* If set to true, the parser will automatically release messages on send.
|
||||
* Otherwise, will not release when the message is sent.
|
||||
*/
|
||||
boolean releaseOnSend = true;
|
||||
|
||||
|
||||
/**
|
||||
@ -110,7 +116,9 @@ public class NetworkParser {
|
||||
for(NetworkMessage message : outgoingMessageQueue){
|
||||
outgoingMessageQueue.remove(message);
|
||||
outgoingStream.write(message.getRawBytes());
|
||||
this.pool.release(message);
|
||||
if(this.releaseOnSend){
|
||||
this.pool.release(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,5 +185,14 @@ public class NetworkParser {
|
||||
public MessagePool getMessagePool(){
|
||||
return this.pool;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set to true, the parser will automatically release messages on send.
|
||||
* Otherwise, will not release when the message is sent.
|
||||
* @param releaseOnSend true to release messages on send, false otherwise
|
||||
*/
|
||||
public void setReleaseOnSend(boolean releaseOnSend){
|
||||
this.releaseOnSend = releaseOnSend;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -129,6 +129,7 @@ public class ServerConnectionHandler implements Runnable {
|
||||
if(this.local){
|
||||
//run if serverconnectionHandler is created by passing in input/output streams
|
||||
networkParser = new NetworkParser(inputStream,outputStream);
|
||||
networkParser.setReleaseOnSend(false);
|
||||
messageProtocol = new MessageProtocol(this);
|
||||
} else {
|
||||
//run if ServerConnectionHandler is created by passing in a socket
|
||||
|
||||
@ -7,7 +7,6 @@ import electrosphere.logger.LoggerInterface;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.state.movement.jump.ServerJumpTree;
|
||||
@ -33,7 +32,7 @@ public class ServerSynchronizationManager {
|
||||
|
||||
|
||||
//The list of messages to loop through
|
||||
List<SynchronizationMessage> messages = new CopyOnWriteArrayList<SynchronizationMessage>();
|
||||
List<SynchronizationMessage> messages = new LinkedList<SynchronizationMessage>();
|
||||
|
||||
/**
|
||||
* Pushes a message into the queue to be processed
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
package electrosphere.server.datacell;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
@ -26,11 +26,19 @@ import electrosphere.server.fluid.simulator.FluidAcceleratedSimulator;
|
||||
*/
|
||||
public class RealmManager {
|
||||
|
||||
//All realms in this manager
|
||||
Set<Realm> realms = new CopyOnWriteArraySet<Realm>();
|
||||
//Map of entities to the realm the entity is in
|
||||
/**
|
||||
* All realms in this manager
|
||||
*/
|
||||
Set<Realm> realms = new HashSet<Realm>();
|
||||
|
||||
/**
|
||||
* Map of entities to the realm the entity is in
|
||||
*/
|
||||
Map<Entity,Realm> entityToRealmMap = new HashMap<Entity,Realm>();
|
||||
//Map of player to the realm the player is in
|
||||
|
||||
/**
|
||||
* Map of player to the realm the player is in
|
||||
*/
|
||||
Map<Player,Realm> playerToRealmMap = new HashMap<Player,Realm>();
|
||||
|
||||
/**
|
||||
@ -165,7 +173,10 @@ public class RealmManager {
|
||||
* @return The set containing all realms in the manager
|
||||
*/
|
||||
public Set<Realm> getRealms(){
|
||||
return realms;
|
||||
lock.lock();
|
||||
Set<Realm> rVal = new HashSet<Realm>(realms);
|
||||
lock.unlock();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
@ -174,6 +185,7 @@ public class RealmManager {
|
||||
*/
|
||||
public void simulate(){
|
||||
Globals.profiler.beginCpuSample("RealmManager.simulate");
|
||||
Set<Realm> realms = this.getRealms();
|
||||
for(Realm realm : realms){
|
||||
realm.simulate();
|
||||
}
|
||||
@ -209,6 +221,7 @@ public class RealmManager {
|
||||
* @param saveName The name of the save
|
||||
*/
|
||||
public void save(String saveName){
|
||||
Set<Realm> realms = this.getRealms();
|
||||
for(Realm realm : realms){
|
||||
realm.save(saveName);
|
||||
}
|
||||
|
||||
@ -52,8 +52,10 @@ public class GriddedDataCellLoaderService {
|
||||
//let the service know we've finished this job
|
||||
lock.lock();
|
||||
queuedWorkLock.remove(key);
|
||||
jobOperationMap.remove(key);
|
||||
lock.unlock();
|
||||
};
|
||||
jobOperationMap.put(key,operation);
|
||||
if(job != null){
|
||||
if(!job.cancel(false)){
|
||||
try {
|
||||
@ -69,80 +71,24 @@ public class GriddedDataCellLoaderService {
|
||||
if(job.isCancelled()){
|
||||
Runnable oldOp = jobOperationMap.remove(key);
|
||||
//queue job to run the old operation first, then the new one
|
||||
opCallback = () -> {
|
||||
Runnable currentOp = () -> {
|
||||
oldOp.run();
|
||||
//load here
|
||||
operation.run();
|
||||
};
|
||||
opCallback = () -> {
|
||||
currentOp.run();
|
||||
//let the service know we've finished this job
|
||||
lock.lock();
|
||||
queuedWorkLock.remove(key);
|
||||
jobOperationMap.remove(key);
|
||||
lock.unlock();
|
||||
};
|
||||
jobOperationMap.put(key,currentOp);
|
||||
}
|
||||
}
|
||||
//queue job to do the operation
|
||||
Future<?> newJob = ioThreadService.submit(opCallback);
|
||||
queuedWorkLock.put(key, newJob);
|
||||
jobOperationMap.put(key,operation);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a cell
|
||||
* @param key The key for the cell
|
||||
*/
|
||||
protected static void loadCell(long key, Runnable loadLogic){
|
||||
lock.lock();
|
||||
//if there is a job queued and we couldn't cancel it, wait
|
||||
Future<?> job = queuedWorkLock.get(key);
|
||||
if(job != null && !job.cancel(false)){
|
||||
try {
|
||||
Globals.profiler.beginCpuSample("Waiting for cell io job to finish");
|
||||
job.wait();
|
||||
Globals.profiler.endCpuSample();
|
||||
} catch (InterruptedException e) {
|
||||
LoggerInterface.loggerEngine.ERROR("Failed to wait for previous job for cell!", e);
|
||||
}
|
||||
}
|
||||
//queue job to load the cell
|
||||
Future<?> newJob = ioThreadService.submit(() -> {
|
||||
//load here
|
||||
loadLogic.run();
|
||||
//let the service know we've finished this job
|
||||
lock.lock();
|
||||
queuedWorkLock.remove(key);
|
||||
lock.unlock();
|
||||
});
|
||||
queuedWorkLock.put(key, newJob);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unloads a cell
|
||||
* @param key The key for the cell
|
||||
*/
|
||||
protected static void unloadCell(long key, Runnable unloadLogic){
|
||||
lock.lock();
|
||||
//if there is a job queued and we couldn't cancel it, wait
|
||||
Future<?> job = queuedWorkLock.get(key);
|
||||
if(job != null && !job.cancel(false)){
|
||||
try {
|
||||
Globals.profiler.beginCpuSample("Waiting for cell io job to finish");
|
||||
job.wait();
|
||||
Globals.profiler.endCpuSample();
|
||||
} catch (InterruptedException e) {
|
||||
LoggerInterface.loggerEngine.ERROR("Failed to wait for previous job for cell!", e);
|
||||
}
|
||||
}
|
||||
//queue job to load the cell
|
||||
ioThreadService.submit(() -> {
|
||||
//unload here
|
||||
unloadLogic.run();
|
||||
//let the service know we've finished this job
|
||||
lock.lock();
|
||||
queuedWorkLock.remove(key);
|
||||
lock.unlock();
|
||||
});
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
|
||||
@ -296,10 +296,12 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
*/
|
||||
private void createTerrainPhysicsEntities(Vector3i worldPos){
|
||||
Long key = this.getServerDataCellKey(worldPos);
|
||||
loadedCellsLock.lock();
|
||||
if(posPhysicsMap.containsKey(key)){
|
||||
PhysicsDataCell cell = posPhysicsMap.get(key);
|
||||
cell.retireCell();
|
||||
}
|
||||
loadedCellsLock.unlock();
|
||||
//get data to generate with
|
||||
Vector3d realPos = new Vector3d(
|
||||
worldPos.x * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET,
|
||||
@ -325,7 +327,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
cell.setTerrainChunk(terrainChunk);
|
||||
cell.setBlockChunk(blockChunkData);
|
||||
cell.generatePhysics();
|
||||
loadedCellsLock.lock();
|
||||
posPhysicsMap.put(key, cell);
|
||||
loadedCellsLock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -742,8 +746,10 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
serverContentManager.generateContentForDataCell(parent, worldPos, rVal, cellKey);
|
||||
});
|
||||
//generates physics for the cell in a dedicated thread then finally registers
|
||||
loadedCellsLock.lock();
|
||||
PhysicsDataCell cell = posPhysicsMap.get(key);
|
||||
GriddedDataCellManager.runPhysicsGenerationThread(worldPos,key,cell,this.posPhysicsMap,this.groundDataCells,this.parent);
|
||||
loadedCellsLock.unlock();
|
||||
|
||||
|
||||
Globals.profiler.endCpuSample();
|
||||
|
||||
@ -4,6 +4,7 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.btree.BehaviorTree;
|
||||
@ -17,14 +18,24 @@ import electrosphere.server.datacell.ServerDataCell;
|
||||
*/
|
||||
public class ServerBehaviorTreeUtils {
|
||||
|
||||
/**
|
||||
* The map of entity to set of behavior trees attached to it
|
||||
*/
|
||||
static Map<Entity,Set<BehaviorTree>> entityBTreeMap = new HashMap<Entity,Set<BehaviorTree>>();
|
||||
|
||||
/**
|
||||
* Lock for thread-safeing the util
|
||||
*/
|
||||
static ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
/**
|
||||
* Tracks behavior trees attached to this entity
|
||||
* @param entity
|
||||
*/
|
||||
public static void registerEntity(Entity entity){
|
||||
lock.lock();
|
||||
entityBTreeMap.put(entity, new HashSet<BehaviorTree>());
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -32,6 +43,7 @@ public class ServerBehaviorTreeUtils {
|
||||
* @param entity
|
||||
*/
|
||||
public static void deregisterEntity(Entity entity){
|
||||
lock.lock();
|
||||
Set<BehaviorTree> trees = entityBTreeMap.remove(entity);
|
||||
ServerDataCell currentCell = DataCellSearchUtils.getEntityDataCell(entity);
|
||||
if(trees != null){
|
||||
@ -39,6 +51,7 @@ public class ServerBehaviorTreeUtils {
|
||||
currentCell.getScene().deregisterBehaviorTree(tree);
|
||||
}
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,10 +60,12 @@ public class ServerBehaviorTreeUtils {
|
||||
* @param behaviorTree The behavior tree
|
||||
*/
|
||||
public static void attachBTreeToEntity(Entity entity, BehaviorTree behaviorTree){
|
||||
lock.lock();
|
||||
entityBTreeMap.get(entity).add(behaviorTree);
|
||||
//register to cell
|
||||
ServerDataCell currentCell = DataCellSearchUtils.getEntityDataCell(entity);
|
||||
currentCell.getScene().registerBehaviorTree(behaviorTree);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -59,10 +74,12 @@ public class ServerBehaviorTreeUtils {
|
||||
* @param behaviorTree The behavior tree
|
||||
*/
|
||||
public static void detatchBTreeFromEntity(Entity entity, BehaviorTree behaviorTree){
|
||||
lock.lock();
|
||||
entityBTreeMap.get(entity).remove(behaviorTree);
|
||||
//deregister from cell
|
||||
ServerDataCell currentCell = DataCellSearchUtils.getEntityDataCell(entity);
|
||||
currentCell.getScene().deregisterBehaviorTree(behaviorTree);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
|
||||
@ -72,6 +89,7 @@ public class ServerBehaviorTreeUtils {
|
||||
* @param oldCell The cell the entity used to inhabit
|
||||
*/
|
||||
public static void updateCell(Entity entity, ServerDataCell oldCell){
|
||||
lock.lock();
|
||||
Set<BehaviorTree> trees = entityBTreeMap.get(entity);
|
||||
ServerDataCell newCell = DataCellSearchUtils.getEntityDataCell(entity);
|
||||
if(trees != null){
|
||||
@ -82,6 +100,7 @@ public class ServerBehaviorTreeUtils {
|
||||
newCell.getScene().registerBehaviorTree(tree);
|
||||
}
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
package electrosphere.server.saves;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import electrosphere.entity.scene.Scene;
|
||||
|
||||
/**
|
||||
* Top level save object that stores information about the save
|
||||
*/
|
||||
@ -24,9 +20,6 @@ public class Save {
|
||||
//The name of the save
|
||||
String name;
|
||||
|
||||
//The scenes
|
||||
List<Scene> scenes;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue
Block a user