diff --git a/rendering/src/main/java/de/staropensource/engine/rendering/RenderingSubsystem.java b/rendering/src/main/java/de/staropensource/engine/rendering/RenderingSubsystem.java index 3ad044c..e67f4d6 100644 --- a/rendering/src/main/java/de/staropensource/engine/rendering/RenderingSubsystem.java +++ b/rendering/src/main/java/de/staropensource/engine/rendering/RenderingSubsystem.java @@ -213,135 +213,6 @@ public final class RenderingSubsystem extends SubsystemClass { Logger.error("Rendering error occurred: " + error); } - // -----> APIs - /** - * Renders all windows once. - * To render all windows continuously, invoke - * {@link #runRenderLoop(Runnable)} instead. - * - * @return map of windows and their {@link Throwable}s - * @throws NotOnMainThreadException if not running on the main thread - * @since v1-alpha9 - */ - public LinkedHashMap<@NotNull Window, @NotNull Throwable> renderWindows() throws NotOnMainThreadException { - // Ensure running on the main thread - if (!Miscellaneous.onMainThread()) - throw new NotOnMainThreadException(); - - LinkedHashMap<@NotNull Window, @NotNull Throwable> throwables = new LinkedHashMap<>(); - - // Poll for events - glfwPollEvents(); - - // Update and render all windows - for (Window window : Window.getWindows()) { - if (!window.isRendering()) - continue; - - try { - window.updateState(); - window.render(); - } catch (Throwable throwable) { - Logger.error("Rendering window " + window + " failed: Threw throwable " + throwable.getClass().getName() + (throwable.getMessage() == null ? "" : ": " + throwable.getMessage())); - throwables.put(window, throwable); - } - - //bgfx_frame(false); - } - - return throwables; - } - /** - * - * Renders all windows continuously. - * To render all windows just once, invoke - * {@link #renderWindows()} instead. - *
- * Immediately returns when a {@link #renderWindows()} call fails.
- *
- * @param frameCode code which shall be invoked before a frame is rendered
- * @return see {@link #renderWindows()} (on failure)
- * @throws NotOnMainThreadException if not running on the main thread
- * @since v1-alpha9
- */
- public LinkedHashMap<@NotNull Window, @NotNull Throwable> runRenderLoop(@NotNull Runnable frameCode) throws NotOnMainThreadException {
- // Ensure running on the main thread
- if (!Miscellaneous.onMainThread())
- throw new NotOnMainThreadException();
-
- // Define variables
- AtomicReference
- * Note that monitors stop working unannounced when disconnected,
- * call {@link #isConnected()} before using to avoid unexpected behaviour.
- *
- * @since v1-alpha9
- */
-@SuppressWarnings({ "JavadocDeclaration" })
-public final class Monitor {
- /**
- * Contains the unique identifier.
- *
- * This identifier is unique to every monitor and does not change during runtime.
- *
- * @since v1-alpha9
- * -- GETTER --
- * Returns the unique identifier.
- *
- * This identifier is unique to every monitor and does not change during runtime.
- *
- * @return unique identifier
- * @since v1-alpha9
- */
- @Getter
- private final UUID uniqueIdentifier = UUID.randomUUID();
-
- /**
- * Contains the monitor identifier.
- *
- * This identifier is used by the windowing API to refer to a monitor and may change during runtime.
- *
- * @since v1-alpha9
- * -- GETTER --
- * Returns the monitor identifier.
- *
- * This identifier is used by the windowing API to refer to a monitor and may change during runtime.
- *
- * @return monitor identifier
- * @since v1-alpha9
- * -- SETTER --
- * Sets the monitor identifier.
- *
- * This identifier is used by the windowing API to refer to a monitor and may change during runtime.
- *
- * @param identifier new monitor identifier
- * @since v1-alpha9
- */
- private final long identifier;
-
- /**
- * Creates and initializes an instance of this abstract class.
- *
- * @throws InvalidMonitorException if the monitor isn't connected
- * @since v1-alpha9
- */
- public Monitor(long identifier) throws InvalidMonitorException {
- this.identifier = identifier;
-
- checkConnected();
- }
-
- /**
- * Returns a set of all connected monitors.
- *
- * @return connected monitors
- * @since v1-alpha9
- */
- public static @NotNull LinkedHashSet<@NotNull Monitor> getMonitors() throws NoMonitorsFoundException {
- PointerBuffer monitors = glfwGetMonitors();
- LinkedHashSet<@NotNull Monitor> output = new LinkedHashSet<>();
- if (monitors == null)
- throw new NoMonitorsFoundException();
-
- while (monitors.hasRemaining())
- output.add(new Monitor(monitors.get()));
-
- return output;
- }
-
- /**
- * Checks if this monitor is actually connected.
- * If not, throws an {@link InvalidMonitorException}.
- *
- * @since v1-alpha9
- */
- public void checkConnected() throws InvalidMonitorException, NoMonitorsFoundException {
- if (!isConnected())
- throw new InvalidMonitorException();
- }
-
- /**
- * Checks if this monitor is connected.
- *
- * @return connection status
- * @since v1-alpha9
- */
- public boolean isConnected() throws NoMonitorsFoundException {
- return glfwGetMonitorName(identifier) != null;
- }
-
- /**
- * Returns the name of this monitor.
- *
- * @return monitor name
- * @since v1-alpha9
- */
- public @NotNull String getName() throws InvalidMonitorException, NoMonitorsFoundException {
- checkConnected();
- return Objects.requireNonNull(glfwGetMonitorName(identifier));
- }
-
- /**
- * Returns size of this monitor.
- *
- * @return monitor size
- * @since v1-alpha9
- */
- public @NotNull Vec2i getSize() throws InvalidMonitorException, NoMonitorsFoundException {
- checkConnected();
-
- GLFWVidMode videoMode = Objects.requireNonNull(glfwGetVideoMode(identifier));
-
- return new Vec2i(videoMode.width(), videoMode.height());
- }
-
- /**
- * Returns refresh rate of this monitor in hertz.
- *
- * @return monitor refresh rate
- * @since v1-alpha9
- */
- public short getRefreshRate() throws InvalidMonitorException, NoMonitorsFoundException {
- checkConnected();
- return (short) Objects.requireNonNull(glfwGetVideoMode(identifier)).refreshRate();
- }
-}
diff --git a/rendering/src/main/java/de/staropensource/engine/rendering/type/Window.java b/rendering/src/main/java/de/staropensource/engine/rendering/type/Window.java
index acf4bb0..bbe44d5 100644
--- a/rendering/src/main/java/de/staropensource/engine/rendering/type/Window.java
+++ b/rendering/src/main/java/de/staropensource/engine/rendering/type/Window.java
@@ -36,12 +36,12 @@ import lombok.Setter;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.lwjgl.bgfx.BGFX;
import org.lwjgl.bgfx.BGFXInit;
import org.lwjgl.glfw.*;
import org.lwjgl.stb.STBImage;
import org.lwjgl.system.MemoryStack;
+import java.io.Closeable;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.file.Path;
@@ -63,7 +63,8 @@ import static org.lwjgl.system.MemoryUtil.*;
*/
@Getter
@SuppressWarnings({ "unused", "JavadocDeclaration" })
-public final class Window implements AutoCloseable {
+public final class Window implements Closeable {
+ // -----> Static variables
/**
* A set of all active windows.
*
@@ -71,7 +72,42 @@ public final class Window implements AutoCloseable {
*/
private static final @NotNull List<@NotNull Window> windows = new ArrayList<>();
- // -----> Internal fields
+
+ // -----> Instance variables
+ /**
+ * Contains the unique window identifier.
+ *
+ * This identifier is unique to every window and does not change during runtime.
+ *
+ * @since v1-alpha9
+ * -- GETTER --
+ * Returns the unique window identifier.
+ *
+ * This identifier is unique to every window and does not change during runtime.
+ *
+ * @return unique identifier
+ * @since v1-alpha9
+ */
+ private final UUID uniqueIdentifier = UUID.randomUUID();
+
+ /**
+ * Contains if this window can be interacted with or not.
+ *
+ * @since v1-alpha9
+ * -- GETTER --
+ * Returns if this window can be interacted with or not.
+ *
+ * @return closed flag state
+ * @since v1-alpha9
+ * -- SETTER --
+ * Sets if this window can be interacted with or not.
+ *
+ * @param closed new closed flag state
+ * @since v1-alpha9
+ */
+ @Setter(AccessLevel.PROTECTED)
+ private boolean terminated = false;
+
/**
* Contains if this window is fresh.
*
@@ -92,70 +128,44 @@ public final class Window implements AutoCloseable {
*/
@Getter(value = AccessLevel.NONE)
@Setter(value = AccessLevel.NONE)
- private boolean fresh;
+ private boolean fresh = true;
+
+ /**
+ * Contains if to reinitialize this
+ * window on the next state update.
+ *
+ * @since v1-alpha9
+ */
+ @Getter(value = AccessLevel.NONE)
+ @Setter(value = AccessLevel.NONE)
+ private boolean reinitialize = false;
/**
* Contains the internal GLFW window identifier.
*
* @since v1-alpha9
- * -- GETTER --
- * Returns the internal GLFW window identifier.
- *
- * @return GLFW window identifier
- * @since v1-alpha9
*/
@Getter(value = AccessLevel.NONE)
@Setter(value = AccessLevel.NONE)
- private long internalWindowIdentifier;
+ private long internalWindowIdentifier = 0L;
/**
* Contains the internal bgfx view identifier.
*
* @since v1-alpha9
- * -- GETTER --
- * Returns the internal bgfx view identifier.
- *
- * @return bgfx view identifier
- * @since v1-alpha9
*/
@Getter(value = AccessLevel.NONE)
@Setter(value = AccessLevel.NONE)
- private int internalViewIdentifier;
-
- // -----> Window properties
- /**
- * Contains if this window can be interacted with or not.
- *
- * @since v1-alpha9
- * -- GETTER --
- * Returns if this window can be interacted with or not.
- *
- * @return closed flag state
- * @since v1-alpha9
- * -- SETTER --
- * Sets if this window can be interacted with or not.
- *
- * @param closed new closed flag state
- * @since v1-alpha9
- */
- @Setter(AccessLevel.PROTECTED)
- private boolean terminated;
+ private int internalViewIdentifier = 0;
/**
- * Contains the unique window identifier.
- *
- * This identifier is unique to every window and does not change during runtime.
+ * Contains queued window property updates.
*
- * @since v1-alpha9
- * -- GETTER --
- * Returns the unique window identifier.
- *
- * This identifier is unique to every window and does not change during runtime.
- *
- * @return unique identifier
- * @since v1-alpha9
+ * @since v1-release0
*/
- private final UUID uniqueIdentifier;
+ @Getter(value = AccessLevel.NONE)
+ @Setter(value = AccessLevel.NONE)
+ private final @NotNull Map<@NotNull String, @NotNull Object> queuedPropertyUpdates = new HashMap<>();
/**
* Contains the name of this window.
@@ -195,7 +205,7 @@ public final class Window implements AutoCloseable {
* @return window title
* @since v1-alpha9
*/
- private @NotNull String name;
+ private String name;
/**
* Contains the title of this window.
@@ -207,7 +217,7 @@ public final class Window implements AutoCloseable {
* @return window title
* @since v1-alpha9
*/
- private @NotNull String title;
+ private String title;
/**
* Contains file paths to window
@@ -221,7 +231,7 @@ public final class Window implements AutoCloseable {
* @return file paths to icons
* @since v1-alpha9
*/
- private @NotNull Path @Nullable [] icons;
+ private @NotNull Path [] icons;
/**
* Contains the size of this window.
@@ -233,7 +243,7 @@ public final class Window implements AutoCloseable {
* @return window size
* @since v1-alpha9
*/
- private @NotNull Vec2i size;
+ private Vec2i size;
/**
* Contains the minimum size of this window.
@@ -249,7 +259,7 @@ public final class Window implements AutoCloseable {
* @return minimum window size
* @since v1-alpha9
*/
- private @NotNull Vec2i minimumSize;
+ private Vec2i minimumSize;
/**
* Contains the maximum size of this window.
@@ -265,7 +275,7 @@ public final class Window implements AutoCloseable {
* @return maximum window size
* @since v1-alpha9
*/
- private @NotNull Vec2i maximumSize;
+ private Vec2i maximumSize;
/**
* Contains the position of this window.
@@ -277,7 +287,7 @@ public final class Window implements AutoCloseable {
* @return window position
* @since v1-alpha9
*/
- private @NotNull Vec2i position;
+ private Vec2i position;
/**
* Contains in which {@link Mode} this window is in.
@@ -289,25 +299,7 @@ public final class Window implements AutoCloseable {
* @return window mode
* @since v1-alpha9
*/
- private @NotNull Window.Mode mode;
-
- /**
- * Contains on which {@link Monitor} the window is displayed on.
- *
- * @since v1-alpha9
- * -- GETTER --
- * Returns the {@link Monitor} the window is displayed on.
- *
- * @return target monitor
- * @since v1-alpha9
- * -- SETTER --
- * Sets the {@link Monitor} the window is displayed on.
- *
- * @param monitor new target monitor
- * @since v1-alpha9
- */
- @Setter
- private @NotNull Monitor monitor;
+ private Window.Mode mode;
/**
* Contains if this window can be resized by the user.
@@ -334,14 +326,14 @@ public final class Window implements AutoCloseable {
private boolean borderless;
/**
- * Contains if the window can be focused.
+ * Contains if the window is focused.
* -- GETTER --
- * Returns if the window can be focused.
+ * Returns if the window is focused.
*
* @return focusable flag state
* @since v1-alpha9
*/
- private boolean focusable;
+ private boolean focused;
/**
* Contains if this window should be displayed on top of all other windows.
@@ -420,87 +412,38 @@ public final class Window implements AutoCloseable {
}
- // -----> Initialization
+ // -----> Creation
/**
- * Creates and initializes an instance of this abstract class.
+ * Creates and initializes an
+ * instance of this abstract class.
*
- * @param name name
- * @param title title
- * @param icons icon file paths
- * @param size size
- * @param minimumSize minimum size
- * @param maximumSize maximum size
- * @param position position
- * @param mode window mode
- * @param monitor monitor
- * @param resizable resizable flag
- * @param borderless borderless flag
- * @param focusable focusable flag
- * @param onTop on top flag
- * @param transparent transparency flag
- * @param rendering rendering flag
* @throws NotOnMainThreadException if not running on the main thread
* @since v1-alpha9
*/
- private Window(@NotNull String name,
- @NotNull String title,
- @NotNull Path @Nullable [] icons,
- @NotNull Vec2i size,
- @NotNull Vec2i minimumSize,
- @NotNull Vec2i maximumSize,
- @NotNull Vec2i position,
- @NotNull Window.Mode mode,
- @NotNull Monitor monitor,
- boolean resizable,
- boolean borderless,
- boolean focusable,
- boolean onTop,
- boolean transparent,
- boolean rendering) throws NotOnMainThreadException {
- // Initialize variables
- this.fresh = true;
- this.internalWindowIdentifier = 0L;
- this.internalViewIdentifier = 0;
- this.uniqueIdentifier = UUID.randomUUID();
- this.terminated = false;
- this.name = name;
- this.title = title;
- this.icons = icons;
- this.size = size;
- this.minimumSize = minimumSize;
- this.maximumSize = maximumSize;
- this.position = position;
- this.mode = mode;
- this.monitor = monitor;
- this.resizable = resizable;
- this.borderless = borderless;
- this.focusable = focusable;
- this.onTop = onTop;
- this.transparent = transparent;
- this.rendering = rendering;
+ private Window() {}
- // Log about window creation
- Logger.verb("Creating new window " + this.uniqueIdentifier + "\n" +
- "-> Name: " + this.name + "\n" +
- "-> Title: " + this.title + "\n" +
- "-> Size: " + this.size + "\n" +
- " -> Minimum: " + this.minimumSize + "\n" +
- " -> Maximum: " + this.maximumSize + "\n" +
- "-> Position: " + this.position + "\n" +
- "-> Mode: " + this.mode + "\n" +
- "-> Monitor: " + this.monitor + "\n" +
- "-> Resizable: " + this.resizable + "\n" +
- "-> Borderless: " + this.borderless + "\n" +
- "-> Focusable: " + this.focusable + "\n" +
- "-> On top: " + this.onTop + "\n" +
- "-> Transparent: " + this.transparent + "\n" +
- "-> Rendering: " + this.rendering
+ /**
+ * Finishes the window creation phase.
+ *
+ * @since v1-alpha9
+ */
+ private void finishWindowCreation() {
+ Logger.verb(
+ "Created new window " + uniqueIdentifier + "\n" +
+ "-> Name: " + name + "\n" +
+ "-> Title: " + title + "\n" +
+ "-> Size: " + size + "\n" +
+ " -> Minimum: " + minimumSize + "\n" +
+ " -> Maximum: " + maximumSize + "\n" +
+ "-> Position: " + position + "\n" +
+ "-> Mode: " + mode + "\n" +
+ "-> Resizable: " + resizable + "\n" +
+ "-> Borderless: " + borderless + "\n" +
+ "-> On top: " + onTop + "\n" +
+ "-> Transparent: " + transparent + "\n" +
+ "-> Rendering: " + rendering
);
- // Check if another window already exists
- if (!Window.getWindows().isEmpty())
- Logger.crash("Window already present\nThe StarOpenSource Engine is unable to initialize more than one window at the moment, sorry.");
-
// Initialize window
initializeWindow();
@@ -509,14 +452,26 @@ public final class Window implements AutoCloseable {
// Initialize bgfx
if (glfwGetPlatform() != GLFW_PLATFORM_NULL)
- initBgfx();
+ initializeBgfx();
- // Add to window set
+ // Declare window as ready
windows.add(this);
fresh = false;
}
+ // -----> Initialization
+ /**
+ * Triggers a window reinitialization
+ * in the next state update.
+ *
+ * @since v1-alpha9
+ */
+ private void triggerReinitialization() {
+ if (!fresh && !reinitialize)
+ reinitialize = true;
+ }
+
/**
* Initializes this window.
*
@@ -528,38 +483,30 @@ public final class Window implements AutoCloseable {
if (!Miscellaneous.onMainThread())
throw new NotOnMainThreadException();
- // Get current focus and destroy existing window
- boolean focused = false;
- if (!fresh) {
- focused = isFocused();
+ // Destroy existing window
+ if (!fresh)
closeInternal();
- }
// Set window hints
- if (RenderingSubsystemConfiguration.getInstance().isDebugAllowPositionUpdates()) {
- glfwWindowHint(GLFW_POSITION_X, getPosition().getX());
- glfwWindowHint(GLFW_POSITION_Y, getPosition().getY());
- }
- glfwWindowHint(GLFW_CENTER_CURSOR, 0);
- glfwWindowHint(GLFW_FOCUSED, TypeConversion.booleanToInteger(focused));
- glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, TypeConversion.booleanToInteger(transparent));
- glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
+ glfwWindowHint(GLFW_POSITION_X, position.getX());
+ glfwWindowHint(GLFW_POSITION_Y, position.getY());
+ glfwWindowHint(GLFW_CENTER_CURSOR, GLFW_FALSE);
+ glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE);
+ glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_TRUE);
+ glfwWindowHint(GLFW_AUTO_ICONIFY, GLFW_FALSE);
+ glfwWindowHint(GLFW_DECORATED, TypeConversion.booleanToInteger(!borderless));
+ glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); // we want to use bgfx
glfwWindowHint(GLFW_COCOA_RETINA_FRAMEBUFFER, GLFW_FALSE);
- glfwWindowHintString(GLFW_WAYLAND_APP_ID, getName());
- glfwWindowHintString(GLFW_X11_CLASS_NAME, getName());
- glfwWindowHintString(GLFW_X11_INSTANCE_NAME, getName());
+ glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, TypeConversion.booleanToInteger(transparent));
+ glfwWindowHintString(GLFW_WAYLAND_APP_ID, name);
+ glfwWindowHintString(GLFW_X11_CLASS_NAME, name);
+ glfwWindowHintString(GLFW_X11_INSTANCE_NAME, name);
// Create window
- internalWindowIdentifier = glfwCreateWindow(getSize().getX(), getSize().getY(), getTitle(), NULL, NULL);
+ internalWindowIdentifier = glfwCreateWindow(size.getX(), size.getY(), title, NULL, NULL);
if (internalWindowIdentifier == NULL)
throw new WindowCreationFailureException();
- // Own context
- //glfwMakeContextCurrent(identifier);
-
- // Set swap interval based on V-Sync mode setting
- //glfwSwapInterval(RenderingSubsystemConfiguration.getInstance().getVsyncMode() == VsyncMode.ON ? 1 : 0);
-
// Create callbacks
keyCallback = GLFWKeyCallback.create(new KeyCallback(this));
mouseButtonCallback = GLFWMouseButtonCallback.create(new MouseButtonCallback(this));
@@ -567,13 +514,6 @@ public final class Window implements AutoCloseable {
// Set callback
glfwSetKeyCallback(internalWindowIdentifier, keyCallback);
glfwSetMouseButtonCallback(internalWindowIdentifier, mouseButtonCallback);
-
- // Update the window state
- setIcons(getIcons());
- setSize(getSize());
- setMinimumSize(getMinimumSize());
- setMaximumSize(getMaximumSize());
- setMode(getMode());
}
/**
@@ -581,7 +521,7 @@ public final class Window implements AutoCloseable {
*
* @since v1-alpha9
*/
- private void initBgfx() {
+ private void initializeBgfx() {
// Ensure the window is not terminated
if (terminated)
return;
@@ -613,9 +553,7 @@ public final class Window implements AutoCloseable {
it -> it
.width(size.getX())
.height(size.getY())
- .reset(
- BGFX_RESET_VSYNC
- )
+ .reset(BGFX_RESET_NONE)
);
// Determine platform to render for
@@ -667,48 +605,88 @@ public final class Window implements AutoCloseable {
if (!Miscellaneous.onMainThread())
throw new NotOnMainThreadException();
- // Update window mode
- if (TypeConversion.integerToBoolean(glfwGetWindowAttrib(internalWindowIdentifier, GLFW_ICONIFIED)))
- mode = Mode.MINIMIZED;
- else if (TypeConversion.integerToBoolean(glfwGetWindowAttrib(internalWindowIdentifier, GLFW_MAXIMIZED)))
- mode = Mode.MAXIMIZED;
- else if (TypeConversion.integerToBoolean(glfwGetWindowAttrib(internalWindowIdentifier, GLFW_VISIBLE)))
- mode = Mode.WINDOWED;
- else if (TypeConversion.integerToBoolean(glfwGetWindowAttrib(internalWindowIdentifier, GLFW_VISIBLE)))
- mode = Mode.HIDDEN;
-
- // Update monitor
- if (!getMonitor().isConnected()) {
- Monitor newMonitor = null;
-
- for (Monitor monitor : Monitor.getMonitors())
- if (monitor.isConnected())
- newMonitor = monitor;
-
- if (newMonitor == null) {
- Logger.crash("Unable to set a new target monitor for window " + getUniqueIdentifier() + " as no monitors are connected to the system");
- return;
- }
-
- monitor = newMonitor;
+ if (reinitialize) {
+ reinitialize = false;
+ initializeWindow();
}
- // Update vectors
+
+ // Update basic properties
+ // -> Title
+ if (queuedPropertyUpdates.containsKey("title")) glfwSetWindowTitle(internalWindowIdentifier, (String) queuedPropertyUpdates.get("title"));
+ else title = glfwGetWindowTitle(internalWindowIdentifier);
+ // -> Minimum & maximum size
+ glfwSetWindowSizeLimits(internalWindowIdentifier, minimumSize.getX(), minimumSize.getY(), maximumSize.getX(), maximumSize.getY());
+
+
+ // Update window mode
+ if (queuedPropertyUpdates.containsKey("mode"))
+ switch ((Mode) queuedPropertyUpdates.get("mode")) {
+ case HIDDEN -> glfwHideWindow(internalWindowIdentifier);
+ case WINDOWED -> {
+ glfwShowWindow(internalWindowIdentifier);
+ glfwRestoreWindow(internalWindowIdentifier);
+ }
+ case MINIMIZED -> {
+ glfwShowWindow(internalWindowIdentifier);
+ glfwIconifyWindow(internalWindowIdentifier);
+ }
+ case MAXIMIZED -> {
+ glfwShowWindow(internalWindowIdentifier);
+ glfwMaximizeWindow(internalWindowIdentifier);
+ }
+ }
+ else
+ if (!TypeConversion.integerToBoolean(glfwGetWindowAttrib(internalWindowIdentifier, GLFW_VISIBLE)))
+ mode = Mode.HIDDEN;
+ if (TypeConversion.integerToBoolean(glfwGetWindowAttrib(internalWindowIdentifier, GLFW_ICONIFIED)))
+ mode = Mode.MINIMIZED;
+ else if (TypeConversion.integerToBoolean(glfwGetWindowAttrib(internalWindowIdentifier, GLFW_MAXIMIZED)))
+ mode = Mode.MAXIMIZED;
+ else
+ mode = Mode.WINDOWED;
+
+
+ // Update size and position
try (MemoryStack stack = stackPush()) {
- IntBuffer width = stack.mallocInt(2);
- IntBuffer height = stack.mallocInt(2);
+ IntBuffer width = stack.mallocInt(3);
+ IntBuffer height = stack.mallocInt(3);
- glfwGetWindowSize(internalWindowIdentifier, width, height);
- size = new Vec2i(width.get(), height.get());
+ if (queuedPropertyUpdates.containsKey("size")) {
+ width.put(((Vec2i) queuedPropertyUpdates.get("size")).getX());
+ height.put(((Vec2i) queuedPropertyUpdates.get("size")).getY());
+ glfwSetWindowSize(internalWindowIdentifier, width.get(), height.get());
+ } else {
+ glfwGetWindowSize(internalWindowIdentifier, width, height);
+ size = new Vec2i(width.get(), height.get());
+ }
- glfwGetWindowPos(internalWindowIdentifier, width, height);
- position = new Vec2i(width.get(), height.get());
+ if (RenderingSubsystemConfiguration.getInstance().isDebugAllowPositionUpdates() && queuedPropertyUpdates.containsKey("position")) {
+ width.put(((Vec2i) queuedPropertyUpdates.get("position")).getX());
+ height.put(((Vec2i) queuedPropertyUpdates.get("position")).getY());
+ glfwSetWindowPos(internalWindowIdentifier, width.get(), height.get());
+ } else {
+ glfwGetWindowPos(internalWindowIdentifier, width, height);
+ position = new Vec2i(width.get(), height.get());
+ }
}
// Update booleans
- resizable = TypeConversion.integerToBoolean(glfwGetWindowAttrib(internalWindowIdentifier, GLFW_RESIZABLE));
- onTop = TypeConversion.integerToBoolean(glfwGetWindowAttrib(internalWindowIdentifier, GLFW_FLOATING));
- transparent = TypeConversion.integerToBoolean(glfwGetWindowAttrib(internalWindowIdentifier, GLFW_TRANSPARENT_FRAMEBUFFER));
+ // -> Resizable
+ if (queuedPropertyUpdates.containsKey("resizable"))
+ glfwSetWindowAttrib(internalWindowIdentifier, GLFW_RESIZABLE, TypeConversion.booleanToInteger((Boolean) queuedPropertyUpdates.get("resizable")));
+ else
+ resizable = TypeConversion.integerToBoolean(glfwGetWindowAttrib(internalWindowIdentifier, GLFW_RESIZABLE));
+ // -> Focused
+ focused = TypeConversion.integerToBoolean(glfwGetWindowAttrib(internalWindowIdentifier, GLFW_FOCUSED));
+ // -> On top
+ if (queuedPropertyUpdates.containsKey("onTop"))
+ glfwSetWindowAttrib(internalWindowIdentifier, GLFW_FLOATING, TypeConversion.booleanToInteger((Boolean) queuedPropertyUpdates.get("onTop")));
+ else
+ onTop = TypeConversion.integerToBoolean(glfwGetWindowAttrib(internalWindowIdentifier, GLFW_FLOATING));
+
+ // Clear property updates queue
+ queuedPropertyUpdates.clear();
}
/**
@@ -768,6 +746,49 @@ public final class Window implements AutoCloseable {
glfwDestroyWindow(internalWindowIdentifier);
}
+ /**
+ * Requests the user's attention.
+ *
+ * What the window manager or compositor will
+ * do with that request is uncertain. It may
+ * be ignored, cause the icon in some bar or
+ * dock to flash to blink or who knows what.
+ *
+ * @since v1-alpha9
+ */
+ public void requestAttention() {
+ // Ensure running on the main thread
+ if (!Miscellaneous.onMainThread())
+ throw new NotOnMainThreadException();
+
+ // Ensure the window is not terminated
+ if (terminated)
+ return;
+
+ glfwRequestWindowAttention(internalWindowIdentifier);
+ }
+
+ /**
+ * Will cause the window to be
+ * focused immediately, even
+ * without any user input.
+ *
+ * @since v1-alpha9
+ */
+ public void focus() {
+ // Ensure running on the main thread
+ if (!Miscellaneous.onMainThread())
+ throw new NotOnMainThreadException();
+
+ // Ensure the window is not terminated
+ if (terminated)
+ return;
+
+ glfwFocusWindow(internalWindowIdentifier);
+ }
+
+
+ // -----> Getters & setters
/**
* Returns if the user, window manager or
* compositor send a request for the window to close.
@@ -787,66 +808,6 @@ public final class Window implements AutoCloseable {
return glfwWindowShouldClose(internalWindowIdentifier);
}
- /**
- * Returns if the window is currently focused.
- *
- * @return {@code true} if focused, {@code false} otherwise
- * @since v1-alpha9
- */
- public boolean isFocused() {
- // Ensure running on the main thread
- if (!Miscellaneous.onMainThread())
- throw new NotOnMainThreadException();
-
- // Ensure the window is not terminated
- if (terminated)
- return false;
-
- return TypeConversion.integerToBoolean(glfwGetWindowAttrib(internalWindowIdentifier, GLFW_FOCUSED));
- }
-
- /**
- * Will cause the window to be focused immediately, even
- * without any user input.
- *
- * @since v1-alpha9
- */
- public void focus() {
- // Ensure running on the main thread
- if (!Miscellaneous.onMainThread())
- throw new NotOnMainThreadException();
-
- // Ensure the window is not terminated
- if (terminated)
- return;
-
- glfwFocusWindow(internalWindowIdentifier);
- }
-
- /**
- * Will request user attention.
- *
- * What the window manager or compositor does
- * with this request is uncertain. It may be
- * ignored, or will cause the icon in some bar
- * or dock flash or blink.
- *
- * @since v1-alpha9
- */
- public void requestAttention() {
- // Ensure running on the main thread
- if (!Miscellaneous.onMainThread())
- throw new NotOnMainThreadException();
-
- // Ensure the window is not terminated
- if (terminated)
- return;
-
- glfwRequestWindowAttention(internalWindowIdentifier);
- }
-
- // -----> Setters & getters
-
/**
* Sets the name of this window.
*
@@ -873,7 +834,7 @@ public final class Window implements AutoCloseable {
return;
this.name = name;
- initializeWindow();
+ triggerReinitialization();
}
/**
@@ -888,12 +849,10 @@ public final class Window implements AutoCloseable {
return;
this.title = title;
- glfwSetWindowTitle(internalWindowIdentifier, title);
}
/**
- * Sets file paths to window
- * icons in the PNG format.
+ * Sets the icon(s) for this window.
*
* @param icons new file paths to icons
* @since v1-alpha9
@@ -904,6 +863,10 @@ public final class Window implements AutoCloseable {
if (terminated)
return;
+ // TODO
+ if (System.currentTimeMillis() > 0)
+ return;
+
this.icons = icons;
if (icons != null)
try (GLFWImage.Buffer iconsBuffer = GLFWImage.malloc(icons.length)) {
@@ -955,9 +918,9 @@ public final class Window implements AutoCloseable {
}
/**
- * Sets the window size.
+ * Sets the size of this window.
*
- * @param size new window size
+ * @param size new size
* @since v1-alpha9
*/
public void setSize(@NotNull Vec2i size) {
@@ -966,13 +929,15 @@ public final class Window implements AutoCloseable {
return;
this.size = size;
- glfwSetWindowSize(internalWindowIdentifier, size.getX(), size.getY());
+ queuedPropertyUpdates.put("size", size);
}
/**
- * Sets the minimum window size.
+ * Sets the minimum size this window can have.
*
- * If set to {@code -1}, will enforce no minimum window size.
+ * No minimum size will be enforced for
+ * an axis if it's respective value is
+ * set to {@code -1}.
*
* @param minimumSize new minimum size
* @since v1-alpha9
@@ -983,13 +948,15 @@ public final class Window implements AutoCloseable {
return;
this.minimumSize = minimumSize;
- glfwSetWindowSizeLimits(internalWindowIdentifier, minimumSize.getX(), minimumSize.getY(), getMaximumSize().getX(), getMaximumSize().getY());
+ queuedPropertyUpdates.put("minimumSize", minimumSize);
}
/**
- * Sets the maximum window size.
+ * Sets the maximum size this window can have.
*
- * If set to {@code -1}, will enforce no maximum window size.
+ * No maximum size will be enforced for
+ * an axis if it's respective value is
+ * set to {@code -1}.
*
* @param maximumSize new maximum size
* @since v1-alpha9
@@ -1000,26 +967,26 @@ public final class Window implements AutoCloseable {
return;
this.maximumSize = maximumSize;
- glfwSetWindowSizeLimits(internalWindowIdentifier, getMinimumSize().getX(), getMinimumSize().getY(), maximumSize.getX(), maximumSize.getY());
+ queuedPropertyUpdates.put("maximumSize", maximumSize);
}
/**
- * Sets the window position.
+ * Sets the position of this window.
*
* @param position new position
* @since v1-alpha9
*/
public void setPosition(@NotNull Vec2i position) {
// Ensure the window is not terminated
- if (isTerminated() || !RenderingSubsystemConfiguration.getInstance().isDebugAllowPositionUpdates())
+ if (isTerminated())
return;
this.position = position;
- glfwSetWindowSize(internalWindowIdentifier, position.getX(), position.getY());
+ queuedPropertyUpdates.put("position", position);
}
/**
- * Sets the window mode.
+ * Sets in which mode this window shall be in.
*
* @param mode new mode
* @since v1-alpha9
@@ -1030,39 +997,13 @@ public final class Window implements AutoCloseable {
return;
this.mode = mode;
- switch (mode) {
- case HIDDEN -> glfwHideWindow(internalWindowIdentifier);
- case WINDOWED -> {
- glfwShowWindow(internalWindowIdentifier);
- glfwRestoreWindow(internalWindowIdentifier);
- }
- case MINIMIZED -> {
- glfwShowWindow(internalWindowIdentifier);
- glfwIconifyWindow(internalWindowIdentifier);
- }
- case MAXIMIZED -> {
- glfwShowWindow(internalWindowIdentifier);
- glfwRestoreWindow(internalWindowIdentifier);
- glfwMaximizeWindow(internalWindowIdentifier);
- }
- case BORDERLESS_FULLSCREEN -> {
- glfwShowWindow(internalWindowIdentifier);
- glfwRestoreWindow(internalWindowIdentifier);
- glfwSetWindowPos(internalWindowIdentifier, 0, 0);
- // TODO
- }
- case EXCLUSIVE_FULLSCREEN -> {
- glfwShowWindow(internalWindowIdentifier);
- glfwRestoreWindow(internalWindowIdentifier);
- glfwSetWindowPos(internalWindowIdentifier, 0, 0);
- }
- }
+ queuedPropertyUpdates.put("mode", mode);
}
/**
- * Sets if the window is resizable.
+ * Sets this window can be resized.
*
- * @param resizable new resizable flag state
+ * @param resizable shall be resizable?
* @since v1-alpha9
*/
public void setResizable(boolean resizable) {
@@ -1071,12 +1012,13 @@ public final class Window implements AutoCloseable {
return;
this.resizable = resizable;
+ queuedPropertyUpdates.put("resizable", resizable);
}
/**
- * Sets if the window should be rendered without any decorations.
+ * Sets if this window shall have any decorations.
*
- * @param borderless new borderless flag state
+ * @param borderless shall have no decorations?
* @since v1-alpha9
*/
public void setBorderless(boolean borderless) {
@@ -1084,27 +1026,14 @@ public final class Window implements AutoCloseable {
if (terminated)
return;
+ triggerReinitialization();
this.borderless = borderless;
}
/**
- * Sets if the window can be focused.
+ * Sets if this window should be displayed above all others.
*
- * @param focusable new focusable flag state
- * @since v1-alpha9
- */
- public void setFocusable(boolean focusable) {
- // Ensure the window is not terminated
- if (terminated)
- return;
-
- this.focusable = focusable;
- }
-
- /**
- * Sets if the window is displayed over regular windows.
- *
- * @param onTop new on top flag state
+ * @param onTop shall be on top of all regular windows?
* @since v1-alpha9
*/
public void setOnTop(boolean onTop) {
@@ -1113,15 +1042,16 @@ public final class Window implements AutoCloseable {
return;
this.onTop = onTop;
+ queuedPropertyUpdates.put("onTop", onTop);
}
/**
- * Sets if the window can be transparent.
+ * Sets if this window can be transparent.
*
* Availability depends on the windowing API, compositor or
* window manager and potentially system settings.
*
- * @param transparent new transparency flag state
+ * @param transparent shall be transparent?
* @since v1-alpha9
*/
public void setTransparent(boolean transparent) {
@@ -1129,8 +1059,8 @@ public final class Window implements AutoCloseable {
if (terminated)
return;
+ triggerReinitialization();
this.transparent = transparent;
- initializeWindow();
}
// -----> Inner classes
@@ -1270,14 +1200,6 @@ public final class Window implements AutoCloseable {
*/
private @Nullable Window.Mode mode = null;
- /**
- * Contains the target monitor.
- *
- * @see Window#monitor
- * @since v1-alpha9
- */
- private @Nullable Monitor monitor = null;
-
/**
* Contains the resizable flag.
*
@@ -1294,14 +1216,6 @@ public final class Window implements AutoCloseable {
*/
private @NotNull Tristate borderless = Tristate.UNSET;
- /**
- * Contains the focusable flag.
- *
- * @see Window#focusable
- * @since v1-alpha9
- */
- private @NotNull Tristate focusable = Tristate.UNSET;
-
/**
* Contains the on top flag.
*
@@ -1371,16 +1285,12 @@ public final class Window implements AutoCloseable {
maximumSize = new Vec2i(-1, -1);
if (mode == null)
mode = Mode.WINDOWED;
- if (monitor == null)
- monitor = Monitor.getMonitors().getFirst();
// Override booleanized tristate defaults
if (resizable == Tristate.FALSE)
resizableBoolean = false;
if (borderless == Tristate.TRUE)
borderlessBoolean = true;
- if (focusable == Tristate.FALSE)
- focusableBoolean = false;
if (onTop == Tristate.TRUE)
onTopBoolean = true;
if (transparent == Tristate.TRUE)
@@ -1389,7 +1299,22 @@ public final class Window implements AutoCloseable {
renderingBoolean = false;
// Create new Window instance
- return new Window(name, title, icons, size, minimumSize, maximumSize, position, mode, monitor, resizableBoolean, borderlessBoolean, focusableBoolean, onTopBoolean, transparentBoolean, renderingBoolean);
+ Window window = new Window();
+ window.setName(name);
+ window.setTitle(title);
+ window.setIcons(icons);
+ window.setSize(size);
+ window.setMinimumSize(minimumSize);
+ window.setMaximumSize(maximumSize);
+ window.setPosition(position);
+ window.setMode(mode);
+ window.setResizable(resizableBoolean);
+ window.setBorderless(borderlessBoolean);
+ window.setOnTop(onTopBoolean);
+ window.setTransparent(transparentBoolean);
+ window.setRendering(renderingBoolean);
+ window.finishWindowCreation();
+ return window;
}
/**
@@ -1481,17 +1406,6 @@ public final class Window implements AutoCloseable {
return mode;
}
- /**
- * Returns the target monitor.
- *
- * @return target monitor
- * @see Window#monitor
- * @since v1-alpha9
- */
- public @Nullable Monitor getMonitor() {
- return monitor;
- }
-
/**
* Returns the resizable flag state.
*
@@ -1514,17 +1428,6 @@ public final class Window implements AutoCloseable {
return borderless;
}
- /**
- * Returns the focusable flag state.
- *
- * @return focusable flag state
- * @see Window#focusable
- * @since v1-alpha9
- */
- public @NotNull Tristate getFocusable() {
- return focusable;
- }
-
/**
* Returns the on top flag state.
*
@@ -1663,19 +1566,6 @@ public final class Window implements AutoCloseable {
return this;
}
- /**
- * Sets the target monitor.
- *
- * @param monitor new target monitor
- * @return builder instance
- * @see Window#monitor
- * @since v1-alpha9
- */
- public synchronized @NotNull Builder setMonitor(@Nullable Monitor monitor) {
- this.monitor = monitor;
- return this;
- }
-
/**
* Sets the resizable flag.
*
@@ -1702,19 +1592,6 @@ public final class Window implements AutoCloseable {
return this;
}
- /**
- * Sets the focusable flag.
- *
- * @param focusable new focusable flag state
- * @return builder instance
- * @see Window#focusable
- * @since v1-alpha9
- */
- public @NotNull Builder setFocusable(@NotNull Tristate focusable) {
- this.focusable = focusable;
- return this;
- }
-
/**
* Sets the on top flag.
*
diff --git a/rendering/src/main/java/de/staropensource/engine/rendering/type/window/VsyncMode.java b/rendering/src/main/java/de/staropensource/engine/rendering/type/window/VsyncMode.java
index 0bb7854..9c09c9e 100644
--- a/rendering/src/main/java/de/staropensource/engine/rendering/type/window/VsyncMode.java
+++ b/rendering/src/main/java/de/staropensource/engine/rendering/type/window/VsyncMode.java
@@ -42,10 +42,5 @@ public enum VsyncMode {
*
* @since v1-alpha9
*/
- ON,
-
- /**
- * Party
- */
- PARTY
+ ON
}