Kotlin revolution (#401)

This commit is contained in:
Uriel
2022-12-27 15:53:05 -03:00
committed by GitHub
parent 34818e925c
commit 5dd5399e99
15 changed files with 285 additions and 264 deletions

View File

@@ -4,3 +4,5 @@ org.gradle.jvmargs=--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAME
--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
kotlin.code.style=official

View File

@@ -1,122 +0,0 @@
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java Library project to get you started.
* For more details take a look at the Java Libraries chapter in the Gradle
* User Manual available at https://docs.gradle.org/6.3/userguide/java_library_plugin.html
*/
plugins {
id 'application'
id "com.github.johnrengelman.shadow" version "7.1.2"
id "com.diffplug.spotless" version "6.5.1"
id "com.github.gmazzo.buildconfig" version "3.1.0"
}
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
// Set compiler to use UTF-8
compileJava.options.encoding = 'UTF-8'
compileTestJava.options.encoding = 'UTF-8'
javadoc.options.encoding = 'UTF-8'
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
// if (JavaVersion.current().isJava9Compatible()) {
// options.release = 8
// }
}
tasks.withType(Test) {
systemProperty('file.encoding', 'UTF-8')
}
tasks.withType(Javadoc) {
options.encoding = 'UTF-8'
}
allprojects {
repositories {
// Use jcenter for resolving dependencies.
// You can declare any Maven/Ivy/file repository here.
mavenCentral()
}
}
dependencies {
implementation project(":solarxr-protocol")
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation group: 'com.google.flatbuffers', name: 'flatbuffers-java', version: '22.10.26'
implementation group: 'commons-cli', name: 'commons-cli', version: '1.3.1'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.6.1'
implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.13.3'
implementation 'com.github.jonpeterson:jackson-module-model-versioning:1.2.2'
implementation 'org.apache.commons:commons-math3:3.6.1'
implementation 'org.apache.commons:commons-lang3:3.12.0'
implementation 'net.java.dev.jna:jna:5.+'
implementation 'net.java.dev.jna:jna-platform:5.+'
implementation 'com.illposed.osc:javaosc-core:0.8'
implementation 'com.fazecast:jSerialComm:2.+'
implementation 'com.google.protobuf:protobuf-java:3.+'
implementation 'org.java-websocket:Java-WebSocket:1.+'
implementation 'com.melloware:jintellitype:1.+'
// Use JUnit test framework
testImplementation platform('org.junit:junit-bom:5.9.0')
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'org.junit.platform:junit-platform-launcher'
}
test {
useJUnitPlatform()
}
shadowJar {
archiveBaseName.set('slimevr')
archiveClassifier.set('')
archiveVersion.set('')
}
application {
getMainClass().set('dev.slimevr.Main')
}
buildConfig {
def gitCommitHash = 'git rev-parse --verify --short HEAD'.execute().text.trim()
def gitVersionTag = 'git --no-pager tag --points-at HEAD'.execute().text.trim()
def gitClean = 'git status --porcelain'.execute().text.isEmpty()
packageName("dev.slimevr")
buildConfigField("String", "GIT_COMMIT_HASH", "\"${gitCommitHash}\"")
buildConfigField("String", "GIT_VERSION_TAG", "\"${gitVersionTag}\"")
buildConfigField("boolean", "GIT_CLEAN", "${gitClean}")
}
spotless {
// optional: limit format enforcement to just the files changed by this feature branch
// ratchetFrom 'origin/main'
format 'misc', {
// define the files to apply `misc` to
target '*.gradle', '*.md', '.gitignore'
// define the steps to apply to those files
trimTrailingWhitespace()
endWithNewline()
indentWithTabs()
}
// format 'yaml', {
// target '*.yml', '*.yaml',
// trimTrailingWhitespace()
// endWithNewline()
// indentWithSpaces(2) // YAML cannot contain tabs: https://yaml.org/faq.html
// }
java {
targetExclude '**/BuildConfig.java'
removeUnusedImports()
// Use eclipse JDT formatter
eclipse().configFile("spotless.xml")
}
}

149
server/build.gradle.kts Normal file
View File

