more visibility into gridded cell manager
This commit is contained in:
parent
72e329d855
commit
7df05d611d
@ -1389,13 +1389,11 @@ Floating world origin
|
|||||||
- Separately simulated regions of physics that dynamically merge/unmerge based on chunk loading
|
- Separately simulated regions of physics that dynamically merge/unmerge based on chunk loading
|
||||||
|
|
||||||
Bug Fixes
|
Bug Fixes
|
||||||
- Server not regenerating physics entities correctly after block edit
|
|
||||||
- Fix hitbox placement does not scale with entity scale on server
|
- Fix hitbox placement does not scale with entity scale on server
|
||||||
- Calculate bounding sphere for meshes by deforming vertices with bone default pose instead of no bone deform
|
- Calculate bounding sphere for meshes by deforming vertices with bone default pose instead of no bone deform
|
||||||
- Fix light cluster mapping for foliage shader
|
- Fix light cluster mapping for foliage shader
|
||||||
- Fix flickering when applying yoga signal (may need to rethink arch here)
|
- Fix flickering when applying yoga signal (may need to rethink arch here)
|
||||||
- Fix virtual scrollables not working
|
- Fix virtual scrollables not working
|
||||||
- Fix single blades of grass generating in bad locations
|
|
||||||
|
|
||||||
Startup Performance
|
Startup Performance
|
||||||
- Allow texture map to bind multiple model paths to a single set of mesh->textures
|
- Allow texture map to bind multiple model paths to a single set of mesh->textures
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import electrosphere.server.datacell.Realm;
|
|||||||
import imgui.ImGui;
|
import imgui.ImGui;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Debug menu for gridded managers
|
||||||
*/
|
*/
|
||||||
public class ImGuiGriddedManager {
|
public class ImGuiGriddedManager {
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ public class ImGuiGriddedManager {
|
|||||||
* Creates the windows in this file
|
* Creates the windows in this file
|
||||||
*/
|
*/
|
||||||
protected static void createGriddedManagerWindows(){
|
protected static void createGriddedManagerWindows(){
|
||||||
createGriddedManagerWindow();
|
ImGuiGriddedManager.createGriddedManagerWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,8 +38,14 @@ public class ImGuiGriddedManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(manager != null && manager.getLoadedCells() != null){
|
if(manager != null){
|
||||||
ImGui.text("Loaded Cells: " + manager.getLoadedCells().size());
|
if(manager.getLoadedCells() != null){
|
||||||
|
ImGui.text("Loaded Cells: " + manager.getLoadedCells().size());
|
||||||
|
}
|
||||||
|
if(manager.getCellPlayerlessFrameMap() != null){
|
||||||
|
ImGui.text("Playerless tracking map size: " + manager.getCellPlayerlessFrameMap().keySet().size());
|
||||||
|
}
|
||||||
|
ImGui.text("Cells cleaned last frame: " + manager.getNumCleaned());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,6 +41,7 @@ public class ServerContentManager {
|
|||||||
* @param cell The cell
|
* @param cell The cell
|
||||||
*/
|
*/
|
||||||
public void generateContentForDataCell(Realm realm, Vector3i worldPos, ServerDataCell cell, Long cellKey){
|
public void generateContentForDataCell(Realm realm, Vector3i worldPos, ServerDataCell cell, Long cellKey){
|
||||||
|
Globals.profiler.beginCpuSample("ServerContentManager.generateContentForDataCell");
|
||||||
String fullPath = "/content/" + cellKey + ".dat";
|
String fullPath = "/content/" + cellKey + ".dat";
|
||||||
if(generateContent){ //in other words, if not arena mode
|
if(generateContent){ //in other words, if not arena mode
|
||||||
if(FileUtils.checkSavePathExists(Globals.currentSave.getName(), fullPath)){
|
if(FileUtils.checkSavePathExists(Globals.currentSave.getName(), fullPath)){
|
||||||
@ -68,6 +69,7 @@ public class ServerContentManager {
|
|||||||
// ),
|
// ),
|
||||||
// Globals.navMeshManager.getBlockerCache().getBlocker(worldPos.x, worldPos.z))
|
// Globals.navMeshManager.getBlockerCache().getBlocker(worldPos.x, worldPos.z))
|
||||||
// );
|
// );
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -131,6 +131,11 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
*/
|
*/
|
||||||
Map<Long,PhysicsDataCell> posPhysicsMap = new HashMap<Long,PhysicsDataCell>();
|
Map<Long,PhysicsDataCell> posPhysicsMap = new HashMap<Long,PhysicsDataCell>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of data cells cleaned up in the most recent frame
|
||||||
|
*/
|
||||||
|
int numCleaned = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param parent The gridded data cell manager's parent realm
|
* @param parent The gridded data cell manager's parent realm
|
||||||
@ -183,8 +188,6 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
LoggerInterface.loggerEngine.DEBUG("Creating new cell @ " + x + " " + y + " " + z);
|
LoggerInterface.loggerEngine.DEBUG("Creating new cell @ " + x + " " + y + " " + z);
|
||||||
//create data cell
|
//create data cell
|
||||||
this.createServerDataCell(targetPos);
|
this.createServerDataCell(targetPos);
|
||||||
//add to loaded cells
|
|
||||||
cellPlayerlessFrameMap.put(groundDataCells.get(getServerDataCellKey(targetPos)),0);
|
|
||||||
//add player
|
//add player
|
||||||
groundDataCells.get(getServerDataCellKey(targetPos)).addPlayer(player);
|
groundDataCells.get(getServerDataCellKey(targetPos)).addPlayer(player);
|
||||||
}
|
}
|
||||||
@ -224,18 +227,16 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
for(int z = newPosition.x - playerSimulationRadius; z < newPosition.z + playerSimulationRadius + 1; z++){
|
for(int z = newPosition.x - playerSimulationRadius; z < newPosition.z + playerSimulationRadius + 1; z++){
|
||||||
if(this.canCreateCell(x, y, z) && this.shouldContainPlayer(new Vector3i(x, y, z), newPosition, playerSimulationRadius)){
|
if(this.canCreateCell(x, y, z) && this.shouldContainPlayer(new Vector3i(x, y, z), newPosition, playerSimulationRadius)){
|
||||||
Vector3i targetPos = new Vector3i(x,y,z);
|
Vector3i targetPos = new Vector3i(x,y,z);
|
||||||
if(groundDataCells.get(getServerDataCellKey(targetPos)) != null){
|
if(groundDataCells.get(this.getServerDataCellKey(targetPos)) != null){
|
||||||
loadedCellsLock.lock();
|
loadedCellsLock.lock();
|
||||||
groundDataCells.get(getServerDataCellKey(targetPos)).addPlayer(player);
|
groundDataCells.get(this.getServerDataCellKey(targetPos)).addPlayer(player);
|
||||||
loadedCellsLock.unlock();
|
loadedCellsLock.unlock();
|
||||||
} else {
|
} else {
|
||||||
loadedCellsLock.lock();
|
loadedCellsLock.lock();
|
||||||
//create data cell
|
//create data cell
|
||||||
createServerDataCell(targetPos);
|
this.createServerDataCell(targetPos);
|
||||||
//add to loaded cells
|
|
||||||
cellPlayerlessFrameMap.put(groundDataCells.get(getServerDataCellKey(targetPos)),0);
|
|
||||||
//add player
|
//add player
|
||||||
groundDataCells.get(getServerDataCellKey(targetPos)).addPlayer(player);
|
groundDataCells.get(this.getServerDataCellKey(targetPos)).addPlayer(player);
|
||||||
loadedCellsLock.unlock();
|
loadedCellsLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -327,6 +328,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
* @return True if the player changed cell, false otherwise
|
* @return True if the player changed cell, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean updatePlayerPositions(){
|
public boolean updatePlayerPositions(){
|
||||||
|
Globals.profiler.beginCpuSample("GriddedDataCellManager.updatePlayerPositions");
|
||||||
boolean playerChangedChunk = false;
|
boolean playerChangedChunk = false;
|
||||||
for(Player player : Globals.playerManager.getPlayers()){
|
for(Player player : Globals.playerManager.getPlayers()){
|
||||||
Entity playerEntity = player.getPlayerEntity();
|
Entity playerEntity = player.getPlayerEntity();
|
||||||
@ -342,6 +344,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
|
|
||||||
//remove from cells that are out of range
|
//remove from cells that are out of range
|
||||||
loadedCellsLock.lock();
|
loadedCellsLock.lock();
|
||||||
|
Globals.profiler.beginCpuSample("GriddedDataCellManager.updatePlayerPositions - Remove from old cells");
|
||||||
for(ServerDataCell cell : this.groundDataCells.values()){
|
for(ServerDataCell cell : this.groundDataCells.values()){
|
||||||
Vector3i cellWorldPos = this.getCellWorldPosition(cell);
|
Vector3i cellWorldPos = this.getCellWorldPosition(cell);
|
||||||
if(cell.containsPlayer(player) && !this.shouldContainPlayer(cellWorldPos, newPosition, playerSimulationRadius)){
|
if(cell.containsPlayer(player) && !this.shouldContainPlayer(cellWorldPos, newPosition, playerSimulationRadius)){
|
||||||
@ -352,9 +355,11 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
this.broadcastDestructionToPlayer(player, cell);
|
this.broadcastDestructionToPlayer(player, cell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
loadedCellsLock.unlock();
|
loadedCellsLock.unlock();
|
||||||
|
|
||||||
//Add to cells that are in range
|
//Add to cells that are in range
|
||||||
|
Globals.profiler.beginCpuSample("GriddedDataCellManager.updatePlayerPositions - Create new cells");
|
||||||
for(int x = newPosition.x - playerSimulationRadius + 1; x < newPosition.x + playerSimulationRadius; x++){
|
for(int x = newPosition.x - playerSimulationRadius + 1; x < newPosition.x + playerSimulationRadius; x++){
|
||||||
for(int y = newPosition.y - playerSimulationRadius + 1; y < newPosition.y + playerSimulationRadius; y++){
|
for(int y = newPosition.y - playerSimulationRadius + 1; y < newPosition.y + playerSimulationRadius; y++){
|
||||||
for(int z = newPosition.z - playerSimulationRadius + 1; z < newPosition.z + playerSimulationRadius; z++){
|
for(int z = newPosition.z - playerSimulationRadius + 1; z < newPosition.z + playerSimulationRadius; z++){
|
||||||
@ -371,8 +376,6 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
loadedCellsLock.lock();
|
loadedCellsLock.lock();
|
||||||
//create data cell
|
//create data cell
|
||||||
this.createServerDataCell(targetPos);
|
this.createServerDataCell(targetPos);
|
||||||
//add to loaded cells
|
|
||||||
cellPlayerlessFrameMap.put(groundDataCells.get(this.getServerDataCellKey(targetPos)),0);
|
|
||||||
//add player
|
//add player
|
||||||
groundDataCells.get(this.getServerDataCellKey(targetPos)).addPlayer(player);
|
groundDataCells.get(this.getServerDataCellKey(targetPos)).addPlayer(player);
|
||||||
loadedCellsLock.unlock();
|
loadedCellsLock.unlock();
|
||||||
@ -381,8 +384,10 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
return playerChangedChunk;
|
return playerChangedChunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,9 +396,11 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
* Unloads all chunks that haven't had players in them for a set amount of time
|
* Unloads all chunks that haven't had players in them for a set amount of time
|
||||||
*/
|
*/
|
||||||
public void unloadPlayerlessChunks(){
|
public void unloadPlayerlessChunks(){
|
||||||
|
Globals.profiler.beginCpuSample("GriddedDataCellManager.unloadPlayerlessChunks");
|
||||||
if(this.unloadCells){
|
if(this.unloadCells){
|
||||||
//TODO: improve to make have less performance impact
|
//TODO: improve to make have less performance impact
|
||||||
loadedCellsLock.lock();
|
loadedCellsLock.lock();
|
||||||
|
Globals.profiler.beginCpuSample("GriddedDataCellManager.unloadPlayerlessChunks - Increment cleaning time");
|
||||||
for(ServerDataCell cell : this.groundDataCells.values()){
|
for(ServerDataCell cell : this.groundDataCells.values()){
|
||||||
if(cellPlayerlessFrameMap.containsKey(cell)){
|
if(cellPlayerlessFrameMap.containsKey(cell)){
|
||||||
if(cell.isReady() && cell.getPlayers().size() < 1){
|
if(cell.isReady() && cell.getPlayers().size() < 1){
|
||||||
@ -409,6 +416,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
|
Globals.profiler.beginCpuSample("GriddedDataCellManager.unloadPlayerlessChunks - Deconstruct timed out cells");
|
||||||
|
this.numCleaned = toCleanQueue.size();
|
||||||
for(ServerDataCell cell : toCleanQueue){
|
for(ServerDataCell cell : toCleanQueue){
|
||||||
boolean containsPlayerEntity = false;
|
boolean containsPlayerEntity = false;
|
||||||
//clear all entities in cell
|
//clear all entities in cell
|
||||||
@ -433,24 +443,38 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
if(containsPlayerEntity){
|
if(containsPlayerEntity){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
parent.deregisterCell(cell);
|
Vector3i worldPos = this.getCellWorldPosition(cell);
|
||||||
Vector3i worldPos = getCellWorldPosition(cell);
|
Long key = this.getServerDataCellKey(worldPos);
|
||||||
Long key = getServerDataCellKey(worldPos);
|
|
||||||
groundDataCells.remove(key);
|
|
||||||
this.posPhysicsMap.remove(key);
|
|
||||||
this.cellPositionMap.remove(cell);
|
|
||||||
this.cellPlayerlessFrameMap.remove(cell);
|
|
||||||
//offload all entities in cell to chunk file
|
//offload all entities in cell to chunk file
|
||||||
|
//entities are saved before tracking is removed. This makes sure that any side effects from calling destroyEntity (ie if it looks up the chunk that we're deleting)
|
||||||
|
//don't trigger the chunk to be re-created
|
||||||
|
Globals.profiler.beginCpuSample("GriddedDataCellManager.unloadPlayerlessChunks - Destroy entities");
|
||||||
serverContentManager.saveContentToDisk(key, cell.getScene().getEntityList());
|
serverContentManager.saveContentToDisk(key, cell.getScene().getEntityList());
|
||||||
for(Entity entity : cell.getScene().getEntityList()){
|
for(Entity entity : cell.getScene().getEntityList()){
|
||||||
ServerEntityUtils.destroyEntity(entity);
|
ServerEntityUtils.destroyEntity(entity);
|
||||||
}
|
}
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
|
|
||||||
//save terrain to disk
|
//save terrain to disk
|
||||||
|
//terrain is saved before tracking is removed. This makes sure that any side effects from calling savePositionToDisk (ie if it looks up the chunk that we're deleting)
|
||||||
|
//don't trigger the chunk to be re-created
|
||||||
|
Globals.profiler.beginCpuSample("GriddedDataCellManager.unloadPlayerlessChunks - Store terrain");
|
||||||
serverTerrainManager.savePositionToDisk(worldPos);
|
serverTerrainManager.savePositionToDisk(worldPos);
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
|
|
||||||
|
//deregister from all tracking structures
|
||||||
|
parent.deregisterCell(cell);
|
||||||
|
groundDataCells.remove(key);
|
||||||
|
this.posPhysicsMap.remove(key);
|
||||||
|
this.cellPositionMap.remove(cell);
|
||||||
|
this.cellPlayerlessFrameMap.remove(cell);
|
||||||
}
|
}
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
loadedCellsLock.unlock();
|
loadedCellsLock.unlock();
|
||||||
toCleanQueue.clear();
|
toCleanQueue.clear();
|
||||||
}
|
}
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -534,8 +558,6 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
loadedCellsLock.lock();
|
loadedCellsLock.lock();
|
||||||
//create data cell
|
//create data cell
|
||||||
this.createServerDataCell(worldPos);
|
this.createServerDataCell(worldPos);
|
||||||
//add to loaded cells
|
|
||||||
cellPlayerlessFrameMap.put(groundDataCells.get(this.getServerDataCellKey(worldPos)),0);
|
|
||||||
loadedCellsLock.unlock();
|
loadedCellsLock.unlock();
|
||||||
} else if(groundDataCells.get(this.getServerDataCellKey(worldPos)) == null) {
|
} else if(groundDataCells.get(this.getServerDataCellKey(worldPos)) == null) {
|
||||||
LoggerInterface.loggerEngine.ERROR(
|
LoggerInterface.loggerEngine.ERROR(
|
||||||
@ -574,20 +596,24 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
//queue fluid simulation
|
//queue fluid simulation
|
||||||
Vector3i cellPos = this.getCellWorldPosition(cell);
|
if(Globals.RUN_FLUIDS){
|
||||||
if(cellPos != null){
|
Vector3i cellPos = this.getCellWorldPosition(cell);
|
||||||
this.serverFluidManager.queue(cellPos.x, cellPos.y, cellPos.z);
|
if(cellPos != null){
|
||||||
|
this.serverFluidManager.queue(cellPos.x, cellPos.y, cellPos.z);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//simulate fluids
|
//simulate fluids
|
||||||
this.serverFluidManager.simulate((ServerFluidChunk fluidChunk) -> {
|
if(Globals.RUN_FLUIDS){
|
||||||
ServerDataCell cell = getCellAtWorldPosition(fluidChunk.getWorldPosition());
|
this.serverFluidManager.simulate((ServerFluidChunk fluidChunk) -> {
|
||||||
ServerFluidChunk chunk = getFluidChunkAtPosition(fluidChunk.getWorldPosition());
|
ServerDataCell cell = getCellAtWorldPosition(fluidChunk.getWorldPosition());
|
||||||
cell.broadcastNetworkMessage(
|
ServerFluidChunk chunk = getFluidChunkAtPosition(fluidChunk.getWorldPosition());
|
||||||
TerrainMessage.constructupdateFluidDataMessage(fluidChunk.getWorldX(), fluidChunk.getWorldY(), fluidChunk.getWorldZ(), TerrainProtocol.constructFluidByteBuffer(chunk).array())
|
cell.broadcastNetworkMessage(
|
||||||
);
|
TerrainMessage.constructupdateFluidDataMessage(fluidChunk.getWorldX(), fluidChunk.getWorldY(), fluidChunk.getWorldZ(), TerrainProtocol.constructFluidByteBuffer(chunk).array())
|
||||||
});
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
loadedCellsLock.unlock();
|
loadedCellsLock.unlock();
|
||||||
this.unloadPlayerlessChunks();
|
this.unloadPlayerlessChunks();
|
||||||
@ -683,9 +709,11 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
* @param cell The cell itself
|
* @param cell The cell itself
|
||||||
*/
|
*/
|
||||||
private ServerDataCell createServerDataCell(Vector3i worldPos){
|
private ServerDataCell createServerDataCell(Vector3i worldPos){
|
||||||
|
Globals.profiler.beginCpuSample("GriddedDataCellManager.createServerDataCell");
|
||||||
ServerDataCell rVal = parent.createNewCell();
|
ServerDataCell rVal = parent.createNewCell();
|
||||||
Long cellKey = this.getServerDataCellKey(worldPos);
|
Long cellKey = this.getServerDataCellKey(worldPos);
|
||||||
groundDataCells.put(cellKey,rVal);
|
groundDataCells.put(cellKey,rVal);
|
||||||
|
cellPlayerlessFrameMap.put(rVal,0);
|
||||||
LoggerInterface.loggerEngine.DEBUG("Create server data cell with key " + cellKey);
|
LoggerInterface.loggerEngine.DEBUG("Create server data cell with key " + cellKey);
|
||||||
cellPositionMap.put(rVal,new Vector3i(worldPos));
|
cellPositionMap.put(rVal,new Vector3i(worldPos));
|
||||||
serverContentManager.generateContentForDataCell(parent, worldPos, rVal, cellKey);
|
serverContentManager.generateContentForDataCell(parent, worldPos, rVal, cellKey);
|
||||||
@ -693,6 +721,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
Long key = this.getServerDataCellKey(worldPos);
|
Long key = this.getServerDataCellKey(worldPos);
|
||||||
PhysicsDataCell cell = posPhysicsMap.get(key);
|
PhysicsDataCell cell = posPhysicsMap.get(key);
|
||||||
GriddedDataCellManager.runPhysicsGenerationThread(worldPos,key,cell,this.posPhysicsMap,this.groundDataCells,this.parent);
|
GriddedDataCellManager.runPhysicsGenerationThread(worldPos,key,cell,this.posPhysicsMap,this.groundDataCells,this.parent);
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -858,14 +887,6 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
return returnPos;
|
return returnPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the set of loaded cells
|
|
||||||
* @return The set of loaded cells
|
|
||||||
*/
|
|
||||||
public Collection<ServerDataCell> getLoadedCells(){
|
|
||||||
return Collections.unmodifiableCollection(this.groundDataCells.values());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops the executor service
|
* Stops the executor service
|
||||||
*/
|
*/
|
||||||
@ -918,4 +939,28 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
terrainEditLock.release();
|
terrainEditLock.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the set of loaded cells
|
||||||
|
* @return The set of loaded cells
|
||||||
|
*/
|
||||||
|
public Collection<ServerDataCell> getLoadedCells(){
|
||||||
|
return Collections.unmodifiableCollection(this.groundDataCells.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of cells cleaned in the most recent frame
|
||||||
|
* @return The number of cells cleaned
|
||||||
|
*/
|
||||||
|
public int getNumCleaned(){
|
||||||
|
return this.numCleaned;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the playerless cell->frame count map
|
||||||
|
* @return The playerless cell->frame count map
|
||||||
|
*/
|
||||||
|
public Map<ServerDataCell,Integer> getCellPlayerlessFrameMap(){
|
||||||
|
return cellPlayerlessFrameMap;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -308,8 +308,8 @@ public class ServerTerrainManager {
|
|||||||
* @param position The position to save
|
* @param position The position to save
|
||||||
*/
|
*/
|
||||||
public void savePositionToDisk(Vector3i position){
|
public void savePositionToDisk(Vector3i position){
|
||||||
if(chunkDiskMap != null){
|
if(chunkDiskMap != null && chunkCache.containsChunk(position.x, position.y, position.z, ChunkData.NO_STRIDE)){
|
||||||
chunkDiskMap.saveToDisk(getChunk(position.x, position.y, position.z));
|
chunkDiskMap.saveToDisk(this.getChunk(position.x, position.y, position.z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user