diff --git a/.gitignore b/.gitignore index 19efae5c..d25c0223 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,5 @@ /src/native/common/Release /src/native/windows/Debug /src/native/windows/Release -/src/native/*/org_lwjgl_*.h -/src/native/*/*/org_lwjgl_*.h +/src/native/**/*.h /src/native/linux/org_lwjgl_opengl_Display.c diff --git a/.tool-versions b/.tool-versions index ab6a3328..6e8b53ee 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1 +1 @@ -java adoptopenjdk-8.0.322+6 +java temurin-17.0.3+7 diff --git a/build.xml b/build.xml index 04cc7176..5083b6b6 100644 --- a/build.xml +++ b/build.xml @@ -16,6 +16,8 @@ + + @@ -25,8 +27,6 @@ - - - @@ -76,21 +75,11 @@ - - - - - - - - - - @@ -108,7 +97,7 @@ - + @@ -117,13 +106,13 @@ - + - + @@ -175,144 +164,202 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -452,35 +499,23 @@ - - - - - - - - - - - - @@ -488,16 +523,12 @@ - - - - @@ -516,17 +547,11 @@ - - - - - - diff --git a/platform_build/build-definitions.xml b/platform_build/build-definitions.xml index ce34c328..97829d93 100644 --- a/platform_build/build-definitions.xml +++ b/platform_build/build-definitions.xml @@ -2,23 +2,31 @@ + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - diff --git a/platform_build/build-generator.xml b/platform_build/build-generator.xml index 430e76fe..01441891 100644 --- a/platform_build/build-generator.xml +++ b/platform_build/build-generator.xml @@ -3,7 +3,7 @@ - + @@ -35,17 +35,19 @@ - + + + + - + - - + @@ -83,13 +85,14 @@ + + - + - - + @@ -105,8 +108,10 @@ + + - + @@ -121,8 +126,10 @@ + + - + @@ -160,13 +167,14 @@ + + - + - - + @@ -182,8 +190,10 @@ + + - + @@ -228,13 +238,14 @@ + + - + - - + @@ -250,8 +261,10 @@ + + - + diff --git a/platform_build/linux_ant/build.xml b/platform_build/linux_ant/build.xml index bde9a127..344d4e3d 100644 --- a/platform_build/linux_ant/build.xml +++ b/platform_build/linux_ant/build.xml @@ -3,8 +3,8 @@ - - + + @@ -52,7 +52,7 @@ - + @@ -72,19 +72,19 @@ - + - + - + @@ -104,13 +104,13 @@ - + - - + + diff --git a/platform_build/linux_ant/build_es.xml b/platform_build/linux_ant/build_es.xml index b50f170f..73dde1dc 100644 --- a/platform_build/linux_ant/build_es.xml +++ b/platform_build/linux_ant/build_es.xml @@ -5,8 +5,8 @@ - - + + diff --git a/platform_build/macosx_ant/build.xml b/platform_build/macosx_ant/build.xml index da69903b..3f49d651 100644 --- a/platform_build/macosx_ant/build.xml +++ b/platform_build/macosx_ant/build.xml @@ -95,7 +95,7 @@ - + @@ -117,12 +117,12 @@ - - + + - + @@ -173,7 +173,7 @@ - + @@ -198,12 +198,12 @@ - + - - + + diff --git a/src/java/org/lwjgl/LWJGLUtil.java b/src/java/org/lwjgl/LWJGLUtil.java index 0ab810e0..697399f6 100644 --- a/src/java/org/lwjgl/LWJGLUtil.java +++ b/src/java/org/lwjgl/LWJGLUtil.java @@ -268,6 +268,32 @@ public class LWJGLUtil { private static final int PLATFORM; + private static StupidSimpleLogger logger = msg -> { + //if (DEBUG) { + System.err.println("[LWJGL] " + msg); + //} + }; + + public static StupidSimpleLogger logger() { + return logger; + } + + public static void logger(StupidSimpleLogger newLogger) { + logger = newLogger; + } + + /** + * Logs the given message. + * + * @param msg Message to print + * + * @deprecated Use {@link #logger} instead. + */ + @Deprecated + public static void log(CharSequence msg) { + logger().log(() -> msg.toString()); + } + static { final String osName = getPrivilegedProperty("os.name"); if ( osName.startsWith("Windows") ) @@ -504,17 +530,6 @@ public class LWJGLUtil { }); } - /** - * Prints the given message to System.err if DEBUG is true. - * - * @param msg Message to print - */ - public static void log(CharSequence msg) { - if (DEBUG) { - System.err.println("[LWJGL] " + msg); - } - } - /** * Method to determine if the current system is running a version of * Mac OS X better than the given version. This is only useful for Mac OS X diff --git a/src/java/org/lwjgl/MemoryUtilSun.java b/src/java/org/lwjgl/MemoryUtilSun.java index 683f372b..f5829c78 100644 --- a/src/java/org/lwjgl/MemoryUtilSun.java +++ b/src/java/org/lwjgl/MemoryUtilSun.java @@ -31,13 +31,14 @@ */ package org.lwjgl; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.nio.Buffer; import sun.misc.Unsafe; -import sun.reflect.FieldAccessor; /** * MemoryUtil.Accessor implementations that depend on sun.misc. @@ -103,33 +104,35 @@ final class MemoryUtilSun { } - /** Implementation using reflection on ByteBuffer, FieldAccessor is used directly. */ + /** Implementation using {@link java.lang.MethodHandle}s on ByteBuffer. Reflection is used to acquire the handle. */ private static class AccessorReflectFast implements MemoryUtil.Accessor { - private final FieldAccessor addressAccessor; + private final MethodHandle addressAccessor; AccessorReflectFast() { - Field address; + Field addressField; try { - address = MemoryUtil.getAddressField(); + addressField = MemoryUtil.getAddressField(); } catch (NoSuchFieldException e) { throw new UnsupportedOperationException(e); } - address.setAccessible(true); + addressField.setAccessible(true); try { - Method m = Field.class.getDeclaredMethod("acquireFieldAccessor", boolean.class); - m.setAccessible(true); - addressAccessor = (FieldAccessor)m.invoke(address, true); - } catch (Exception e) { + addressAccessor = MethodHandles.lookup().unreflectGetter(addressField); + } catch (ReflectiveOperationException e) { throw new UnsupportedOperationException(e); } } public long getAddress(final Buffer buffer) { - return addressAccessor.getLong(buffer); + try { + return (long) addressAccessor.invokeExact(buffer); + } catch (Throwable e) { + throw new RuntimeException(e); + } } } -} \ No newline at end of file +} diff --git a/src/java/org/lwjgl/StupidSimpleLogger.java b/src/java/org/lwjgl/StupidSimpleLogger.java new file mode 100644 index 00000000..1e7b5c7f --- /dev/null +++ b/src/java/org/lwjgl/StupidSimpleLogger.java @@ -0,0 +1,58 @@ +package org.lwjgl; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.function.Supplier; + +/** + * A (mostly) stupidly simple logger. + */ +@FunctionalInterface +public interface StupidSimpleLogger { + /** + * Logs a message provided lazily. + */ + void log(Supplier message); + + /** + * Logs a message. + */ + default void log(String message) { + log(() -> message); + } + + /** + * Logs a message provided lazily and an error. + */ + default void log(Supplier message, Throwable throwable) { + log(() -> { + StringWriter buf = new StringWriter().append(message.get()).append('\n'); + throwable.printStackTrace(new PrintWriter(buf)); + return buf.toString(); + }); + } + + /** + * Logs a message and an error. + */ + default void log(String message, Throwable throwable) { + log(() -> message, throwable); + } + + /** + * A No-Op implementation of the logger. All default forwarding methods are overidden with No-Op implementations. + */ + public static final StupidSimpleLogger NOOP = new StupidSimpleLogger() { + @Override + public void log(Supplier message) {} + + @Override + public void log(String message) {} + + @Override + public void log(Supplier message, Throwable throwable) {} + + @Override + public void log(String message, Throwable throwable) {} + }; +} diff --git a/src/java/org/lwjgl/opengl/AWTGLCanvas.java b/src/java/org/lwjgl/opengl/AWTGLCanvas.java index bf7ab1ba..ca784a5f 100644 --- a/src/java/org/lwjgl/opengl/AWTGLCanvas.java +++ b/src/java/org/lwjgl/opengl/AWTGLCanvas.java @@ -216,7 +216,7 @@ public class AWTGLCanvas extends Canvas implements DrawableLWJGL, ComponentListe } /** Set swap interval. */ - public void setSwapInterval(int swap_interval) { + public void setSwapInterval(int swap_interval) throws LWJGLException { synchronized ( SYNC_LOCK ) { if ( context == null ) throw new IllegalStateException("Canvas not yet displayable"); @@ -225,7 +225,7 @@ public class AWTGLCanvas extends Canvas implements DrawableLWJGL, ComponentListe } /** Enable vsync */ - public void setVSyncEnabled(boolean enabled) { + public void setVSyncEnabled(boolean enabled) throws LWJGLException { setSwapInterval(enabled ? 1 : 0); } @@ -411,4 +411,4 @@ public class AWTGLCanvas extends Canvas implements DrawableLWJGL, ComponentListe setUpdate(); } -} \ No newline at end of file +} diff --git a/src/java/org/lwjgl/opengl/ContextGL.java b/src/java/org/lwjgl/opengl/ContextGL.java index b5738537..22ecb45a 100644 --- a/src/java/org/lwjgl/opengl/ContextGL.java +++ b/src/java/org/lwjgl/opengl/ContextGL.java @@ -228,7 +228,7 @@ final class ContextGL implements Context { *

* A video frame period is the time required to display a full frame of video data. */ - public static void setSwapInterval(int value) { + public static void setSwapInterval(int value) throws LWJGLException { implementation.setSwapInterval(value); } @@ -296,4 +296,4 @@ final class ContextGL implements Context { } } -} \ No newline at end of file +} diff --git a/src/java/org/lwjgl/opengl/ContextImplementation.java b/src/java/org/lwjgl/opengl/ContextImplementation.java index 62a828d9..8db3525f 100644 --- a/src/java/org/lwjgl/opengl/ContextImplementation.java +++ b/src/java/org/lwjgl/opengl/ContextImplementation.java @@ -81,7 +81,7 @@ interface ContextImplementation { */ boolean isCurrent(ByteBuffer handle) throws LWJGLException; - void setSwapInterval(int value); + void setSwapInterval(int value) throws LWJGLException; /** * Destroys the Context. diff --git a/src/java/org/lwjgl/opengl/Display.java b/src/java/org/lwjgl/opengl/Display.java index 8b0a55f1..b367cfca 100644 --- a/src/java/org/lwjgl/opengl/Display.java +++ b/src/java/org/lwjgl/opengl/Display.java @@ -328,7 +328,7 @@ public final class Display { context.releaseDrawable(); } } catch (LWJGLException e) { - LWJGLUtil.log("Exception occurred while trying to release context: " + e); + LWJGLUtil.logger().log("Exception occurred while trying to release context", e); } } @@ -413,16 +413,12 @@ public final class Display { /** @return the title of the window */ public static String getTitle() { - synchronized ( GlobalLock.lock ) { - return title; - } + return title; } /** Return the last parent set with setParent(). */ public static Canvas getParent() { - synchronized ( GlobalLock.lock ) { - return parent; - } + return parent; } /** @@ -521,9 +517,7 @@ public final class Display { /** @return whether the Display is in fullscreen mode */ public static boolean isFullscreen() { - synchronized ( GlobalLock.lock ) { - return fullscreen && current_mode.isFullscreenCapable(); - } + return fullscreen && current_mode.isFullscreenCapable(); } /** @@ -1026,7 +1020,7 @@ public final class Display { try { drawable.checkGLError(); } catch (OpenGLException e) { - LWJGLUtil.log("OpenGL error during context creation: " + e.getMessage()); + LWJGLUtil.logger().log("OpenGL error during context creation", e); } setSwapInterval(swap_interval); } @@ -1042,20 +1036,19 @@ public final class Display { /** Gets a boolean property as a privileged action. */ static boolean getPrivilegedBoolean(final String property_name) { - return AccessController.doPrivileged(new PrivilegedAction() { - public Boolean run() { - return Boolean.getBoolean(property_name); + String s = getPrivilegedString(property_name); + if (s == null || s.equals("false")) return false; + if (LWJGLUtil.DEBUG) { + if (!s.equals("true")) { + LWJGLUtil.logger().log(() -> "Value of boolean property " + property_name + " is not one of [true, false]: " + s); } - }); + } + return true; } /** Gets a string property as a privileged action. */ static String getPrivilegedString(final String property_name) { - return AccessController.doPrivileged(new PrivilegedAction() { - public String run() { - return System.getProperty(property_name); - } - }); + return AccessController.doPrivileged((PrivilegedAction) () -> System.getProperty(property_name)); } private static void initControls() { @@ -1065,22 +1058,14 @@ public final class Display { try { Mouse.create(); } catch (LWJGLException e) { - if ( LWJGLUtil.DEBUG ) { - e.printStackTrace(System.err); - } else { - LWJGLUtil.log("Failed to create Mouse: " + e); - } + LWJGLUtil.logger().log("Failed to create Mouse", e); } } if ( !Keyboard.isCreated() && !getPrivilegedBoolean("org.lwjgl.opengl.Display.nokeyboard") ) { try { Keyboard.create(); } catch (LWJGLException e) { - if ( LWJGLUtil.DEBUG ) { - e.printStackTrace(System.err); - } else { - LWJGLUtil.log("Failed to create Keyboard: " + e); - } + LWJGLUtil.logger().log("Failed to create Keyboard", e); } } } @@ -1091,7 +1076,7 @@ public final class Display { * regardless of whether the Display was the current rendering context. */ public static void destroy() { - if(isCreated()) { + if (isCreated()) { drawable.destroy(); } } @@ -1108,9 +1093,7 @@ public final class Display { /** @return true if the window's native peer has been created */ public static boolean isCreated() { - synchronized ( GlobalLock.lock ) { - return window_created; - } + return window_created; } /** @@ -1122,7 +1105,7 @@ public final class Display { * * @param value The swap interval in frames, 0 to disable */ - public static void setSwapInterval(int value) { + public static void setSwapInterval(int value) throws LWJGLException { synchronized ( GlobalLock.lock ) { swap_interval = value; if ( isCreated() ) @@ -1137,10 +1120,8 @@ public final class Display { * * @param sync true to synchronize; false to ignore synchronization */ - public static void setVSyncEnabled(boolean sync) { - synchronized ( GlobalLock.lock ) { - setSwapInterval(sync ? 1 : 0); - } + public static void setVSyncEnabled(boolean sync) throws LWJGLException { + setSwapInterval(sync ? 1 : 0); } /** @@ -1178,9 +1159,7 @@ public final class Display { * @return a String */ public static String getAdapter() { - synchronized ( GlobalLock.lock ) { - return display_impl.getAdapter(); - } + return display_impl.getAdapter(); } /** @@ -1190,9 +1169,7 @@ public final class Display { * @return a String */ public static String getVersion() { - synchronized ( GlobalLock.lock ) { - return display_impl.getVersion(); - } + return display_impl.getVersion(); } /** diff --git a/src/java/org/lwjgl/opengl/DrawableGL.java b/src/java/org/lwjgl/opengl/DrawableGL.java index b1b767c9..886df156 100644 --- a/src/java/org/lwjgl/opengl/DrawableGL.java +++ b/src/java/org/lwjgl/opengl/DrawableGL.java @@ -82,7 +82,7 @@ abstract class DrawableGL implements DrawableLWJGL { Util.checkGLError(); } - public void setSwapInterval(final int swap_interval) { + public void setSwapInterval(final int swap_interval) throws LWJGLException { ContextGL.setSwapInterval(swap_interval); } diff --git a/src/java/org/lwjgl/opengl/DrawableLWJGL.java b/src/java/org/lwjgl/opengl/DrawableLWJGL.java index e4d989df..af46cbd2 100644 --- a/src/java/org/lwjgl/opengl/DrawableLWJGL.java +++ b/src/java/org/lwjgl/opengl/DrawableLWJGL.java @@ -62,10 +62,10 @@ interface DrawableLWJGL extends Drawable { void checkGLError(); - void setSwapInterval(int swap_interval); + void setSwapInterval(int swap_interval) throws LWJGLException; void swapBuffers() throws LWJGLException; void initContext(final float r, final float g, final float b); -} \ No newline at end of file +} diff --git a/src/java/org/lwjgl/opengl/LinuxCanvasImplementation.java b/src/java/org/lwjgl/opengl/LinuxCanvasImplementation.java index e84d4000..0672413f 100644 --- a/src/java/org/lwjgl/opengl/LinuxCanvasImplementation.java +++ b/src/java/org/lwjgl/opengl/LinuxCanvasImplementation.java @@ -102,8 +102,7 @@ final class LinuxCanvasImplementation implements AWTCanvasImplementation { } private static int findVisualIDFromFormat(int screen, PixelFormat pixel_format) throws LWJGLException { - try { - LinuxDisplay.lockAWT(); + try (LinuxDisplay.AWTLock _lock = LinuxDisplay.awtLock()) { try { GLContext.loadOpenGLLibrary(); try { @@ -115,8 +114,6 @@ final class LinuxCanvasImplementation implements AWTCanvasImplementation { } finally { GLContext.unloadOpenGLLibrary(); } - } finally { - LinuxDisplay.unlockAWT(); } } private static native int nFindVisualIDFromFormat(long display, int screen, PixelFormat pixel_format) throws LWJGLException; diff --git a/src/java/org/lwjgl/opengl/LinuxContextImplementation.java b/src/java/org/lwjgl/opengl/LinuxContextImplementation.java index 753a45e7..046fda1a 100644 --- a/src/java/org/lwjgl/opengl/LinuxContextImplementation.java +++ b/src/java/org/lwjgl/opengl/LinuxContextImplementation.java @@ -44,16 +44,13 @@ import java.nio.IntBuffer; final class LinuxContextImplementation implements ContextImplementation { public ByteBuffer create(PeerInfo peer_info, IntBuffer attribs, ByteBuffer shared_context_handle) throws LWJGLException { - LinuxDisplay.lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = LinuxDisplay.awtLock()) { ByteBuffer peer_handle = peer_info.lockAndGetHandle(); try { return nCreate(peer_handle, attribs, shared_context_handle); } finally { peer_info.unlock(); } - } finally { - LinuxDisplay.unlockAWT(); } } @@ -72,16 +69,13 @@ final class LinuxContextImplementation implements ContextImplementation { throw new IllegalStateException("No context is current"); synchronized ( current_context ) { PeerInfo current_peer_info = current_context.getPeerInfo(); - LinuxDisplay.lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = LinuxDisplay.awtLock()) { ByteBuffer peer_handle = current_peer_info.lockAndGetHandle(); try { nSwapBuffers(peer_handle); } finally { current_peer_info.unlock(); } - } finally { - LinuxDisplay.unlockAWT(); } } } @@ -94,16 +88,13 @@ final class LinuxContextImplementation implements ContextImplementation { throw new IllegalStateException("No context is current"); synchronized ( current_context ) { PeerInfo current_peer_info = current_context.getPeerInfo(); - LinuxDisplay.lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = LinuxDisplay.awtLock()) { ByteBuffer peer_handle = current_peer_info.lockAndGetHandle(); try { nReleaseCurrentContext(peer_handle); } finally { current_peer_info.unlock(); } - } finally { - LinuxDisplay.unlockAWT(); } } } @@ -114,34 +105,29 @@ final class LinuxContextImplementation implements ContextImplementation { } public void makeCurrent(PeerInfo peer_info, ByteBuffer handle) throws LWJGLException { - LinuxDisplay.lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = LinuxDisplay.awtLock()) { ByteBuffer peer_handle = peer_info.lockAndGetHandle(); try { nMakeCurrent(peer_handle, handle); } finally { peer_info.unlock(); } - } finally { - LinuxDisplay.unlockAWT(); } } private static native void nMakeCurrent(ByteBuffer peer_handle, ByteBuffer context_handle) throws LWJGLException; public boolean isCurrent(ByteBuffer handle) throws LWJGLException { - LinuxDisplay.lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = LinuxDisplay.awtLock()) { boolean result = nIsCurrent(handle); return result; - } finally { - LinuxDisplay.unlockAWT(); } } private static native boolean nIsCurrent(ByteBuffer context_handle) throws LWJGLException; - public void setSwapInterval(int value) { + @Override + public void setSwapInterval(int value) throws LWJGLException { ContextGL current_context = ContextGL.getCurrentContext(); if ( current_context == null ) @@ -150,19 +136,13 @@ final class LinuxContextImplementation implements ContextImplementation { PeerInfo peer_info = current_context.getPeerInfo(); synchronized ( current_context ) { - LinuxDisplay.lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = LinuxDisplay.awtLock()) { ByteBuffer peer_handle = peer_info.lockAndGetHandle(); try { nSetSwapInterval(peer_handle, current_context.getHandle(), value); } finally { peer_info.unlock(); } - } catch (LWJGLException e) { - // API CHANGE - this methods should throw LWJGLException - e.printStackTrace(); - } finally { - LinuxDisplay.unlockAWT(); } } } @@ -170,16 +150,13 @@ final class LinuxContextImplementation implements ContextImplementation { private static native void nSetSwapInterval(ByteBuffer peer_handle, ByteBuffer context_handle, int value); public void destroy(PeerInfo peer_info, ByteBuffer handle) throws LWJGLException { - LinuxDisplay.lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = LinuxDisplay.awtLock()) { ByteBuffer peer_handle = peer_info.lockAndGetHandle(); try { nDestroy(peer_handle, handle); } finally { peer_info.unlock(); } - } finally { - LinuxDisplay.unlockAWT(); } } diff --git a/src/java/org/lwjgl/opengl/LinuxDisplay.java b/src/java/org/lwjgl/opengl/LinuxDisplay.java index 30728fa3..71e08936 100644 --- a/src/java/org/lwjgl/opengl/LinuxDisplay.java +++ b/src/java/org/lwjgl/opengl/LinuxDisplay.java @@ -178,8 +178,7 @@ final class LinuxDisplay implements DisplayImplementation { }; private static ByteBuffer getCurrentGammaRamp() throws LWJGLException { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { incDisplay(); try { if (isXF86VidModeSupported()) @@ -189,8 +188,6 @@ final class LinuxDisplay implements DisplayImplementation { } finally { decDisplay(); } - } finally { - unlockAWT(); } } private static native ByteBuffer nGetCurrentGammaRamp(long display, int screen) throws LWJGLException; @@ -213,8 +210,7 @@ final class LinuxDisplay implements DisplayImplementation { private static boolean isXrandrSupported() { if (Display.getPrivilegedBoolean("LWJGL_DISABLE_XRANDR")) return false; - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { incDisplay(); try { return nIsXrandrSupported(getDisplay()); @@ -224,15 +220,12 @@ final class LinuxDisplay implements DisplayImplementation { } catch (LWJGLException e) { LWJGLUtil.log("Got exception while querying Xrandr support: " + e); return false; - } finally { - unlockAWT(); } } private static native boolean nIsXrandrSupported(long display) throws LWJGLException; private static boolean isXF86VidModeSupported() { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { incDisplay(); try { return nIsXF86VidModeSupported(getDisplay()); @@ -242,8 +235,6 @@ final class LinuxDisplay implements DisplayImplementation { } catch (LWJGLException e) { LWJGLUtil.log("Got exception while querying XF86VM support: " + e); return false; - } finally { - unlockAWT(); } } private static native boolean nIsXF86VidModeSupported(long display) throws LWJGLException; @@ -251,8 +242,7 @@ final class LinuxDisplay implements DisplayImplementation { private static boolean isNetWMFullscreenSupported() throws LWJGLException { if (Display.getPrivilegedBoolean("LWJGL_DISABLE_NETWM")) return false; - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { incDisplay(); try { return nIsNetWMFullscreenSupported(getDisplay(), getDefaultScreen()); @@ -262,32 +252,38 @@ final class LinuxDisplay implements DisplayImplementation { } catch (LWJGLException e) { LWJGLUtil.log("Got exception while querying NetWM support: " + e); return false; - } finally { - unlockAWT(); } } private static native boolean nIsNetWMFullscreenSupported(long display, int screen) throws LWJGLException; + public static final class AWTLock implements AutoCloseable { + private static final AWTLock INSTANCE = new AWTLock(); + + @Override + public void close() { + try { + nUnlockAWT(); + } catch (LWJGLException e) { + LWJGLUtil.log("Caught exception while unlocking AWT: " + e); + } + } + } + /* Since Xlib is not guaranteed to be thread safe, we need a way to synchronize LWJGL * Xlib calls with AWT Xlib calls. Fortunately, JAWT implements Lock()/Unlock() to * do just that. */ - static void lockAWT() { + static AWTLock awtLock() { try { nLockAWT(); } catch (LWJGLException e) { LWJGLUtil.log("Caught exception while locking AWT: " + e); } + return AWTLock.INSTANCE; } + private static native void nLockAWT() throws LWJGLException; - static void unlockAWT() { - try { - nUnlockAWT(); - } catch (LWJGLException e) { - LWJGLUtil.log("Caught exception while unlocking AWT: " + e); - } - } private static native void nUnlockAWT() throws LWJGLException; /** @@ -452,8 +448,7 @@ final class LinuxDisplay implements DisplayImplementation { } public void createWindow(final DrawableLWJGL drawable, DisplayMode mode, Canvas parent, int x, int y) throws LWJGLException { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { incDisplay(); try { if ( drawable instanceof DrawableGLES ) @@ -527,8 +522,6 @@ final class LinuxDisplay implements DisplayImplementation { decDisplay(); throw e; } - } finally { - unlockAWT(); } } private static native long nCreateWindow(long display, int screen, ByteBuffer peer_info_handle, DisplayMode mode, int window_mode, int x, int y, boolean undecorated, long parent_handle, boolean resizable) throws LWJGLException; @@ -576,8 +569,7 @@ final class LinuxDisplay implements DisplayImplementation { } public void destroyWindow() { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { if (parent != null) { parent.removeFocusListener(focus_listener); } @@ -594,19 +586,14 @@ final class LinuxDisplay implements DisplayImplementation { if ( current_window_mode != WINDOWED ) Compiz.setLegacyFullscreenSupport(false); - } finally { - unlockAWT(); } } static native void nDestroyWindow(long display, long window); public void switchDisplayMode(DisplayMode mode) throws LWJGLException { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { switchDisplayModeOnTmpDisplay(mode); current_mode = mode; - } finally { - unlockAWT(); } } @@ -636,8 +623,7 @@ final class LinuxDisplay implements DisplayImplementation { static native long nInternAtom(long display, String atom_name, boolean only_if_exists); public void resetDisplayMode() { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { if( current_displaymode_extension == XRANDR ) { AccessController.doPrivileged(new PrivilegedAction() { @@ -657,16 +643,13 @@ final class LinuxDisplay implements DisplayImplementation { Compiz.setLegacyFullscreenSupport(false); } catch (LWJGLException e) { LWJGLUtil.log("Caught exception while resetting mode: " + e); - } finally { - unlockAWT(); } } public int getGammaRampLength() { if (!isXF86VidModeSupported()) return 0; - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { try { incDisplay(); try { @@ -681,8 +664,6 @@ final class LinuxDisplay implements DisplayImplementation { LWJGLUtil.log("Failed to get gamma ramp length: " + e); return 0; } - } finally { - unlockAWT(); } } private static native int nGetGammaRampLength(long display, int screen) throws LWJGLException; @@ -694,12 +675,9 @@ final class LinuxDisplay implements DisplayImplementation { } private void doSetGamma(ByteBuffer native_gamma) throws LWJGLException { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { setGammaRampOnTmpDisplay(native_gamma); current_gamma = native_gamma; - } finally { - unlockAWT(); } } @@ -727,8 +705,7 @@ final class LinuxDisplay implements DisplayImplementation { } public DisplayMode init() throws LWJGLException { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { Compiz.init(); delete_atom = internAtom("WM_DELETE_WINDOW", false); @@ -756,22 +733,17 @@ final class LinuxDisplay implements DisplayImplementation { saved_gamma = getCurrentGammaRamp(); current_gamma = saved_gamma; return saved_mode; - } finally { - unlockAWT(); } } private static DisplayMode getCurrentXRandrMode() throws LWJGLException { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { incDisplay(); try { return nGetCurrentXRandrMode(getDisplay(), getDefaultScreen()); } finally { decDisplay(); } - } finally { - unlockAWT(); } } @@ -779,26 +751,20 @@ final class LinuxDisplay implements DisplayImplementation { private static native DisplayMode nGetCurrentXRandrMode(long display, int screen) throws LWJGLException; public void setTitle(String title) { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { final ByteBuffer titleText = MemoryUtil.encodeUTF8(title); nSetTitle(getDisplay(), getWindow(), MemoryUtil.getAddress(titleText), titleText.remaining() - 1); - } finally { - unlockAWT(); } } private static native void nSetTitle(long display, long window, long title, int len); /** the WM_CLASS hint is needed by some WM's e.g. gnome shell */ private void setClassHint(String wm_name, String wm_class) { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { final ByteBuffer nameText = MemoryUtil.encodeUTF8(wm_name); final ByteBuffer classText = MemoryUtil.encodeUTF8(wm_class); nSetClassHint(getDisplay(), getWindow(), MemoryUtil.getAddress(nameText), MemoryUtil.getAddress(classText)); - } finally { - unlockAWT(); } } private static native void nSetClassHint(long display, long window, long wm_name, long wm_class); @@ -916,28 +882,21 @@ final class LinuxDisplay implements DisplayImplementation { } public void update() { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { processEvents(); checkInput(); - } finally { - unlockAWT(); } } public void reshape(int x, int y, int width, int height) { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { nReshape(getDisplay(), getWindow(), x, y, width, height); - } finally { - unlockAWT(); } } private static native void nReshape(long display, long window, int x, int y, int width, int height); public DisplayMode[] getAvailableDisplayModes() throws LWJGLException { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { incDisplay(); if (current_displaymode_extension == XRANDR) { // nGetAvailableDisplayModes cannot be trusted. Use it only for bitsPerPixel @@ -961,8 +920,6 @@ final class LinuxDisplay implements DisplayImplementation { decDisplay(); } } - } finally { - unlockAWT(); } } private static native DisplayMode[] nGetAvailableDisplayModes(long display, int screen, int extension) throws LWJGLException; @@ -977,11 +934,8 @@ final class LinuxDisplay implements DisplayImplementation { } public void createMouse() throws LWJGLException { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { mouse = new LinuxMouse(getDisplay(), getWindow(), getWindow()); - } finally { - unlockAWT(); } } @@ -991,29 +945,20 @@ final class LinuxDisplay implements DisplayImplementation { } public void pollMouse(IntBuffer coord_buffer, ByteBuffer buttons) { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { mouse.poll(grab, coord_buffer, buttons); - } finally { - unlockAWT(); } } public void readMouse(ByteBuffer buffer) { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { mouse.read(buffer); - } finally { - unlockAWT(); } } public void setCursorPosition(int x, int y) { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { mouse.setCursorPosition(x, y); - } finally { - unlockAWT(); } } @@ -1165,15 +1110,12 @@ final class LinuxDisplay implements DisplayImplementation { } public void grabMouse(boolean new_grab) { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { if (new_grab != grab) { grab = new_grab; updateInputGrab(); mouse.changeGrabbed(grab, shouldWarpPointer()); } - } finally { - unlockAWT(); } } @@ -1182,8 +1124,7 @@ final class LinuxDisplay implements DisplayImplementation { } public int getNativeCursorCapabilities() { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { incDisplay(); try { return nGetNativeCursorCapabilities(getDisplay()); @@ -1192,25 +1133,19 @@ final class LinuxDisplay implements DisplayImplementation { } } catch (LWJGLException e) { throw new RuntimeException(e); - } finally { - unlockAWT(); } } private static native int nGetNativeCursorCapabilities(long display) throws LWJGLException; public void setNativeCursor(Object handle) throws LWJGLException { current_cursor = getCursorHandle(handle); - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { updateCursor(); - } finally { - unlockAWT(); } } public int getMinCursorSize() { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { incDisplay(); try { return nGetMinCursorSize(getDisplay(), getWindow()); @@ -1220,15 +1155,12 @@ final class LinuxDisplay implements DisplayImplementation { } catch (LWJGLException e) { LWJGLUtil.log("Exception occurred in getMinCursorSize: " + e); return 0; - } finally { - unlockAWT(); } } private static native int nGetMinCursorSize(long display, long window); public int getMaxCursorSize() { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { incDisplay(); try { return nGetMaxCursorSize(getDisplay(), getWindow()); @@ -1238,47 +1170,33 @@ final class LinuxDisplay implements DisplayImplementation { } catch (LWJGLException e) { LWJGLUtil.log("Exception occurred in getMaxCursorSize: " + e); return 0; - } finally { - unlockAWT(); } } private static native int nGetMaxCursorSize(long display, long window); /* Keyboard */ public void createKeyboard() throws LWJGLException { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { keyboard = new LinuxKeyboard(getDisplay(), getWindow()); - } finally { - unlockAWT(); } } public void destroyKeyboard() { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { keyboard.destroy(getDisplay()); keyboard = null; - } finally { - unlockAWT(); } } public void pollKeyboard(ByteBuffer keyDownBuffer) { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { keyboard.poll(keyDownBuffer); - } finally { - unlockAWT(); } } public void readKeyboard(ByteBuffer buffer) { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { keyboard.read(buffer); - } finally { - unlockAWT(); } } @@ -1290,8 +1208,7 @@ final class LinuxDisplay implements DisplayImplementation { static native long nCreateBlankCursor(long display, long window); public Object createCursor(int width, int height, int xHotspot, int yHotspot, int numImages, IntBuffer images, IntBuffer delays) throws LWJGLException { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { incDisplay(); try { long cursor = nCreateCursor(getDisplay(), width, height, xHotspot, yHotspot, numImages, images, images.position(), delays, delays != null ? delays.position() : -1); @@ -1300,8 +1217,6 @@ final class LinuxDisplay implements DisplayImplementation { decDisplay(); throw e; } - } finally { - unlockAWT(); } } @@ -1310,19 +1225,15 @@ final class LinuxDisplay implements DisplayImplementation { } public void destroyCursor(Object cursorHandle) { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { nDestroyCursor(getDisplay(), getCursorHandle(cursorHandle)); decDisplay(); - } finally { - unlockAWT(); } } static native void nDestroyCursor(long display, long cursorHandle); public int getPbufferCapabilities() { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { incDisplay(); try { return nGetPbufferCapabilities(getDisplay(), getDefaultScreen()); @@ -1332,8 +1243,6 @@ final class LinuxDisplay implements DisplayImplementation { } catch (LWJGLException e) { LWJGLUtil.log("Exception occurred in getPbufferCapabilities: " + e); return 0; - } finally { - unlockAWT(); } } private static native int nGetPbufferCapabilities(long display, int screen); @@ -1426,8 +1335,7 @@ final class LinuxDisplay implements DisplayImplementation { * @return number of icons used. */ public int setIcon(ByteBuffer[] icons) { - lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = awtLock()) { incDisplay(); try { // get icons as cardinal ARGB format @@ -1441,8 +1349,6 @@ final class LinuxDisplay implements DisplayImplementation { } catch (LWJGLException e) { LWJGLUtil.log("Failed to set display icon: " + e); return 0; - } finally { - unlockAWT(); } } diff --git a/src/java/org/lwjgl/opengl/LinuxDisplayPeerInfo.java b/src/java/org/lwjgl/opengl/LinuxDisplayPeerInfo.java index 76af84a4..0ffca744 100644 --- a/src/java/org/lwjgl/opengl/LinuxDisplayPeerInfo.java +++ b/src/java/org/lwjgl/opengl/LinuxDisplayPeerInfo.java @@ -52,8 +52,7 @@ final class LinuxDisplayPeerInfo extends LinuxPeerInfo { LinuxDisplayPeerInfo(PixelFormat pixel_format) throws LWJGLException { egl = false; - LinuxDisplay.lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = LinuxDisplay.awtLock()) { GLContext.loadOpenGLLibrary(); try { LinuxDisplay.incDisplay(); @@ -67,18 +66,13 @@ final class LinuxDisplayPeerInfo extends LinuxPeerInfo { GLContext.unloadOpenGLLibrary(); throw e; } - } finally { - LinuxDisplay.unlockAWT(); } } private static native void initDefaultPeerInfo(long display, int screen, ByteBuffer peer_info_handle, PixelFormat pixel_format) throws LWJGLException; protected void doLockAndInitHandle() throws LWJGLException { - LinuxDisplay.lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = LinuxDisplay.awtLock()) { initDrawable(LinuxDisplay.getWindow(), getHandle()); - } finally { - LinuxDisplay.unlockAWT(); } } private static native void initDrawable(long window, ByteBuffer peer_info_handle); @@ -90,13 +84,13 @@ final class LinuxDisplayPeerInfo extends LinuxPeerInfo { public void destroy() { super.destroy(); - if ( egl ) + if (egl) { org.lwjgl.opengles.GLContext.unloadOpenGLLibrary(); - else { - LinuxDisplay.lockAWT(); - LinuxDisplay.decDisplay(); - GLContext.unloadOpenGLLibrary(); - LinuxDisplay.unlockAWT(); + } else { + try (LinuxDisplay.AWTLock _lock = LinuxDisplay.awtLock()) { + LinuxDisplay.decDisplay(); + GLContext.unloadOpenGLLibrary(); + } } } } diff --git a/src/java/org/lwjgl/opengl/LinuxPbufferPeerInfo.java b/src/java/org/lwjgl/opengl/LinuxPbufferPeerInfo.java index 3828c014..fbb12a62 100644 --- a/src/java/org/lwjgl/opengl/LinuxPbufferPeerInfo.java +++ b/src/java/org/lwjgl/opengl/LinuxPbufferPeerInfo.java @@ -43,8 +43,7 @@ import org.lwjgl.LWJGLException; */ final class LinuxPbufferPeerInfo extends LinuxPeerInfo { LinuxPbufferPeerInfo(int width, int height, PixelFormat pixel_format) throws LWJGLException { - LinuxDisplay.lockAWT(); - try { + try (LinuxDisplay.AWTLock _lock = LinuxDisplay.awtLock()) { GLContext.loadOpenGLLibrary(); try { LinuxDisplay.incDisplay(); @@ -58,18 +57,16 @@ final class LinuxPbufferPeerInfo extends LinuxPeerInfo { GLContext.unloadOpenGLLibrary(); throw e; } - } finally { - LinuxDisplay.unlockAWT(); } } private static native void nInitHandle(long display, int screen, ByteBuffer handle, int width, int height, PixelFormat pixel_format) throws LWJGLException; public void destroy() { - LinuxDisplay.lockAWT(); - nDestroy(getHandle()); - LinuxDisplay.decDisplay(); - GLContext.unloadOpenGLLibrary(); - LinuxDisplay.unlockAWT(); + try (LinuxDisplay.AWTLock _lock = LinuxDisplay.awtLock()) { + nDestroy(getHandle()); + LinuxDisplay.decDisplay(); + GLContext.unloadOpenGLLibrary(); + } } private static native void nDestroy(ByteBuffer handle); diff --git a/src/java/org/lwjgl/test/input/HWCursorTest.java b/src/java/org/lwjgl/test/input/HWCursorTest.java index a52d8162..58f41540 100644 --- a/src/java/org/lwjgl/test/input/HWCursorTest.java +++ b/src/java/org/lwjgl/test/input/HWCursorTest.java @@ -35,6 +35,7 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.IntBuffer; +import org.lwjgl.LWJGLException; import org.lwjgl.input.Cursor; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; @@ -389,7 +390,11 @@ public class HWCursorTest { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //sync frame (only works on windows) - Display.setVSyncEnabled(true); + try { + Display.setVSyncEnabled(true); + } catch (LWJGLException e) { + throw new RuntimeException(e); + } } /** diff --git a/src/java/org/lwjgl/test/opengl/FullScreenWindowedTest.java b/src/java/org/lwjgl/test/opengl/FullScreenWindowedTest.java index 532ecdfb..04c6f360 100644 --- a/src/java/org/lwjgl/test/opengl/FullScreenWindowedTest.java +++ b/src/java/org/lwjgl/test/opengl/FullScreenWindowedTest.java @@ -267,8 +267,13 @@ public class FullScreenWindowedTest { glViewport(0, 0, mode.getWidth(), mode.getHeight()); //set clear color to black glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - //sync frame (only works on windows) - Display.setVSyncEnabled(true); + + try { + //sync frame (only works on windows) + Display.setVSyncEnabled(true); + } catch (LWJGLException e) { + throw new RuntimeException(e); + } } /** * Test entry point diff --git a/src/java/org/lwjgl/test/opengl/PbufferTest.java b/src/java/org/lwjgl/test/opengl/PbufferTest.java index c4e572bc..a9fdbb1a 100644 --- a/src/java/org/lwjgl/test/opengl/PbufferTest.java +++ b/src/java/org/lwjgl/test/opengl/PbufferTest.java @@ -367,8 +367,12 @@ public class PbufferTest { * Initializes OGL */ private void glInit() { - //sync frame (only works on windows) - Display.setVSyncEnabled(true); + try { + //sync frame (only works on windows) + Display.setVSyncEnabled(true); + } catch (LWJGLException e) { + throw new RuntimeException(e); + } glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glEnable(GL_TEXTURE_2D); diff --git a/src/java/org/lwjgl/test/opengl/pbuffers/PbufferTest.java b/src/java/org/lwjgl/test/opengl/pbuffers/PbufferTest.java index 572e02e4..25fc1d71 100644 --- a/src/java/org/lwjgl/test/opengl/pbuffers/PbufferTest.java +++ b/src/java/org/lwjgl/test/opengl/pbuffers/PbufferTest.java @@ -376,8 +376,12 @@ public final class PbufferTest { * Initializes OGL */ private void glInit() { - // Sync frame (only works on windows) - Display.setVSyncEnabled(true); + try { + // Sync frame (only works on windows) + Display.setVSyncEnabled(true); + } catch (LWJGLException e) { + throw new RuntimeException(e); + } // Create shared texture IntBuffer buffer = BufferUtils.createIntBuffer(1); diff --git a/src/java/org/lwjgl/test/opengl/sprites/SpriteShootout.java b/src/java/org/lwjgl/test/opengl/sprites/SpriteShootout.java index 280be1f2..c4755fef 100644 --- a/src/java/org/lwjgl/test/opengl/sprites/SpriteShootout.java +++ b/src/java/org/lwjgl/test/opengl/sprites/SpriteShootout.java @@ -249,7 +249,7 @@ public final class SpriteShootout { renderer.updateBalls(ballCount); } - private void run() { + private void run() throws LWJGLException { long startTime = System.currentTimeMillis() + 5000; long fps = 0; @@ -288,7 +288,7 @@ public final class SpriteShootout { } } - private void handleInput() { + private void handleInput() throws LWJGLException { if ( Display.isCloseRequested() ) run = false; @@ -746,4 +746,4 @@ public final class SpriteShootout { } -} \ No newline at end of file +} diff --git a/src/java/org/lwjgl/test/opengl/sprites/SpriteShootout2P.java b/src/java/org/lwjgl/test/opengl/sprites/SpriteShootout2P.java index cd97319a..17245857 100644 --- a/src/java/org/lwjgl/test/opengl/sprites/SpriteShootout2P.java +++ b/src/java/org/lwjgl/test/opengl/sprites/SpriteShootout2P.java @@ -247,7 +247,7 @@ public final class SpriteShootout2P { renderer.updateBalls(ballCount); } - private void run() { + private void run() throws LWJGLException { long startTime = System.currentTimeMillis() + 5000; long fps = 0; @@ -284,7 +284,7 @@ public final class SpriteShootout2P { } } - private void handleInput() { + private void handleInput() throws LWJGLException { if ( Display.isCloseRequested() ) run = false; @@ -621,4 +621,4 @@ public final class SpriteShootout2P { } -} \ No newline at end of file +} diff --git a/src/java/org/lwjgl/test/opengl/sprites/SpriteShootoutCL.java b/src/java/org/lwjgl/test/opengl/sprites/SpriteShootoutCL.java index 80bdc803..8dcdf8e3 100644 --- a/src/java/org/lwjgl/test/opengl/sprites/SpriteShootoutCL.java +++ b/src/java/org/lwjgl/test/opengl/sprites/SpriteShootoutCL.java @@ -302,7 +302,7 @@ public final class SpriteShootoutCL { renderer.updateBalls(ballCount); } - private void run() { + private void run() throws LWJGLException { long startTime = System.currentTimeMillis() + 5000; long fps = 0; @@ -338,7 +338,7 @@ public final class SpriteShootoutCL { } } - private void handleInput() { + private void handleInput() throws LWJGLException { if ( Display.isCloseRequested() ) run = false; @@ -595,4 +595,4 @@ public final class SpriteShootoutCL { } -} \ No newline at end of file +} diff --git a/src/java/org/lwjgl/test/opengl/sprites/SpriteShootoutMapped.java b/src/java/org/lwjgl/test/opengl/sprites/SpriteShootoutMapped.java index 83805d17..00f20a13 100644 --- a/src/java/org/lwjgl/test/opengl/sprites/SpriteShootoutMapped.java +++ b/src/java/org/lwjgl/test/opengl/sprites/SpriteShootoutMapped.java @@ -281,7 +281,7 @@ public final class SpriteShootoutMapped { renderer.updateBalls(ballCount); } - private void run() { + private void run() throws LWJGLException { long startTime = System.currentTimeMillis() + 5000; long fps = 0; @@ -320,7 +320,7 @@ public final class SpriteShootoutMapped { } } - private void handleInput() { + private void handleInput() throws LWJGLException { if ( Display.isCloseRequested() ) run = false; @@ -835,4 +835,4 @@ public final class SpriteShootoutMapped { } -} \ No newline at end of file +} diff --git a/src/java/org/lwjgl/test/opengles/FullScreenWindowedTest.java b/src/java/org/lwjgl/test/opengles/FullScreenWindowedTest.java index b674f49c..9034988d 100644 --- a/src/java/org/lwjgl/test/opengles/FullScreenWindowedTest.java +++ b/src/java/org/lwjgl/test/opengles/FullScreenWindowedTest.java @@ -279,7 +279,7 @@ public class FullScreenWindowedTest { } /** Initializes OGL */ - private void glInit() { + private void glInit() throws LWJGLException { // Go into orthographic projection mode. glMatrixMode(GL_PROJECTION); glLoadIdentity(); diff --git a/src/java/org/lwjgl/util/generator/GeneratorProcessor.java b/src/java/org/lwjgl/util/generator/GeneratorProcessor.java index e718f3fd..b564b991 100644 --- a/src/java/org/lwjgl/util/generator/GeneratorProcessor.java +++ b/src/java/org/lwjgl/util/generator/GeneratorProcessor.java @@ -52,7 +52,7 @@ import javax.tools.Diagnostic; */ @SupportedAnnotationTypes({ "*" }) @SupportedSourceVersion(SourceVersion.RELEASE_8) -@SupportedOptions({ "binpath", "typemap", "generatechecks", "contextspecific" }) +@SupportedOptions({ "binpath", "genpath", "typemap", "generatechecks", "nogeneratechecks", "contextspecific" }) public class GeneratorProcessor extends AbstractProcessor { private static boolean first_round = true; @@ -66,11 +66,16 @@ public class GeneratorProcessor extends AbstractProcessor { Map options = processingEnv.getOptions(); String typemap_classname = options.get("typemap"); String bin_path = options.get("binpath"); - boolean generate_error_checks = options.containsKey("generatechecks"); + String gen_path = options.get("genpath"); + boolean generate_error_checks = options.containsKey("generatechecks") && !options.containsKey("nogeneratechecks"); boolean context_specific = options.containsKey("contextspecific"); if ( bin_path == null ) { throw new RuntimeException("No path specified for the bin directory with -Abinpath="); } + + if ( gen_path == null ) { + throw new RuntimeException("No path specified for the gen directory with -Agenpath="); + } if ( typemap_classname == null ) { throw new RuntimeException("No TypeMap class name specified with -Atypemap="); @@ -82,7 +87,7 @@ public class GeneratorProcessor extends AbstractProcessor { TypeMap type_map = (TypeMap)(Class.forName(typemap_classname).newInstance()); for ( Iterator it = ElementFilter.typesIn(roundEnv.getRootElements()).iterator(); it.hasNext(); ) { lastFile = it.next(); - lastFile.accept(new GeneratorVisitor(processingEnv, type_map, generate_error_checks, context_specific, generatorLM), null); + lastFile.accept(new GeneratorVisitor(processingEnv, gen_path, type_map, generate_error_checks, context_specific, generatorLM), null); } first_round = false; return true; diff --git a/src/java/org/lwjgl/util/generator/GeneratorVisitor.java b/src/java/org/lwjgl/util/generator/GeneratorVisitor.java index aca76220..822ce485 100644 --- a/src/java/org/lwjgl/util/generator/GeneratorVisitor.java +++ b/src/java/org/lwjgl/util/generator/GeneratorVisitor.java @@ -34,11 +34,18 @@ package org.lwjgl.util.generator; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.io.Reader; +import java.io.Writer; +import java.io.FileWriter; import java.io.PrintWriter; +import java.io.StringWriter; import java.lang.annotation.Annotation; import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Collection; import java.util.List; import javax.annotation.processing.ProcessingEnvironment; @@ -60,13 +67,15 @@ import javax.tools.StandardLocation; public class GeneratorVisitor extends ElementKindVisitor6 { private final ProcessingEnvironment env; + private final String gen_path; private final TypeMap type_map; private final boolean generate_error_checks; private final boolean context_specific; private final long generatorLM; - public GeneratorVisitor(ProcessingEnvironment env, TypeMap type_map, boolean generate_error_checks, boolean context_specific, long generatorLM) { + public GeneratorVisitor(ProcessingEnvironment env, String gen_path, TypeMap type_map, boolean generate_error_checks, boolean context_specific, long generatorLM) { this.env = env; + this.gen_path = gen_path; this.type_map = type_map; this.generate_error_checks = generate_error_checks; this.context_specific = context_specific; @@ -238,8 +247,6 @@ public class GeneratorVisitor extends ElementKindVisitor6 { } JavaMethodsGenerator.generateMethodsJava(env, type_map, java_writer, d, generate_error_checks, context_specific); java_writer.println("}"); - String qualified_interface_name = Utils.getQualifiedClassName(d); - env.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generated class " + qualified_interface_name); } private void generateNativeSource(TypeElement d) throws IOException { @@ -277,46 +284,92 @@ public class GeneratorVisitor extends ElementKindVisitor6 { env.getMessager().printMessage(Kind.NOTE, "Generated C source " + qualified_interface_name); } + private boolean isFileExistingAndIdentical(Path file, String expected) throws IOException { + if (!Files.exists(file)) return false; + + try (Reader existingIs = Files.newBufferedReader(file, Charset.forName("UTF-8"))) { + int i = 0; + int c; + do { + c = existingIs.read(); + if (c == -1) return i == expected.length(); + if (expected.length() <= i || c != expected.charAt(i++)) { + if (expected.length() > (i-1)) { + env.getMessager().printMessage(Kind.NOTE, "mismatch at " + i + ": " + c); + } else { + env.getMessager().printMessage(Kind.NOTE, "mismatch at " + i + ": EOF"); + } + return false; + } + } while (c != -1); + if (i != expected.length()) { + return false; + } + } + + return true; + } + @Override public Void visitTypeAsInterface(TypeElement e, Void p) { final File input = new File("src/templates/" + e.getQualifiedName().toString().replace('.', '/') + ".java"); final Collection methods = Utils.getMethods(e); - if ( methods.isEmpty() && Utils.getFields(e).isEmpty() ) { + if (methods.isEmpty() && Utils.getFields(e).isEmpty()) { return DEFAULT_VALUE; } //env.getMessager().printMessage(Kind.NOTE, "methods count : " + Utils.getMethods(e).size() + " fields count : " + Utils.getFields(e).size(), e); - for ( final ExecutableElement method : methods ) { + for (ExecutableElement method : methods) { validateMethod(method); } // TODO: Back-port LWJGL 3's generation file handling (generate in-memory and avoid touching files if nothing has changed) - try (PrintWriter java_writer = new PrintWriter(env.getFiler().createSourceFile(Utils.getQualifiedClassName(e), env.getElementUtils().getPackageOf(e)).openWriter())) { - generateJavaSource(e, java_writer); + StringWriter java_writer = new StringWriter(); + try { + generateJavaSource(e, new PrintWriter(java_writer)); + } catch (IOException ex) { + throw new RuntimeException("Failed to generate the Java sources for " + e, ex); + } - if ( methods.size() > 0 ) { - boolean noNative = true; - for ( final ExecutableElement method : methods ) { - Alternate alt_annotation = method.getAnnotation(Alternate.class); - if ( (alt_annotation == null || alt_annotation.nativeAlt()) && method.getAnnotation(Reuse.class) == null ) { - noNative = false; - break; - } - } - if ( noNative ) { - return DEFAULT_VALUE; - } - - try { - generateNativeSource(e); - } catch (IOException ex) { - throw new RuntimeException(ex); - } + String qualified_interface_name = Utils.getQualifiedClassName(e); + final Path output = Path.of(this.gen_path + "/" + qualified_interface_name.replace('.', '/') + ".java"); + String newStr = java_writer.toString(); + try { + if (isFileExistingAndIdentical(output, newStr)) { + return DEFAULT_VALUE; } - return DEFAULT_VALUE; + Files.createDirectories(output.getParent()); + Files.createFile(output); + } catch (IOException ex) { + throw new RuntimeException("Failed to create the output file for " + e, ex); + } + //try (Writer java_file_writer = env.getFiler().createSourceFile(Utils.getQualifiedClassName(e), env.getElementUtils().getPackageOf(e)).openWriter()) { + try (Writer java_file_writer = new FileWriter(output.toFile())) { + java_file_writer.write(newStr); + env.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generated class " + qualified_interface_name); } catch (Exception ex) { throw new RuntimeException(ex); } + if (methods.size() > 0) { + boolean noNative = true; + for (ExecutableElement method : methods) { + Alternate alt_annotation = method.getAnnotation(Alternate.class); + if ((alt_annotation == null || alt_annotation.nativeAlt()) && method.getAnnotation(Reuse.class) == null) { + noNative = false; + break; + } + } + if (noNative) { + return DEFAULT_VALUE; + } + + try { + generateNativeSource(e); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + return DEFAULT_VALUE; } private static ByteBuffer readFile(final File file) throws IOException {