@@ -0,0 +1,149 @@
/*
* This file was generated by the Gradle "init" task.
*
* This generated file contains a sample Java Library project to get you started.
* For more details take a look at the Java Libraries chapter in the Gradle
* User Manual available at https://docs.gradle.org/6.3/userguide/java_library_plugin.html
*/
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.io.ByteArrayOutputStream
plugins {
kotlin("jvm") version "1.7.21"
application
id("com.github.johnrengelman.shadow") version "7.1.2"
id("com.diffplug.spotless") version "6.11.0"
id("com.github.gmazzo.buildconfig") version "3.1.0"
}
kotlin {
jvmToolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "17"
}
// Set compiler to use UTF-8
tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
}
tasks.withType<Test> {
systemProperty("file.encoding", "UTF-8")
}
tasks.withType<Javadoc> {
options.encoding = "UTF-8"
}
allprojects {
repositories {
// Use jcenter for resolving dependencies.
// You can declare any Maven/Ivy/file repository here.
mavenCentral()
}
}
dependencies {
implementation(project(":solarxr-protocol"))
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation("com.google.flatbuffers:flatbuffers-java:22.10.26")
implementation("commons-cli:commons-cli:1.3.1")
implementation("com.fasterxml.jackson.core:jackson-databind:2.12.6.1")
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.3")
implementation("com.github.jonpeterson:jackson-module-model-versioning:1.2.2")
implementation("org.apache.commons:commons-math3:3.6.1")
implementation("org.apache.commons:commons-lang3:3.12.0")
implementation("net.java.dev.jna:jna:5.+")
implementation("net.java.dev.jna:jna-platform:5.+")
implementation("com.illposed.osc:javaosc-core:0.8")
implementation("com.fazecast:jSerialComm:2.+")
implementation("com.google.protobuf:protobuf-java:3.+")
implementation("org.java-websocket:Java-WebSocket:1.+")
implementation("com.melloware:jintellitype:1.+")
testImplementation(kotlin("test"))
// Use JUnit test framework
testImplementation(platform("org.junit:junit-bom:5.9.0"))
testImplementation("org.junit.jupiter:junit-jupiter")
testImplementation("org.junit.platform:junit-platform-launcher")
}
tasks.test {
useJUnitPlatform()
}
tasks.shadowJar {
archiveBaseName.set("slimevr")
archiveClassifier.set("")
archiveVersion.set("")
}
application {
mainClass.set("dev.slimevr.Main")
}
fun String.runCommand(currentWorkingDir: File = file("./")): String {
val byteOut = ByteArrayOutputStream()
project.exec {
workingDir = currentWorkingDir
commandLine = this@runCommand.split("\\s".toRegex())
standardOutput = byteOut
}
return String(byteOut.toByteArray()).trim()
}
buildConfig {
val gitCommitHash = "git rev-parse --verify --short HEAD".runCommand().trim()
val gitVersionTag = "git --no-pager tag --points-at HEAD".runCommand().trim()
val gitClean = "git status --porcelain".runCommand().trim().isEmpty()
useKotlinOutput { topLevelConstants = true }
packageName("dev.slimevr")
buildConfigField("String", "GIT_COMMIT_HASH", "\"${gitCommitHash}\"")
buildConfigField("String", "GIT_VERSION_TAG", "\"${gitVersionTag}\"")
buildConfigField("boolean", "GIT_CLEAN", gitClean.toString())
}
spotless {
// optional: limit format enforcement to just the files changed by this feature branch
// ratchetFrom "origin/main"
format("misc") {
// define the files to apply `misc` to
target("*.gradle", "*.md", ".gitignore")
// define the steps to apply to those files
trimTrailingWhitespace()
endWithNewline()
indentWithTabs()
}
// format "yaml", {
// target "*.yml", "*.yaml",
// trimTrailingWhitespace()
// endWithNewline()
// indentWithSpaces(2) // YAML cannot contain tabs: https://yaml.org/faq.html
// }
format("kts") {
target("**/*.kts")
targetExclude("**/build/**/*.kts")
}
kotlin {
target("**/*.kt")
targetExclude("**/build/**.kts")
ktlint("0.47.1")
}
java {
targetExclude("**/BuildConfig.java")
removeUnusedImports()
// Use eclipse JDT formatter
eclipse().configFile("spotless.xml")
}
}

View File

