Fix backing out to main menu
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2024-11-20 19:12:18 -05:00
parent fc4f124a25
commit b892bea3d3
19 changed files with 166 additions and 36 deletions

View File

@ -1093,6 +1093,10 @@ Add engine logo to title menu
Use STBttf for font loading/remove dependency on java.awt.fonts
Fix font height lookups in string carousel, text input, and word
Fix invalid audio source ID bug
Up threshold on tests for approximate color matching
Refactor signal service subscription mechanism
Add main thread signal service
Fix backing out to main menu
# TODO
@ -1119,10 +1123,6 @@ Implement gadgets
- Torch
- Throwable potions
Ability to fully reload game engine state without exiting client
- Back out to main menu and load a new level without any values persisting
- Receive a teleport packet from server and flush all game state before requesting state from server again
Bug Fixes
- Fix hitbox placement does not scale with entity scale on server
- Fix not all grass tiles update when updating a nearby voxel (ie it doesn't go into negative coordinates to scan for foliage updates)

View File

@ -9,6 +9,7 @@ import electrosphere.client.entity.instance.InstanceTemplate;
import electrosphere.client.entity.instance.InstancedEntityUtils;
import electrosphere.engine.assetmanager.AssetDataStrings;
import electrosphere.engine.signal.Signal;
import electrosphere.engine.signal.Signal.SignalType;
import electrosphere.engine.signal.SignalServiceImpl;
import electrosphere.entity.DrawableUtils;
import electrosphere.entity.Entity;
@ -73,7 +74,12 @@ public class ParticleService extends SignalServiceImpl {
* Constructor
*/
public ParticleService() {
super("ParticleService");
super(
"ParticleService",
new SignalType[]{
SignalType.RENDERING_ENGINE_READY,
}
);
}
@Override

View File

@ -7,8 +7,6 @@ import electrosphere.client.ui.menu.WindowUtils;
import electrosphere.controls.ControlHandler.ControlsState;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType;
import electrosphere.engine.signal.Signal.SignalType;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
@ -77,7 +75,7 @@ public class MenuGeneratorsInGame {
//Return to main menu
div.addChild(Button.createButton("Return To Main Menu", () -> {
Globals.threadManager.start(new LoadingThread(LoadingThreadType.RETURN_TITLE_MENU));
Globals.signalSystem.post(SignalType.ENGINE_RETURN_TO_TITLE);
}));

View File

@ -39,7 +39,7 @@ import electrosphere.engine.loadingthreads.InitialAssetLoading;
import electrosphere.engine.profiler.Profiler;
import electrosphere.engine.service.ServiceManager;
import electrosphere.engine.signal.SignalSystem;
import electrosphere.engine.signal.Signal.SignalType;
import electrosphere.engine.signal.sync.MainThreadSignalService;
import electrosphere.engine.threads.ThreadManager;
import electrosphere.engine.time.Timekeeper;
import electrosphere.entity.Entity;
@ -329,6 +329,9 @@ public class Globals {
//script engine
public static ScriptEngine scriptEngine;
//services
public static MainThreadSignalService mainThreadSignalService;
//client scene management
public static Scene clientScene;
@ -534,6 +537,7 @@ public class Globals {
Globals.elementService = (ElementService)serviceManager.registerService(new ElementService());
Globals.particleService = (ParticleService)serviceManager.registerService(new ParticleService());
Globals.scriptEngine = (ScriptEngine)serviceManager.registerService(new ScriptEngine());
Globals.mainThreadSignalService = (MainThreadSignalService)serviceManager.registerService(new MainThreadSignalService());
serviceManager.instantiate();
//
//End service manager
@ -541,11 +545,10 @@ public class Globals {
//
//Register all signals
Globals.signalSystem.registerService(SignalType.YOGA_APPLY, Globals.elementService);
Globals.signalSystem.registerService(SignalType.YOGA_DESTROY, Globals.elementService);
Globals.signalSystem.registerService(SignalType.UI_MODIFICATION, Globals.elementService);
Globals.signalSystem.registerService(SignalType.RENDERING_ENGINE_READY, Globals.particleService);
Globals.signalSystem.registerService(SignalType.SCRIPT_RECOMPILE, Globals.scriptEngine);
Globals.signalSystem.registerService(Globals.elementService);
Globals.signalSystem.registerService(Globals.particleService);
Globals.signalSystem.registerService(Globals.scriptEngine);
Globals.signalSystem.registerService(Globals.mainThreadSignalService);
}

View File

@ -15,6 +15,7 @@ import electrosphere.controls.ControlHandler.ControlsState;
import electrosphere.engine.cli.CLIParser;
import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType;
import electrosphere.engine.signal.SynchronousSignalHandling;
import electrosphere.engine.time.Timekeeper;
import electrosphere.game.server.world.MacroData;
import electrosphere.logger.LoggerInterface;
@ -298,7 +299,7 @@ public class Main {
///
/// S Y N C H R O N O U S S I G N A L H A N D L I N G
///
Globals.scriptEngine.handleAllSignals();
SynchronousSignalHandling.runMainThreadSignalHandlers();
///
/// S C R I P T E N G I N E

View File

@ -7,7 +7,6 @@ import electrosphere.engine.Globals;
import electrosphere.engine.signal.Signal.SignalType;
import electrosphere.engine.threads.LabeledThread.ThreadLabel;
import electrosphere.renderer.ui.elements.Window;
import electrosphere.server.datacell.RealmManager;
/**
* Loading thread that returns the client to the main menu
@ -19,7 +18,7 @@ public class MainMenuLoading {
* Resets all state to main menu
* @param params not necessary
*/
protected static void returnToMainMenu(Object[] params){
public static void returnToMainMenu(Object[] params){
//
//stop rendering game
Globals.RENDER_FLAG_RENDER_SHADOW_MAP = false;
@ -59,7 +58,8 @@ public class MainMenuLoading {
Globals.server.close();
Globals.server = null;
Globals.serverSynchronizationManager = null;
Globals.realmManager = new RealmManager();
Globals.realmManager.reset();
Globals.realmManager = null;
Globals.macroSimulation = null;
}

View File

@ -16,6 +16,7 @@ public class Signal {
//CORE ENGINE
//
ENGINE_SHUTDOWN,
ENGINE_RETURN_TO_TITLE,
//
//RENDERING

View File

@ -1,6 +1,9 @@
package electrosphere.engine.signal;
import java.util.Collection;
import electrosphere.engine.service.Service;
import electrosphere.engine.signal.Signal.SignalType;
/**
* A service that can receive a signal
@ -13,4 +16,10 @@ public interface SignalService extends Service {
*/
public void post(Signal signal);
/**
* Gets the collection of signal types that this service wants to subscribe to
* @return The collection of signal types
*/
public Collection<SignalType> getSubscriptionTargets();
}

View File

@ -1,9 +1,12 @@
package electrosphere.engine.signal;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Semaphore;
import electrosphere.engine.signal.Signal.SignalType;
import electrosphere.logger.LoggerInterface;
/**
@ -26,13 +29,20 @@ public class SignalServiceImpl implements SignalService {
*/
String serviceName;
/**
* The list of signal types that this service wants to listen for
*/
List<SignalType> targetTypes;
/**
* Constructor, used to require certain fields be provided to this service instance
* @param serviceName The name of the service
* @param types The types of signals this service wants to subscribe to
*/
public SignalServiceImpl(String serviceName){
public SignalServiceImpl(String serviceName, SignalType[] types){
this.serviceName = serviceName;
this.targetTypes = Arrays.asList(types);
}
@Override
@ -108,5 +118,10 @@ public class SignalServiceImpl implements SignalService {
public boolean handle(Signal signal){
throw new UnsupportedOperationException("Unimplemented method 'getName'");
}
@Override
public Collection<SignalType> getSubscriptionTargets() {
return this.targetTypes;
}
}

View File

@ -51,7 +51,30 @@ public class SignalSystem implements Service {
* @param signalType The type of signal
* @param service The service to associate with that signal type
*/
public void registerService(SignalType signalType, SignalService service){
public void registerService(SignalService service){
systemLock.acquireUninterruptibly();
LoggerInterface.loggerEngine.DEBUG("[SignalSystem] Register signal service " + service.getName());
for(SignalType signalType : service.getSubscriptionTargets()){
if(typeServiceMap.containsKey(signalType)){
Set<SignalService> services = this.typeServiceMap.get(signalType);
if(!services.contains(service)){
services.add(service);
}
} else {
Set<SignalService> services = new HashSet<SignalService>();
services.add(service);
this.typeServiceMap.put(signalType, services);
}
}
systemLock.release();
}
/**
* Registers a service to a type of signal
* @param signalType The type of signal
* @param service The service to associate with that signal type
*/
public void registerServiceToSignal(SignalType signalType, SignalService service){
systemLock.acquireUninterruptibly();
LoggerInterface.loggerEngine.DEBUG("[SignalSystem] Register signal service " + service.getName());
if(typeServiceMap.containsKey(signalType)){
@ -72,7 +95,7 @@ public class SignalSystem implements Service {
* @param signalType The type of signal
* @param service The signal service to unassociate from that signal type
*/
public void deregisterService(SignalType signalType, SignalService service){
public void deregisterServiceToSignal(SignalType signalType, SignalService service){
systemLock.acquireUninterruptibly();
LoggerInterface.loggerEngine.DEBUG("[SignalSystem] Deregister signal service " + service.getName());
if(typeServiceMap.containsKey(signalType)){

View File

@ -0,0 +1,18 @@
package electrosphere.engine.signal;
import electrosphere.engine.Globals;
/**
* Synchronously handles signals
*/
public class SynchronousSignalHandling {
/**
* Runs the main thread signal handlers
*/
public static void runMainThreadSignalHandlers(){
Globals.scriptEngine.handleAllSignals();
Globals.mainThreadSignalService.handleAllSignals();
}
}

View File

@ -0,0 +1,38 @@
package electrosphere.engine.signal.sync;
import electrosphere.engine.loadingthreads.MainMenuLoading;
import electrosphere.engine.signal.Signal;
import electrosphere.engine.signal.Signal.SignalType;
import electrosphere.engine.signal.SignalServiceImpl;
import electrosphere.logger.LoggerInterface;
public class MainThreadSignalService extends SignalServiceImpl {
/**
* Constructor
*/
public MainThreadSignalService() {
super(
"MainThreadSignalService",
new SignalType[]{
SignalType.ENGINE_RETURN_TO_TITLE,
}
);
}
@Override
public boolean handle(Signal signal){
boolean rVal = false;
switch(signal.getType()){
case ENGINE_RETURN_TO_TITLE: {
MainMenuLoading.returnToMainMenu(null);
rVal = true;
} break;
default: {
LoggerInterface.loggerEngine.WARNING("MainThreadSignalService received signal that it does not have handling for! " + signal);
} break;
}
return rVal;
}
}

View File

@ -112,7 +112,7 @@ public class ThreadManager {
Globals.server.close();
}
if(Globals.realmManager.getRealms() != null){
if(Globals.realmManager != null && Globals.realmManager.getRealms() != null){
for(Realm realm : Globals.realmManager.getRealms()){
if(realm.getServerWorldData() != null && realm.getServerWorldData().getServerTerrainManager() != null){
realm.getServerWorldData().getServerTerrainManager().closeThreads();

View File

@ -8,7 +8,6 @@ import electrosphere.net.parser.net.message.NetworkMessage;
import electrosphere.net.parser.net.message.ServerMessage;
import electrosphere.net.parser.net.raw.NetworkParser;
import electrosphere.net.server.player.Player;
import electrosphere.util.CodeUtils;
import java.io.IOException;
import java.io.InputStream;
@ -321,7 +320,7 @@ public class ServerConnectionHandler implements Runnable {
TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException ex) {
//silently ignore
CodeUtils.todo(ex, "Handle sleep interrupt on server connection");
// CodeUtils.todo(ex, "Handle sleep interrupt on server connection");
}
return rVal;
}

View File

@ -13,6 +13,7 @@ import org.joml.Vector2i;
import electrosphere.engine.Globals;
import electrosphere.engine.signal.Signal;
import electrosphere.engine.signal.Signal.SignalType;
import electrosphere.engine.signal.SignalServiceImpl;
import electrosphere.renderer.ui.elements.Window;
import electrosphere.renderer.ui.elementtypes.ContainerElement;
@ -39,7 +40,14 @@ public class ElementService extends SignalServiceImpl {
* Constructor
*/
public ElementService() {
super("ElementService");
super(
"ElementService",
new SignalType[]{
SignalType.YOGA_APPLY,
SignalType.YOGA_DESTROY,
SignalType.UI_MODIFICATION,
}
);
}
Map<String,Element> elementMap = new ConcurrentHashMap<String,Element>();

View File

@ -28,6 +28,7 @@ import electrosphere.client.ui.menu.tutorial.TutorialMenus;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.engine.signal.Signal;
import electrosphere.engine.signal.Signal.SignalType;
import electrosphere.engine.signal.SignalServiceImpl;
import electrosphere.logger.LoggerInterface;
import electrosphere.script.translation.JSServerUtils;
@ -134,7 +135,12 @@ public class ScriptEngine extends SignalServiceImpl {
* Constructor
*/
public ScriptEngine(){
super("ScriptEngine");
super(
"ScriptEngine",
new SignalType[]{
SignalType.SCRIPT_RECOMPILE,
}
);
sourceMap = new HashMap<String,Source>();
this.fs = FileSystems.getDefault();
try {

View File

@ -209,6 +209,11 @@ public class RealmManager {
* Resets the realm manager
*/
public void reset(){
for(Realm realm : this.realms){
if(realm.getServerWorldData() != null && realm.getServerWorldData().getServerTerrainManager() != null){
realm.getServerWorldData().getServerTerrainManager().closeThreads();
}
}
this.realms.clear();
this.entityToRealmMap.clear();
this.playerToRealmMap.clear();

View File

@ -36,7 +36,7 @@ public class SignalSystemTests {
SignalService service = Mockito.mock(SignalService.class);
signalSystem.registerService(SignalType.YOGA_APPLY, service);
signalSystem.registerServiceToSignal(SignalType.YOGA_APPLY, service);
}
@ -46,7 +46,7 @@ public class SignalSystemTests {
signalSystem.init();
SignalService service = Mockito.mock(SignalService.class);
signalSystem.registerService(SignalType.YOGA_APPLY, service);
signalSystem.registerServiceToSignal(SignalType.YOGA_APPLY, service);
signalSystem.post(SignalType.YOGA_APPLY);
@ -60,8 +60,8 @@ public class SignalSystemTests {
SignalService service = Mockito.mock(SignalService.class);
SignalService service2 = Mockito.mock(SignalService.class);
signalSystem.registerService(SignalType.YOGA_APPLY, service);
signalSystem.registerService(SignalType.YOGA_APPLY, service2);
signalSystem.registerServiceToSignal(SignalType.YOGA_APPLY, service);
signalSystem.registerServiceToSignal(SignalType.YOGA_APPLY, service2);
signalSystem.post(SignalType.YOGA_APPLY);
@ -77,9 +77,9 @@ public class SignalSystemTests {
SignalService service = Mockito.mock(SignalService.class);
SignalService service2 = Mockito.mock(SignalService.class);
SignalService service3 = Mockito.mock(SignalService.class);
signalSystem.registerService(SignalType.YOGA_APPLY, service);
signalSystem.registerService(SignalType.YOGA_APPLY, service2);
signalSystem.registerService(SignalType.ENGINE_SHUTDOWN, service3);
signalSystem.registerServiceToSignal(SignalType.YOGA_APPLY, service);
signalSystem.registerServiceToSignal(SignalType.YOGA_APPLY, service2);
signalSystem.registerServiceToSignal(SignalType.ENGINE_SHUTDOWN, service3);
signalSystem.post(SignalType.YOGA_APPLY);
@ -95,8 +95,8 @@ public class SignalSystemTests {
signalSystem.init();
SignalService service = Mockito.mock(SignalService.class);
signalSystem.registerService(SignalType.YOGA_APPLY, service);
signalSystem.deregisterService(SignalType.YOGA_APPLY, service);
signalSystem.registerServiceToSignal(SignalType.YOGA_APPLY, service);
signalSystem.deregisterServiceToSignal(SignalType.YOGA_APPLY, service);
signalSystem.post(SignalType.YOGA_APPLY);
Mockito.verify(service, Mockito.never()).post(signalCaptor.capture());

View File

@ -20,7 +20,7 @@ public class Assertions {
/**
* The threshold at which we say the colors are 'close enough'
*/
static final int COLOR_COMPARE_THRESHOLD = 3;
static final int COLOR_COMPARE_THRESHOLD = 4;
/**
* A very small number for comparisons