diff --git a/gradle.properties b/gradle.properties index ecfbe7ee..f0013a91 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,7 +18,5 @@ jdkEnablePreview=true jdkEarlyAccessDoc=jdk22 kotlinTargetJdkVersion=21 -overrunMarshalVersion=0.1.0-alpha.9-jdk22 +overrunMarshalVersion=0.1.0-alpha.10-jdk22 overrunPlatformVersion=1.0.0 - -cLibraryVersion=0.1.0.0 diff --git a/modules/overrungl.core/src/main/java/overrungl/internal/RuntimeHelper.java b/modules/overrungl.core/src/main/java/overrungl/internal/RuntimeHelper.java index a37ae62c..3eb0dc38 100644 --- a/modules/overrungl.core/src/main/java/overrungl/internal/RuntimeHelper.java +++ b/modules/overrungl.core/src/main/java/overrungl/internal/RuntimeHelper.java @@ -60,6 +60,9 @@ public final class RuntimeHelper { public static final boolean CHECKS = Configurations.CHECKS.get(); private static final StackWalker STACK_WALKER = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); private static final Map CANONICAL_LAYOUTS = LINKER.canonicalLayouts(); + /** + * Some canonical layouts + */ public static final MemoryLayout LONG = CANONICAL_LAYOUTS.get("long"), SIZE_T = CANONICAL_LAYOUTS.get("size_t"), WCHAR_T = CANONICAL_LAYOUTS.get("wchar_t"); diff --git a/modules/overrungl.core/src/main/java/overrungl/util/DebugAllocator.java b/modules/overrungl.core/src/main/java/overrungl/util/DebugAllocator.java index 62d44085..1fe6bf5c 100644 --- a/modules/overrungl.core/src/main/java/overrungl/util/DebugAllocator.java +++ b/modules/overrungl.core/src/main/java/overrungl/util/DebugAllocator.java @@ -20,7 +20,6 @@ import org.jetbrains.annotations.Nullable; import overrungl.Configurations; import overrungl.OverrunGL; -import overrungl.internal.Exceptions; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -99,7 +98,7 @@ private static void trackAbort(long address, Allocation allocationOld, Allocatio trackAbortPrint(allocationOld, "Old", addressHex); trackAbortPrint(allocationNew, "New", addressHex); - throw Exceptions.ISE."The memory address specified is already being tracked: 0x\{addressHex}"; + throw new IllegalStateException(STR."The memory address specified is already being tracked: 0x\{addressHex}"); } private static void trackAbortPrint(Allocation allocation, String name, String address) { @@ -138,7 +137,7 @@ static long untrack(long address) { private static void untrackAbort(long address) { String addressHex = Long.toHexString(address).toUpperCase(); - throw Exceptions.ISE."The memory address specified is not being tracked: 0x\{addressHex}"; + throw new IllegalStateException(STR."The memory address specified is not being tracked: 0x\{addressHex}"); } private record Allocation(long address, long size, long threadId, @Nullable Object[] stacktrace) { diff --git a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFW.java b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFW.java index cc542346..f3647013 100644 --- a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFW.java +++ b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFW.java @@ -1757,7 +1757,7 @@ public static MemorySegment ngetVideoModes(MemorySegment monitor, MemorySegment * error occurred. * @see #ngetVideoModes(MemorySegment, MemorySegment) ngetVideoModes */ - public static @Nullable GLFWVidMode.Buffer getVideoModes(MemorySegment monitor) { + public static @Nullable GLFWVidMode getVideoModes(MemorySegment monitor) { var stack = MemoryStack.stackGet(); long stackPointer = stack.getPointer(); try { @@ -1765,7 +1765,7 @@ public static MemorySegment ngetVideoModes(MemorySegment monitor, MemorySegment var pModes = ngetVideoModes(monitor, pCount); return RuntimeHelper.isNullptr(pModes) ? null : - new GLFWVidMode.Buffer(pModes, pCount.get(JAVA_INT, 0)); + new GLFWVidMode(pModes, pCount.get(JAVA_INT, 0)); } finally { stack.setPointer(stackPointer); } @@ -1931,7 +1931,7 @@ public static void nsetGammaRamp(MemorySegment monitor, MemorySegment ramp) { * @see #nsetGammaRamp(MemorySegment, MemorySegment) nsetGammaRamp */ public static void setGammaRamp(MemorySegment monitor, GLFWGammaRamp ramp) { - nsetGammaRamp(monitor, ramp.address()); + nsetGammaRamp(monitor, ramp.segment()); } /** @@ -2395,11 +2395,11 @@ public static void nsetWindowIcon(MemorySegment window, int count, MemorySegment * count is zero. * @see #nsetWindowIcon(MemorySegment, int, MemorySegment) nsetWindowIcon */ - public static void setWindowIcon(MemorySegment window, int count, GLFWImage.Buffer images) { + public static void setWindowIcon(MemorySegment window, int count, GLFWImage images) { if (images == null || count == 0) { nsetWindowIcon(window, 0, MemorySegment.NULL); } else { - nsetWindowIcon(window, count, images.address()); + nsetWindowIcon(window, count, images.segment()); } } @@ -2411,12 +2411,8 @@ public static void setWindowIcon(MemorySegment window, int count, GLFWImage.Buff * revert to the default window icon. * @see #nsetWindowIcon(MemorySegment, int, MemorySegment) nsetWindowIcon */ - public static void setWindowIcon(MemorySegment window, @Nullable GLFWImage.Buffer images) { - if (images == null) { - nsetWindowIcon(window, 0, MemorySegment.NULL); - } else { - setWindowIcon(window, (int) Math.min(images.elementCount(), Integer.MAX_VALUE), images); - } + public static void setWindowIcon(MemorySegment window, @Nullable GLFWImage images) { + setWindowIcon(window, images == null ? 0 : Math.toIntExact(images.elementCount()), images); } /** @@ -4401,7 +4397,7 @@ public static MemorySegment ncreateCursor(MemorySegment image, int xhot, int yho * @see #ncreateCursor(MemorySegment, int, int) ncreateCursor */ public static MemorySegment createCursor(GLFWImage image, int xhot, int yhot) { - return ncreateCursor(image.address(), xhot, yhot); + return ncreateCursor(image.segment(), xhot, yhot); } /** @@ -5384,7 +5380,7 @@ public static boolean ngetGamepadState(int jid, MemorySegment state) { * @see #ngetGamepadState(int, MemorySegment) ngetGamepadState */ public static boolean getGamepadState(int jid, GLFWGamepadState state) { - return ngetGamepadState(jid, state.address()); + return ngetGamepadState(jid, state.segment()); } /** @@ -5767,7 +5763,7 @@ public static boolean extensionSupported(String extension) { * without a current context will cause a {@link #NO_CURRENT_CONTEXT} error. *

* This function does not apply to Vulkan. If you are rendering with Vulkan, - * see {@link GLFWVulkan#nglfwGetInstanceProcAddress(MemorySegment, MemorySegment) glfwGetInstanceProcAddress}, + * see {@link GLFWVulkan#ngetInstanceProcAddress(MemorySegment, MemorySegment) glfwGetInstanceProcAddress}, * {@code vkGetInstanceProcAddr} and {@code vkGetDeviceProcAddr} instead. * * @param procName The ASCII encoded name of the function. @@ -5823,7 +5819,7 @@ public static MemorySegment getProcAddress(String procName) { * surface creation or even instance creation is possible. Call * {@link #ngetRequiredInstanceExtensions getRequiredInstanceExtensions} to check whether the * extensions necessary for Vulkan surface creation are available and - * {@link GLFWVulkan#glfwGetPhysicalDevicePresentationSupport glfwGetPhysicalDevicePresentationSupport} + * {@link GLFWVulkan#getPhysicalDevicePresentationSupport glfwGetPhysicalDevicePresentationSupport} * to check whether a queue family of a physical device supports image presentation. * * @return {@code true} if Vulkan is minimally available, or {@code false} diff --git a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWGamepadState.java b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWGamepadState.java index 0ff1095a..a7133d8b 100644 --- a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWGamepadState.java +++ b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWGamepadState.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2022-2023 Overrun Organization + * Copyright (c) 2022-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,81 +16,78 @@ package overrungl.glfw; -import overrungl.Struct; +import overrun.marshal.struct.Struct; import java.lang.foreign.*; -import java.lang.foreign.MemoryLayout.PathElement; -import java.lang.invoke.VarHandle; /** * This describes the input state of a gamepad. *

Layout

*

  * struct GLFWgamepadstate {
- *     unsigned char {@link #buttons() buttons}[15];
- *     float {@link #axes() axes}[6];
+ *     unsigned char {@link #buttons}[15];
+ *     float {@link #axes}[6];
  * }
* * @author squid233 * @since 0.1.0 */ public final class GLFWGamepadState extends Struct { - /** - * The struct member layout. - */ - public static final SequenceLayout - BUTTONS_LAYOUT = MemoryLayout.sequenceLayout(15, ValueLayout.JAVA_BYTE).withName("buttons"), - AXES_LAYOUT = MemoryLayout.sequenceLayout(6, ValueLayout.JAVA_FLOAT).withName("axes"); /** * The struct layout. */ public static final StructLayout LAYOUT = MemoryLayout.structLayout( - BUTTONS_LAYOUT, - MemoryLayout.paddingLayout(8), // padding needed. will FFM API adds padding automatically in the future? - AXES_LAYOUT + MemoryLayout.sequenceLayout(15, ValueLayout.JAVA_BYTE).withName("buttons"), + MemoryLayout.paddingLayout(1L), + MemoryLayout.sequenceLayout(6, ValueLayout.JAVA_FLOAT).withName("axes") ); - private static final VarHandle - pButtons = LAYOUT.varHandle(PathElement.groupElement("buttons"), PathElement.sequenceElement()), - pAxes = LAYOUT.varHandle(PathElement.groupElement("axes"), PathElement.sequenceElement()); + /** + * The states of each gamepad button, + * {@link GLFW#PRESS} or {@link GLFW#RELEASE}. + */ + public final StructHandleSizedByteArray buttons = StructHandleSizedByteArray.of(this, "buttons"); + /** + * The states of each gamepad axis, + * in the range -1.0 to 1.0 inclusive. + */ + public final StructHandleSizedFloatArray axes = StructHandleSizedFloatArray.of(this, "axes"); /** - * Create a {@code GLFWgamepadstate} instance. + * Creates a struct with the given layout. * - * @param address the address. + * @param segment the segment + * @param elementCount the element count */ - public GLFWGamepadState(MemorySegment address) { - super(address, LAYOUT); + public GLFWGamepadState(MemorySegment segment, long elementCount) { + super(segment, elementCount, LAYOUT); } /** - * {@return the elements size of this struct in bytes} + * Allocates a struct with the given layout. + * + * @param allocator the allocator + * @param elementCount the element count */ - public static long sizeof() { - return LAYOUT.byteSize(); + public GLFWGamepadState(SegmentAllocator allocator, long elementCount) { + super(allocator, elementCount, LAYOUT); } /** - * Creates a {@code GLFWgamepadstate} instance with the given allocator. + * Creates a struct with the given layout. * - * @param allocator the allocator - * @return the instance + * @param segment the segment */ - public static GLFWGamepadState create(SegmentAllocator allocator) { - return new GLFWGamepadState(allocator.allocate(LAYOUT)); + public GLFWGamepadState(MemorySegment segment) { + super(segment, LAYOUT); } /** - * Gets the button state array. + * Allocates a struct with the given layout. * - * @return The states of each gamepad button, - * {@code PRESS} or {@code RELEASE}. + * @param allocator the allocator */ - public byte[] buttons() { - byte[] arr = new byte[15]; - for (int i = 0; i < arr.length; i++) { - arr[i] = (byte) pButtons.get(segment(), (long) i); - } - return arr; + public GLFWGamepadState(SegmentAllocator allocator) { + super(allocator, LAYOUT); } /** @@ -100,21 +97,7 @@ public byte[] buttons() { * @return the state, {@code PRESS} or {@code RELEASE} */ public boolean button(int index) { - return (byte) pButtons.get(segment(), (long) index) == GLFW.PRESS; - } - - /** - * Gets the axe state array. - * - * @return The states of each gamepad axis, - * in the range -1.0 to 1.0 inclusive. - */ - public float[] axes() { - float[] arr = new float[6]; - for (int i = 0; i < arr.length; i++) { - arr[i] = (float) pAxes.get(segment(), (long) i); - } - return arr; + return buttons.get(index) == GLFW.PRESS; } /** @@ -124,6 +107,6 @@ public float[] axes() { * @return the state, in the range -1.0 to 1.0 inclusive */ public float axe(int index) { - return (float) pAxes.get(segment(), (long) index); + return axes.get(index); } } diff --git a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWGammaRamp.java b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWGammaRamp.java index 75d7eb81..85d8aae2 100644 --- a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWGammaRamp.java +++ b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWGammaRamp.java @@ -16,11 +16,12 @@ package overrungl.glfw; -import overrungl.internal.RuntimeHelper; -import overrungl.Struct; +import overrun.marshal.Marshal; +import overrun.marshal.Unmarshal; +import overrun.marshal.struct.Struct; +import overrun.marshal.struct.StructHandle; import java.lang.foreign.*; -import java.lang.invoke.VarHandle; import static java.lang.foreign.ValueLayout.*; @@ -29,9 +30,9 @@ *

Layout

*

  * struct GLFWgammaramp {
- *     unsigned short* {@link #red() red};
- *     unsigned short* {@link #green() green};
- *     unsigned short* {@link #blue() blue};
+ *     unsigned short* {@link #red};
+ *     unsigned short* {@link #green};
+ *     unsigned short* {@link #blue};
  *     unsigned int {@link #size};
  * }
* @@ -41,7 +42,7 @@ * @since 0.1.0 */ public final class GLFWGammaRamp extends Struct { - private static final AddressLayout SHORT_ARRAY = ADDRESS.withTargetLayout(MemoryLayout.sequenceLayout(Long.MAX_VALUE / JAVA_SHORT.byteSize(), JAVA_SHORT)); + private static final AddressLayout SHORT_ARRAY = ADDRESS.withTargetLayout(MemoryLayout.sequenceLayout(0L, JAVA_SHORT)); /** * The struct layout. */ @@ -51,190 +52,58 @@ public final class GLFWGammaRamp extends Struct { SHORT_ARRAY.withName("blue"), JAVA_INT.withName("size") ); - private static final VarHandle - ppRed = LAYOUT.varHandle(PathElement.groupElement("red")), - ppGreen = LAYOUT.varHandle(PathElement.groupElement("green")), - ppBlue = LAYOUT.varHandle(PathElement.groupElement("blue")), - pRed = LAYOUT.varHandle(PathElement.groupElement("red"), PathElement.dereferenceElement(), PathElement.sequenceElement()), - pGreen = LAYOUT.varHandle(PathElement.groupElement("green"), PathElement.dereferenceElement(), PathElement.sequenceElement()), - pBlue = LAYOUT.varHandle(PathElement.groupElement("blue"), PathElement.dereferenceElement(), PathElement.sequenceElement()), - pSize = LAYOUT.varHandle(PathElement.groupElement("size")); - - /** - * Create a {@code GLFWgammaramp const} instance. - * - * @param address the address. - */ - public GLFWGammaRamp(MemorySegment address) { - super(address, LAYOUT); - } - - /** - * {@return the elements size of this struct in bytes} - */ - public static long sizeof() { - return LAYOUT.byteSize(); - } - - /** - * Creates a {@code GLFWgammaramp} instance with the given allocator. - * - * @param allocator the allocator - * @return the instance - */ - public static GLFWGammaRamp create(SegmentAllocator allocator) { - return new GLFWGammaRamp(allocator.allocate(LAYOUT)); - } - - /** - * Sets the red value array. - * - * @param allocator the allocator of the array. - * @param reds the array - * @return this - */ - public GLFWGammaRamp red(SegmentAllocator allocator, short[] reds) { - ppRed.set(segment(), allocator.allocateFrom(JAVA_SHORT, reds)); - return this; - } - - /** - * Sets the green value array. - * - * @param allocator the allocator of the array. - * @param greens the array - * @return this - */ - public GLFWGammaRamp green(SegmentAllocator allocator, short[] greens) { - ppGreen.set(segment(), allocator.allocateFrom(JAVA_SHORT, greens)); - return this; - } - - /** - * Sets the blue value array. - * - * @param allocator the allocator of the array. - * @param blues the array - * @return this - */ - public GLFWGammaRamp blue(SegmentAllocator allocator, short[] blues) { - ppBlue.set(segment(), allocator.allocateFrom(JAVA_SHORT, blues)); - return this; - } - - /** - * Sets the size of arrays. - * - * @param size The number of elements in each array. - * @return this - */ - public GLFWGammaRamp size(int size) { - pSize.set(segment(), size); - return this; - } - - /** - * Gets a red value at the given index. - * - * @param index the index - * @return the red value - */ - public short red(int index) { - return (short) pRed.get(segment(), (long) index); - } - - /** - * Gets a green value at the given index. - * - * @param index the index - * @return the green value - */ - public short green(int index) { - return (short) pGreen.get(segment(), (long) index); - } - /** - * Gets a blue value at the given index. - * - * @param index the index - * @return the blue value + * An array of value describing the response of the red channel. */ - public short blue(int index) { - return (short) pBlue.get(segment(), (long) index); - } - + public final StructHandle.Array red = StructHandle.ofArray(this, "red", Marshal::marshal, Unmarshal::unmarshalAsShortArray); /** - * {@return the red value array} - * - * @param size the array size + * An array of value describing the response of the green channel. */ - public short[] reds(int size) { - return RuntimeHelper.toArray(nred(), new short[size]); - } - + public final StructHandle.Array green = StructHandle.ofArray(this, "green", Marshal::marshal, Unmarshal::unmarshalAsShortArray); /** - * {@return the green value array} - * - * @param size the array size + * An array of value describing the response of the blue channel. */ - public short[] greens(int size) { - return RuntimeHelper.toArray(ngreen(), new short[size]); - } - + public final StructHandle.Array blue = StructHandle.ofArray(this, "blue", Marshal::marshal, Unmarshal::unmarshalAsShortArray); /** - * {@return the blue value array} - * - * @param size the array size + * The number of elements in each array. */ - public short[] blues(int size) { - return RuntimeHelper.toArray(nblue(), new short[size]); - } + public final StructHandle.Int size = StructHandle.ofInt(this, "size"); /** - * Gets the red value array. + * Creates a struct with the given layout. * - * @return An array of value describing the response of the red channel. + * @param segment the segment + * @param elementCount the element count */ - public short[] red() { - return reds(size()); + public GLFWGammaRamp(MemorySegment segment, long elementCount) { + super(segment, elementCount, LAYOUT); } /** - * Gets the green value array. + * Allocates a struct with the given layout. * - * @return An array of value describing the response of the green channel. + * @param allocator the allocator + * @param elementCount the element count */ - public short[] green() { - return greens(size()); + public GLFWGammaRamp(SegmentAllocator allocator, long elementCount) { + super(allocator, elementCount, LAYOUT); } /** - * Gets the blue value array. + * Creates a struct with the given layout. * - * @return An array of value describing the response of the blue channel. + * @param segment the segment */ - public short[] blue() { - return blues(size()); + public GLFWGammaRamp(MemorySegment segment) { + super(segment, LAYOUT); } /** - * Gets the arrays size. + * Allocates a struct with the given layout. * - * @return The number of elements in each array. + * @param allocator the allocator */ - public int size() { - return (int) pSize.get(segment()); - } - - public MemorySegment nred() { - return (MemorySegment) ppRed.get(segment()); - } - - public MemorySegment ngreen() { - return (MemorySegment) ppGreen.get(segment()); - } - - public MemorySegment nblue() { - return (MemorySegment) ppBlue.get(segment()); + public GLFWGammaRamp(SegmentAllocator allocator) { + super(allocator, LAYOUT); } } diff --git a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWImage.java b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWImage.java index 3fc1ad19..b9136a8f 100644 --- a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWImage.java +++ b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWImage.java @@ -16,15 +16,10 @@ package overrungl.glfw; -import overrungl.ArrayPointer; -import overrungl.Struct; -import overrungl.internal.RuntimeHelper; +import overrun.marshal.struct.Struct; +import overrun.marshal.struct.StructHandle; import java.lang.foreign.*; -import java.lang.foreign.MemoryLayout.PathElement; -import java.lang.invoke.VarHandle; - -import static java.lang.foreign.ValueLayout.*; /** * This describes a single 2D image. See the documentation for each related @@ -32,251 +27,71 @@ *

Layout

*

  * struct GLFWimage {
- *     int {@link #width() width};
- *     int {@link #height() height};
- *     unsigned char* {@link #pixels() pixels};
+ *     int {@link #width};
+ *     int {@link #height};
+ *     unsigned char* {@link #pixels};
  * }
* * @author squid233 * @since 0.1.0 */ -public sealed class GLFWImage extends Struct { +public final class GLFWImage extends Struct { /** * The struct layout. */ public static final StructLayout LAYOUT = MemoryLayout.structLayout( - JAVA_INT.withName("width"), - JAVA_INT.withName("height"), - ADDRESS.withTargetLayout(RuntimeHelper.ADDRESS_UNBOUNDED).withName("pixels") + ValueLayout.JAVA_INT.withName("width"), + ValueLayout.JAVA_INT.withName("height"), + ValueLayout.ADDRESS.withName("pixels") ); - private static final VarHandle - pWidth = LAYOUT.varHandle(PathElement.groupElement("width")), - pHeight = LAYOUT.varHandle(PathElement.groupElement("height")), - pPixels = LAYOUT.varHandle(PathElement.groupElement("pixels")); - - /** - * Create a {@code GLFWImage} instance. - * - * @param address the address. - */ - public GLFWImage(MemorySegment address) { - super(address, LAYOUT); - } - - /** - * Creates a struct instance with the given memory layout. - * - * @param address the address. - * @param layout the memory layout of this struct. - */ - protected GLFWImage(MemorySegment address, MemoryLayout layout) { - super(address, layout); - } - - /** - * {@return the elements size of this struct in bytes} - */ - public static long sizeof() { - return LAYOUT.byteSize(); - } - - /** - * Creates a {@code GLFWImage} instance with the given allocator. - * - * @param allocator the allocator - * @return the instance - */ - public static GLFWImage create(SegmentAllocator allocator) { - return new GLFWImage(allocator.allocate(LAYOUT)); - } - - /** - * Creates a {@code GLFWImage.Buffer} instance with the given allocator and count. - * - * @param allocator the allocator - * @param count the count - * @return the instance - */ - public static Buffer create(SegmentAllocator allocator, long count) { - return new Buffer(allocator.allocate(LAYOUT, count), count); - } - /** - * Sets the image width. - * - * @param width The width, in pixels, of this image. - * @return this + * The width, in pixels, of this image. */ - public GLFWImage width(int width) { - pWidth.set(segment(), width); - return this; - } - + public final StructHandle.Int width = StructHandle.ofInt(this, "width"); /** - * Sets the image height. - * - * @param height The height, in pixels, of this image. - * @return this + * The height, in pixels, of this image. */ - public GLFWImage height(int height) { - pHeight.set(segment(), height); - return this; - } - + public final StructHandle.Int height = StructHandle.ofInt(this, "height"); /** - * Sets the image pixels address. - * - * @param pixels The pixel data address of this image, arranged left-to-right, top-to-bottom. - * @return this + * The pixel data address of this image, arranged left-to-right, top-to-bottom. */ - public GLFWImage pixels(MemorySegment pixels) { - pPixels.set(segment(), pixels); - return this; - } + public final StructHandle.Address pixels = StructHandle.ofAddress(this, "pixels"); /** - * Gets the image width. + * Creates a struct with the given layout. * - * @return The width, in pixels, of this image. + * @param segment the segment + * @param elementCount the element count */ - public int width() { - return (int) pWidth.get(segment()); + public GLFWImage(MemorySegment segment, long elementCount) { + super(segment, elementCount, LAYOUT); } /** - * Gets the image height. + * Allocates a struct with the given layout. * - * @return The height, in pixels, of this image. + * @param allocator the allocator + * @param elementCount the element count */ - public int height() { - return (int) pHeight.get(segment()); + public GLFWImage(SegmentAllocator allocator, long elementCount) { + super(allocator, elementCount, LAYOUT); } /** - * Gets the image pixels address. + * Creates a struct with the given layout. * - * @return The pixel data address of this image, arranged left-to-right, top-to-bottom. + * @param segment the segment */ - public MemorySegment pixels() { - return (MemorySegment) pPixels.get(segment()); + public GLFWImage(MemorySegment segment) { + super(segment, LAYOUT); } /** - * This describes 2D images. + * Allocates a struct with the given layout. * - * @author squid233 - * @since 0.1.0 + * @param allocator the allocator */ - public static final class Buffer extends GLFWImage implements ArrayPointer { - private final VarHandle pWidth, pHeight, pPixels; - - /** - * Create a {@code GLFWImage.Buffer} instance. - * - * @param address the address. - * @param elementCount the element count - */ - public Buffer(MemorySegment address, long elementCount) { - super(address, MemoryLayout.sequenceLayout(elementCount, LAYOUT)); - pWidth = layout().varHandle(PathElement.sequenceElement(), PathElement.groupElement("width")); - pHeight = layout().varHandle(PathElement.sequenceElement(), PathElement.groupElement("height")); - pPixels = layout().varHandle(PathElement.sequenceElement(), PathElement.groupElement("pixels")); - } - - /** - * Sets the image width at the given index. - * - * @param index the index - * @param width The width, in pixels, of this image. - * @return this - */ - public Buffer width(long index, int width) { - pWidth.set(segment(), index, width); - return this; - } - - /** - * Sets the image height at the given index. - * - * @param index the index - * @param height The height, in pixels, of this image. - * @return this - */ - public Buffer height(long index, int height) { - pHeight.set(segment(), index, height); - return this; - } - - /** - * Sets the image pixels address at the given index. - * - * @param index the index - * @param pixels The pixel data address of this image, arranged left-to-right, top-to-bottom. - * @return this - */ - public Buffer pixels(long index, MemorySegment pixels) { - pPixels.set(segment(), index, pixels); - return this; - } - - @Override - public Buffer width(int width) { - return width(0, width); - } - - @Override - public Buffer height(int height) { - return height(0, height); - } - - @Override - public Buffer pixels(MemorySegment pixels) { - return pixels(0, pixels); - } - - /** - * Gets the image width at the given index. - * - * @param index the index - * @return The width, in pixels, of this image. - */ - public int widthAt(long index) { - return (int) pWidth.get(segment(), index); - } - - /** - * Gets the image height at the given index. - * - * @param index the index - * @return The height, in pixels, of this image. - */ - public int heightAt(long index) { - return (int) pHeight.get(segment(), index); - } - - /** - * Gets the image pixels address at the given index. - * - * @param index the index - * @return The pixel data address of this image, arranged left-to-right, top-to-bottom. - */ - public MemorySegment pixelsAt(long index) { - return (MemorySegment) pPixels.get(segment(), index); - } - - @Override - public int width() { - return widthAt(0); - } - - @Override - public int height() { - return heightAt(0); - } - - @Override - public MemorySegment pixels() { - return pixelsAt(0); - } + public GLFWImage(SegmentAllocator allocator) { + super(allocator, LAYOUT); } } diff --git a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWNative.java b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWNative.java index 970053c2..18f3cf01 100644 --- a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWNative.java +++ b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWNative.java @@ -17,12 +17,13 @@ package overrungl.glfw; import org.jetbrains.annotations.Nullable; -import overrungl.util.MemoryStack; +import overrun.marshal.Downcall; +import overrun.marshal.gen.Convert; +import overrun.marshal.gen.Entrypoint; +import overrun.marshal.gen.Ref; +import overrun.marshal.gen.Type; import java.lang.foreign.MemorySegment; -import java.lang.foreign.ValueLayout; - -import static overrungl.glfw.Handles.*; /** * This is the header file of the native access functions. @@ -34,10 +35,11 @@ * @author squid233 * @since 0.1.0 */ -public final class GLFWNative { - private GLFWNative() { - //no instance - } +public interface GLFWNative { + /** + * The instance of GLFWNative. + */ + GLFWNative INSTANCE = Downcall.load(Handles.lookup); /** * Returns the adapter device name of the specified monitor. @@ -49,12 +51,9 @@ private GLFWNative() { * @glfw.errors Possible errors include {@link GLFW#NOT_INITIALIZED}. * @glfw.thread_safety This function may be called from any thread. Access is not synchronized. */ - public static MemorySegment ngetWin32Adapter(MemorySegment monitor) { - try { - return (MemorySegment) glfwGetWin32Adapter.invokeExact(monitor); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetWin32Adapter") + default MemorySegment ngetWin32Adapter(MemorySegment monitor) { + return MemorySegment.NULL; } /** @@ -66,8 +65,9 @@ public static MemorySegment ngetWin32Adapter(MemorySegment monitor) { * occurred. * @see #ngetWin32Adapter(MemorySegment) ngetWin32Adapter */ - public static String getWin32Adapter(MemorySegment monitor) { - return ngetWin32Adapter(monitor).getString(0); + @Entrypoint("glfwGetWin32Adapter") + default String getWin32Adapter(MemorySegment monitor) { + return null; } /** @@ -81,12 +81,9 @@ public static String getWin32Adapter(MemorySegment monitor) { * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static MemorySegment ngetWin32Monitor(MemorySegment monitor) { - try { - return (MemorySegment) glfwGetWin32Monitor.invokeExact(monitor); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetWin32Monitor") + default MemorySegment ngetWin32Monitor(MemorySegment monitor) { + return MemorySegment.NULL; } /** @@ -98,8 +95,9 @@ public static MemorySegment ngetWin32Monitor(MemorySegment monitor) { * error occurred. * @see #ngetWin32Monitor(MemorySegment) ngetWin32Monitor */ - public static String getWin32Monitor(MemorySegment monitor) { - return ngetWin32Monitor(monitor).getString(0); + @Entrypoint("glfwGetWin32Monitor") + default String getWin32Monitor(MemorySegment monitor) { + return null; } /** @@ -117,12 +115,9 @@ public static String getWin32Monitor(MemorySegment monitor) { * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static MemorySegment getWin32Window(MemorySegment window) { - try { - return (MemorySegment) glfwGetWin32Window.invokeExact(window); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetWin32Window") + default MemorySegment getWin32Window(MemorySegment window) { + return MemorySegment.NULL; } /** @@ -140,12 +135,9 @@ public static MemorySegment getWin32Window(MemorySegment window) { * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static MemorySegment getWGLContext(MemorySegment window) { - try { - return (MemorySegment) glfwGetWGLContext.invokeExact(window); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetWGLContext") + default MemorySegment getWGLContext(MemorySegment window) { + return MemorySegment.NULL; } /** @@ -158,12 +150,9 @@ public static MemorySegment getWGLContext(MemorySegment window) { * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static int getCocoaMonitor(MemorySegment monitor) { - try { - return (int) glfwGetCocoaMonitor.invokeExact(monitor); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetCocoaMonitor") + default int getCocoaMonitor(MemorySegment monitor) { + return 0; } /** @@ -176,12 +165,9 @@ public static int getCocoaMonitor(MemorySegment monitor) { * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static MemorySegment getCocoaWindow(MemorySegment window) { - try { - return (MemorySegment) glfwGetCocoaWindow.invokeExact(window); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetCocoaWindow") + default MemorySegment getCocoaWindow(MemorySegment window) { + return MemorySegment.NULL; } /** @@ -194,12 +180,9 @@ public static MemorySegment getCocoaWindow(MemorySegment window) { * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static MemorySegment getNSGLContext(MemorySegment window) { - try { - return (MemorySegment) glfwGetNSGLContext.invokeExact(window); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetNSGLContext") + default MemorySegment getNSGLContext(MemorySegment window) { + return MemorySegment.NULL; } /** @@ -211,12 +194,9 @@ public static MemorySegment getNSGLContext(MemorySegment window) { * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static MemorySegment getX11Display() { - try { - return (MemorySegment) glfwGetX11Display.invokeExact(); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetX11Display") + default MemorySegment getX11Display() { + return MemorySegment.NULL; } /** @@ -229,12 +209,9 @@ public static MemorySegment getX11Display() { * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static long getX11Adapter(MemorySegment monitor) { - try { - return (long) glfwGetX11Adapter.invokeExact(monitor); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetX11Adapter") + default long getX11Adapter(MemorySegment monitor) { + return 0L; } /** @@ -247,12 +224,9 @@ public static long getX11Adapter(MemorySegment monitor) { * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static long getX11Monitor(MemorySegment monitor) { - try { - return (long) glfwGetX11Monitor.invokeExact(monitor); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetX11Monitor") + default long getX11Monitor(MemorySegment monitor) { + return 0L; } /** @@ -265,12 +239,9 @@ public static long getX11Monitor(MemorySegment monitor) { * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static long getX11Window(MemorySegment window) { - try { - return (long) glfwGetX11Window.invokeExact(window); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetX11Window") + default long getX11Window(MemorySegment window) { + return 0L; } /** @@ -284,12 +255,8 @@ public static long getX11Window(MemorySegment window) { * @see #ngetX11SelectionString() getX11SelectionString * @see GLFW#nsetClipboardString(MemorySegment) setClipboardString */ - public static void nsetX11SelectionString(MemorySegment string) { - try { - glfwSetX11SelectionString.invokeExact(string); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwSetX11SelectionString") + default void nsetX11SelectionString(MemorySegment string) { } /** @@ -298,14 +265,8 @@ public static void nsetX11SelectionString(MemorySegment string) { * @param string A UTF-8 encoded string. * @see #nsetX11SelectionString(MemorySegment) nsetX11SelectionString */ - public static void setX11SelectionString(String string) { - final MemoryStack stack = MemoryStack.stackGet(); - final long stackPointer = stack.getPointer(); - try { - nsetX11SelectionString(stack.allocateFrom(string)); - } finally { - stack.setPointer(stackPointer); - } + @Entrypoint("glfwSetX11SelectionString") + default void setX11SelectionString(String string) { } /** @@ -325,12 +286,9 @@ public static void setX11SelectionString(String string) { * @see #nsetX11SelectionString(MemorySegment) setX11SelectionString * @see GLFW#ngetClipboardString() getClipboardString */ - public static MemorySegment ngetX11SelectionString() { - try { - return (MemorySegment) glfwGetX11SelectionString.invokeExact(); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetX11SelectionString") + default MemorySegment ngetX11SelectionString() { + return MemorySegment.NULL; } /** @@ -340,9 +298,9 @@ public static MemorySegment ngetX11SelectionString() { * if an error occurred. * @see #ngetX11SelectionString() ngetX11SelectionString */ - public static String getX11SelectionString() { - final MemorySegment seg = ngetX11SelectionString(); - return seg != null ? seg.getString(0) : null; + @Entrypoint("glfwGetX11SelectionString") + default String getX11SelectionString() { + return null; } /** @@ -355,12 +313,9 @@ public static String getX11SelectionString() { * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static MemorySegment getGLXContext(MemorySegment window) { - try { - return (MemorySegment) glfwGetGLXContext.invokeExact(window); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetGLXContext") + default MemorySegment getGLXContext(MemorySegment window) { + return MemorySegment.NULL; } /** @@ -373,12 +328,9 @@ public static MemorySegment getGLXContext(MemorySegment window) { * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static long getGLXWindow(MemorySegment window) { - try { - return (long) glfwGetGLXWindow.invokeExact(window); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetGLXWindow") + default long getGLXWindow(MemorySegment window) { + return 0L; } /** @@ -390,12 +342,9 @@ public static long getGLXWindow(MemorySegment window) { * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static MemorySegment getWaylandDisplay() { - try { - return (MemorySegment) glfwGetWaylandDisplay.invokeExact(); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetWaylandDisplay") + default MemorySegment getWaylandDisplay() { + return MemorySegment.NULL; } /** @@ -408,12 +357,9 @@ public static MemorySegment getWaylandDisplay() { * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static MemorySegment getWaylandMonitor(MemorySegment monitor) { - try { - return (MemorySegment) glfwGetWaylandMonitor.invokeExact(monitor); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetWaylandMonitor") + default MemorySegment getWaylandMonitor(MemorySegment monitor) { + return MemorySegment.NULL; } /** @@ -426,12 +372,9 @@ public static MemorySegment getWaylandMonitor(MemorySegment monitor) { * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static MemorySegment getWaylandWindow(MemorySegment window) { - try { - return (MemorySegment) glfwGetWaylandWindow.invokeExact(window); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetWaylandWindow") + default MemorySegment getWaylandWindow(MemorySegment window) { + return MemorySegment.NULL; } /** @@ -445,12 +388,9 @@ public static MemorySegment getWaylandWindow(MemorySegment window) { * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static MemorySegment getEGLDisplay() { - try { - return (MemorySegment) glfwGetEGLDisplay.invokeExact(); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetEGLDisplay") + default MemorySegment getEGLDisplay() { + return MemorySegment.NULL; } /** @@ -463,12 +403,9 @@ public static MemorySegment getEGLDisplay() { * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static MemorySegment getEGLContext(MemorySegment window) { - try { - return (MemorySegment) glfwGetEGLContext.invokeExact(window); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetEGLContext") + default MemorySegment getEGLContext(MemorySegment window) { + return MemorySegment.NULL; } /** @@ -481,23 +418,20 @@ public static MemorySegment getEGLContext(MemorySegment window) { * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static MemorySegment getEGLSurface(MemorySegment window) { - try { - return (MemorySegment) glfwGetEGLSurface.invokeExact(window); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetEGLSurface") + default MemorySegment getEGLSurface(MemorySegment window) { + return MemorySegment.NULL; } /** * Retrieves the color buffer associated with the specified window. * - * @param window window The window whose color buffer to retrieve. - * @param width width Where to store the width of the color buffer, or {@link MemorySegment#NULL NULL}. - * @param height height Where to store the height of the color buffer, or {@link MemorySegment#NULL NULL}. - * @param format format Where to store the OSMesa pixel format of the color + * @param window The window whose color buffer to retrieve. + * @param width Where to store the width of the color buffer, or {@link MemorySegment#NULL NULL}. + * @param height Where to store the height of the color buffer, or {@link MemorySegment#NULL NULL}. + * @param format Where to store the OSMesa pixel format of the color * buffer, or {@link MemorySegment#NULL NULL}. - * @param buffer buffer Where to store the address of the color buffer, or + * @param buffer Where to store the address of the color buffer, or * {@link MemorySegment#NULL NULL}. * @return {@code true} if successful, or {@code false} if an * error occurred. @@ -505,53 +439,30 @@ public static MemorySegment getEGLSurface(MemorySegment window) { * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static boolean ngetOSMesaColorBuffer(MemorySegment window, MemorySegment width, MemorySegment height, MemorySegment format, MemorySegment buffer) { - try { - return (int) glfwGetOSMesaColorBuffer.invokeExact(window, width, height, format, buffer) != GLFW.FALSE; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Convert(Type.INT) + @Entrypoint("glfwGetOSMesaColorBuffer") + default boolean ngetOSMesaColorBuffer(MemorySegment window, MemorySegment width, MemorySegment height, MemorySegment format, MemorySegment buffer) { + return false; } /** * Retrieves the color buffer associated with the specified window. * - * @param window window The window whose color buffer to retrieve. - * @param width width Where to store the width of the color buffer, or {@code null}. - * @param height height Where to store the height of the color buffer, or {@code null}. - * @param format format Where to store the OSMesa pixel format of the color + * @param window The window whose color buffer to retrieve. + * @param width Where to store the width of the color buffer, or {@code null}. + * @param height Where to store the height of the color buffer, or {@code null}. + * @param format Where to store the OSMesa pixel format of the color * buffer, or {@code null}. - * @param buffer buffer Where to store the address of the color buffer, or - * {@code null}. + * @param buffer Where to store the address of the color buffer, or + * {@code NULL}. * @return {@code true} if successful, or {@code false} if an * error occurred. * @see #ngetOSMesaColorBuffer(MemorySegment, MemorySegment, MemorySegment, MemorySegment, MemorySegment) ngetOSMesaColorBuffer */ - public static boolean getOSMesaColorBuffer(MemorySegment window, int @Nullable [] width, int @Nullable [] height, int @Nullable [] format, MemorySegment @Nullable [] buffer) { - final MemoryStack stack = MemoryStack.stackGet(); - final long stackPointer = stack.getPointer(); - try { - final MemorySegment pWidth = width != null ? stack.callocInt() : MemorySegment.NULL; - final MemorySegment pHeight = height != null ? stack.callocInt() : MemorySegment.NULL; - final MemorySegment pFormat = format != null ? stack.callocInt() : MemorySegment.NULL; - final MemorySegment pBuffer = buffer != null ? stack.callocPointer() : MemorySegment.NULL; - final boolean success = ngetOSMesaColorBuffer(window, pWidth, pHeight, pFormat, pBuffer); - if (width != null && width.length > 0) { - width[0] = pWidth.get(ValueLayout.JAVA_INT, 0); - } - if (height != null && height.length > 0) { - height[0] = pHeight.get(ValueLayout.JAVA_INT, 0); - } - if (format != null && format.length > 0) { - format[0] = pFormat.get(ValueLayout.JAVA_INT, 0); - } - if (buffer != null && buffer.length > 0) { - buffer[0] = pBuffer.get(ValueLayout.ADDRESS, 0); - } - return success; - } finally { - stack.setPointer(stackPointer); - } + @Convert(Type.INT) + @Entrypoint("glfwGetOSMesaColorBuffer") + default boolean getOSMesaColorBuffer(MemorySegment window, @Ref int @Nullable [] width, @Ref int @Nullable [] height, @Ref int @Nullable [] format, MemorySegment buffer) { + return false; } /** @@ -570,12 +481,10 @@ public static boolean getOSMesaColorBuffer(MemorySegment window, int @Nullable [ * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static boolean ngetOSMesaDepthBuffer(MemorySegment window, MemorySegment width, MemorySegment height, MemorySegment bytesPerValue, MemorySegment buffer) { - try { - return (int) glfwGetOSMesaDepthBuffer.invokeExact(window, width, height, bytesPerValue, buffer) != GLFW.FALSE; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Convert(Type.INT) + @Entrypoint("glfwGetOSMesaDepthBuffer") + default boolean ngetOSMesaDepthBuffer(MemorySegment window, MemorySegment width, MemorySegment height, MemorySegment bytesPerValue, MemorySegment buffer) { + return false; } /** @@ -592,31 +501,10 @@ public static boolean ngetOSMesaDepthBuffer(MemorySegment window, MemorySegment * error occurred. * @see #ngetOSMesaDepthBuffer(MemorySegment, MemorySegment, MemorySegment, MemorySegment, MemorySegment) ngetOSMesaDepthBuffer */ - public static boolean getOSMesaDepthBuffer(MemorySegment window, int @Nullable [] width, int @Nullable [] height, int @Nullable [] bytesPerValue, MemorySegment @Nullable [] buffer) { - final MemoryStack stack = MemoryStack.stackGet(); - final long stackPointer = stack.getPointer(); - try { - final MemorySegment pWidth = width != null ? stack.callocInt() : MemorySegment.NULL; - final MemorySegment pHeight = height != null ? stack.callocInt() : MemorySegment.NULL; - final MemorySegment pBPV = bytesPerValue != null ? stack.callocInt() : MemorySegment.NULL; - final MemorySegment pBuffer = buffer != null ? stack.callocPointer() : MemorySegment.NULL; - final boolean success = ngetOSMesaDepthBuffer(window, pWidth, pHeight, pBPV, pBuffer); - if (width != null && width.length > 0) { - width[0] = pWidth.get(ValueLayout.JAVA_INT, 0); - } - if (height != null && height.length > 0) { - height[0] = pHeight.get(ValueLayout.JAVA_INT, 0); - } - if (bytesPerValue != null && bytesPerValue.length > 0) { - bytesPerValue[0] = pBPV.get(ValueLayout.JAVA_INT, 0); - } - if (buffer != null && buffer.length > 0) { - buffer[0] = pBuffer.get(ValueLayout.ADDRESS, 0); - } - return success; - } finally { - stack.setPointer(stackPointer); - } + @Convert(Type.INT) + @Entrypoint("glfwGetOSMesaDepthBuffer") + default boolean getOSMesaDepthBuffer(MemorySegment window, @Ref int @Nullable [] width, @Ref int @Nullable [] height, @Ref int @Nullable [] bytesPerValue, MemorySegment buffer) { + return false; } /** @@ -629,11 +517,8 @@ public static boolean getOSMesaDepthBuffer(MemorySegment window, int @Nullable [ * @glfw.thread_safety This function may be called from any thread. Access is not * synchronized. */ - public static MemorySegment getOSMesaContext(MemorySegment window) { - try { - return (MemorySegment) glfwGetOSMesaContext.invokeExact(window); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("glfwGetOSMesaContext") + default MemorySegment getOSMesaContext(MemorySegment window) { + return MemorySegment.NULL; } } diff --git a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWVidMode.java b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWVidMode.java index 41758b48..3f341976 100644 --- a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWVidMode.java +++ b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWVidMode.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2022-2023 Overrun Organization + * Copyright (c) 2022-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,12 +16,10 @@ package overrungl.glfw; -import overrungl.ArrayPointer; -import overrungl.Struct; +import overrun.marshal.struct.Struct; +import overrun.marshal.struct.StructHandle; import java.lang.foreign.*; -import java.lang.foreign.MemoryLayout.PathElement; -import java.lang.invoke.VarHandle; /** * This describes a single video mode. @@ -41,7 +39,7 @@ * @see GLFW#getVideoModes * @since 0.1.0 */ -public sealed class GLFWVidMode extends Struct { +public final class GLFWVidMode extends Struct { /** * The struct layout. */ @@ -53,108 +51,74 @@ public sealed class GLFWVidMode extends Struct { ValueLayout.JAVA_INT.withName("blueBits"), ValueLayout.JAVA_INT.withName("refreshRate") ); - private static final VarHandle - pWidth = LAYOUT.varHandle(PathElement.groupElement("width")), - pHeight = LAYOUT.varHandle(PathElement.groupElement("height")), - pRedBits = LAYOUT.varHandle(PathElement.groupElement("redBits")), - pGreenBits = LAYOUT.varHandle(PathElement.groupElement("greenBits")), - pBlueBits = LAYOUT.varHandle(PathElement.groupElement("blueBits")), - pRefreshRate = LAYOUT.varHandle(PathElement.groupElement("refreshRate")); - /** - * Create a {@code GLFWvidmode} instance. - * - * @param address the address. + * the width, in screen coordinates, of the video mode */ - public GLFWVidMode(MemorySegment address) { - super(address, LAYOUT); - } - + public final StructHandle.Int width = StructHandle.ofInt(this, "width"); /** - * Creates a struct instance with the given memory layout. - * - * @param address the address. - * @param layout the memory layout of this struct. + * the height, in screen coordinates, of the video mode */ - protected GLFWVidMode(MemorySegment address, MemoryLayout layout) { - super(address, layout); - } - + public final StructHandle.Int height = StructHandle.ofInt(this, "height"); /** - * {@return the elements size of this struct in bytes} - */ - public static long sizeof() { - return LAYOUT.byteSize(); - } - - /** - * Creates a {@code GLFWVidMode} instance with the given allocator. - * - * @param allocator the allocator - * @return the instance + * the bit depth of the red channel of the video mode */ - public static GLFWVidMode create(SegmentAllocator allocator) { - return new GLFWVidMode(allocator.allocate(LAYOUT)); - } - + public final StructHandle.Int redBits = StructHandle.ofInt(this, "redBits"); /** - * Creates a {@code GLFWVidMode.Buffer} instance with the given allocator and count. - * - * @param allocator the allocator - * @param count the count - * @return the instance + * the bit depth of the green channel of the video mode */ - public static Buffer create(SegmentAllocator allocator, long count) { - return new Buffer(allocator.allocate(LAYOUT, count), count); - } - + public final StructHandle.Int greenBits = StructHandle.ofInt(this, "greenBits"); /** - * {@return an immutable state of this struct} + * the bit depth of the blue channel of the video mode */ - public Value value() { - return new Value(width(), height(), redBits(), greenBits(), blueBits(), refreshRate()); - } - + public final StructHandle.Int blueBits = StructHandle.ofInt(this, "blueBits"); /** - * {@return the width, in screen coordinates, of the video mode} + * the refresh rate, in Hz, of the video mode */ - public int width() { - return (int) pWidth.get(segment(), 0L); - } + public final StructHandle.Int refreshRate = StructHandle.ofInt(this, "refreshRate"); /** - * {@return the height, in screen coordinates, of the video mode} + * Creates a struct with the given layout. + * + * @param segment the segment + * @param elementCount the element count */ - public int height() { - return (int) pHeight.get(segment(), 0L); + public GLFWVidMode(MemorySegment segment, long elementCount) { + super(segment, elementCount, LAYOUT); } /** - * {@return the bit depth of the red channel of the video mode} + * Allocates a struct with the given layout. + * + * @param allocator the allocator + * @param elementCount the element count */ - public int redBits() { - return (int) pRedBits.get(segment(), 0L); + public GLFWVidMode(SegmentAllocator allocator, long elementCount) { + super(allocator, elementCount, LAYOUT); } /** - * {@return the bit depth of the green channel of the video mode} + * Creates a struct with the given layout. + * + * @param segment the segment */ - public int greenBits() { - return (int) pGreenBits.get(segment(), 0L); + public GLFWVidMode(MemorySegment segment) { + super(segment, LAYOUT); } /** - * {@return the bit depth of the blue channel of the video mode} + * Allocates a struct with the given layout. + * + * @param allocator the allocator */ - public int blueBits() { - return (int) pBlueBits.get(segment(), 0L); + public GLFWVidMode(SegmentAllocator allocator) { + super(allocator, LAYOUT); } /** - * {@return the refresh rate, in Hz, of the video mode} + * {@return an immutable state of this struct} */ - public int refreshRate() { - return (int) pRefreshRate.get(segment(), 0L); + public Value value() { + return new Value(width.get(), height.get(), redBits.get(), greenBits.get(), blueBits.get(), refreshRate.get()); } /** @@ -178,120 +142,4 @@ public int refreshRate() { int refreshRate ) { } - - /** - * This describes video modes. - * - * @author squid233 - * @since 0.1.0 - */ - public static final class Buffer extends GLFWVidMode implements ArrayPointer { - private final VarHandle pWidth, pHeight, pRedBits, pGreenBits, pBlueBits, pRefreshRate; - - /** - * Create a {@code GLFWvidmode.Buffer} instance. - * - * @param address the address. - * @param elementCount the element count - */ - public Buffer(MemorySegment address, long elementCount) { - super(address, MemoryLayout.sequenceLayout(elementCount, LAYOUT)); - pWidth = layout().varHandle(PathElement.sequenceElement(), PathElement.groupElement("width")); - pHeight = layout().varHandle(PathElement.sequenceElement(), PathElement.groupElement("height")); - pRedBits = layout().varHandle(PathElement.sequenceElement(), PathElement.groupElement("redBits")); - pGreenBits = layout().varHandle(PathElement.sequenceElement(), PathElement.groupElement("greenBits")); - pBlueBits = layout().varHandle(PathElement.sequenceElement(), PathElement.groupElement("blueBits")); - pRefreshRate = layout().varHandle(PathElement.sequenceElement(), PathElement.groupElement("refreshRate")); - } - - /** - * Gets the width at the given index. - * - * @param index the index - * @return The width, in screen coordinates, of the video mode. - */ - public int widthAt(long index) { - return (int) pWidth.get(segment(), index); - } - - /** - * Gets the height at the given index. - * - * @param index the index - * @return The height, in screen coordinates, of the video mode. - */ - public int heightAt(long index) { - return (int) pHeight.get(segment(), index); - } - - /** - * Gets the red bits at the given index. - * - * @param index the index - * @return The bit depth of the red channel, of the video mode. - */ - public int redBitsAt(long index) { - return (int) pRedBits.get(segment(), index); - } - - /** - * Gets the green bits at the given index. - * - * @param index the index - * @return The bit depth of the green channel, of the video mode. - */ - public int greenBitsAt(long index) { - return (int) pGreenBits.get(segment(), index); - } - - /** - * Gets the blue bits at the given index. - * - * @param index the index - * @return The bit depth of the blue channel, of the video mode. - */ - public int blueBitsAt(long index) { - return (int) pBlueBits.get(segment(), index); - } - - /** - * Gets the refresh rate at the given index. - * - * @param index the index - * @return The refresh rate, in Hz, of the video mode. - */ - public int refreshRateAt(long index) { - return (int) pRefreshRate.get(segment(), index); - } - - @Override - public int width() { - return widthAt(0); - } - - @Override - public int height() { - return heightAt(0); - } - - @Override - public int redBits() { - return redBitsAt(0); - } - - @Override - public int greenBits() { - return greenBitsAt(0); - } - - @Override - public int blueBits() { - return blueBitsAt(0); - } - - @Override - public int refreshRate() { - return refreshRateAt(0); - } - } } diff --git a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWVulkan.java b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWVulkan.java index 5ac28dc3..b537c585 100644 --- a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWVulkan.java +++ b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWVulkan.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2022-2023 Overrun Organization + * Copyright (c) 2022-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,12 +16,13 @@ package overrungl.glfw; -import overrungl.util.MemoryStack; +import overrun.marshal.Downcall; +import overrun.marshal.gen.Convert; +import overrun.marshal.gen.Entrypoint; +import overrun.marshal.gen.Ref; +import overrun.marshal.gen.Type; import java.lang.foreign.MemorySegment; -import java.lang.foreign.ValueLayout; - -import static overrungl.glfw.Handles.*; /** * The GLFW Vulkan binding. @@ -29,13 +30,11 @@ * @author squid233 * @since 0.1.0 */ -public final class GLFWVulkan { +public interface GLFWVulkan { /** - * constructor + * The instance of GLFWVulkan. */ - private GLFWVulkan() { - throw new IllegalStateException("Do not construct instance"); - } + GLFWVulkan INSTANCE = Downcall.load(Handles.lookup); /** * Returns the address of the specified Vulkan instance function. @@ -70,13 +69,8 @@ private GLFWVulkan() { * is terminated. * @glfw.thread_safety This function may be called from any thread. */ - public static MemorySegment nglfwGetInstanceProcAddress(MemorySegment instance, MemorySegment procName) { - try { - return (MemorySegment) glfwGetInstanceProcAddress.invokeExact(instance, procName); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("glfwGetInstanceProcAddress") + MemorySegment ngetInstanceProcAddress(MemorySegment instance, MemorySegment procName); /** * Returns the address of the specified Vulkan instance function. @@ -86,17 +80,10 @@ public static MemorySegment nglfwGetInstanceProcAddress(MemorySegment instance, * @param procName The ASCII encoded name of the function. * @return The address of the function, or {@link MemorySegment#NULL NULL} if an * error occurred. - * @see #nglfwGetInstanceProcAddress(MemorySegment, MemorySegment) nglfwGetInstanceProcAddress + * @see #ngetInstanceProcAddress(MemorySegment, MemorySegment) nglfwGetInstanceProcAddress */ - public static MemorySegment glfwGetInstanceProcAddress(MemorySegment instance, String procName) { - final MemoryStack stack = MemoryStack.stackGet(); - final long stackPointer = stack.getPointer(); - try { - return nglfwGetInstanceProcAddress(instance, stack.allocateFrom(procName)); - } finally { - stack.setPointer(stackPointer); - } - } + @Entrypoint("glfwGetInstanceProcAddress") + MemorySegment getInstanceProcAddress(MemorySegment instance, String procName); /** * Returns whether the specified queue family can present images. @@ -125,13 +112,9 @@ public static MemorySegment glfwGetInstanceProcAddress(MemorySegment instance, S * @glfw.thread_safety This function may be called from any thread. For * synchronization details of Vulkan objects, see the Vulkan specification. */ - public static boolean glfwGetPhysicalDevicePresentationSupport(MemorySegment instance, MemorySegment device, int queueFamily) { - try { - return (int) glfwGetPhysicalDevicePresentationSupport.invokeExact(instance, device, queueFamily) != GLFW.FALSE; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("glfwGetPhysicalDevicePresentationSupport") + boolean getPhysicalDevicePresentationSupport(MemorySegment instance, MemorySegment device, int queueFamily); /** * Creates a Vulkan surface for the specified window. @@ -188,13 +171,8 @@ public static boolean glfwGetPhysicalDevicePresentationSupport(MemorySegment ins * synchronization details of Vulkan objects, see the Vulkan specification. * @see GLFW#ngetRequiredInstanceExtensions(MemorySegment) getRequiredInstanceExtensions */ - public static int nglfwCreateWindowSurface(MemorySegment instance, MemorySegment window, MemorySegment allocator, MemorySegment surface) { - try { - return (int) glfwCreateWindowSurface.invokeExact(instance, window, allocator, surface); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("glfwCreateWindowSurface") + int ncreateWindowSurface(MemorySegment instance, MemorySegment window, MemorySegment allocator, MemorySegment surface); /** * Creates a Vulkan surface for the specified window. @@ -207,18 +185,8 @@ public static int nglfwCreateWindowSurface(MemorySegment instance, MemorySegment * to {@code VK_NULL_HANDLE} if an error occurred. * @return {@code VK_SUCCESS} if successful, or a Vulkan error code if an * error occurred. - * @see #nglfwCreateWindowSurface(MemorySegment, MemorySegment, MemorySegment, MemorySegment) nglfwCreateWindowSurface + * @see #ncreateWindowSurface(MemorySegment, MemorySegment, MemorySegment, MemorySegment) nglfwCreateWindowSurface */ - public static int glfwCreateWindowSurface(MemorySegment instance, MemorySegment window, MemorySegment allocator, long[] surface) { - var stack = MemoryStack.stackGet(); - long stackPointer = stack.getPointer(); - try { - var pSurface = stack.callocLong(); - int result = nglfwCreateWindowSurface(instance, window, allocator, pSurface); - surface[0] = pSurface.get(ValueLayout.JAVA_LONG, 0); - return result; - } finally { - stack.setPointer(stackPointer); - } - } + @Entrypoint("glfwCreateWindowSurface") + int createWindowSurface(MemorySegment instance, MemorySegment window, MemorySegment allocator, @Ref long[] surface); } diff --git a/modules/overrungl.glfw/src/main/java/overrungl/glfw/Handles.java b/modules/overrungl.glfw/src/main/java/overrungl/glfw/Handles.java index c3ff845f..d2da6127 100644 --- a/modules/overrungl.glfw/src/main/java/overrungl/glfw/Handles.java +++ b/modules/overrungl.glfw/src/main/java/overrungl/glfw/Handles.java @@ -38,7 +38,7 @@ * @since 0.1.0 */ final class Handles { - private static final SymbolLookup lookup; + static final SymbolLookup lookup; static { final Supplier lib = () -> RuntimeHelper.load("glfw", "glfw3", OverrunGL.GLFW_VERSION); @@ -162,13 +162,6 @@ final class Handles { glfwGetProcAddress = downcall("glfwGetProcAddress", PP), glfwVulkanSupported = downcall("glfwVulkanSupported", I), glfwGetRequiredInstanceExtensions = downcall("glfwGetRequiredInstanceExtensions", Pp); - - // GLFW Vulkan - static final MethodHandle - glfwGetInstanceProcAddress = downcall("glfwGetInstanceProcAddress", PPP), - glfwGetPhysicalDevicePresentationSupport = downcall("glfwGetPhysicalDevicePresentationSupport", PPII), - glfwCreateWindowSurface = downcall("glfwCreateWindowSurface", PPPPI); - // GLFW Native static final MethodHandle glfwGetWin32Adapter = downcallNative("glfwGetWin32Adapter", Pp), diff --git a/modules/overrungl.glfw/src/main/java/overrungl/glfw/StructHandleSizedByteArray.java b/modules/overrungl.glfw/src/main/java/overrungl/glfw/StructHandleSizedByteArray.java new file mode 100644 index 00000000..96eef129 --- /dev/null +++ b/modules/overrungl.glfw/src/main/java/overrungl/glfw/StructHandleSizedByteArray.java @@ -0,0 +1,87 @@ +/* + * MIT License + * + * Copyright (c) 2024 Overrun Organization + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + */ + +package overrungl.glfw; + +import overrun.marshal.struct.Struct; +import overrun.marshal.struct.StructHandle; + +import java.lang.invoke.VarHandle; + +/** + * Sized array struct handle + * + * @author squid233 + * @since 0.1.0 + */ +public final class StructHandleSizedByteArray extends StructHandle { + private StructHandleSizedByteArray(VarHandle varHandle) { + super(varHandle); + } + + /** + * Creates it + * + * @param struct struct + * @param name name + * @return handle + */ + static StructHandleSizedByteArray of(Struct struct, String name) { + return new StructHandleSizedByteArray(StructHandle.ofSizedArray(struct, name)); + } + + /** + * Sets the value at the given index. + * + * @param index the index + * @param arrayIndex the array index + * @param value the value + */ + public void set(long index, long arrayIndex, byte value) { + varHandle.set(0L, index, arrayIndex, value); + } + + /** + * Sets the value. + * + * @param arrayIndex the array index + * @param value the value + */ + public void set(long arrayIndex, byte value) { + set(0L, arrayIndex, value); + } + + /** + * Gets the value at the given index. + * + * @param index the index + * @param arrayIndex the array index + * @return the value + */ + public byte get(long index, long arrayIndex) { + return (byte) varHandle.get(0L, index, arrayIndex); + } + + /** + * Gets the value. + * + * @param arrayIndex the array index + * @return the value + */ + public byte get(long arrayIndex) { + return get(0L, arrayIndex); + } +} diff --git a/modules/overrungl.glfw/src/main/java/overrungl/glfw/StructHandleSizedFloatArray.java b/modules/overrungl.glfw/src/main/java/overrungl/glfw/StructHandleSizedFloatArray.java new file mode 100644 index 00000000..9424cdcc --- /dev/null +++ b/modules/overrungl.glfw/src/main/java/overrungl/glfw/StructHandleSizedFloatArray.java @@ -0,0 +1,87 @@ +/* + * MIT License + * + * Copyright (c) 2024 Overrun Organization + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + */ + +package overrungl.glfw; + +import overrun.marshal.struct.Struct; +import overrun.marshal.struct.StructHandle; + +import java.lang.invoke.VarHandle; + +/** + * Sized array struct handle + * + * @author squid233 + * @since 0.1.0 + */ +public final class StructHandleSizedFloatArray extends StructHandle { + private StructHandleSizedFloatArray(VarHandle varHandle) { + super(varHandle); + } + + /** + * Creates it + * + * @param struct struct + * @param name name + * @return handle + */ + static StructHandleSizedFloatArray of(Struct struct, String name) { + return new StructHandleSizedFloatArray(StructHandle.ofSizedArray(struct, name)); + } + + /** + * Sets the value at the given index. + * + * @param index the index + * @param arrayIndex the array index + * @param value the value + */ + public void set(long index, long arrayIndex, float value) { + varHandle.set(0L, index, arrayIndex, value); + } + + /** + * Sets the value. + * + * @param arrayIndex the array index + * @param value the value + */ + public void set(long arrayIndex, float value) { + set(0L, arrayIndex, value); + } + + /** + * Gets the value at the given index. + * + * @param index the index + * @param arrayIndex the array index + * @return the value + */ + public float get(long index, long arrayIndex) { + return (short) varHandle.get(0L, index, arrayIndex); + } + + /** + * Gets the value. + * + * @param arrayIndex the array index + * @return the value + */ + public float get(long arrayIndex) { + return get(0L, arrayIndex); + } +} diff --git a/modules/samples/src/test/java/overrungl/demo/glfw/GLFWJoystickTest.java b/modules/samples/src/test/java/overrungl/demo/glfw/GLFWJoystickTest.java index 4292a3a4..535eb9fe 100644 --- a/modules/samples/src/test/java/overrungl/demo/glfw/GLFWJoystickTest.java +++ b/modules/samples/src/test/java/overrungl/demo/glfw/GLFWJoystickTest.java @@ -76,10 +76,9 @@ private void init() { private void loop() { var states = new GLFWGamepadState[GLFW.JOYSTICK_LAST + 1]; for (int i = 0; i < states.length; i++) { - states[i] = GLFWGamepadState.create(Arena.global()); + states[i] = new GLFWGamepadState(Arena.ofAuto()); } while (!GLFW.windowShouldClose(window)) { -// try (var arena = Arena.openShared()) { for (int i = 0; i <= GLFW.JOYSTICK_LAST; i++) { if (GLFW.joystickPresent(i)) { if (GLFW.joystickIsGamepad(i)) { @@ -97,7 +96,6 @@ private void loop() { } } } -// } GLFW.waitEventsTimeout(3); } } diff --git a/modules/samples/src/test/java/overrungl/demo/glfw/GLFWWindowIconTest.java b/modules/samples/src/test/java/overrungl/demo/glfw/GLFWWindowIconTest.java index adb97763..cacff5c4 100644 --- a/modules/samples/src/test/java/overrungl/demo/glfw/GLFWWindowIconTest.java +++ b/modules/samples/src/test/java/overrungl/demo/glfw/GLFWWindowIconTest.java @@ -74,10 +74,11 @@ private void init(Arena arena) { IOUtil.ioResourceToSegment(arena, "image.png", 256), px, py, pc, STBImage.RGB_ALPHA ); - GLFW.setWindowIcon(window, GLFWImage.create(arena, 1) - .width(px.get(JAVA_INT, 0)) - .height(py.get(JAVA_INT, 0)) - .pixels(data)); + final GLFWImage image = new GLFWImage(arena); + image.width.set(px.get(JAVA_INT, 0)); + image.height.set(py.get(JAVA_INT, 0)); + image.pixels.set(data); + GLFW.setWindowIcon(window, image); stbImage.free(data); } catch (IOException e) { throw new RuntimeException(e);