@@ -1,117 +0,0 @@
package dev.slimevr;
import io.eiren.util.logging.LogManager;
import org.apache.commons.cli.*;
import org.apache.commons.lang3.JavaVersion;
import org.apache.commons.lang3.SystemUtils;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
public class Main {
public static final String VERSION = (BuildConfig.GIT_VERSION_TAG.isEmpty()
? BuildConfig.GIT_COMMIT_HASH
: BuildConfig.GIT_VERSION_TAG) + (BuildConfig.GIT_CLEAN ? "" : "-dirty");
public static VRServer vrServer;
public static void main(String[] args) {
System.setProperty("awt.useSystemAAFontSettings", "on");
System.setProperty("swing.aatext", "true");
CommandLineParser parser = new DefaultParser();
HelpFormatter formatter = new HelpFormatter();
CommandLine cmd = null;
Options options = new Options();
Option help = new Option("h", "help", false, "Show help");
Option version = new Option("V", "version", false, "Show version");
options.addOption(help);
options.addOption(version);
try {
cmd = parser.parse(options, args, true);
} catch (ParseException e) {
System.out.println(e.getMessage());
formatter.printHelp("slimevr.jar", options);
System.exit(1);
}
if (cmd.hasOption("help")) {
formatter.printHelp("slimevr.jar", options);
System.exit(0);
}
if (cmd.hasOption("version")) {
System.out.println("SlimeVR Server " + VERSION);
System.exit(0);
}
File dir = new File("").getAbsoluteFile();
try {
LogManager.initialize(new File(dir, "logs/"), dir);
} catch (Exception e1) {
e1.printStackTrace();
}
LogManager.info("Running version " + VERSION);
if (!SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_17)) {
LogManager.severe("SlimeVR start-up error! A minimum of Java 17 is required.");
JOptionPane
.showMessageDialog(
null,
"SlimeVR start-up error! A minimum of Java 17 is required.",
"SlimeVR: Java Runtime Mismatch",
JOptionPane.ERROR_MESSAGE
);
return;
}
try {
// This is disabled because the config can't be read at this point
// new ServerSocket(6969).close();
new ServerSocket(35903).close();
new ServerSocket(21110).close();
} catch (IOException e) {
LogManager
.severe(
"SlimeVR start-up error! Required ports are busy. Make sure there is no other instance of SlimeVR Server running."
);
JOptionPane
.showMessageDialog(
null,
"SlimeVR start-up error! Required ports are busy. Make sure there is no other instance of SlimeVR Server running.",
"SlimeVR: Ports are busy",
JOptionPane.ERROR_MESSAGE
);
return;
}
try {
vrServer = new VRServer();
vrServer.start();
new Keybinding(vrServer);
} catch (Throwable e) {
e.printStackTrace();
try {
Thread.sleep(2000L);
} catch (InterruptedException e2) {
e.printStackTrace();
}
System.exit(1); // Exit in case error happened on init and window
// not appeared, but some thread
// started
} finally {
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,106 @@
@file:JvmName("Main")
package dev.slimevr
import io.eiren.util.logging.LogManager
import org.apache.commons.cli.CommandLine
import org.apache.commons.cli.CommandLineParser
import org.apache.commons.cli.DefaultParser
import org.apache.commons.cli.HelpFormatter
import org.apache.commons.cli.Option
import org.apache.commons.cli.Options
import org.apache.commons.lang3.SystemUtils
import java.io.File
import java.io.IOException
import java.lang.System
import java.net.ServerSocket
import javax.swing.JOptionPane
import kotlin.system.exitProcess
val VERSION: String = (GIT_VERSION_TAG.ifEmpty { GIT_COMMIT_HASH }) + if (GIT_CLEAN) "" else "-dirty"
var vrServer: VRServer? = null
fun main(args: Array<String>) {
System.setProperty("awt.useSystemAAFontSettings", "on")
System.setProperty("swing.aatext", "true")
val parser: CommandLineParser = DefaultParser()
val formatter = HelpFormatter()
val options = Options()
val help = Option("h", "help", false, "Show help")
val version = Option("V", "version", false, "Show version")
options.addOption(help)
options.addOption(version)
val cmd: CommandLine = try {
parser.parse(options, args, true)
} catch (e: org.apache.commons.cli.ParseException) {
formatter.printHelp("slimevr.jar", options)
exitProcess(1)
}
if (cmd.hasOption("help")) {
formatter.printHelp("slimevr.jar", options)
exitProcess(0)
}
if (cmd.hasOption("version")) {
println("SlimeVR Server $VERSION")
exitProcess(0)
}
val dir = File("").absoluteFile
try {
LogManager.initialize(File(dir, "logs/"), dir)
} catch (e1: java.lang.Exception) {
e1.printStackTrace()
}
LogManager.info("Running version $VERSION")
if (!SystemUtils.isJavaVersionAtLeast(org.apache.commons.lang3.JavaVersion.JAVA_17)) {
LogManager.severe("SlimeVR start-up error! A minimum of Java 17 is required.")
JOptionPane
.showMessageDialog(
null,
"SlimeVR start-up error! A minimum of Java 17 is required.",
"SlimeVR: Java Runtime Mismatch",
JOptionPane.ERROR_MESSAGE
)
return
}
try {
// This is disabled because the config can't be read at this point
// new ServerSocket(6969).close();
ServerSocket(35903).close()
ServerSocket(21110).close()
} catch (e: IOException) {
LogManager
.severe(
"SlimeVR start-up error! Required ports are busy. Make sure there is no other instance of SlimeVR Server running."
)
JOptionPane
.showMessageDialog(
null,
"SlimeVR start-up error! Required ports are busy. Make sure there is no other instance of SlimeVR Server running.",
"SlimeVR: Ports are busy",
JOptionPane.ERROR_MESSAGE
)
return
}
try {
vrServer = VRServer()
vrServer!!.start()
Keybinding(vrServer)
} catch (e: Throwable) {
e.printStackTrace()
try {
Thread.sleep(2000L)
} catch (e2: InterruptedException) {
e.printStackTrace()
}
exitProcess(1) // Exit in case error happened on init and window
// not appeared, but some thread
// started
} finally {
try {
Thread.sleep(2000L)
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
}

View File

@@ -167,7 +167,7 @@ public abstract class ProtobufBridge<T extends VRTracker> implements Bridge {
if (trackerAdded.getTrackerRole() == TrackerRole.HMD.id) {
hmdTracker = tracker;
} else {
Main.vrServer.registerTracker(tracker);
Main.getVrServer().registerTracker(tracker);
}
}
@@ -179,10 +179,10 @@ public abstract class ProtobufBridge<T extends VRTracker> implements Bridge {
.warning("[" + bridgeName + "] Received deprecated user action 'calibrate'!");
case "reset":
// TODO : Check pose field
Main.vrServer.resetTrackers();
Main.getVrServer().resetTrackers();
break;
case "fast_reset":
Main.vrServer.resetTrackersYaw();
Main.getVrServer().resetTrackersYaw();
break;
}
}

View File

@@ -18,7 +18,7 @@ public class FiltersConfig {
}
public void updateTrackersFilters() {
for (Tracker t : Main.vrServer.getAllTrackers()) {
for (Tracker t : Main.getVrServer().getAllTrackers()) {
Tracker tracker = t.get();
if (tracker instanceof TrackerWithFiltering) {
((TrackerWithFiltering) tracker)

View File

@@ -36,7 +36,7 @@ public class QuaternionMovingAverage {
float amount,
Quaternion initialRotation
) {
fpsTimer = Main.vrServer.getFpsTimer();
fpsTimer = Main.getVrServer().getFpsTimer();
// amount should range from 0 to 1.
// GUI should clamp it from 0.01 (1%) or 0.1 (10%)

View File

@@ -76,7 +76,7 @@ public abstract class SteamVRBridge extends ProtobufBridge<VRTracker> implements
removeSharedTracker(tr);
}
config.setBridgeTrackerRole(role, share);
Main.vrServer.getConfigManager().saveConfig();
Main.getVrServer().getConfigManager().saveConfig();
}
}
}
@@ -85,7 +85,8 @@ public abstract class SteamVRBridge extends ProtobufBridge<VRTracker> implements
@VRServerThread
protected VRTracker createNewTracker(ProtobufMessages.TrackerAdded trackerAdded) {
// Todo: We need the manufacturer
Device device = Main.vrServer
Device device = Main
.getVrServer()
.getDeviceManager()
.createDevice(
trackerAdded.getTrackerName(),
@@ -103,7 +104,7 @@ public abstract class SteamVRBridge extends ProtobufBridge<VRTracker> implements
);
device.getTrackers().add(tracker);
Main.vrServer.getDeviceManager().addDevice(device);
Main.getVrServer().getDeviceManager().addDevice(device);
TrackerRole role = TrackerRole.getById(trackerAdded.getTrackerRole());
if (role != null) {
tracker.setBodyPosition(TrackerPosition.getByTrackerRole(role).orElse(null));

View File

@@ -60,7 +60,7 @@ public class UnixSocketBridge extends SteamVRBridge implements AutoCloseable {
this.channel = server.accept();
if (this.channel == null)
continue;
Main.vrServer.queueTask(this::reconnected);
Main.getVrServer().queueTask(this::reconnected);
LogManager
.info(
"["
@@ -179,7 +179,7 @@ public class UnixSocketBridge extends SteamVRBridge implements AutoCloseable {
this.channel = null;
this.socketError = false;
this.dst.clear();
Main.vrServer.queueTask(this::disconnected);
Main.getVrServer().queueTask(this::disconnected);
}
private ServerSocketChannel createSocket() throws IOException {

View File

@@ -161,7 +161,7 @@ public class WindowsNamedPipeBridge extends SteamVRBridge {
private void resetPipe() {
WindowsPipe.safeDisconnect(pipe);
pipe.state = PipeState.CREATED;
Main.vrServer.queueTask(this::disconnected);
Main.getVrServer().queueTask(this::disconnected);
}
private void createPipe() throws IOException {
@@ -199,7 +199,7 @@ public class WindowsNamedPipeBridge extends SteamVRBridge {
) {
pipe.state = PipeState.OPEN;
LogManager.info("[" + bridgeName + "] Pipe " + pipe.name + " is open");
Main.vrServer.queueTask(this::reconnected);
Main.getVrServer().queueTask(this::reconnected);
return true;
}
LogManager

View File

@@ -427,7 +427,8 @@ public class SkeletonConfig {
// Remove from config to use default if they change in the future.
Arrays.fill(changedValues, false);
for (SkeletonConfigValues value : SkeletonConfigValues.values) {
Main.vrServer
Main
.getVrServer()
.getConfigManager()
.getVrConfig()
.getSkeleton()
@@ -454,7 +455,8 @@ public class SkeletonConfig {
// Remove from config to use default if they change in the future.
Arrays.fill(changedToggles, false);
for (SkeletonConfigToggles value : SkeletonConfigToggles.values) {
Main.vrServer
Main
.getVrServer()
.getConfigManager()
.getVrConfig()
.getSkeleton()
@@ -507,7 +509,8 @@ public class SkeletonConfig {
}
public void save() {
dev.slimevr.config.SkeletonConfig skeletonConfig = Main.vrServer
dev.slimevr.config.SkeletonConfig skeletonConfig = Main
.getVrServer()
.getConfigManager()
.getVrConfig()
.getSkeleton();

View File

@@ -25,7 +25,6 @@ import java.util.function.Consumer;
* Receives trackers data by UDP using extended owoTrack protocol.
*/
public class TrackersUDPServer extends Thread {
/**
* Change between IMU axes and OpenGL/SteamVR axes
*/
@@ -125,7 +124,7 @@ public class TrackersUDPServer extends Thread {
}
if (connection == null) {
connection = new UDPDevice(handshakePacket.getSocketAddress(), addr);
Main.vrServer.getDeviceManager().addDevice(connection);
Main.getVrServer().getDeviceManager().addDevice(connection);
connection.firmwareBuild = handshake.firmwareBuild;
if (handshake.firmware == null || handshake.firmware.length() == 0) {
// Only old owoTrack doesn't report firmware and have different
@@ -235,7 +234,7 @@ public class TrackersUDPServer extends Thread {
connection.name + "/" + trackerId,
connection.descriptiveName + "/" + trackerId,
this,
Main.vrServer
Main.getVrServer()
);
connection.getTrackers().add(imu);

View File

@@ -170,8 +170,8 @@ public class WebSocketVRBridge extends WebsocketAPI implements Bridge {
private void parseAction(ObjectNode json, WebSocket conn) {
switch (json.get("name").asText()) {
case "calibrate" -> Main.vrServer.resetTrackersYaw();
case "full_calibrate" -> Main.vrServer.resetTrackers();
case "calibrate" -> Main.getVrServer().resetTrackersYaw();
case "full_calibrate" -> Main.getVrServer().resetTrackers();
}
}

View File

@@ -7,11 +7,11 @@
* in the user manual at https://docs.gradle.org/6.3/userguide/multi_project_builds.html
*/
rootProject.name = 'SlimeVR Server'
rootProject.name = "SlimeVR Server"
include ':solarxr-protocol'
project(':solarxr-protocol').projectDir = new File('solarxr-protocol/protocol/java')
include(":solarxr-protocol")
project(":solarxr-protocol").projectDir = File("solarxr-protocol/protocol/java")
include ':server'
project(':server').projectDir = new File('server')
include(":server")
project(":server").projectDir = File("server")