From 9c48c3c756a3df8528c34978f862876107744007 Mon Sep 17 00:00:00 2001 From: JeremyStarTM Date: Fri, 26 Jul 2024 13:22:16 +0200 Subject: [PATCH] Move continuous render loop to interface (now class) --- .../glfw/classes/GlfwManagementClass.java | 45 +---------- .../graphics/classes/ApiManagementClass.java | 76 +++++++++++++++++-- 2 files changed, 72 insertions(+), 49 deletions(-) diff --git a/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/classes/GlfwManagementClass.java b/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/classes/GlfwManagementClass.java index 1dcc9b57..6e86b191 100644 --- a/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/classes/GlfwManagementClass.java +++ b/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/classes/GlfwManagementClass.java @@ -22,9 +22,7 @@ package de.staropensource.sosengine.graphics.glfw.classes; import de.staropensource.sosengine.base.logging.LoggerInstance; import de.staropensource.sosengine.base.types.CodePart; import de.staropensource.sosengine.base.types.logging.LogIssuer; -import de.staropensource.sosengine.base.utility.Math; import de.staropensource.sosengine.base.utility.Miscellaneous; -import de.staropensource.sosengine.graphics.GraphicsSubsystemConfiguration; import de.staropensource.sosengine.graphics.classes.ApiManagementClass; import de.staropensource.sosengine.graphics.classes.Window; import de.staropensource.sosengine.graphics.glfw.exceptions.NotOnMainThreadException; @@ -32,12 +30,11 @@ import lombok.Getter; import org.jetbrains.annotations.NotNull; import java.util.*; -import java.util.concurrent.atomic.AtomicReference; import static org.lwjgl.glfw.GLFW.*; @Getter -public abstract class GlfwManagementClass implements ApiManagementClass { +public abstract class GlfwManagementClass extends ApiManagementClass { /** * Contains the {@link LoggerInstance} for this class. * @@ -83,44 +80,6 @@ public abstract class GlfwManagementClass implements ApiManagementClass { if (!Miscellaneous.onMainThread()) throw new NotOnMainThreadException(); - AtomicReference> output = new AtomicReference<>(new LinkedHashMap<>()); // runRenderLoop output - long renderTime; // Amount of time spent rendering - long sleepDuration; // Time spent sleeping the thread - LinkedList splitDeltaTime = new LinkedList<>(); // Used for calculating the delta time (render time average over one second) - long reportDuration = System.currentTimeMillis(); // Used for determining when to report frame count and delta time - double deltaTime; // Contains the average render time over one second (delta time) - - // Run while the 'output' is empty - while (output.get().isEmpty()) { - renderTime = Miscellaneous.measureExecutionTime(() -> { - output.set(runRenderLoop()); - frameCode.run(); - }); - - // TODO v-sync is currently broken, monitor api needs to be implemented first - - // Calculate amount of time the thread should spend sleeping - sleepDuration = (long) (1d / GraphicsSubsystemConfiguration.getInstance().getMaximumFramesPerSecond() * 1000d) - renderTime; - // Add render and sleep time to list used for calculating the delta time value - splitDeltaTime.add(renderTime + sleepDuration); - - try { - //noinspection BusyWait // true, true - Thread.sleep(sleepDuration); - } catch (InterruptedException exception) { - logger.crash("Rendering loop got interrupted. This is unsupported behaviour.", exception); - } - - // Calculate delta time and frame count every second - if (System.currentTimeMillis() >= reportDuration + 1000) { - deltaTime = Math.getMeanLong(splitDeltaTime); // Calculate delta time - logger.info("Delta time average: " + deltaTime + " | Frames/s: " + 1000 / deltaTime); // Print delta time and frame count to console - - reportDuration = System.currentTimeMillis(); // Update 'reportDuration' - splitDeltaTime.clear(); // Clear 'splitDeltaTime' list - } - } - - return output.get(); + return super.runRenderLoopContinuously(frameCode); } } diff --git a/graphics/src/main/java/de/staropensource/sosengine/graphics/classes/ApiManagementClass.java b/graphics/src/main/java/de/staropensource/sosengine/graphics/classes/ApiManagementClass.java index 950fe3fd..3b819f6c 100644 --- a/graphics/src/main/java/de/staropensource/sosengine/graphics/classes/ApiManagementClass.java +++ b/graphics/src/main/java/de/staropensource/sosengine/graphics/classes/ApiManagementClass.java @@ -19,33 +19,57 @@ package de.staropensource.sosengine.graphics.classes; +import de.staropensource.sosengine.base.logging.LoggerInstance; +import de.staropensource.sosengine.base.types.CodePart; +import de.staropensource.sosengine.base.types.logging.LogIssuer; +import de.staropensource.sosengine.base.utility.Math; +import de.staropensource.sosengine.base.utility.Miscellaneous; +import de.staropensource.sosengine.graphics.GraphicsSubsystemConfiguration; +import lombok.AccessLevel; +import lombok.Getter; import org.jetbrains.annotations.NotNull; import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.concurrent.atomic.AtomicReference; /** * The interface for Graphics API management classes. * * @since v1-alpha0 */ -@SuppressWarnings({ "unused" }) -public interface ApiManagementClass { +@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" }) +public abstract class ApiManagementClass { + /** + * Contains the logger instance for this class. + * + * @since v1-alpha2 + * + * -- GETTER -- + * Returns the logger instance for this class. + * + * @return logger instance + * @since v1-alpha2 + */ + @Getter(value = AccessLevel.PROTECTED) + private final LoggerInstance logger = new LoggerInstance(new LogIssuer(getClass(), CodePart.ENGINE)); + /** * Returns if this Graphics API must be interacted with on the main thread. * * @return {@code true} if Graphics API must be interacted with on the main thread, {@code false} otherwise * @since v1-alpha2 */ - boolean mustRunOnMainThread(); + public abstract boolean mustRunOnMainThread(); /** * Runs the render loop once. - * To run the render loop continuously, see {@link #runRenderLoopContinuously()}. + * To run the render loop continuously, see {@link #runRenderLoopContinuously(Runnable)}. * * @return map of windows and their thrown throwables * @since v1-alpha2 */ - LinkedHashMap<@NotNull Window, @NotNull Throwable> runRenderLoop(); + public abstract LinkedHashMap<@NotNull Window, @NotNull Throwable> runRenderLoop(); /** * Runs the render loop for ever. @@ -57,5 +81,45 @@ public interface ApiManagementClass { * @return see {@link #runRenderLoop()} * @since v1-alpha2 */ - LinkedHashMap<@NotNull Window, @NotNull Throwable> runRenderLoopContinuously(@NotNull Runnable frameCode); + public LinkedHashMap<@NotNull Window, @NotNull Throwable> runRenderLoopContinuously(@NotNull Runnable frameCode) { + AtomicReference> output = new AtomicReference<>(new LinkedHashMap<>()); // runRenderLoop output + long renderTime; // Amount of time spent rendering + long sleepDuration; // Time spent sleeping the thread + LinkedList splitDeltaTime = new LinkedList<>(); // Used for calculating the delta time (render time average over one second) + long reportDuration = System.currentTimeMillis(); // Used for determining when to report frame count and delta time + double deltaTime; // Contains the average render time over one second (delta time) + + // Run while the 'output' is empty + while (output.get().isEmpty()) { + renderTime = Miscellaneous.measureExecutionTime(() -> { + output.set(runRenderLoop()); + frameCode.run(); + }); + + // TODO v-sync is currently broken, monitor api needs to be implemented first + + // Calculate amount of time the thread should spend sleeping + sleepDuration = (long) (1d / GraphicsSubsystemConfiguration.getInstance().getMaximumFramesPerSecond() * 1000d) - renderTime; + // Add render and sleep time to list used for calculating the delta time value + splitDeltaTime.add(renderTime + sleepDuration); + + try { + //noinspection BusyWait // true, true + Thread.sleep(sleepDuration); + } catch (InterruptedException exception) { + logger.crash("Rendering loop got interrupted. This is unsupported behaviour.", exception); + } + + // Calculate delta time and frame count every second + if (System.currentTimeMillis() >= reportDuration + 1000) { + deltaTime = Math.getMeanLong(splitDeltaTime); // Calculate delta time + logger.info("Delta time average: " + deltaTime + " | Frames/s: " + 1000 / deltaTime); // Print delta time and frame count to console + + reportDuration = System.currentTimeMillis(); // Update 'reportDuration' + splitDeltaTime.clear(); // Clear 'splitDeltaTime' list + } + } + + return output.get(); + } }