move bridges to desktop

This commit is contained in:
ImUrX
2023-06-15 15:37:21 -03:00
parent a8ce510f70
commit ffe530dc94
12 changed files with 207 additions and 166 deletions

View File

@@ -45,7 +45,7 @@ fun main(activity: AppCompatActivity) {
e1.printStackTrace()
}
try {
vrServer = VRServer(File(activity.filesDir, "vrconfig.yml").absolutePath)
vrServer = VRServer(configPath = File(activity.filesDir, "vrconfig.yml").absolutePath)
vrServer.start()
Keybinding(vrServer)
vrServer.join()

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

@@ -0,0 +1,64 @@
plugins {
id("com.diffplug.spotless")
}
repositories {
mavenCentral()
}
configure<com.diffplug.gradle.spotless.SpotlessExtension> {
// 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
// }
// .editorconfig doesn't work so, manual override
// https://github.com/diffplug/spotless/issues/142
val editorConfig =
mapOf(
"indent_size" to 4,
"indent_style" to "tab",
// "max_line_length" to 88,
"ktlint_experimental" to "enabled",
"ij_kotlin_packages_to_use_import_on_demand" to
"java.util.*,kotlin.math.*,dev.slimevr.autobone.errors.*,io.github.axisangles.ktmath.*,kotlinx.atomicfu.*",
"ij_kotlin_allow_trailing_comma" to true
)
val ktlintVersion = "0.47.1"
kotlinGradle {
target("**/*.gradle.kts") // default target for kotlinGradle
ktlint(ktlintVersion)
.setUseExperimental(true)
.editorConfigOverride(editorConfig)
}
kotlin {
target("**/*.kt")
targetExclude("**/build/**/**.kt")
ktlint(ktlintVersion)
.setUseExperimental(true)
.editorConfigOverride(editorConfig)
}
java {
target("**/*.java")
targetExclude("**/BuildConfig.java")
removeUnusedImports()
// Use eclipse JDT formatter
eclipse().configFile("spotless.xml")
}
}

View File

@@ -12,7 +12,6 @@ plugins {
kotlin("jvm")
kotlin("plugin.serialization")
`java-library`
id("com.diffplug.spotless")
}
// FIXME: Please replace these to Java 11 as that's what they actually are
@@ -74,11 +73,9 @@ dependencies {
implementation("org.apache.commons:commons-lang3:3.12.0")
implementation("org.apache.commons:commons-collections4:4.4")
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.21.12")
api("com.google.protobuf:protobuf-java:3.21.12")
implementation("org.java-websocket:Java-WebSocket:1.+")
implementation("com.melloware:jintellitype:1.+")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1")
@@ -103,58 +100,3 @@ fun String.runCommand(currentWorkingDir: File = file("./")): String {
}
return String(byteOut.toByteArray()).trim()
}
configure<com.diffplug.gradle.spotless.SpotlessExtension> {
// 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
// }
// .editorconfig doesn't work so, manual override
// https://github.com/diffplug/spotless/issues/142
val editorConfig =
mapOf(
"indent_size" to 4,
"indent_style" to "tab",
// "max_line_length" to 88,
"ktlint_experimental" to "enabled",
"ij_kotlin_packages_to_use_import_on_demand" to
"java.util.*,kotlin.math.*,dev.slimevr.autobone.errors.*,io.github.axisangles.ktmath.*,kotlinx.atomicfu.*",
"ij_kotlin_allow_trailing_comma" to true
)
val ktlintVersion = "0.47.1"
kotlinGradle {
target("*.gradle.kts") // default target for kotlinGradle
ktlint(ktlintVersion)
.setUseExperimental(true)
.editorConfigOverride(editorConfig)
}
kotlin {
targetExclude("build/**/**.kt")
ktlint(ktlintVersion)
.setUseExperimental(true)
.editorConfigOverride(editorConfig)
}
java {
targetExclude("**/BuildConfig.java")
removeUnusedImports()
// Use eclipse JDT formatter
eclipse().configFile("spotless.xml")
}
}

View File

@@ -9,8 +9,6 @@ import dev.slimevr.osc.OSCRouter
import dev.slimevr.osc.VMCHandler
import dev.slimevr.osc.VRCOSCHandler
import dev.slimevr.platform.SteamVRBridge
import dev.slimevr.platform.linux.UnixSocketBridge
import dev.slimevr.platform.windows.WindowsNamedPipeBridge
import dev.slimevr.posestreamer.BVHRecorder
import dev.slimevr.protocol.ProtocolAPI
import dev.slimevr.reset.ResetHandler
@@ -26,19 +24,27 @@ import dev.slimevr.tracking.trackers.TrackerPosition
import dev.slimevr.tracking.trackers.udp.TrackersUDPServer
import dev.slimevr.util.ann.VRServerThread
import dev.slimevr.websocketapi.WebSocketVRBridge
import io.eiren.util.OperatingSystem
import io.eiren.util.ann.ThreadSafe
import io.eiren.util.ann.ThreadSecure
import io.eiren.util.collections.FastList
import io.eiren.util.logging.LogManager
import solarxr_protocol.datatypes.TrackerIdT
import java.nio.file.Paths
import java.util.*
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.atomic.AtomicInteger
import java.util.function.Consumer
class VRServer @JvmOverloads constructor(configPath: String? = "vrconfig.yml") : Thread("VRServer") {
typealias SteamBridgeProvider = (
server: VRServer,
hmdTracker: Tracker,
computedTrackers: List<Tracker>,
) -> SteamVRBridge?
class VRServer constructor(
driverBridgeProvider: SteamBridgeProvider = { _: VRServer, _: Tracker, _: List<Tracker> -> null },
feederBridgeProvider: (VRServer) -> SteamVRBridge? = { _: VRServer -> null },
configPath: String,
) : Thread("VRServer") {
@JvmField
val configManager: ConfigManager
@@ -107,12 +113,9 @@ class VRServer @JvmOverloads constructor(configPath: String? = "vrconfig.yml") :
"HMD",
TrackerPosition.HEAD,
null,
true,
true,
false,
false,
false,
true
hasPosition = true,
hasRotation = true,
isComputed = true
)
humanPoseManager = HumanPoseManager(this)
val computedTrackers = humanPoseManager.computedTrackers
@@ -124,81 +127,19 @@ class VRServer @JvmOverloads constructor(configPath: String? = "vrconfig.yml") :
trackerPort,
"Sensors UDP server"
) { tracker: Tracker -> registerTracker(tracker) }
val driverBridge: SteamVRBridge?
if (OperatingSystem.getCurrentPlatform() == OperatingSystem.WINDOWS) {
// Create named pipe bridge for SteamVR driver
driverBridge = WindowsNamedPipeBridge(
this,
hmdTracker,
"steamvr",
"SteamVR Driver Bridge",
"\\\\.\\pipe\\SlimeVRDriver",
computedTrackers
)
// Start bridges for SteamVR and Feeder
val driverBridge = driverBridgeProvider(this, hmdTracker, computedTrackers)
if (driverBridge != null) {
tasks.add(Runnable { driverBridge.startBridge() })
bridges.add(driverBridge)
// Create named pipe bridge for SteamVR input
// TODO: how do we want to handle HMD input from the feeder app?
val feederBridge = WindowsNamedPipeBridge(
this,
null,
"steamvr_feeder",
"SteamVR Feeder Bridge",
"\\\\.\\pipe\\SlimeVRInput",
FastList()
)
}
val feederBridge = feederBridgeProvider(this)
if (feederBridge != null) {
tasks.add(Runnable { feederBridge.startBridge() })
bridges.add(feederBridge)
} else if (OperatingSystem.getCurrentPlatform() == OperatingSystem.LINUX) {
var linuxBridge: SteamVRBridge? = null
try {
linuxBridge = UnixSocketBridge(
this,
hmdTracker,
"steamvr",
"SteamVR Driver Bridge",
Paths.get(OperatingSystem.getTempDirectory(), "SlimeVRDriver").toString(),
computedTrackers
)
} catch (ex: Exception) {
LogManager.severe("Failed to initiate Unix socket, disabling driver bridge...", ex)
}
driverBridge = linuxBridge
if (driverBridge != null) {
tasks.add(Runnable { driverBridge.startBridge() })
bridges.add(driverBridge)
}
try {
val feederBridge: SteamVRBridge = UnixSocketBridge(
this,
null,
"steamvr_feeder",
"SteamVR Feeder Bridge",
Paths.get(OperatingSystem.getTempDirectory(), "SlimeVRInput").toString(),
FastList()
)
tasks.add(Runnable { feederBridge.startBridge() })
bridges.add(feederBridge)
} catch (ex: Exception) {
LogManager.severe("Failed to initiate Unix socket, disabling feeder bridge...", ex)
}
} else {
driverBridge = null
}
// Add shutdown hook
Runtime.getRuntime().addShutdownHook(
Thread {
try {
(driverBridge as? UnixSocketBridge)?.close()
} catch (e: Exception) {
throw RuntimeException(e)
}
}
)
// Create WebSocket server
val wsBridge = WebSocketVRBridge(hmdTracker, computedTrackers, this)
tasks.add(Runnable { wsBridge.startBridge() })

View File

@@ -1,14 +0,0 @@
package dev.slimevr.hardware.magentometer;
import com.sun.jna.Library;
import com.sun.jna.Native;
public interface Magneto extends Library {
Magneto INSTANCE = Native.load("MagnetoLib", Magneto.class);
void calculate(double[] data, int nlines, double nxsrej, double hm, double[] B, double[] A_1);
double calculateHnorm(double[] data, int nlines);
}

View File

@@ -64,9 +64,10 @@ dependencies {
implementation("commons-cli:commons-cli:1.5.0")
implementation("org.apache.commons:commons-lang3:3.12.0")
implementation("net.java.dev.jna:jna:5.+")
implementation("net.java.dev.jna:jna-platform:5.+")
}
tasks.shadowJar {
minimize {
exclude(dependency("com.fazecast:jSerialComm:.*"))
@@ -97,13 +98,15 @@ buildConfig {
useKotlinOutput { topLevelConstants = true }
packageName("dev.slimevr.desktop")
val gitVersionTag = grgit.describe(mapOf(
"tags" to true,
"abbrev" to 0,
))
val gitVersionTag = grgit.describe(
mapOf(
"tags" to true,
"abbrev" to 0
)
)
val latestCommitTag =
grgit.tag.list().find { it.name == gitVersionTag }!!.commit.abbreviatedId == grgit.head().abbreviatedId
val gitLatestVersionTag = if (latestCommitTag) { gitVersionTag} else { "" }
val gitLatestVersionTag = if (latestCommitTag) { gitVersionTag } else { "" }
buildConfigField("String", "GIT_COMMIT_HASH", "\"${grgit.head().abbreviatedId}\"")
buildConfigField("String", "GIT_VERSION_TAG", "\"${gitLatestVersionTag}\"")
buildConfigField("boolean", "GIT_CLEAN", grgit.status().isClean.toString())

View File

@@ -4,6 +4,12 @@ package dev.slimevr.desktop
import dev.slimevr.Keybinding
import dev.slimevr.VRServer
import dev.slimevr.desktop.platform.linux.UnixSocketBridge
import dev.slimevr.desktop.platform.windows.WindowsNamedPipeBridge
import dev.slimevr.platform.SteamVRBridge
import dev.slimevr.tracking.trackers.Tracker
import io.eiren.util.OperatingSystem
import io.eiren.util.collections.FastList
import io.eiren.util.logging.LogManager
import org.apache.commons.cli.CommandLine
import org.apache.commons.cli.CommandLineParser
@@ -15,6 +21,7 @@ import java.io.File
import java.io.IOException
import java.lang.System
import java.net.ServerSocket
import java.nio.file.Paths
import javax.swing.JOptionPane
import kotlin.concurrent.thread
import kotlin.system.exitProcess
@@ -99,7 +106,7 @@ fun main(args: Array<String>) {
return
}
try {
val vrServer = VRServer()
val vrServer = VRServer(::provideSteamVRBridge, ::provideFeederBridge, "vrconfig.yml")
vrServer.start()
Keybinding(vrServer)
val scanner = thread {
@@ -119,3 +126,89 @@ fun main(args: Array<String>) {
exitProcess(1)
}
}
fun provideSteamVRBridge(
server: VRServer,
hmdTracker: Tracker,
computedTrackers: List<Tracker>,
): SteamVRBridge? {
val driverBridge: SteamVRBridge?
if (OperatingSystem.getCurrentPlatform() == OperatingSystem.WINDOWS) {
// Create named pipe bridge for SteamVR driver
driverBridge = WindowsNamedPipeBridge(
server,
hmdTracker,
"steamvr",
"SteamVR Driver Bridge",
"""\\.\pipe\SlimeVRDriver""",
computedTrackers
)
} else if (OperatingSystem.getCurrentPlatform() == OperatingSystem.LINUX) {
var linuxBridge: SteamVRBridge? = null
try {
linuxBridge = UnixSocketBridge(
server,
hmdTracker,
"steamvr",
"SteamVR Driver Bridge",
Paths.get(OperatingSystem.getTempDirectory(), "SlimeVRDriver")
.toString(),
computedTrackers
)
} catch (ex: Exception) {
LogManager.severe(
"Failed to initiate Unix socket, disabling driver bridge...",
ex
)
}
driverBridge = linuxBridge
if (driverBridge != null) {
// Close the named socket on shutdown, or otherwise it's not going to get removed
Runtime.getRuntime().addShutdownHook(
Thread {
try {
(driverBridge as? UnixSocketBridge)?.close()
} catch (e: Exception) {
throw RuntimeException(e)
}
}
)
}
} else {
driverBridge = null
}
return driverBridge
}
fun provideFeederBridge(
server: VRServer,
): SteamVRBridge? {
val feederBridge: SteamVRBridge?
if (OperatingSystem.getCurrentPlatform() == OperatingSystem.WINDOWS) {
// Create named pipe bridge for SteamVR input
// TODO: how do we want to handle HMD input from the feeder app?
feederBridge = WindowsNamedPipeBridge(
server,
null,
"steamvr_feeder",
"SteamVR Feeder Bridge",
"""\\.\pipe\SlimeVRInput""",
FastList()
)
} else if (OperatingSystem.getCurrentPlatform() == OperatingSystem.LINUX) {
feederBridge = UnixSocketBridge(
server,
null,
"steamvr_feeder",
"SteamVR Feeder Bridge",
Paths.get(OperatingSystem.getTempDirectory(), "SlimeVRInput")
.toString(),
FastList()
)
} else {
feederBridge = null
}
return feederBridge
}

View File

@@ -1,4 +1,4 @@
package dev.slimevr.platform.linux;
package dev.slimevr.desktop.platform.linux;
import com.google.protobuf.InvalidProtocolBufferException;
import dev.slimevr.VRServer;
@@ -9,7 +9,10 @@ import dev.slimevr.tracking.trackers.Tracker;
import io.eiren.util.ann.ThreadSafe;
import io.eiren.util.logging.LogManager;
import java.io.File;
import java.io.IOException;
import java.net.StandardProtocolFamily;
import java.net.UnixDomainSocketAddress;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.ServerSocketChannel;
@@ -21,6 +24,7 @@ import java.util.List;
public class UnixSocketBridge extends SteamVRBridge implements AutoCloseable {
public final String socketPath;
public final UnixDomainSocketAddress socketAddress;
private final ByteBuffer dst = ByteBuffer.allocate(2048);
private final ByteBuffer src = ByteBuffer.allocate(2048).order(ByteOrder.LITTLE_ENDIAN);
@@ -39,8 +43,13 @@ public class UnixSocketBridge extends SteamVRBridge implements AutoCloseable {
) {
super(server, hmd, "Named socket thread", bridgeName, bridgeSettingsKey, shareableTrackers);
this.socketPath = socketPath;
this.socketAddress = UnixDomainSocketAddress.of(socketPath);
throw new RuntimeException("Unix socket cannot be run on Android.");
File socketFile = new File(socketPath);
if (socketFile.exists()) {
throw new RuntimeException(socketPath + " socket already exists.");
}
socketFile.deleteOnExit();
}
@Override
@@ -218,7 +227,10 @@ public class UnixSocketBridge extends SteamVRBridge implements AutoCloseable {
}
private ServerSocketChannel createSocket() throws IOException {
return null;
ServerSocketChannel server = ServerSocketChannel.open(StandardProtocolFamily.UNIX);
server.bind(this.socketAddress);
LogManager.info("[" + bridgeName + "] Socket " + this.socketPath + " created");
return server;
}
@Override

View File

@@ -1,4 +1,4 @@
package dev.slimevr.platform.windows;
package dev.slimevr.desktop.platform.windows;
import com.google.protobuf.CodedOutputStream;
import com.google.protobuf.InvalidProtocolBufferException;

View File

@@ -1,4 +1,4 @@
package dev.slimevr.platform.windows;
package dev.slimevr.desktop.platform.windows;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinBase;

View File

@@ -1,4 +1,4 @@
package dev.slimevr.platform.windows;
package dev.slimevr.desktop.platform.windows;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinNT.HANDLE;