Skip to content

Commit

Permalink
Merge pull request #73 from Over-Run/feature
Browse files Browse the repository at this point in the history
  • Loading branch information
squid233 authored Jan 15, 2025
2 parents 580f095 + 9852523 commit ff26bbc
Show file tree
Hide file tree
Showing 1,524 changed files with 123,736 additions and 63,995 deletions.
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,36 @@
[![Java CI with Gradle](https://github.com/Over-Run/overrungl/actions/workflows/gradle.yml/badge.svg?event=push)](https://github.com/Over-Run/overrungl/actions/workflows/gradle.yml)
[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/8279/badge)](https://www.bestpractices.dev/projects/8279)

## Overview

```java
void main() {
// invoke native functions via static methods
glfwInit();
// use MemorySegment to represent memory addresses
MemorySegment window = glfwCreateWindow(...);

int width, height;
// use MemoryStack for one-time and quick allocation
try (var stack = MemoryStack.pushLocal()) {
// use SegmentAllocator to allocate memory
var pWidth = stack.allocate(ValueLayout.JAVA_INT);
var pHeight = stack.allocate(ValueLayout.JAVA_INT);

glfwGetFramebufferSize(window, pWidth, pHeight);

// use accessors in MemorySegment to read and write memory
width = pWidth.get(ValueLayout.JAVA_INT, 0L);
height = pHeight.get(ValueLayout.JAVA_INT, 0L);
}

// for OpenGL and Vulkan, create instances of wrappers
var gl = new GL(GLFW::glfwGetProcAddress);
// invoke OpenGL/Vulkan functions via instance methods
gl.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
```

## Introduction

Overrun Game Library is a high-performance library implemented with Java 23,
Expand Down
245 changes: 126 additions & 119 deletions generators/src/main/kotlin/overrungl/gen/Struct.kt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class VkDowncall(
write: Boolean = true,
action: VkDowncall.() -> Unit
) {
var modifier: String? = null
val imports = mutableSetOf<String>()
val extends = mutableListOf<String>()
val fields = mutableListOf<VkDowncallField>()
Expand Down Expand Up @@ -192,7 +193,11 @@ class VkDowncall(
)
if (packageName != vulkanPackage) sb.appendLine("import overrungl.vulkan.*;")
imports.sorted().forEach { sb.appendLine("import $it;") }
sb.append("public class $className")
sb.append("public ")
if (modifier != null) {
sb.append("$modifier ")
}
sb.append("class $className")
if (extends.isNotEmpty()) {
sb.append(" extends ${extends.joinToString(", ")}")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ fun main() {
}
}
nameIndex++
if (nameIndex < childNodeList.length - 1) {
if (nameIndex < childNodeList.length) {
// scan fixed size array
val sb = StringBuilder()
for (i2 in nameIndex until childNodeList.length) {
Expand All @@ -297,7 +297,9 @@ fun main() {
}
}
}
fixedSize = sb.split('[', ']')[1]
if (sb.startsWith("[")) {
fixedSize = sb.split('[', ']')[1]
}
}
members.add(VkStructMember(typeComp, memberName!!, fixedSize))
if (fixedSize != null && fixedSize.startsWith("VK_")) {
Expand Down Expand Up @@ -575,6 +577,8 @@ fun main() {

if (featureNumber == "1.0") {
customCode = """
public static final MemorySegment VK_NULL_HANDLE = MemorySegment.NULL;
public static int VK_MAKE_API_VERSION(int variant, int major, int minor, int patch) {
return (variant << 29) | (major << 22) | (minor << 12) | patch;
}
Expand Down Expand Up @@ -671,19 +675,24 @@ fun main() {
addReqEnums(extReqEnums)
addReqCommand(extReqCommands, commandMap, commandAliasMap)

constructor = buildString {
append("public $extName(")
when (extType) {
"device" -> append("""@CType("VkDevice") MemorySegment device""")
"instance" -> append("""@CType("VkInstance") MemorySegment instance""")
}
appendLine(", VKLoadFunc func) {")
extReqCommands.forEach { command ->
append(""" PFN_$command = func.invoke($extType, "$command"""")
commandAliasMap[command]?.onEach { append(""", "$it"""") }
appendLine(");")
if (extReqCommands.isEmpty()){
modifier = "final"
constructor = "private $extName() { }"
}else {
constructor = buildString {
append("public $extName(")
when (extType) {
"device" -> append("""@CType("VkDevice") MemorySegment device""")
"instance" -> append("""@CType("VkInstance") MemorySegment instance""")
}
appendLine(", VKLoadFunc func) {")
extReqCommands.forEach { command ->
append(""" PFN_$command = func.invoke($extType, "$command"""")
commandAliasMap[command]?.onEach { append(""", "$it"""") }
appendLine(");")
}
append("}")
}
append("}")
}
}
extensionDowncalls[rawName] = downcall
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2024 Overrun Organization
* Copyright (c) 2024-2025 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
Expand Down Expand Up @@ -168,9 +168,7 @@ private MemorySegment trySlice(long byteSize, long byteAlignment) {
/**
* {@inheritDoc}
* The returned memory segment is a slice of the {@linkplain #segment() backing segment}
* and is not initialized with zero.
* <p>
* Use {@link MemorySegment#fill(byte) fill((byte)0)} to initialize with zero.
* and is initialized with zero.
*
* @throws IndexOutOfBoundsException if there is not enough space to allocate
* @throws IllegalArgumentException if {@code byteSize < 0}, {@code byteAlignment <= 0},
Expand All @@ -184,7 +182,7 @@ public MemorySegment allocate(long byteSize, long byteAlignment) {
if (byteAlignment <= 0 || ((byteAlignment & (byteAlignment - 1)) != 0L)) {
throw new IllegalArgumentException("Invalid alignment constraint: " + byteAlignment);
}
return trySlice(byteSize, byteAlignment);
return trySlice(byteSize, byteAlignment).fill((byte) 0);
}

/**
Expand Down
116 changes: 81 additions & 35 deletions modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWAllocator.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
/// void* user;
/// } GLFWAllocator;
/// ```
public final class GLFWAllocator extends Struct {
public sealed class GLFWAllocator extends Struct {
/// The struct layout of `GLFWallocator`.
public static final StructLayout LAYOUT = LayoutBuilder.struct(
ValueLayout.ADDRESS.withName("allocate"),
Expand All @@ -69,6 +69,11 @@ public final class GLFWAllocator extends Struct {
/// @return the created instance or `null` if the segment is `NULL`
public static GLFWAllocator of(MemorySegment segment) { return Unmarshal.isNullPointer(segment) ? null : new GLFWAllocator(segment); }

/// Creates `GLFWAllocator` with the given segment.
/// @param segment the memory segment
/// @return the created instance or `null` if the segment is `NULL`
public static Buffer ofBuffer(MemorySegment segment) { return Unmarshal.isNullPointer(segment) ? null : new Buffer(segment, estimateCount(segment, LAYOUT)); }

/// Creates `GLFWAllocator` with the given segment.
///
/// Reinterprets the segment if zero-length.
Expand All @@ -82,7 +87,7 @@ public final class GLFWAllocator extends Struct {
/// @param segment the memory segment
/// @param count the count of the buffer
/// @return the created instance or `null` if the segment is `NULL`
public static GLFWAllocator ofNative(MemorySegment segment, long count) { return Unmarshal.isNullPointer(segment) ? null : new GLFWAllocator(segment.byteSize() == 0 ? segment.reinterpret(LAYOUT.scale(0, count)) : segment); }
public static Buffer ofNative(MemorySegment segment, long count) { return Unmarshal.isNullPointer(segment) ? null : new Buffer(segment.byteSize() == 0 ? segment.reinterpret(LAYOUT.scale(0, count)) : segment, count); }

/// Allocates a `GLFWAllocator` with the given segment allocator.
/// @param allocator the segment allocator
Expand All @@ -93,7 +98,21 @@ public final class GLFWAllocator extends Struct {
/// @param allocator the segment allocator
/// @param count the count
/// @return the allocated `GLFWAllocator`
public static GLFWAllocator alloc(SegmentAllocator allocator, long count) { return new GLFWAllocator(allocator.allocate(LAYOUT, count)); }
public static Buffer alloc(SegmentAllocator allocator, long count) { return new Buffer(allocator.allocate(LAYOUT, count), count); }

/// Allocates a `GLFWAllocator` with the given segment allocator and the initializing arguments.
/// @param allocator the segment allocator
/// @return the allocated `GLFWAllocator`
public static GLFWAllocator allocInit(SegmentAllocator allocator, @CType("GLFWallocatefun") java.lang.foreign.MemorySegment allocate, @CType("GLFWreallocatefun") java.lang.foreign.MemorySegment reallocate, @CType("GLFWdeallocatefun") java.lang.foreign.MemorySegment deallocate, @CType("void*") java.lang.foreign.MemorySegment user) { return alloc(allocator).allocate(allocate).reallocate(reallocate).deallocate(deallocate).user(user); }

/// Copies from the given source.
/// @param src the source
/// @return `this`
public GLFWAllocator copyFrom(GLFWAllocator src) { this.segment().copyFrom(src.segment()); return this; }

/// Converts this instance to a buffer.
/// @return the buffer
public Buffer asBuffer() { return new Buffer(this.segment(), this.estimateCount()); }

/// {@return `allocate` at the given index}
/// @param segment the segment of the struct
Expand All @@ -102,9 +121,6 @@ public final class GLFWAllocator extends Struct {
/// {@return `allocate`}
/// @param segment the segment of the struct
public static @CType("GLFWallocatefun") java.lang.foreign.MemorySegment get_allocate(MemorySegment segment) { return GLFWAllocator.get_allocate(segment, 0L); }
/// {@return `allocate` at the given index}
/// @param index the index
public @CType("GLFWallocatefun") java.lang.foreign.MemorySegment allocateAt(long index) { return GLFWAllocator.get_allocate(this.segment(), index); }
/// {@return `allocate`}
public @CType("GLFWallocatefun") java.lang.foreign.MemorySegment allocate() { return GLFWAllocator.get_allocate(this.segment()); }
/// Sets `allocate` with the given value at the given index.
Expand All @@ -116,11 +132,6 @@ public final class GLFWAllocator extends Struct {
/// @param segment the segment of the struct
/// @param value the value
public static void set_allocate(MemorySegment segment, @CType("GLFWallocatefun") java.lang.foreign.MemorySegment value) { GLFWAllocator.set_allocate(segment, 0L, value); }
/// Sets `allocate` with the given value at the given index.
/// @param index the index
/// @param value the value
/// @return `this`
public GLFWAllocator allocateAt(long index, @CType("GLFWallocatefun") java.lang.foreign.MemorySegment value) { GLFWAllocator.set_allocate(this.segment(), index, value); return this; }
/// Sets `allocate` with the given value.
/// @param value the value
/// @return `this`
Expand All @@ -133,9 +144,6 @@ public final class GLFWAllocator extends Struct {
/// {@return `reallocate`}
/// @param segment the segment of the struct
public static @CType("GLFWreallocatefun") java.lang.foreign.MemorySegment get_reallocate(MemorySegment segment) { return GLFWAllocator.get_reallocate(segment, 0L); }
/// {@return `reallocate` at the given index}
/// @param index the index
public @CType("GLFWreallocatefun") java.lang.foreign.MemorySegment reallocateAt(long index) { return GLFWAllocator.get_reallocate(this.segment(), index); }
/// {@return `reallocate`}
public @CType("GLFWreallocatefun") java.lang.foreign.MemorySegment reallocate() { return GLFWAllocator.get_reallocate(this.segment()); }
/// Sets `reallocate` with the given value at the given index.
Expand All @@ -147,11 +155,6 @@ public final class GLFWAllocator extends Struct {
/// @param segment the segment of the struct
/// @param value the value
public static void set_reallocate(MemorySegment segment, @CType("GLFWreallocatefun") java.lang.foreign.MemorySegment value) { GLFWAllocator.set_reallocate(segment, 0L, value); }
/// Sets `reallocate` with the given value at the given index.
/// @param index the index
/// @param value the value
/// @return `this`
public GLFWAllocator reallocateAt(long index, @CType("GLFWreallocatefun") java.lang.foreign.MemorySegment value) { GLFWAllocator.set_reallocate(this.segment(), index, value); return this; }
/// Sets `reallocate` with the given value.
/// @param value the value
/// @return `this`
Expand All @@ -164,9 +167,6 @@ public final class GLFWAllocator extends Struct {
/// {@return `deallocate`}
/// @param segment the segment of the struct
public static @CType("GLFWdeallocatefun") java.lang.foreign.MemorySegment get_deallocate(MemorySegment segment) { return GLFWAllocator.get_deallocate(segment, 0L); }
/// {@return `deallocate` at the given index}
/// @param index the index
public @CType("GLFWdeallocatefun") java.lang.foreign.MemorySegment deallocateAt(long index) { return GLFWAllocator.get_deallocate(this.segment(), index); }
/// {@return `deallocate`}
public @CType("GLFWdeallocatefun") java.lang.foreign.MemorySegment deallocate() { return GLFWAllocator.get_deallocate(this.segment()); }
/// Sets `deallocate` with the given value at the given index.
Expand All @@ -178,11 +178,6 @@ public final class GLFWAllocator extends Struct {
/// @param segment the segment of the struct
/// @param value the value
public static void set_deallocate(MemorySegment segment, @CType("GLFWdeallocatefun") java.lang.foreign.MemorySegment value) { GLFWAllocator.set_deallocate(segment, 0L, value); }
/// Sets `deallocate` with the given value at the given index.
/// @param index the index
/// @param value the value
/// @return `this`
public GLFWAllocator deallocateAt(long index, @CType("GLFWdeallocatefun") java.lang.foreign.MemorySegment value) { GLFWAllocator.set_deallocate(this.segment(), index, value); return this; }
/// Sets `deallocate` with the given value.
/// @param value the value
/// @return `this`
Expand All @@ -195,9 +190,6 @@ public final class GLFWAllocator extends Struct {
/// {@return `user`}
/// @param segment the segment of the struct
public static @CType("void*") java.lang.foreign.MemorySegment get_user(MemorySegment segment) { return GLFWAllocator.get_user(segment, 0L); }
/// {@return `user` at the given index}
/// @param index the index
public @CType("void*") java.lang.foreign.MemorySegment userAt(long index) { return GLFWAllocator.get_user(this.segment(), index); }
/// {@return `user`}
public @CType("void*") java.lang.foreign.MemorySegment user() { return GLFWAllocator.get_user(this.segment()); }
/// Sets `user` with the given value at the given index.
Expand All @@ -209,14 +201,68 @@ public final class GLFWAllocator extends Struct {
/// @param segment the segment of the struct
/// @param value the value
public static void set_user(MemorySegment segment, @CType("void*") java.lang.foreign.MemorySegment value) { GLFWAllocator.set_user(segment, 0L, value); }
/// Sets `user` with the given value at the given index.
/// @param index the index
/// @param value the value
/// @return `this`
public GLFWAllocator userAt(long index, @CType("void*") java.lang.foreign.MemorySegment value) { GLFWAllocator.set_user(this.segment(), index, value); return this; }
/// Sets `user` with the given value.
/// @param value the value
/// @return `this`
public GLFWAllocator user(@CType("void*") java.lang.foreign.MemorySegment value) { GLFWAllocator.set_user(this.segment(), value); return this; }

/// A buffer of [GLFWAllocator].
public static final class Buffer extends GLFWAllocator {
private final long elementCount;

/// Creates `GLFWAllocator.Buffer` with the given segment.
/// @param segment the memory segment
/// @param elementCount the element count
public Buffer(MemorySegment segment, long elementCount) { super(segment); this.elementCount = elementCount; }

@Override public long estimateCount() { return elementCount; }

/// Creates a slice of `GLFWAllocator`.
/// @param index the index of the struct buffer
/// @return the slice of `GLFWAllocator`
public GLFWAllocator asSlice(long index) { return new GLFWAllocator(this.segment().asSlice(LAYOUT.scale(0L, index), LAYOUT)); }

/// Creates a slice of `GLFWAllocator`.
/// @param index the index of the struct buffer
/// @param count the count
/// @return the slice of `GLFWAllocator`
public Buffer asSlice(long index, long count) { return new Buffer(this.segment().asSlice(LAYOUT.scale(0L, index), LAYOUT.byteSize() * count), count); }

/// {@return `allocate` at the given index}
/// @param index the index
public @CType("GLFWallocatefun") java.lang.foreign.MemorySegment allocateAt(long index) { return GLFWAllocator.get_allocate(this.segment(), index); }
/// Sets `allocate` with the given value at the given index.
/// @param index the index
/// @param value the value
/// @return `this`
public Buffer allocateAt(long index, @CType("GLFWallocatefun") java.lang.foreign.MemorySegment value) { GLFWAllocator.set_allocate(this.segment(), index, value); return this; }

/// {@return `reallocate` at the given index}
/// @param index the index
public @CType("GLFWreallocatefun") java.lang.foreign.MemorySegment reallocateAt(long index) { return GLFWAllocator.get_reallocate(this.segment(), index); }
/// Sets `reallocate` with the given value at the given index.
/// @param index the index
/// @param value the value
/// @return `this`
public Buffer reallocateAt(long index, @CType("GLFWreallocatefun") java.lang.foreign.MemorySegment value) { GLFWAllocator.set_reallocate(this.segment(), index, value); return this; }

/// {@return `deallocate` at the given index}
/// @param index the index
public @CType("GLFWdeallocatefun") java.lang.foreign.MemorySegment deallocateAt(long index) { return GLFWAllocator.get_deallocate(this.segment(), index); }
/// Sets `deallocate` with the given value at the given index.
/// @param index the index
/// @param value the value
/// @return `this`
public Buffer deallocateAt(long index, @CType("GLFWdeallocatefun") java.lang.foreign.MemorySegment value) { GLFWAllocator.set_deallocate(this.segment(), index, value); return this; }

/// {@return `user` at the given index}
/// @param index the index
public @CType("void*") java.lang.foreign.MemorySegment userAt(long index) { return GLFWAllocator.get_user(this.segment(), index); }
/// Sets `user` with the given value at the given index.
/// @param index the index
/// @param value the value
/// @return `this`
public Buffer userAt(long index, @CType("void*") java.lang.foreign.MemorySegment value) { GLFWAllocator.set_user(this.segment(), index, value); return this; }

}
}
Loading

0 comments on commit ff26bbc

Please sign in to comment.