Renderer/src/main/java/electrosphere/server/datacell/RealmManager.java
austin 7da8472d0e
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
bugfixes
2024-11-20 20:59:05 -05:00

231 lines
7.0 KiB
Java

package electrosphere.server.datacell;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import org.joml.Vector3d;
import electrosphere.collision.CollisionEngine;
import electrosphere.collision.CollisionWorldData;
import electrosphere.collision.hitbox.HitboxManager;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.net.server.player.Player;
import electrosphere.server.chemistry.ServerChemistryCollisionCallback;
import electrosphere.server.collision.ServerHitboxResolutionCallback;
import electrosphere.server.content.ServerContentManager;
/**
* Manages all realms for the engine. Should be a singleton
*/
public class RealmManager {
//All realms in this manager
Set<Realm> realms = new CopyOnWriteArraySet<Realm>();
//Map of entities to the realm the entity is in
Map<Entity,Realm> entityToRealmMap = new ConcurrentHashMap<Entity,Realm>();
//Map of player to the realm the player is in
Map<Player,Realm> playerToRealmMap = new ConcurrentHashMap<Player,Realm>();
/**
* Constructor
*/
public RealmManager(){
}
/**
* Creates a realm
* @return The realm
*/
public Realm createRealm(){
//create chemistry engine
CollisionEngine chemistryEngine = new CollisionEngine();
chemistryEngine.setCollisionResolutionCallback(new ServerChemistryCollisionCallback());
return new Realm(
new ServerWorldData(),
new CollisionEngine(),
chemistryEngine,
new HitboxManager(new ServerHitboxResolutionCallback()),
ServerContentManager.createServerContentManager(false)
);
}
/**
* Creates a realm that uses a gridded layout (ie an array of cells in 3d space)
* @return The realm
*/
public Realm createGriddedRealm(ServerWorldData serverWorldData, ServerContentManager serverContentManager){
//create collision engine
CollisionEngine collisionEngine = new CollisionEngine();
collisionEngine.setCollisionWorldData(new CollisionWorldData(serverWorldData));
//create chemistry engine
CollisionEngine chemistryEngine = new CollisionEngine();
chemistryEngine.setCollisionWorldData(new CollisionWorldData(serverWorldData));
chemistryEngine.setCollisionResolutionCallback(new ServerChemistryCollisionCallback());
//create realm
Realm realm = new Realm(
serverWorldData,
collisionEngine,
chemistryEngine,
new HitboxManager(new ServerHitboxResolutionCallback()),
serverContentManager
);
//create function classes
GriddedDataCellManager griddedDataCellManager = new GriddedDataCellManager(realm);
//add function classes to realm
realm.setDataCellManager(griddedDataCellManager);
//register within the manager
realms.add(realm);
return realm;
}
/**
* Creates a viewport realm
* @return The viewport realm
*/
public Realm createViewportRealm(Vector3d minPoint, Vector3d maxPoint){
//create the server world data
ServerWorldData serverWorldData = ServerWorldData.createFixedWorldData(minPoint, maxPoint);
//create collision engine
CollisionEngine collisionEngine = new CollisionEngine();
collisionEngine.setCollisionWorldData(new CollisionWorldData(serverWorldData));
//create chemistry engine
CollisionEngine chemistryEngine = new CollisionEngine();
chemistryEngine.setCollisionWorldData(new CollisionWorldData(serverWorldData));
chemistryEngine.setCollisionResolutionCallback(new ServerChemistryCollisionCallback());
//create realm
Realm realm = new Realm(
serverWorldData,
collisionEngine,
chemistryEngine,
new HitboxManager(new ServerHitboxResolutionCallback()),
ServerContentManager.createServerContentManager(false)
);
//add function classes to realm
realm.setDataCellManager(ViewportDataCellManager.create(realm));
//register
realms.add(realm);
return realm;
}
/**
* Maps an entity to a realm
* @param entity The entity
* @param realm The realm
*/
public void mapEntityToRealm(Entity entity, Realm realm){
entityToRealmMap.put(entity, realm);
}
/**
* Removes the entity from tracking in this realm manager
* @param entity The entity to remove
*/
public void removeEntity(Entity entity){
entityToRealmMap.remove(entity);
}
/**
* Gets the realm an entity is inside of
* @param entity The entity
* @return The realm, or null if the entity is not inside a realm
*/
public Realm getEntityRealm(Entity entity){
return entityToRealmMap.get(entity);
}
/**
* Gets the set containing all realms in the manager
* @return The set containing all realms in the manager
*/
public Set<Realm> getRealms(){
return realms;
}
/**
* Simulates all realms in this manager
*/
public void simulate(){
Globals.profiler.beginCpuSample("RealmManager.simulate");
for(Realm realm : realms){
realm.simulate();
}
Globals.profiler.endCpuSample();
}
//TODO: !!URGENT!! come up with some mechanism to enforce this actually being called every time a player is added to a server data cell
/**
* Adds a player to a realm
* @param player The player
* @param realm The realm
*/
public void setPlayerRealm(Player player, Realm realm){
playerToRealmMap.put(player, realm);
}
/**
* Gets the realm of a given player
* @param player The player
* @return The realm
*/
public Realm getPlayerRealm(Player player){
return playerToRealmMap.get(player);
}
/**
* Saves all cells in all realms in the realm manager
* @param saveName The name of the save
*/
public void save(String saveName){
for(Realm realm : realms){
realm.save(saveName);
}
}
/**
* Returns the first realm in the manager
* @return The first realm in the manager
*/
public Realm first(){
if(realms.size() == 0){
return null;
}
return realms.iterator().next();
}
/**
* Resets the realm manager
*/
public void reset(){
this.realms.clear();
this.entityToRealmMap.clear();
this.playerToRealmMap.clear();
}
/**
* Closes the realm manager, destroying all resources
*/
public void close(){
for(Realm realm : this.realms){
if(realm.getServerWorldData() != null && realm.getServerWorldData().getServerTerrainManager() != null){
realm.getServerWorldData().getServerTerrainManager().closeThreads();
}
}
this.reset();
}
}