fix reloading world repeatedly

This commit is contained in:
austin 2025-05-15 11:28:37 -04:00
parent 7ad7a0c477
commit 2cf14bcdd2
15 changed files with 125 additions and 5 deletions

View File

@ -1797,6 +1797,7 @@ Utilities to free all of a type of resource
Slowdown entity tests to prevent VSCode from exploding when running tests Slowdown entity tests to prevent VSCode from exploding when running tests
Fix static state caching between tests in visual shader construction Fix static state caching between tests in visual shader construction
Safe executor service creation in non final static contexts Safe executor service creation in non final static contexts
Fix reloading client world repeatedly

View File

@ -729,6 +729,7 @@ public class Globals {
Globals.realmManager.reset(); Globals.realmManager.reset();
} }
Globals.dbController.disconnect(); Globals.dbController.disconnect();
Globals.serviceManager.unloadScene();
} }
/** /**

View File

@ -35,6 +35,8 @@ public class MainMenuLoading {
Globals.unloadScene(); Globals.unloadScene();
Globals.threadManager.interruptLabel(ThreadLabel.NETWORKING_CLIENT); Globals.threadManager.interruptLabel(ThreadLabel.NETWORKING_CLIENT);
Globals.threadManager.interruptLabel(ThreadLabel.NETWORKING_SERVER); Globals.threadManager.interruptLabel(ThreadLabel.NETWORKING_SERVER);
Globals.threadManager.awaitThreadClose(ThreadLabel.NETWORKING_CLIENT);
Globals.threadManager.awaitThreadClose(ThreadLabel.NETWORKING_SERVER);
// //
//reveal in game main menu //reveal in game main menu

View File

@ -15,6 +15,11 @@ public interface Service {
*/ */
public void destroy(); public void destroy();
/**
* Resets the service on closing the client and/or server
*/
public void unloadScene();
/** /**
* Returns the name of the service * Returns the name of the service
* @return * @return

View File

@ -62,4 +62,13 @@ public class ServiceManager {
this.trackedServices = null; this.trackedServices = null;
} }
/**
* Fires all functions required to unload a scene.
*/
public void unloadScene(){
for(Service serivce : this.trackedServices){
serivce.unloadScene();
}
}
} }

View File

@ -124,4 +124,11 @@ public class SignalServiceImpl implements SignalService {
return this.targetTypes; return this.targetTypes;
} }
@Override
public void unloadScene(){
this.threadLock.acquireUninterruptibly();
this.signals.clear();
this.threadLock.release();
}
} }

View File

@ -143,4 +143,8 @@ public class SignalSystem implements Service {
this.post(type,(Object)runnable); this.post(type,(Object)runnable);
} }
@Override
public void unloadScene(){
}
} }

View File

