Skip to content

Feature/native api #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ Cargo.lock
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
bin/
bin/
native/src/main/resources/native/
30 changes: 0 additions & 30 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,25 +98,13 @@
"request": "launch",
"mainClass": "org.xxdc.oss.example.App",
"projectName": "app",
"env": {
"LIB_PATH": "${workspaceFolder}/app/build/cargo/debug",
"PATH": "${workspaceFolder}/app/build/cargo/debug",
"LD_LIBRARY_PATH": "${workspaceFolder}/app/build/cargo/debug",
"DYLD_LIBRARY_PATH": "${workspaceFolder}/app/build/cargo/debug"
}
},
{
"type": "java",
"name": "GameClient",
"request": "launch",
"mainClass": "org.xxdc.oss.example.GameClient",
"projectName": "app",
"env": {
"LIB_PATH": "${workspaceFolder}/app/build/cargo/debug",
"PATH": "${workspaceFolder}/app/build/cargo/debug",
"LD_LIBRARY_PATH": "${workspaceFolder}/app/build/cargo/debug",
"DYLD_LIBRARY_PATH": "${workspaceFolder}/app/build/cargo/debug"
}
},
{
"type": "java",
Expand All @@ -125,25 +113,13 @@
"vmArgs": "-XX:+UseZGC",
"mainClass": "org.xxdc.oss.example.GameClient",
"projectName": "app",
"env": {
"LIB_PATH": "${workspaceFolder}/app/build/cargo/debug",
"PATH": "${workspaceFolder}/app/build/cargo/debug",
"LD_LIBRARY_PATH": "${workspaceFolder}/app/build/cargo/debug",
"DYLD_LIBRARY_PATH": "${workspaceFolder}/app/build/cargo/debug"
}
},
{
"type": "java",
"name": "GameServer",
"request": "launch",
"mainClass": "org.xxdc.oss.example.GameServer",
"projectName": "app",
"env": {
"LIB_PATH": "${workspaceFolder}/app/build/cargo/debug",
"PATH": "${workspaceFolder}/app/build/cargo/debug",
"LD_LIBRARY_PATH": "${workspaceFolder}/app/build/cargo/debug",
"DYLD_LIBRARY_PATH": "${workspaceFolder}/app/build/cargo/debug"
}
},
{
"type": "java",
Expand All @@ -152,12 +128,6 @@
"vmArgs": "-XX:+UseZGC",
"mainClass": "org.xxdc.oss.example.GameServer",
"projectName": "app",
"env": {
"LIB_PATH": "${workspaceFolder}/app/build/cargo/debug",
"PATH": "${workspaceFolder}/app/build/cargo/debug",
"LD_LIBRARY_PATH": "${workspaceFolder}/app/build/cargo/debug",
"DYLD_LIBRARY_PATH": "${workspaceFolder}/app/build/cargo/debug"
}
}
]
}
2 changes: 0 additions & 2 deletions api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ val libSuffix = when {

dependencies {
// Native Library (Rust)
implementation(project(":native"))
//testRuntimeOnly("org.xxdc.oss.example:tictactoe-native-$libSuffix:1.1.0")

// JDK9: Platform Logging (Third-Party)
// -> JDK API -> SLF4J -> Logback
Expand Down
21 changes: 18 additions & 3 deletions api/src/main/java/org/xxdc/oss/example/GameBoard.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
Expand Down Expand Up @@ -113,15 +114,29 @@ static GameBoard withDimension(int dimension) {
GameBoard gameBoard;
try {
if (useNative.get()) {
gameBoard = new GameBoardNativeImpl(dimension);
// Use the native implementation of the game board if it is available
// using reflection.
Class<?> gameBoardNativeImplClass =
Class.forName("org.xxdc.oss.example.GameBoardNativeImpl");
gameBoard =
(GameBoard)
gameBoardNativeImplClass.getDeclaredConstructor(int.class).newInstance(dimension);
} else {
gameBoard = new GameBoardLocalImpl(dimension);
}
} catch (ExceptionInInitializerError e) {
} catch (ExceptionInInitializerError
| InstantiationException
| IllegalAccessException
| IllegalArgumentException
| InvocationTargetException
| NoSuchMethodException
| SecurityException
| ClassNotFoundException e) {
// Fallback to the Java implementation.
log.log(
Level.WARNING,
"Unable to use native logger, falling back to local logger: {0}",
"Unable to use native game board, falling back to local game board: {0}({1})",
e.getClass(),
e.getMessage());
useNative.set(false);
gameBoard = new GameBoardLocalImpl(dimension);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.xxdc.oss.example;

import java.lang.System.Logger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.IntStream;
Expand All @@ -10,8 +9,6 @@
@Ignore
public class GamePerformanceTest {

private static final Logger log = System.getLogger(GamePerformanceTest.class.getName());

@Test
public void testGameBotPerformanceInSerial() throws Exception {
for (int i = 0; i < 1000; i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ testing {
}
}

val projectVersion by extra("1.1.1")
val projectVersion by extra("1.2.1")

public val jdkVersion = 22
// Apply a specific Java toolchain to ease working on different environments.
Expand Down
18 changes: 11 additions & 7 deletions native/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ repositories {
gradlePluginPortal()
}

dependencies {
implementation(project(":api"))
}

testing {
suites {
// Configure the built-in test suite
Expand Down Expand Up @@ -78,20 +82,20 @@ tasks.register<Delete>("cleanRust") {
tasks.named("clean") {
dependsOn("cleanRust")
}
// Force a build before running the application
tasks.named("build") {
dependsOn("formatRust")
}
tasks.named<Jar>("jar") {
from("${cargoBuildDir}/debug") {
include(libName)
}
tasks.register<Copy>("copyLib") {
from(libPath)
into("src/main/resources/native")
include(libName)
}
tasks.named("processResources") {
dependsOn("copyLib")
}
//
// Rust Build End
//
java {
}

// https://docs.gradle.org/current/userguide/publishing_maven.html
publishing {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

public class NativeLoader {

public static String NATIVE_ROOT = "/native/";

public static SymbolLookup loadLibrary(String libraryName, Arena arena) {
try {
var platformLibraryName = platformLibraryName(libraryName);
Expand All @@ -23,7 +25,7 @@ private static String platformLibraryName(String libraryName) {

private static SymbolLookup fromClassPathToTemp(String platformLibraryName, Arena arena)
throws IOException {
var resourceLookupString = "/" + platformLibraryName;
var resourceLookupString = NATIVE_ROOT + platformLibraryName;
var tempResourceFile = Files.createTempFile(platformLibraryName, ".tmp");
try (var inputStream = NativeLoader.class.getResourceAsStream(resourceLookupString);
OutputStream outputStream = Files.newOutputStream(tempResourceFile)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.xxdc.oss.example;

import static org.testng.Assert.assertNotNull;
import static org.xxdc.oss.example.TestData.*;

import java.lang.System.Logger;
import java.lang.System.Logger.Level;
Expand Down Expand Up @@ -103,4 +102,16 @@ public void should_clean_up_native_resources() {
}
}
}

public static GameBoard createBoardWith(String[][] content) {
GameBoard board = GameBoard.withDimension(content.length);
for (int row = 0; row < content.length; row++) {
for (int col = 0; col < content[row].length; col++) {
if (content[row][col] != null && !content[row][col].equals("_")) {
board = board.withMove(content[row][col], row * content.length + col);
}
}
}
return board;
}
}
15 changes: 15 additions & 0 deletions native/src/test/java/org/xxdc/oss/example/GameBoardTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.xxdc.oss.example;

import static org.testng.Assert.assertEquals;

import org.testng.annotations.Test;

public class GameBoardTest {

@Test
public void test_default_game_board_type_is_native() {
// should use the native implementation by default since it's in the classpath
GameBoard gameBoard = GameBoard.withDimension(3);
assertEquals(gameBoard.getClass(), GameBoardNativeImpl.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
import org.xxdc.oss.example.PlayerNode;

@Ignore
public class GamePerformanceTest {
public class GameServerPerformanceTest {

private static final Logger log = System.getLogger(GamePerformanceTest.class.getName());
private static final Logger log = System.getLogger(GameServerPerformanceTest.class.getName());

@Test
public void testGameClientServerBotPerformanceInParallelWithPlatformThreads() throws Exception {
Expand Down
Loading