diff --git a/src/main/java/electrosphere/engine/Globals.java b/src/main/java/electrosphere/engine/Globals.java index 7d0922ea..f26797a8 100644 --- a/src/main/java/electrosphere/engine/Globals.java +++ b/src/main/java/electrosphere/engine/Globals.java @@ -623,9 +623,9 @@ public class Globals { } /** - * Resets global values + * Unloads scene */ - public static void resetGlobals(){ + public static void unloadScene(){ Globals.playerEntity = null; Globals.playerCamera = null; Globals.firstPersonEntity = null; @@ -635,6 +635,15 @@ public class Globals { Globals.clientSceneWrapper = new ClientSceneWrapper(Globals.clientScene, new CollisionEngine()); Globals.clientSynchronizationManager = new ClientSynchronizationManager(); Globals.realmManager = null; + } + + /** + * Resets global values + */ + public static void resetGlobals(){ + Globals.unloadScene(); + // + //Actual globals to destroy Globals.assetManager = null; // //Destroy services diff --git a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java index a4c0845f..70c404e3 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java @@ -103,8 +103,8 @@ public class ClientLoading { */ protected static void loadViewport(Object[] params){ Window loadingWindow = (Window)Globals.elementService.getWindow(WindowStrings.WINDOW_LOADING); - WindowUtils.recursiveSetVisible(Globals.elementService.getWindow(WindowStrings.WINDOW_MENU_MAIN), false); WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu()); + WindowUtils.recursiveSetVisible(Globals.elementService.getWindow(WindowStrings.WINDOW_MENU_MAIN), false); loadingWindow.setVisible(true); //disable menu input Globals.controlHandler.hintUpdateControlState(ControlHandler.ControlsState.NO_INPUT); diff --git a/src/main/java/electrosphere/engine/loadingthreads/LoadingThread.java b/src/main/java/electrosphere/engine/loadingthreads/LoadingThread.java index 2f111286..25a91c3d 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/LoadingThread.java +++ b/src/main/java/electrosphere/engine/loadingthreads/LoadingThread.java @@ -90,61 +90,70 @@ public class LoadingThread extends Thread { @Override public void run(){ - switch(threadType){ + execSync(this.threadType, this.params); + isDone = true; + } + + /** + * Executes a loading task in the current thread + * @param type The type of loading task + * @param params The params for the loading task + */ + public static void execSync(LoadingThreadType type, Object ... params){ + switch(type){ case TITLE_MENU: { - MainMenuLoading.loadMainMenu(this.params); + MainMenuLoading.loadMainMenu(params); } break; case RETURN_TITLE_MENU: { - MainMenuLoading.returnToMainMenu(this.params); + MainMenuLoading.returnToMainMenu(params); } break; case MAIN_GAME: { - ServerLoading.loadMainGameServer(this.params); + ServerLoading.loadMainGameServer(params); } break; case CHARACTER_SERVER: { - ClientLoading.loadCharacterServer(this.params); + ClientLoading.loadCharacterServer(params); } break; case CLIENT_WORLD: { - ClientLoading.loadClientWorld(this.params); + ClientLoading.loadClientWorld(params); } break; //intended to act like you went through the steps of setting up a vanilla settings SP world case DEBUG_RANDOM_SP_WORLD: { - DebugSPWorldLoading.loadDebugSPWorld(this.params); + DebugSPWorldLoading.loadDebugSPWorld(params); } break; //loads the level editor case LEVEL_EDITOR: { - LevelEditorLoading.loadLevelEditor(this.params); + LevelEditorLoading.loadLevelEditor(params); } break; //loads the save in Globals.currentSave as a level case LEVEL: { - LevelLoading.loadLevel(this.params); + LevelLoading.loadLevel(params); } break; //the demo menu ui case DEMO_MENU: { - DemoLoading.loadDemoMenu(this.params); + DemoLoading.loadDemoMenu(params); } break; //Inits the script engine case SCRIPT_ENGINE: { - EngineInitLoading.loadScriptingEngine(this.params); + EngineInitLoading.loadScriptingEngine(params); } break; //Loads the viewport case LOAD_VIEWPORT: { - ViewportLoading.loadViewport(this.params); + ViewportLoading.loadViewport(params); } break; } - isDone = true; } /** diff --git a/src/main/java/electrosphere/engine/loadingthreads/MainMenuLoading.java b/src/main/java/electrosphere/engine/loadingthreads/MainMenuLoading.java index e121e460..dab3b9cf 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/MainMenuLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/MainMenuLoading.java @@ -31,7 +31,7 @@ public class MainMenuLoading { //reset state MainMenuLoading.resetClientState(); MainMenuLoading.resetServerState(); - Globals.resetGlobals(); + Globals.unloadScene(); Globals.threadManager.interruptLabel(ThreadLabel.NETWORKING_CLIENT); Globals.threadManager.interruptLabel(ThreadLabel.NETWORKING_SERVER); diff --git a/src/main/java/electrosphere/menu/WindowUtils.java b/src/main/java/electrosphere/menu/WindowUtils.java index b20b53f2..f426177c 100644 --- a/src/main/java/electrosphere/menu/WindowUtils.java +++ b/src/main/java/electrosphere/menu/WindowUtils.java @@ -56,6 +56,19 @@ public class WindowUtils { } } + /** + * Checks if the window string is visible + * @param windowString The window string + * @return true if is visible, false otherwise + */ + public static boolean windowIsVisible(String windowString){ + Element windowElement = Globals.elementService.getWindow(windowString); + 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/test/java/electrosphere/engine/loadingthreads/MainMenuLoadingTests.java b/src/test/java/electrosphere/engine/loadingthreads/MainMenuLoadingTests.java new file mode 100644 index 00000000..5eae8e72 --- /dev/null +++ b/src/test/java/electrosphere/engine/loadingthreads/MainMenuLoadingTests.java @@ -0,0 +1,40 @@ +package electrosphere.engine.loadingthreads; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +import org.junit.jupiter.api.AfterEach; + +import electrosphere.engine.Main; +import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType; +import electrosphere.test.annotations.IntegrationTest; +import electrosphere.test.testutils.EngineInit; +import electrosphere.test.testutils.TestEngineUtils; + +/** + * Tests (re)loading the main menu + */ +public class MainMenuLoadingTests { + + @AfterEach + public void clearTest(){ + Main.shutdown(); + } + + @IntegrationTest + public void testBackout_ThrowsError_False(){ + //init engine + EngineInit.initGraphicalEngine(); + + //load viewport + EngineInit.setupConnectedTestViewport(); + + //make sure backout doesn't crash + assertDoesNotThrow(()->{ + LoadingThread.execSync(LoadingThreadType.RETURN_TITLE_MENU); + + //guarantees the engine can continue to execute after the thread resolves) + TestEngineUtils.simulateFrames(1); + }); + } + +} diff --git a/src/test/java/electrosphere/engine/loadingthreads/ViewportLoadingTests.java b/src/test/java/electrosphere/engine/loadingthreads/ViewportLoadingTests.java index 13d38fa8..8da6cde7 100644 --- a/src/test/java/electrosphere/engine/loadingthreads/ViewportLoadingTests.java +++ b/src/test/java/electrosphere/engine/loadingthreads/ViewportLoadingTests.java @@ -1,22 +1,31 @@ package electrosphere.engine.loadingthreads; -import org.junit.jupiter.api.Assertions; +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.AfterEach; import electrosphere.test.annotations.IntegrationTest; +import electrosphere.engine.Globals; import electrosphere.engine.Main; +import electrosphere.menu.WindowStrings; +import electrosphere.menu.WindowUtils; import electrosphere.test.testutils.EngineInit; -import electrosphere.test.testutils.TestEngineUtils; /** * Tests loading viewport */ public class ViewportLoadingTests { + + @AfterEach + public void clearTest(){ + Main.shutdown(); + } @IntegrationTest - public void testViewportLoading(){ - Assertions.assertDoesNotThrow(() -> { + public void testViewportLoading_ThrowsError_False(){ + assertDoesNotThrow(() -> { //init engine - TestEngineUtils.initGraphicalEngine(); + EngineInit.initGraphicalEngine(); //load scene EngineInit.setupConnectedTestViewport(); @@ -26,4 +35,98 @@ public class ViewportLoadingTests { }); } + @IntegrationTest + public void testViewportLoading_MainMenuVisible_False(){ + //init engine + EngineInit.initGraphicalEngine(); + + //load scene + EngineInit.setupConnectedTestViewport(); + + //should see viewport here + assertEquals(false,WindowUtils.windowIsVisible(WindowStrings.WINDOW_MENU_MAIN)); + } + + @IntegrationTest + public void testViewportLoadingTwice_MainMenuVisible_False(){ + //init engine once + + //init engine + EngineInit.initGraphicalEngine(); + + //load scene + EngineInit.setupConnectedTestViewport(); + + //should see viewport here + + //shutdown engine + Main.shutdown(); + + //init engine second time + + //init engine + EngineInit.initGraphicalEngine(); + + //load scene + EngineInit.setupConnectedTestViewport(); + + //should still see viewport here + assertEquals(false,WindowUtils.windowIsVisible(WindowStrings.WINDOW_MENU_MAIN)); + } + + @IntegrationTest + public void testViewportLoadingTwice_LoadingMenuVisible_False(){ + //init engine once + + //init engine + EngineInit.initGraphicalEngine(); + + //load scene + EngineInit.setupConnectedTestViewport(); + + //should see viewport here + + //shutdown engine + Main.shutdown(); + + //init engine second time + + //init engine + EngineInit.initGraphicalEngine(); + + //load scene + EngineInit.setupConnectedTestViewport(); + + //should still see viewport here + assertEquals(false,WindowUtils.windowIsVisible(WindowStrings.WINDOW_LOADING)); + } + + @IntegrationTest + public void testViewportLoadingTwice_ScreenFramebufferFlags_True(){ + //init engine once + + //init engine + EngineInit.initGraphicalEngine(); + + //load scene + EngineInit.setupConnectedTestViewport(); + + //should see viewport here + + //shutdown engine + Main.shutdown(); + + //init engine second time + + //init engine + EngineInit.initGraphicalEngine(); + + //load scene + EngineInit.setupConnectedTestViewport(); + + //should still see viewport here + assertEquals(true,Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER); + assertEquals(true,Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT); + } + } diff --git a/src/test/java/electrosphere/test/template/extensions/EntityExtension.java b/src/test/java/electrosphere/test/template/extensions/EntityExtension.java index f1651043..124dcf4e 100644 --- a/src/test/java/electrosphere/test/template/extensions/EntityExtension.java +++ b/src/test/java/electrosphere/test/template/extensions/EntityExtension.java @@ -6,7 +6,6 @@ import org.junit.jupiter.api.extension.ExtensionContext; import electrosphere.engine.Main; import electrosphere.test.testutils.EngineInit; -import electrosphere.test.testutils.TestEngineUtils; /** * Spins up and tears down entity testing environment @@ -16,7 +15,7 @@ public class EntityExtension implements BeforeEachCallback, AfterEachCallback { @Override public void beforeEach(ExtensionContext context) throws Exception { //init engine - TestEngineUtils.initGraphicalEngine(); + EngineInit.initGraphicalEngine(); //load scene EngineInit.setupConnectedTestViewport(); diff --git a/src/test/java/electrosphere/test/template/extensions/RenderingExtension.java b/src/test/java/electrosphere/test/template/extensions/RenderingExtension.java index 151ef815..92a180a2 100644 --- a/src/test/java/electrosphere/test/template/extensions/RenderingExtension.java +++ b/src/test/java/electrosphere/test/template/extensions/RenderingExtension.java @@ -6,7 +6,7 @@ import org.junit.jupiter.api.extension.ExtensionContext; import electrosphere.engine.Globals; import electrosphere.engine.Main; -import electrosphere.test.testutils.TestEngineUtils; +import electrosphere.test.testutils.EngineInit; /** * Spins up an tears down generic rendering environment @@ -20,7 +20,7 @@ public class RenderingExtension implements BeforeEachCallback, AfterEachCallback Globals.RUN_AUDIO = false; Globals.WINDOW_WIDTH = 1920; Globals.WINDOW_HEIGHT = 1080; - TestEngineUtils.initGraphicalEngine(); + EngineInit.initGraphicalEngine(); } @Override diff --git a/src/test/java/electrosphere/test/testutils/EngineInit.java b/src/test/java/electrosphere/test/testutils/EngineInit.java index 3bbd0a6d..02e93fd9 100644 --- a/src/test/java/electrosphere/test/testutils/EngineInit.java +++ b/src/test/java/electrosphere/test/testutils/EngineInit.java @@ -3,13 +3,42 @@ package electrosphere.test.testutils; import java.util.concurrent.TimeUnit; 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; public class EngineInit { //The maximum number of frames to wait before failing the startup routine public static final int MAX_FRAMES_TO_WAIT = 100; + + /** + * Initializes the engine + */ + public static void initHeadlessEngine(){ + Globals.RUN_CLIENT = true; + Globals.RUN_SERVER = true; + Globals.RUN_AUDIO = false; + Globals.HEADLESS = true; + Profiler.PROFILE = false; + NetUtils.setPort(0); + Main.startUp(); + } + + /** + * Initializes the engine + */ + public static void initGraphicalEngine(){ + Globals.RUN_CLIENT = true; + Globals.RUN_SERVER = true; + Globals.RUN_AUDIO = false; + Globals.HEADLESS = false; + Profiler.PROFILE = false; + NetUtils.setPort(0); + Main.startUp(); + } /** * Setups up a locally-connected client and server that have loaded a test scene diff --git a/src/test/java/electrosphere/test/testutils/TestEngineUtils.java b/src/test/java/electrosphere/test/testutils/TestEngineUtils.java index 757d1202..d8d1c218 100644 --- a/src/test/java/electrosphere/test/testutils/TestEngineUtils.java +++ b/src/test/java/electrosphere/test/testutils/TestEngineUtils.java @@ -6,40 +6,12 @@ import java.util.function.Supplier; import electrosphere.engine.Globals; import electrosphere.engine.Main; -import electrosphere.engine.profiler.Profiler; import electrosphere.entity.Entity; -import electrosphere.net.NetUtils; /** * Utils for testing the engine */ public class TestEngineUtils { - - /** - * Initializes the engine - */ - public static void initHeadlessEngine(){ - Globals.RUN_CLIENT = true; - Globals.RUN_SERVER = true; - Globals.RUN_AUDIO = false; - Globals.HEADLESS = true; - Profiler.PROFILE = false; - NetUtils.setPort(0); - Main.startUp(); - } - - /** - * Initializes the engine - */ - public static void initGraphicalEngine(){ - Globals.RUN_CLIENT = true; - Globals.RUN_SERVER = true; - Globals.RUN_AUDIO = false; - Globals.HEADLESS = false; - Profiler.PROFILE = false; - NetUtils.setPort(0); - Main.startUp(); - } /** * Prints a logging message