@ -9,9 +9,21 @@ public class LabeledThread {
* The label associated with the thread * The label associated with the thread
*/ */
public static enum ThreadLabel { public static enum ThreadLabel {
/**
* The server socket networking thread
*/
NETWORKING_SERVER, NETWORKING_SERVER,
/**
* The client networking thread
*/
NETWORKING_CLIENT, NETWORKING_CLIENT,
/**
* The main asset loading thread
*/
ASSET_LOADING, ASSET_LOADING,
/**
* The main loading thread
*/
LOADING, LOADING,
} }

View File

@ -83,8 +83,12 @@ public class ThreadManager {
* @param thread The thread to start * @param thread The thread to start
*/ */
public void start(ThreadLabel label, Thread thread){ public void start(ThreadLabel label, Thread thread){
if(label.toString() == null || label.toString().length() < 1){
throw new Error("Invalid label name! " + label.toString());
}
threadLock.lock(); threadLock.lock();
activeThreads.add(new LabeledThread(label, thread)); activeThreads.add(new LabeledThread(label, thread));
thread.setName(label.toString());
thread.start(); thread.start();
threadLock.unlock(); threadLock.unlock();
} }
@ -117,6 +121,22 @@ public class ThreadManager {
return Collections.unmodifiableList(loadingThreads); return Collections.unmodifiableList(loadingThreads);
} }
/**
* Waits for a named thread to close
* @param label the label of the thread
*/
public void awaitThreadClose(ThreadLabel label){
boolean running = true;
while(running){
try {
TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException e) {
running = false;
}
running = this.isRunning(label);
}
}
/** /**
* Tries to close all threads * Tries to close all threads
*/ */
@ -197,6 +217,39 @@ public class ThreadManager {
threadLock.unlock(); threadLock.unlock();
} }
/**
* Updates the list of active threads
*/
private void updateActiveThreads(){
this.threadLock.lock();
List<LabeledThread> clearQueue = new LinkedList<LabeledThread>();
for(LabeledThread thread : activeThreads){
if(!thread.getThread().isAlive()){
clearQueue.add(thread);
}
}
activeThreads.removeAll(clearQueue);
this.threadLock.unlock();
}
/**
* Checks if a thread label is running
* @param label The label
* @return true if it is actively running, false otherwise
*/
public boolean isRunning(ThreadLabel label){
boolean rVal = false;
threadLock.lock();
this.updateActiveThreads();
for(LabeledThread thread : activeThreads){
if(thread.getLabel() == label){
rVal = true;
}
}
threadLock.unlock();
return rVal;
}
/** /**
* Requests a fixed-size thread pool * Requests a fixed-size thread pool
* @param threads The number of threads * @param threads The number of threads

View File

@ -241,6 +241,17 @@ public class ClientNetworking implements Runnable {
} }
} }
if(this.socket != null){
try {
this.socket.close();
} catch (IOException e) {
LoggerInterface.loggerNetworking.ERROR(e);
}
}
//null out global state
Globals.clientConnection = null;
LoggerInterface.loggerNetworking.INFO("Client networking thread ended"); LoggerInterface.loggerNetworking.INFO("Client networking thread ended");
} }

View File

@ -117,7 +117,9 @@ public class Server implements Runnable {
LoggerInterface.loggerEngine.DEBUG("Failed to sleep", e); LoggerInterface.loggerEngine.DEBUG("Failed to sleep", e);
} }
} }
this.isOpen = false; this.close();
//null out global state
Globals.server = null;
LoggerInterface.loggerNetworking.INFO("Server socket thread ended"); LoggerInterface.loggerNetworking.INFO("Server socket thread ended");
} }

View File

@ -297,6 +297,14 @@ public class ServerConnectionHandler implements Runnable {
} }
} }
if(this.socket != null){
try {
this.socket.close();
} catch (IOException e) {
LoggerInterface.loggerNetworking.ERROR(e);
}
}
LoggerInterface.loggerNetworking.INFO("Server connection thread ended"); LoggerInterface.loggerNetworking.INFO("Server connection thread ended");
} }

View File

@ -10,7 +10,6 @@ import electrosphere.server.physics.block.diskmap.ServerBlockChunkDiskMap;
import electrosphere.util.annotation.Exclude; import electrosphere.util.annotation.Exclude;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.joml.Vector3i; import org.joml.Vector3i;
@ -46,7 +45,7 @@ public class ServerBlockManager {
* The threadpool for chunk generation * The threadpool for chunk generation
*/ */
@Exclude @Exclude
static final ExecutorService chunkExecutorService = Executors.newFixedThreadPool(ThreadCounts.SERVER_BLOCK_GENERATION_THREADS); ExecutorService chunkExecutorService = Globals.threadManager.requestFixedThreadPool(ThreadCounts.SERVER_BLOCK_GENERATION_THREADS);
/** /**
* Constructor * Constructor

View File

@ -20,7 +20,6 @@ import java.nio.ByteBuffer;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
import java.nio.ShortBuffer; import java.nio.ShortBuffer;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.joml.Vector3i; import org.joml.Vector3i;
@ -78,7 +77,7 @@ public class ServerTerrainManager {
* The threadpool for chunk generation * The threadpool for chunk generation
*/ */
@Exclude @Exclude
static final ExecutorService chunkExecutorService = Executors.newFixedThreadPool(ThreadCounts.SERVER_TERRAIN_GENERATION_THREADS); ExecutorService chunkExecutorService = Globals.threadManager.requestFixedThreadPool(ThreadCounts.SERVER_TERRAIN_GENERATION_THREADS);
/** /**
* Constructor * Constructor

View File

@ -275,4 +275,11 @@ public class CharacterService extends SignalServiceImpl {
lock.unlock(); lock.unlock();
} }
@Override
public void unloadScene(){
super.unloadScene();
this.loadedCharacterMap.clear();
this.characterEntityMap.clear();
}
} }