diff --git a/assets/Textures/default_texture_map.json b/assets/Textures/default_texture_map.json index b759c81a..a4fe4449 100644 --- a/assets/Textures/default_texture_map.json +++ b/assets/Textures/default_texture_map.json @@ -37,6 +37,13 @@ "isDefault": true } ], + "Models/basic/geometry/unitcylinder.glb": [ + { + "meshName" : "Cylinder", + "diffuse" : "/Textures/transparent_grey.png", + "isDefault": true + } + ], "Models/basic/geometry/unitcapsule.glb": [ { "meshName" : "Sphere", diff --git a/src/main/java/electrosphere/engine/Globals.java b/src/main/java/electrosphere/engine/Globals.java index 279dd208..718189a5 100644 --- a/src/main/java/electrosphere/engine/Globals.java +++ b/src/main/java/electrosphere/engine/Globals.java @@ -1,5 +1,7 @@ package electrosphere.engine; +import java.lang.management.ManagementFactory; + import java.util.ArrayList; import org.joml.Matrix4f; @@ -431,7 +433,15 @@ public class Globals { * Inits globals */ public static void initGlobals(){ + //initialize logging interfaces + LoggerInterface.initLoggers(); LoggerInterface.loggerStartup.INFO("Initialize global variables"); + //gets java pid of engine + if(Globals.javaPID == null){ + Globals.javaPID = ManagementFactory.getRuntimeMXBean().getName(); + } + //load user settings + UserSettings.loadUserSettings(); //timekeeper timekeeper = new Timekeeper(); threadManager = new ThreadManager(); @@ -503,6 +513,7 @@ 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); } @@ -634,6 +645,8 @@ public class Globals { Globals.clientScene = new Scene(); Globals.clientSceneWrapper = new ClientSceneWrapper(Globals.clientScene, new CollisionEngine()); Globals.clientSynchronizationManager = new ClientSynchronizationManager(); + Globals.server = null; + Globals.serverSynchronizationManager = new ServerSynchronizationManager(); if(Globals.realmManager != null){ Globals.realmManager.reset(); } @@ -649,12 +662,18 @@ public class Globals { Globals.assetManager = null; Globals.elementService = null; Globals.realmManager = null; - // - //Destroy services - if(Globals.serviceManager != null){ - Globals.serviceManager.destroy(); - } + Globals.clientSceneWrapper = null; + Globals.clientScene = null; + Globals.audioEngine = null; + Globals.renderingEngine = null; + Globals.signalSystem = null; Globals.serviceManager = null; + Globals.clientConnection = null; + Globals.clientSynchronizationManager = null; + Globals.server = null; + Globals.serverSynchronizationManager = null; + Globals.javaPID = null; + LoggerInterface.destroyLoggers(); } diff --git a/src/main/java/electrosphere/engine/Main.java b/src/main/java/electrosphere/engine/Main.java index d99a3664..aae16c1a 100644 --- a/src/main/java/electrosphere/engine/Main.java +++ b/src/main/java/electrosphere/engine/Main.java @@ -3,7 +3,6 @@ package electrosphere.engine; import static org.lwjgl.glfw.GLFW.glfwTerminate; import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose; -import java.lang.management.ManagementFactory; import java.util.concurrent.TimeUnit; import org.graalvm.polyglot.HostAccess.Export; @@ -19,7 +18,6 @@ import electrosphere.engine.loadingthreads.LoadingThread; import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType; import electrosphere.engine.threads.LabeledThread.ThreadLabel; import electrosphere.engine.time.Timekeeper; -import electrosphere.game.config.UserSettings; import electrosphere.game.server.world.MacroData; import electrosphere.logger.LoggerInterface; import electrosphere.menu.debug.ImGuiWindowMacros; @@ -85,15 +83,6 @@ public class Main { public static void startUp(String args[]){ //parse command line arguments CLIParser.parseCLIArgs(args); - - //initialize logging interfaces - LoggerInterface.initLoggers(); - - //gets java pid of engine - Globals.javaPID = ManagementFactory.getRuntimeMXBean().getName(); - - //load user settings - UserSettings.loadUserSettings(); //init global variables Globals.initGlobals(); @@ -172,7 +161,9 @@ public class Main { //Sets a hook that fires when the engine process stops Runtime.getRuntime().addShutdownHook(new Thread(() -> { - LoggerInterface.loggerEngine.INFO("Shutdown hook!"); + if(LoggerInterface.loggerEngine != null){ + LoggerInterface.loggerEngine.INFO("Shutdown hook!"); + } })); //uncomment to test loading a model into engine @@ -435,23 +426,24 @@ public class Main { * Shuts down the engine */ public static void shutdown(){ - LoggerInterface.loggerEngine.WARNING("ENGINE SHUTDOWN"); + if(LoggerInterface.loggerEngine != null){ + LoggerInterface.loggerEngine.INFO("ENGINE SHUTDOWN"); + } // // S H U T D O W N // //Terminate the program. - if(Globals.RUN_CLIENT){ + if(Globals.renderingEngine != null){ glfwTerminate(); Globals.renderingEngine.clearGlobalState(); + Globals.renderingEngine.destroy(); } //used to signal threads to stop if(Globals.threadManager != null){ Globals.threadManager.close(); } - //reset globals for good measure (making sure no long-running threads can re-inject entities into scenes) - Globals.resetGlobals(); //shut down audio engine - if(!Globals.HEADLESS && Globals.RUN_CLIENT && Globals.RUN_AUDIO && Globals.audioEngine != null && Globals.audioEngine.initialized()){ + if(Globals.audioEngine != null && Globals.audioEngine.initialized()){ Globals.audioEngine.shutdown(); } //if netmonitor is running, close @@ -463,6 +455,13 @@ public class Main { OdeHelper.closeODE(); initOde = false; } + // + //Destroy services + if(Globals.serviceManager != null){ + Globals.serviceManager.destroy(); + } + //reset globals for good measure (making sure no long-running threads can re-inject entities into scenes) + Globals.resetGlobals(); } static void sleep(int i) { diff --git a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java index 550c4b55..383ab5f8 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java @@ -86,16 +86,15 @@ public class ClientLoading { //make loading window disappear Globals.signalSystem.post(SignalType.UI_MODIFICATION, () -> { WindowUtils.recursiveSetVisible(WindowStrings.WINDOW_LOADING, false); + Globals.RENDER_FLAG_RENDER_SHADOW_MAP = true; + Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT = true; + Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER = true; + Globals.RENDER_FLAG_RENDER_UI = true; + Globals.RENDER_FLAG_RENDER_BLACK_BACKGROUND = false; + Globals.RENDER_FLAG_RENDER_WHITE_BACKGROUND = false; }); //recapture screen Globals.controlHandler.setRecapture(true); - //set rendering flags to main game mode - Globals.RENDER_FLAG_RENDER_SHADOW_MAP = true; - Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT = true; - Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER = true; - Globals.RENDER_FLAG_RENDER_UI = true; - Globals.RENDER_FLAG_RENDER_BLACK_BACKGROUND = false; - Globals.RENDER_FLAG_RENDER_WHITE_BACKGROUND = false; LoggerInterface.loggerEngine.INFO("[Client]Finished loading main game"); //set controls state Globals.controlHandler.hintUpdateControlState(ControlHandler.ControlsState.MAIN_GAME); @@ -129,16 +128,15 @@ public class ClientLoading { //make loading window disappear Globals.signalSystem.post(SignalType.UI_MODIFICATION, () -> { WindowUtils.recursiveSetVisible(WindowStrings.WINDOW_LOADING, false); + Globals.RENDER_FLAG_RENDER_SHADOW_MAP = true; + Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT = true; + Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER = true; + Globals.RENDER_FLAG_RENDER_UI = true; + Globals.RENDER_FLAG_RENDER_BLACK_BACKGROUND = false; + Globals.RENDER_FLAG_RENDER_WHITE_BACKGROUND = false; }); //recapture screen Globals.controlHandler.setRecapture(true); - //set rendering flags to main game mode - Globals.RENDER_FLAG_RENDER_SHADOW_MAP = true; - Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT = true; - Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER = true; - Globals.RENDER_FLAG_RENDER_UI = true; - Globals.RENDER_FLAG_RENDER_BLACK_BACKGROUND = false; - Globals.RENDER_FLAG_RENDER_WHITE_BACKGROUND = false; LoggerInterface.loggerEngine.INFO("[Client]Finished loading main game"); //set controls state Globals.controlHandler.hintUpdateControlState(ControlHandler.ControlsState.MAIN_GAME); diff --git a/src/main/java/electrosphere/engine/loadingthreads/DebugSPWorldLoading.java b/src/main/java/electrosphere/engine/loadingthreads/DebugSPWorldLoading.java index 40c3868a..15c7620c 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/DebugSPWorldLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/DebugSPWorldLoading.java @@ -4,6 +4,7 @@ import java.util.concurrent.TimeUnit; import electrosphere.auth.AuthenticationManager; import electrosphere.engine.Globals; +import electrosphere.engine.signal.Signal.SignalType; import electrosphere.entity.scene.SceneGenerator; import electrosphere.logger.LoggerInterface; import electrosphere.menu.MenuGenerators; @@ -18,11 +19,13 @@ public class DebugSPWorldLoading { protected static void loadDebugSPWorld(Object[] params){ - Window loadingWindow = (Window)Globals.elementService.getWindow(WindowStrings.WINDOW_LOADING); - //show loading - WindowUtils.recursiveSetVisible(Globals.elementService.getWindow(WindowStrings.WINDOW_MENU_MAIN), false); - WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu()); - loadingWindow.setVisible(true); + Globals.signalSystem.post(SignalType.UI_MODIFICATION, ()->{ + Window loadingWindow = (Window)Globals.elementService.getWindow(WindowStrings.WINDOW_LOADING); + //show loading + WindowUtils.recursiveSetVisible(Globals.elementService.getWindow(WindowStrings.WINDOW_MENU_MAIN), false); + WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu()); + loadingWindow.setVisible(true); + }); String saveName = "random_sp_world"; if(!SaveUtils.getSaves().contains(saveName)){ diff --git a/src/main/java/electrosphere/engine/loadingthreads/LevelEditorLoading.java b/src/main/java/electrosphere/engine/loadingthreads/LevelEditorLoading.java index 6fba09d5..0ef1b00b 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/LevelEditorLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/LevelEditorLoading.java @@ -4,6 +4,7 @@ import java.util.concurrent.TimeUnit; import electrosphere.auth.AuthenticationManager; import electrosphere.engine.Globals; +import electrosphere.engine.signal.Signal.SignalType; import electrosphere.entity.scene.SceneFile; import electrosphere.logger.LoggerInterface; import electrosphere.menu.MenuGenerators; @@ -53,11 +54,13 @@ public class LevelEditorLoading { Globals.aiManager.setActive(false); - Window loadingWindow = (Window)Globals.elementService.getWindow(WindowStrings.WINDOW_LOADING); - //show loading - WindowUtils.recursiveSetVisible(Globals.elementService.getWindow(WindowStrings.WINDOW_MENU_MAIN), false); - WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu()); - loadingWindow.setVisible(true); + Globals.signalSystem.post(SignalType.UI_MODIFICATION, ()->{ + Window loadingWindow = (Window)Globals.elementService.getWindow(WindowStrings.WINDOW_LOADING); + //show loading + WindowUtils.recursiveSetVisible(Globals.elementService.getWindow(WindowStrings.WINDOW_MENU_MAIN), false); + WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu()); + loadingWindow.setVisible(true); + }); if(!SaveUtils.getSaves().contains(saveName)){ //init save structure diff --git a/src/main/java/electrosphere/engine/loadingthreads/LevelLoading.java b/src/main/java/electrosphere/engine/loadingthreads/LevelLoading.java index 5a0332e4..a67c1455 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/LevelLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/LevelLoading.java @@ -4,6 +4,7 @@ import java.util.concurrent.TimeUnit; import electrosphere.auth.AuthenticationManager; import electrosphere.engine.Globals; +import electrosphere.engine.signal.Signal.SignalType; import electrosphere.logger.LoggerInterface; import electrosphere.menu.MenuGenerators; import electrosphere.menu.WindowStrings; @@ -27,11 +28,13 @@ public class LevelLoading { } String saveName = (String)params[0]; - Window loadingWindow = (Window)Globals.elementService.getWindow(WindowStrings.WINDOW_LOADING); - //show loading - WindowUtils.recursiveSetVisible(Globals.elementService.getWindow(WindowStrings.WINDOW_MENU_MAIN), false); - WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu()); - loadingWindow.setVisible(true); + Globals.signalSystem.post(SignalType.UI_MODIFICATION, ()->{ + Window loadingWindow = (Window)Globals.elementService.getWindow(WindowStrings.WINDOW_LOADING); + //show loading + WindowUtils.recursiveSetVisible(Globals.elementService.getWindow(WindowStrings.WINDOW_MENU_MAIN), false); + WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu()); + loadingWindow.setVisible(true); + }); //load save SaveUtils.loadSave(saveName, false); diff --git a/src/main/java/electrosphere/engine/loadingthreads/MainMenuLoading.java b/src/main/java/electrosphere/engine/loadingthreads/MainMenuLoading.java index dab3b9cf..541a268a 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/MainMenuLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/MainMenuLoading.java @@ -1,6 +1,7 @@ package electrosphere.engine.loadingthreads; import electrosphere.engine.Globals; +import electrosphere.engine.signal.Signal.SignalType; import electrosphere.engine.threads.LabeledThread.ThreadLabel; import electrosphere.menu.WindowStrings; import electrosphere.menu.WindowUtils; @@ -37,7 +38,9 @@ public class MainMenuLoading { // //reveal in game main menu - WindowUtils.closeWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN); + Globals.signalSystem.post(SignalType.UI_MODIFICATION, ()->{ + WindowUtils.closeWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN); + }); MainMenuLoading.loadMainMenu(params); } @@ -65,16 +68,18 @@ public class MainMenuLoading { * @param params Params (this thread type does not accept any) */ protected static void loadMainMenu(Object[] params){ - Window loadingWindow = (Window)Globals.elementService.getWindow(WindowStrings.WINDOW_LOADING); - if(loadingWindow != null){ - WindowUtils.recursiveSetVisible(loadingWindow,false); - } - WindowUtils.focusWindow(WindowStrings.WINDOW_MENU_MAIN); - Window mainMenuWindow = (Window)Globals.elementService.getWindow(WindowStrings.WINDOW_MENU_MAIN); - WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu()); - if(mainMenuWindow != null){ - WindowUtils.recursiveSetVisible(mainMenuWindow, true); - } + Globals.signalSystem.post(SignalType.UI_MODIFICATION, ()->{ + Window loadingWindow = (Window)Globals.elementService.getWindow(WindowStrings.WINDOW_LOADING); + if(loadingWindow != null){ + WindowUtils.recursiveSetVisible(loadingWindow,false); + } + WindowUtils.focusWindow(WindowStrings.WINDOW_MENU_MAIN); + Window mainMenuWindow = (Window)Globals.elementService.getWindow(WindowStrings.WINDOW_MENU_MAIN); + WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu()); + if(mainMenuWindow != null){ + WindowUtils.recursiveSetVisible(mainMenuWindow, true); + } + }); } } diff --git a/src/main/java/electrosphere/engine/loadingthreads/ViewportLoading.java b/src/main/java/electrosphere/engine/loadingthreads/ViewportLoading.java index a618c031..685b7d7e 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/ViewportLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/ViewportLoading.java @@ -6,6 +6,7 @@ import org.joml.Vector3d; import electrosphere.auth.AuthenticationManager; import electrosphere.engine.Globals; +import electrosphere.engine.signal.Signal.SignalType; import electrosphere.logger.LoggerInterface; import electrosphere.menu.MenuGenerators; import electrosphere.menu.WindowStrings; @@ -26,10 +27,12 @@ public class ViewportLoading { protected static void loadViewport(Object[] params){ // //show loading - Window loadingWindow = (Window)Globals.elementService.getWindow(WindowStrings.WINDOW_LOADING); - WindowUtils.recursiveSetVisible(Globals.elementService.getWindow(WindowStrings.WINDOW_MENU_MAIN), false); - WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu()); - loadingWindow.setVisible(true); + Globals.signalSystem.post(SignalType.UI_MODIFICATION, ()->{ + Window loadingWindow = (Window)Globals.elementService.getWindow(WindowStrings.WINDOW_LOADING); + WindowUtils.recursiveSetVisible(Globals.elementService.getWindow(WindowStrings.WINDOW_MENU_MAIN), false); + WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu()); + loadingWindow.setVisible(true); + }); // //init realm manager with viewport realm diff --git a/src/main/java/electrosphere/engine/signal/SignalServiceImpl.java b/src/main/java/electrosphere/engine/signal/SignalServiceImpl.java index 101c0f16..d0f276b9 100644 --- a/src/main/java/electrosphere/engine/signal/SignalServiceImpl.java +++ b/src/main/java/electrosphere/engine/signal/SignalServiceImpl.java @@ -88,6 +88,18 @@ public class SignalServiceImpl implements SignalService { } } + /** + * Gets the number of signals that are queued for handling + * @return The number of signals + */ + public int getSignalQueueCount(){ + int rVal = 0; + this.threadLock.acquireUninterruptibly(); + rVal = signals.size(); + this.threadLock.release(); + return rVal; + } + /** * Handles a signal * @param signal The signal diff --git a/src/main/java/electrosphere/entity/Scene.java b/src/main/java/electrosphere/entity/Scene.java index 4d63ffc5..f9583ed3 100644 --- a/src/main/java/electrosphere/entity/Scene.java +++ b/src/main/java/electrosphere/entity/Scene.java @@ -18,13 +18,16 @@ import java.util.concurrent.CopyOnWriteArraySet; public class Scene { - Map entityIdMap = new ConcurrentHashMap(); - Map> tagEntityMap = new ConcurrentHashMap>(); + Map entityIdMap; + Map> tagEntityMap; List entityList = new CopyOnWriteArrayList(); - List behaviorTreeList = new CopyOnWriteArrayList(); + List behaviorTreeList; public Scene(){ + entityIdMap = new ConcurrentHashMap(); + tagEntityMap = new ConcurrentHashMap>(); + behaviorTreeList = new CopyOnWriteArrayList(); tagEntityMap.put(EntityTags.BONE_ATTACHED, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.COLLIDABLE, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.SPRINTABLE, new CopyOnWriteArraySet()); diff --git a/src/main/java/electrosphere/game/config/UserSettings.java b/src/main/java/electrosphere/game/config/UserSettings.java index 47344a6f..d761ca5b 100644 --- a/src/main/java/electrosphere/game/config/UserSettings.java +++ b/src/main/java/electrosphere/game/config/UserSettings.java @@ -207,14 +207,16 @@ public class UserSettings { public static void loadUserSettings(){ - LoggerInterface.loggerStartup.INFO("Load user settings"); - Globals.userSettings = FileUtils.loadObjectFromAssetPath("/Config/settings.json", UserSettings.class); if(Globals.userSettings == null){ - Globals.userSettings = getDefault(); + LoggerInterface.loggerStartup.INFO("Load user settings"); + Globals.userSettings = FileUtils.loadObjectFromAssetPath("/Config/settings.json", UserSettings.class); + if(Globals.userSettings == null){ + Globals.userSettings = getDefault(); + } + Globals.WINDOW_WIDTH = Globals.userSettings.displayWidth; + Globals.WINDOW_HEIGHT = Globals.userSettings.displayHeight; + Globals.verticalFOV = Globals.userSettings.graphicsFOV; } - Globals.WINDOW_WIDTH = Globals.userSettings.displayWidth; - Globals.WINDOW_HEIGHT = Globals.userSettings.displayHeight; - Globals.verticalFOV = Globals.userSettings.graphicsFOV; } diff --git a/src/main/java/electrosphere/logger/LoggerInterface.java b/src/main/java/electrosphere/logger/LoggerInterface.java index f031a785..6eaa17df 100644 --- a/src/main/java/electrosphere/logger/LoggerInterface.java +++ b/src/main/java/electrosphere/logger/LoggerInterface.java @@ -47,6 +47,24 @@ public class LoggerInterface { loggerStartup.INFO("Initialized loggers"); } + /** + * Destroys all loggers + */ + public static void destroyLoggers(){ + loggerNetworking = null; + loggerFileIO = null; + loggerGameLogic = null; + loggerRenderer = null; + loggerEngine = null; + loggerStartup = null; + loggerAuth = null; + loggerDB = null; + loggerAudio = null; + loggerUI = null; + loggerScripts = null; + loggerAI = null; + } + /** * Gets the list of all loggers * @return The list of all loggers diff --git a/src/main/java/electrosphere/menu/WindowUtils.java b/src/main/java/electrosphere/menu/WindowUtils.java index 42ec3634..5d8ad715 100644 --- a/src/main/java/electrosphere/menu/WindowUtils.java +++ b/src/main/java/electrosphere/menu/WindowUtils.java @@ -78,6 +78,18 @@ public class WindowUtils { return false; } + /** + * Checks if the window element is visible + * @param windowElement The window element + * @return true if is visible, false otherwise + */ + public static boolean windowIsVisible(Element windowElement){ + if(windowElement instanceof DrawableElement){ + return ((DrawableElement)windowElement).getVisible(); + } + return false; + } + /** * Checks whether the window registered to the provided string is open * @param windowString The window string diff --git a/src/main/java/electrosphere/net/client/ClientNetworking.java b/src/main/java/electrosphere/net/client/ClientNetworking.java index 4ab49e9a..71f92f32 100644 --- a/src/main/java/electrosphere/net/client/ClientNetworking.java +++ b/src/main/java/electrosphere/net/client/ClientNetworking.java @@ -211,7 +211,7 @@ public class ClientNetworking implements Runnable { } } - LoggerInterface.loggerNetworking.WARNING("Client networking thread ended"); + LoggerInterface.loggerNetworking.INFO("Client networking thread ended"); } diff --git a/src/main/java/electrosphere/net/server/Server.java b/src/main/java/electrosphere/net/server/Server.java index 5ea0d7b5..0458673e 100644 --- a/src/main/java/electrosphere/net/server/Server.java +++ b/src/main/java/electrosphere/net/server/Server.java @@ -98,7 +98,7 @@ public class Server implements Runnable { } } this.isOpen = false; - LoggerInterface.loggerNetworking.WARNING("Server socket thread ended"); + LoggerInterface.loggerNetworking.INFO("Server socket thread ended"); } /** diff --git a/src/main/java/electrosphere/net/server/ServerConnectionHandler.java b/src/main/java/electrosphere/net/server/ServerConnectionHandler.java index 305aa1a5..f4d6ea82 100644 --- a/src/main/java/electrosphere/net/server/ServerConnectionHandler.java +++ b/src/main/java/electrosphere/net/server/ServerConnectionHandler.java @@ -244,7 +244,7 @@ public class ServerConnectionHandler implements Runnable { } } - LoggerInterface.loggerNetworking.WARNING("Server connection thread ended"); + LoggerInterface.loggerNetworking.INFO("Server connection thread ended"); } /** diff --git a/src/main/java/electrosphere/renderer/RenderingEngine.java b/src/main/java/electrosphere/renderer/RenderingEngine.java index aed6de28..36d18a9a 100644 --- a/src/main/java/electrosphere/renderer/RenderingEngine.java +++ b/src/main/java/electrosphere/renderer/RenderingEngine.java @@ -667,6 +667,13 @@ public class RenderingEngine { return rVal; } + /** + * Destroys the rendering engine + */ + public void destroy(){ + + } + /** * Checks for any errors currently caught by OpenGL. * Refer: https://docs.gl/gl4/glGetError diff --git a/src/main/java/electrosphere/renderer/ui/elements/Window.java b/src/main/java/electrosphere/renderer/ui/elements/Window.java index 2fd84ca2..fc7f89df 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Window.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Window.java @@ -361,6 +361,20 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme @Override public void applyYoga(int parentX, int parentY) { if(this.yogaNode != Element.NULL_YOGA_ELEMENT && parentWindowYogaNode != Element.NULL_YOGA_ELEMENT){ + if( + Globals.WINDOW_WIDTH <= 0 || + Globals.WINDOW_HEIGHT <= 0 || + width <= 0 || + height <= 0 + ){ + String message = "Window has invalid dimensions!\n" + + "Globals.WINDOW_WIDTH: " + Globals.WINDOW_WIDTH + "\n" + + "Globals.WINDOW_HEIGHT: " + Globals.WINDOW_HEIGHT + "\n" + + "width: " + width + "\n" + + "height: " + height + "\n" + ; + throw new IllegalStateException(message); + } Yoga.YGNodeStyleSetWidth(parentWindowYogaNode, Globals.WINDOW_WIDTH); Yoga.YGNodeStyleSetHeight(parentWindowYogaNode, Globals.WINDOW_HEIGHT); //calculate yoga layout @@ -370,7 +384,7 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode); float widthRaw = Yoga.YGNodeLayoutGetWidth(yogaNode); float heightRaw = Yoga.YGNodeLayoutGetHeight(yogaNode); - // //apply the values to this component + //apply the values to this component this.positionX = (int)leftRaw; this.positionY = (int)topRaw; this.width = (int)widthRaw; diff --git a/src/test/java/electrosphere/engine/GlobalsTests.java b/src/test/java/electrosphere/engine/GlobalsTests.java index 3bceca6d..4b1911a8 100644 --- a/src/test/java/electrosphere/engine/GlobalsTests.java +++ b/src/test/java/electrosphere/engine/GlobalsTests.java @@ -2,8 +2,6 @@ package electrosphere.engine; import static org.junit.jupiter.api.Assertions.*; -import electrosphere.game.config.UserSettings; -import electrosphere.logger.LoggerInterface; import electrosphere.test.annotations.IntegrationTest; /** @@ -13,8 +11,6 @@ public class GlobalsTests { @IntegrationTest public void resetGlobals_Variables_null(){ - LoggerInterface.initLoggers(); - UserSettings.loadUserSettings(); Globals.initGlobals(); Globals.resetGlobals(); assertNull(Globals.assetManager); @@ -30,8 +26,6 @@ public class GlobalsTests { @IntegrationTest public void unloadScene_Variables_notNull(){ - LoggerInterface.initLoggers(); - UserSettings.loadUserSettings(); Globals.initGlobals(); Globals.unloadScene(); assertNotNull(Globals.assetManager); diff --git a/src/test/java/electrosphere/engine/loadingthreads/ViewportLoadingTests.java b/src/test/java/electrosphere/engine/loadingthreads/ViewportLoadingTests.java index 8da6cde7..6a14b2a6 100644 --- a/src/test/java/electrosphere/engine/loadingthreads/ViewportLoadingTests.java +++ b/src/test/java/electrosphere/engine/loadingthreads/ViewportLoadingTests.java @@ -9,6 +9,7 @@ import electrosphere.engine.Globals; import electrosphere.engine.Main; import electrosphere.menu.WindowStrings; import electrosphere.menu.WindowUtils; +import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.test.testutils.EngineInit; /** @@ -44,7 +45,9 @@ public class ViewportLoadingTests { EngineInit.setupConnectedTestViewport(); //should see viewport here - assertEquals(false,WindowUtils.windowIsVisible(WindowStrings.WINDOW_MENU_MAIN)); + for(Element window : Globals.elementService.getWindowList()){ + assertEquals(false,WindowUtils.windowIsVisible(window)); + } } @IntegrationTest diff --git a/src/test/java/electrosphere/entity/state/movement/fall/ServerFallTreeTests.java b/src/test/java/electrosphere/entity/state/movement/fall/ServerFallTreeTests.java index afa68c01..7f47c0f7 100644 --- a/src/test/java/electrosphere/entity/state/movement/fall/ServerFallTreeTests.java +++ b/src/test/java/electrosphere/entity/state/movement/fall/ServerFallTreeTests.java @@ -53,6 +53,7 @@ public class ServerFallTreeTests extends EntityTestTemplate { //make sure we're in in the air TestEngineUtils.simulateFrames(3); + assertEventually(() -> { return !serverFallTree.isFalling(); }); diff --git a/src/test/java/electrosphere/menu/WindowUtilsTests.java b/src/test/java/electrosphere/menu/WindowUtilsTests.java new file mode 100644 index 00000000..1cb6a3c1 --- /dev/null +++ b/src/test/java/electrosphere/menu/WindowUtilsTests.java @@ -0,0 +1,119 @@ +package electrosphere.menu; + +import static org.junit.jupiter.api.Assertions.*; + +import electrosphere.engine.Globals; +import electrosphere.logger.LoggerInterface; +import electrosphere.renderer.ui.ElementService; +import electrosphere.renderer.ui.elements.Div; +import electrosphere.test.annotations.UnitTest; + +/** + * Tests for the window utils + */ +public class WindowUtilsTests { + + @UnitTest + public void closeWindow_ValidWindow_NotVisible(){ + String someWindowString = "test"; + LoggerInterface.initLoggers(); + Globals.elementService = new ElementService(); + Globals.elementService.init(); + Globals.elementService.registerWindow(someWindowString, Div.createDiv()); + + WindowUtils.closeWindow(someWindowString); + + assertEquals(false,WindowUtils.windowIsVisible(someWindowString)); + } + + @UnitTest + public void closeWindow_ValidWindow_NotRegistered(){ + String someWindowString = "test"; + LoggerInterface.initLoggers(); + Globals.elementService = new ElementService(); + Globals.elementService.init(); + Globals.elementService.registerWindow(someWindowString, Div.createDiv()); + + WindowUtils.closeWindow(someWindowString); + + assertNull(Globals.elementService.getWindow(someWindowString)); + } + + @UnitTest + public void closeWindow_ValidWindowAfterGlobalsReinit_NoThrow(){ + assertDoesNotThrow(()->{ + //setup + String someWindowString = "test"; + Globals.initGlobals(); + Globals.elementService.registerWindow(someWindowString, Div.createDiv()); + + //close + WindowUtils.closeWindow(someWindowString); + + //reinit globals + Globals.resetGlobals(); + Globals.initGlobals(); + }); + } + + @UnitTest + public void closeWindow_ValidWindowAfterGlobalsReinit_NotRegistered(){ + //setup + String someWindowString = "test"; + Globals.initGlobals(); + Globals.elementService.registerWindow(someWindowString, Div.createDiv()); + + //close + WindowUtils.closeWindow(someWindowString); + + //reinit globals + Globals.resetGlobals(); + Globals.initGlobals(); + + assertNull(Globals.elementService.getWindow(someWindowString)); + } + + @UnitTest + public void closeWindow_ValidWindowAfterGlobalsReinit_ElementServiceZeroChildren(){ + //setup + String someWindowString = "test"; + Globals.initGlobals(); + Globals.elementService.registerWindow(someWindowString, Div.createDiv()); + + //close + WindowUtils.closeWindow(someWindowString); + + // reinit globals + Globals.resetGlobals(); + Globals.initGlobals(); + + assertEquals(0,Globals.elementService.getWindowList().size()); + } + + // @UnitTest + // public void setVisible_ValidWindowToFalseAfterGlobalsReinit_False(){ + // //setup + // String someWindowString = "test"; + // Globals.initGlobals(); + // Globals.elementService.registerWindow(someWindowString, Div.createDiv()); + + // //visibility toggle + // WindowUtils.recursiveSetVisible(someWindowString,true); + // WindowUtils.recursiveSetVisible(someWindowString,false); + + // //reinit globals + // Globals.resetGlobals(); + // Globals.initGlobals(); + + // //register again + // Globals.initGlobals(); + // Globals.elementService.registerWindow(someWindowString, Div.createDiv()); + + // //visibility toggle + // WindowUtils.recursiveSetVisible(someWindowString,true); + // WindowUtils.recursiveSetVisible(someWindowString,false); + + // assertNull(!WindowUtils.windowIsVisible(someWindowString)); + // } + +} diff --git a/src/test/java/electrosphere/test/template/EntityTestTemplate.java b/src/test/java/electrosphere/test/template/EntityTestTemplate.java index 96c5bc8b..a8851d75 100644 --- a/src/test/java/electrosphere/test/template/EntityTestTemplate.java +++ b/src/test/java/electrosphere/test/template/EntityTestTemplate.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.extension.ExtendWith; import electrosphere.test.template.extensions.EntityExtension; +import electrosphere.test.template.extensions.StateCleanupCheckerExtension; /** * Template for writing tests that do stuff with entities in a proper scene @@ -11,6 +12,7 @@ import electrosphere.test.template.extensions.EntityExtension; @Tag("integration") @Tag("graphical") @Tag("entity") +@ExtendWith(StateCleanupCheckerExtension.class) @ExtendWith(EntityExtension.class) public class EntityTestTemplate { diff --git a/src/test/java/electrosphere/test/template/RenderingTestTemplate.java b/src/test/java/electrosphere/test/template/RenderingTestTemplate.java index b7651eb7..5081b803 100644 --- a/src/test/java/electrosphere/test/template/RenderingTestTemplate.java +++ b/src/test/java/electrosphere/test/template/RenderingTestTemplate.java @@ -6,6 +6,8 @@ import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.extension.ExtendWith; import electrosphere.test.template.extensions.RenderingExtension; +import electrosphere.test.template.extensions.StateCleanupCheckerExtension; + import static electrosphere.test.testutils.Assertions.*; import electrosphere.test.testutils.TestRenderingUtils; @@ -14,6 +16,7 @@ import electrosphere.test.testutils.TestRenderingUtils; */ @Tag("integration") @Tag("graphical") +@ExtendWith(StateCleanupCheckerExtension.class) @ExtendWith(RenderingExtension.class) public class RenderingTestTemplate { diff --git a/src/test/java/electrosphere/test/template/extensions/StateCleanupCheckerExtension.java b/src/test/java/electrosphere/test/template/extensions/StateCleanupCheckerExtension.java new file mode 100644 index 00000000..75b8b1bd --- /dev/null +++ b/src/test/java/electrosphere/test/template/extensions/StateCleanupCheckerExtension.java @@ -0,0 +1,39 @@ +package electrosphere.test.template.extensions; + +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; + +import electrosphere.engine.Globals; +import electrosphere.logger.LoggerInterface; +import electrosphere.renderer.RenderingEngine; + +/** + * Checks to make sure state has been properly reset. Must be the FIRST declared extension to work properly + */ +public class StateCleanupCheckerExtension implements AfterEachCallback { + + @Override + public void afterEach(ExtensionContext context) throws Exception { + Object[] objectsToCheck = new Object[]{ + Globals.realmManager, + Globals.clientSceneWrapper, + Globals.clientScene, + Globals.signalSystem, + Globals.renderingEngine, + Globals.audioEngine, + Globals.javaPID, + Globals.clientConnection, + Globals.clientSynchronizationManager, + Globals.server, + Globals.serverSynchronizationManager, + LoggerInterface.loggerEngine, + RenderingEngine.screenFramebuffer, + }; + for(Object object : objectsToCheck){ + if(object != null){ + throw new Exception("Failed to cleanup state after test! " + object.toString()); + } + } + } + +} diff --git a/src/test/java/electrosphere/test/testutils/EngineInit.java b/src/test/java/electrosphere/test/testutils/EngineInit.java index 02e93fd9..ad3b5986 100644 --- a/src/test/java/electrosphere/test/testutils/EngineInit.java +++ b/src/test/java/electrosphere/test/testutils/EngineInit.java @@ -2,12 +2,16 @@ package electrosphere.test.testutils; import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.Assertions; + import electrosphere.engine.Globals; import electrosphere.engine.Main; import electrosphere.engine.loadingthreads.LoadingThread; import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType; import electrosphere.engine.profiler.Profiler; import electrosphere.net.NetUtils; +import electrosphere.renderer.ui.elementtypes.DrawableElement; +import electrosphere.renderer.ui.elementtypes.Element; public class EngineInit { @@ -67,7 +71,7 @@ public class EngineInit { for(LoadingThread thread : Globals.threadManager.getLoadingThreads()){ errorMessage = errorMessage + thread.getType() + "\n"; } - throw new IllegalStateException(errorMessage); + Assertions.fail("Failed to startup"); } } } @@ -99,9 +103,11 @@ public class EngineInit { for(LoadingThread thread : Globals.threadManager.getLoadingThreads()){ errorMessage = errorMessage + thread.getType() + "\n"; } - throw new IllegalStateException(errorMessage); + Assertions.fail("Failed to startup"); } } + + TestEngineUtils.flush(); } } diff --git a/src/test/java/electrosphere/test/testutils/TestEngineUtils.java b/src/test/java/electrosphere/test/testutils/TestEngineUtils.java index d8d1c218..018f27c6 100644 --- a/src/test/java/electrosphere/test/testutils/TestEngineUtils.java +++ b/src/test/java/electrosphere/test/testutils/TestEngineUtils.java @@ -83,4 +83,15 @@ public class TestEngineUtils { waitForCondition(test,100); } + /** + * Flushes any signals that haven't been processed yet + */ + public static void flush(){ + while( + Globals.elementService.getSignalQueueCount() > 0 + ){ + Globals.elementService.handleAllSignals(); + } + } + }