forked from StarOpenSource/Engine
Fix updateState, add terminate methods
This commit is contained in:
parent
6c0244053b
commit
eea7fce13c
4 changed files with 192 additions and 30 deletions
|
@ -32,8 +32,11 @@ import de.staropensource.sosengine.graphics.types.window.VsyncMode;
|
|||
import de.staropensource.sosengine.graphics.types.window.WindowMode;
|
||||
import lombok.Getter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
|
||||
/**
|
||||
|
@ -57,8 +60,8 @@ public abstract class GlfwWindow extends Window {
|
|||
*/
|
||||
private long identifierLong;
|
||||
|
||||
// ------------------------------------------------ [ Window initialization ] ------------------------------------------------ //
|
||||
/**
|
||||
// ------------------------------------------------ [ Window (de)initialization ] ------------------------------------------------ //
|
||||
* Creates a new window.
|
||||
*
|
||||
* @param name name
|
||||
|
@ -85,10 +88,6 @@ public abstract class GlfwWindow extends Window {
|
|||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected void initializeWindow() throws Throwable {
|
||||
// Ensure running on the main thread
|
||||
if (!Miscellaneous.onMainThread())
|
||||
throw new NotOnMainThreadException();
|
||||
|
||||
createGlfwWindow(); // Create the GLFW window
|
||||
initializeGlfwWindow(); // Call GLFW window initialization method
|
||||
}
|
||||
|
@ -102,22 +101,25 @@ public abstract class GlfwWindow extends Window {
|
|||
protected abstract void initializeGlfwWindow() throws Throwable;
|
||||
|
||||
/**
|
||||
* (Re-)Creates the GLFW window.
|
||||
* (Re-)Creates the associated GLFW window.
|
||||
*
|
||||
* @since v1-alpha2
|
||||
*/
|
||||
public void createGlfwWindow() throws WindowCreationFailureException {
|
||||
// Get current focus
|
||||
boolean focused = true;
|
||||
// Ensure running on the main thread
|
||||
if (!Miscellaneous.onMainThread())
|
||||
throw new NotOnMainThreadException();
|
||||
|
||||
// Destroy existing window
|
||||
// Get current focus and destroy existing window
|
||||
boolean focused = true;
|
||||
if (getIdentifier() != null) {
|
||||
focused = isFocused();
|
||||
glfwDestroyWindow(identifierLong);
|
||||
closeGlfwWindow();
|
||||
}
|
||||
|
||||
// Set window hints
|
||||
setWindowHints();
|
||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // The window's visibility is later changed in setWindowState, this is just for setting up the window
|
||||
glfwWindowHint(GLFW_POSITION_X, getPosition().getX());
|
||||
glfwWindowHint(GLFW_POSITION_Y, getPosition().getY());
|
||||
glfwWindowHint(GLFW_CENTER_CURSOR, 0);
|
||||
|
@ -152,6 +154,23 @@ public abstract class GlfwWindow extends Window {
|
|||
setWindowMode(getWindowMode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the associated GLFW window.
|
||||
*
|
||||
* @since v1-alpha2
|
||||
*/
|
||||
public void closeGlfwWindow() throws WindowCreationFailureException {
|
||||
// Ensure running on the main thread
|
||||
if (!Miscellaneous.onMainThread())
|
||||
throw new NotOnMainThreadException();
|
||||
|
||||
// Close callbacks
|
||||
keyCallback.close();
|
||||
|
||||
// Destroy the window
|
||||
glfwDestroyWindow(identifierLong);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets window hints.
|
||||
*
|
||||
|
@ -159,6 +178,12 @@ public abstract class GlfwWindow extends Window {
|
|||
*/
|
||||
public abstract void setWindowHints();
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void terminate() {
|
||||
setTerminated(true);
|
||||
closeGlfwWindow();
|
||||
}
|
||||
|
||||
// ------------------------------------------------ [ State updates ] ------------------------------------------------ //
|
||||
/**
|
||||
* Updates the window state.
|
||||
|
@ -167,6 +192,10 @@ public abstract class GlfwWindow extends Window {
|
|||
*/
|
||||
@Override
|
||||
public void updateState() {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return;
|
||||
|
||||
// Ensure running on the main thread
|
||||
if (!Miscellaneous.onMainThread())
|
||||
throw new NotOnMainThreadException();
|
||||
|
@ -177,23 +206,16 @@ public abstract class GlfwWindow extends Window {
|
|||
// Set swap interval based on isDisallowTearing setting
|
||||
glfwSwapInterval(Miscellaneous.getIntegerizedBoolean(GraphicsSubsystemConfiguration.getInstance().isDisallowTearing()));
|
||||
|
||||
/*
|
||||
// Initialize IntBuffers, used for 'size' and 'position'
|
||||
IntBuffer width = MemoryUtil.memAllocInt(1);
|
||||
IntBuffer height = MemoryUtil.memAllocInt(1);
|
||||
try (MemoryStack stack = MemoryStack.stackPush()) {
|
||||
IntBuffer width = stack.mallocInt(2);
|
||||
IntBuffer height = stack.mallocInt(2);
|
||||
|
||||
// Update window size
|
||||
glfwGetFramebufferSize(identifierLong, width, height);
|
||||
super.setSize(new Vec2i(width.get(0), height.get(0)));
|
||||
glfwGetWindowSize(identifierLong, width, height);
|
||||
super.setSize(new Vec2i(width.get(), height.get()));
|
||||
|
||||
// Clear IntBuffers
|
||||
width.clear();
|
||||
height.clear();
|
||||
|
||||
// Update window position
|
||||
glfwGetWindowPos(identifierLong, width, height);
|
||||
super.setPosition(new Vec2i(width.get(0), height.get(0)));
|
||||
*/
|
||||
glfwGetWindowPos(identifierLong, width, height);
|
||||
super.setPosition(new Vec2i(width.get(), height.get()));
|
||||
}
|
||||
|
||||
// Update window mode
|
||||
if (Miscellaneous.getBooleanizedInteger(glfwGetWindowAttrib(identifierLong, GLFW_ICONIFIED)))
|
||||
|
@ -226,6 +248,10 @@ public abstract class GlfwWindow extends Window {
|
|||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void render() throws NotOnMainThreadException {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return;
|
||||
|
||||
// Ensure running on the main thread
|
||||
if (!Miscellaneous.onMainThread())
|
||||
throw new NotOnMainThreadException();
|
||||
|
@ -248,22 +274,38 @@ public abstract class GlfwWindow extends Window {
|
|||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public boolean isClosureRequested() {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return false;
|
||||
|
||||
return glfwWindowShouldClose(identifierLong);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public boolean isFocused() {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return false;
|
||||
|
||||
return Tristate.toBoolean(Miscellaneous.getTristatedInteger(glfwGetWindowAttrib(identifierLong, GLFW_FOCUSED)));
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void focus() {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return;
|
||||
|
||||
glfwFocusWindow(identifierLong);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void requestAttention() {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return;
|
||||
|
||||
glfwRequestWindowAttention(identifierLong);
|
||||
}
|
||||
|
||||
|
@ -272,6 +314,10 @@ public abstract class GlfwWindow extends Window {
|
|||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void setName(@NotNull String name) {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return;
|
||||
|
||||
super.setName(name);
|
||||
createGlfwWindow();
|
||||
}
|
||||
|
@ -279,6 +325,10 @@ public abstract class GlfwWindow extends Window {
|
|||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void setTitle(@NotNull String title) {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return;
|
||||
|
||||
super.setTitle(title);
|
||||
glfwSetWindowTitle(identifierLong, title);
|
||||
}
|
||||
|
@ -286,6 +336,10 @@ public abstract class GlfwWindow extends Window {
|
|||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void setSize(@NotNull Vec2i size) {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return;
|
||||
|
||||
super.setSize(size);
|
||||
glfwSetWindowSize(identifierLong, size.getX(), size.getY());
|
||||
}
|
||||
|
@ -293,6 +347,10 @@ public abstract class GlfwWindow extends Window {
|
|||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void setMinimumSize(@NotNull Vec2i minimumSize) {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return;
|
||||
|
||||
super.setMinimumSize(minimumSize);
|
||||
glfwSetWindowSizeLimits(identifierLong, minimumSize.getX(), minimumSize.getY(), getMaximumSize().getX(), getMaximumSize().getY());
|
||||
}
|
||||
|
@ -300,6 +358,10 @@ public abstract class GlfwWindow extends Window {
|
|||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void setMaximumSize(@NotNull Vec2i maximumSize) {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return;
|
||||
|
||||
super.setMaximumSize(maximumSize);
|
||||
glfwSetWindowSizeLimits(identifierLong, getMinimumSize().getX(), getMinimumSize().getY(), maximumSize.getX(), maximumSize.getY());
|
||||
}
|
||||
|
@ -307,6 +369,10 @@ public abstract class GlfwWindow extends Window {
|
|||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void setPosition(@NotNull Vec2i position) {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return;
|
||||
|
||||
super.setPosition(position);
|
||||
glfwSetWindowSize(identifierLong, position.getX(), position.getY());
|
||||
}
|
||||
|
@ -314,6 +380,10 @@ public abstract class GlfwWindow extends Window {
|
|||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void setWindowMode(@NotNull WindowMode windowMode) {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return;
|
||||
|
||||
super.setWindowMode(windowMode);
|
||||
switch (windowMode) {
|
||||
case HIDDEN -> glfwHideWindow(identifierLong);
|
||||
|
@ -346,30 +416,50 @@ public abstract class GlfwWindow extends Window {
|
|||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void setResizable(boolean resizable) {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return;
|
||||
|
||||
super.setResizable(resizable);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void setBorderless(boolean borderless) {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return;
|
||||
|
||||
super.setBorderless(borderless);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void setFocusable(boolean focusable) {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return;
|
||||
|
||||
super.setFocusable(focusable);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void setOnTop(boolean onTop) {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return;
|
||||
|
||||
super.setOnTop(onTop);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void setTransparent(boolean transparent) {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return;
|
||||
|
||||
super.setTransparent(transparent);
|
||||
createGlfwWindow();
|
||||
}
|
||||
|
|
|
@ -89,6 +89,10 @@ public class OpenGlWindow extends GlfwWindow {
|
|||
@NotNull
|
||||
@Override
|
||||
public Vec2i getSizeWithDecorations() {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return new Vec2i(-1, -1);
|
||||
|
||||
return getSize();
|
||||
}
|
||||
|
||||
|
@ -96,6 +100,10 @@ public class OpenGlWindow extends GlfwWindow {
|
|||
@NotNull
|
||||
@Override
|
||||
public Vec2i getPositionWithDecorations() {
|
||||
// Ensure the window is not terminated
|
||||
if (isTerminated())
|
||||
return new Vec2i(-1, -1);
|
||||
|
||||
return getPosition();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ import java.util.Set;
|
|||
// TODO monitors
|
||||
@Getter
|
||||
@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
|
||||
public abstract class Window {
|
||||
public abstract class Window implements AutoCloseable {
|
||||
/**
|
||||
* A set of all active windows.
|
||||
*
|
||||
|
@ -76,6 +76,26 @@ public abstract class Window {
|
|||
@Getter(value = AccessLevel.PROTECTED)
|
||||
private final LoggerInstance logger = new LoggerInstance(new LogIssuer(getClass(), CodePart.ENGINE));
|
||||
|
||||
/**
|
||||
* Determines if this window can be interacted with or not.
|
||||
*
|
||||
* @since v1-alpha2
|
||||
*
|
||||
* -- GETTER --
|
||||
* Returns if this window can be interacted with or not.
|
||||
*
|
||||
* @return closed flag state
|
||||
* @since v1-alpha2
|
||||
*
|
||||
* -- SETTER --
|
||||
* Sets if this window can be interacted with or not.
|
||||
*
|
||||
* @param closed new closed flag state
|
||||
* @since v1-alpha2
|
||||
*/
|
||||
@Setter(AccessLevel.PROTECTED)
|
||||
private boolean terminated;
|
||||
|
||||
/**
|
||||
* Contains the window identifier.
|
||||
*
|
||||
|
@ -499,7 +519,7 @@ public abstract class Window {
|
|||
* @since v1-alpha2
|
||||
*/
|
||||
public Window(@NotNull String name, @NotNull String title, @NotNull Vec2i size, @NotNull Vec2i minimumSize, @NotNull Vec2i maximumSize, @NotNull Vec2i position, @NotNull WindowMode windowMode, @NotNull VsyncMode vsyncMode, boolean resizable, boolean borderless, boolean focusable, boolean onTop, boolean transparent, boolean rendering) throws UnexpectedThrowableException {
|
||||
logger.diag("Creating new window with properties: title=\"" + title + "\" size=" + size + " position=" + position + " windowMode=" + windowMode + " vsyncMode=" + vsyncMode + " resizable=" + resizable + " borderless=" + borderless + " focusable=" + focusable + " onTop=" + onTop + " transparent=" + transparent + " rendering=" + rendering);
|
||||
logger.diag("Creating new window with properties: name=\"" + name + "\" title=\"" + title + "\" size=" + size + " minimumSize=" + minimumSize + " maximumSize=" + maximumSize + " position=" + position + " windowMode=" + windowMode + " vsyncMode=" + vsyncMode + " resizable=" + resizable + " borderless=" + borderless + " focusable=" + focusable + " onTop=" + onTop + " transparent=" + transparent + " rendering=" + rendering);
|
||||
|
||||
// Initialize variables
|
||||
this.name = name;
|
||||
|
@ -548,6 +568,9 @@ public abstract class Window {
|
|||
* <p>
|
||||
* Do not call this method manually or you
|
||||
* may cause unintended side effects.
|
||||
*
|
||||
* @throws Throwable thrown by implementing method
|
||||
* @since v1-alpha2
|
||||
*/
|
||||
public abstract void updateState() throws Throwable;
|
||||
|
||||
|
@ -556,9 +579,29 @@ public abstract class Window {
|
|||
* <p>
|
||||
* Do not call this method manually or you
|
||||
* may cause unintended side effects.
|
||||
*
|
||||
* @throws Throwable thrown by implementing method
|
||||
* @since v1-alpha2
|
||||
*/
|
||||
public abstract void render() throws Throwable;
|
||||
|
||||
/**
|
||||
* Alias for {@link #terminate()}.
|
||||
*
|
||||
* @see #terminate()
|
||||
* @since v1-alpha2
|
||||
*/
|
||||
public void close() {
|
||||
terminate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminates the window, making it unable to be interacted with.
|
||||
*
|
||||
* @since v1-alpha2
|
||||
*/
|
||||
public abstract void terminate();
|
||||
|
||||
/**
|
||||
* Returns the window size including decorations (e.g. title bar).
|
||||
*
|
||||
|
|
|
@ -116,8 +116,9 @@ public class Main {
|
|||
ApiManagementClass management = api.getManagement();
|
||||
|
||||
// Create window
|
||||
Window window;
|
||||
try {
|
||||
Window window = new Window.Builder()
|
||||
window = new Window.Builder()
|
||||
.setName("sosengine-testapp")
|
||||
.setTitle("test application window")
|
||||
.setSize(new Vec2i(960, 540))
|
||||
|
@ -125,13 +126,33 @@ public class Main {
|
|||
.build();
|
||||
} catch (Throwable throwable) {
|
||||
logger.crash("Window.Builder#build() failed", throwable);
|
||||
return;
|
||||
}
|
||||
|
||||
// Sleep for 2.5 seconds
|
||||
logger.diag("Sleeping for 2.5s");
|
||||
try {
|
||||
Thread.sleep(2500);
|
||||
} catch (InterruptedException exception) {
|
||||
logger.crash("Was unable to sleep for 2500ms", exception);
|
||||
}
|
||||
|
||||
// Update state and render window
|
||||
try {
|
||||
logger.diag("Updating state");
|
||||
window.updateState();
|
||||
logger.diag("Rendering");
|
||||
window.render();
|
||||
} catch (Throwable throwable) {
|
||||
logger.crash("Window updating or rendering failed", throwable);
|
||||
}
|
||||
|
||||
// Sleep for five seconds
|
||||
logger.diag("Sleeping for 2.5s");
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
Thread.sleep(2500);
|
||||
} catch (InterruptedException exception) {
|
||||
logger.crash("Was unable to sleep for 5000ms", exception);
|
||||
logger.crash("Was unable to sleep for 2500ms", exception);
|
||||
}
|
||||
|
||||
// Shutdown
|
||||
|
|
Loading…
Reference in a new issue