mirror of
https://github.com/SlimeVR/SlimeVR-Server.git
synced 2026-04-06 02:01:58 +02:00
Format
This commit is contained in:
@@ -15,4 +15,4 @@ object BaseBehaviour : VRServerBehaviour {
|
||||
println("tracker list size changed")
|
||||
}.launchIn(receiver.context.scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,4 +19,4 @@ object DefaultUserBehaviour : UserConfigBehaviour {
|
||||
is UserConfigActions.Update -> state.copy(data = action.transform(state.data))
|
||||
is UserConfigActions.LoadProfile -> action.newState
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,4 +87,4 @@ class AppConfig(
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,4 +41,4 @@ class Context<S, in A>(
|
||||
return Context(mutableStateFlow, applyAction, scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,11 @@ import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
||||
object DeviceStatsBehaviour : DeviceBehaviour {
|
||||
override fun reduce(state: DeviceState, action: DeviceActions) =
|
||||
if (action is DeviceActions.Update) action.transform(state) else state
|
||||
override fun reduce(state: DeviceState, action: DeviceActions) = if (action is DeviceActions.Update) action.transform(state) else state
|
||||
|
||||
override fun observe(receiver: DeviceContext) {
|
||||
receiver.state.onEach {
|
||||
// AppLogger.device.info("Device state changed", it)
|
||||
}.launchIn(receiver.scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,4 +73,4 @@ class Device(
|
||||
return Device(context = context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,16 +3,17 @@ package dev.slimevr.firmware
|
||||
object FirmwareManagerBaseBehaviour : FirmwareManagerBehaviour {
|
||||
override fun reduce(state: FirmwareManagerState, action: FirmwareManagerActions) = when (action) {
|
||||
is FirmwareManagerActions.UpdateJob -> state.copy(
|
||||
jobs = state.jobs + (
|
||||
action.portLocation to FirmwareJobStatus(
|
||||
portLocation = action.portLocation,
|
||||
firmwareDeviceId = action.firmwareDeviceId,
|
||||
status = action.status,
|
||||
progress = action.progress,
|
||||
)
|
||||
),
|
||||
jobs = state.jobs +
|
||||
(
|
||||
action.portLocation to FirmwareJobStatus(
|
||||
portLocation = action.portLocation,
|
||||
firmwareDeviceId = action.firmwareDeviceId,
|
||||
status = action.status,
|
||||
progress = action.progress,
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
is FirmwareManagerActions.RemoveJob -> state.copy(jobs = state.jobs - action.portLocation)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,4 +124,4 @@ class FirmwareManager(
|
||||
return manager
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,13 +12,17 @@ import solarxr_protocol.datatypes.TrackerStatus
|
||||
object HIDRegistrationBehaviour : HIDReceiverBehaviour {
|
||||
override fun reduce(state: HIDReceiverState, action: HIDReceiverActions) = when (action) {
|
||||
is HIDReceiverActions.DeviceRegistered -> state.copy(
|
||||
trackers = state.trackers + (action.hidId to HIDTrackerRecord(
|
||||
hidId = action.hidId,
|
||||
address = action.address,
|
||||
deviceId = action.deviceId,
|
||||
trackerId = null,
|
||||
)),
|
||||
trackers = state.trackers +
|
||||
(
|
||||
action.hidId to HIDTrackerRecord(
|
||||
hidId = action.hidId,
|
||||
address = action.address,
|
||||
deviceId = action.deviceId,
|
||||
trackerId = null,
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
else -> state
|
||||
}
|
||||
|
||||
@@ -59,6 +63,7 @@ object HIDDeviceInfoBehaviour : HIDReceiverBehaviour {
|
||||
val existing = state.trackers[action.hidId] ?: return state
|
||||
state.copy(trackers = state.trackers + (action.hidId to existing.copy(trackerId = action.trackerId)))
|
||||
}
|
||||
|
||||
else -> state
|
||||
}
|
||||
|
||||
@@ -163,4 +168,4 @@ object HIDStatusBehaviour : HIDReceiverBehaviour {
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,4 +117,4 @@ class HIDReceiver(
|
||||
return receiver
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,8 +77,7 @@ data class HIDRotationButton(
|
||||
val rssi: Int,
|
||||
) : HIDPacket
|
||||
|
||||
private fun readLE16Signed(data: ByteArray, offset: Int): Int =
|
||||
data[offset + 1].toInt() shl 8 or data[offset].toUByte().toInt()
|
||||
private fun readLE16Signed(data: ByteArray, offset: Int): Int = data[offset + 1].toInt() shl 8 or data[offset].toUByte().toInt()
|
||||
|
||||
private fun decodeQ15Quat(data: ByteArray, offset: Int): Quaternion {
|
||||
val scale = 1f / 32768f
|
||||
|
||||
@@ -27,4 +27,4 @@ object SerialLogBehaviour : SerialConnectionBehaviour {
|
||||
|
||||
SerialConnectionActions.Disconnected -> state.copy(connected = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,4 +52,4 @@ sealed interface SerialConnection {
|
||||
}
|
||||
|
||||
data object Flashing : SerialConnection
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,4 +123,4 @@ class SerialServer(
|
||||
return server
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,4 +147,4 @@ object DataFeedInitBehaviour : SolarXRConnectionBehaviour {
|
||||
receiver.send(fbb.dataBuffer().moveToByteArray())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,4 +69,4 @@ class FirmwareBehaviour(private val firmwareManager: FirmwareManager) : SolarXRC
|
||||
firmwareManager.cancelAll()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,4 +129,4 @@ class SerialBehaviour(private val serialServer: SerialServer) : SolarXRConnectio
|
||||
if (c is SerialConnection.Console) c.handle.writeCommand(command)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,4 +44,4 @@ class VrcBehaviour(
|
||||
vrcManager.context.dispatch(VRCConfigActions.ToggleMutedWarning(key))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,11 @@ import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
||||
object TrackerInfosBehaviour : TrackerBehaviour {
|
||||
override fun reduce(state: TrackerState, action: TrackerActions) =
|
||||
if (action is TrackerActions.Update) action.transform(state) else state
|
||||
override fun reduce(state: TrackerState, action: TrackerActions) = if (action is TrackerActions.Update) action.transform(state) else state
|
||||
|
||||
override fun observe(receiver: TrackerContext) {
|
||||
receiver.state.onEach {
|
||||
// AppLogger.tracker.info("Tracker state changed {State}", it)
|
||||
}.launchIn(receiver.scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,4 +59,4 @@ class Tracker(
|
||||
return Tracker(context = context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ object PacketBehaviour : UDPConnectionBehaviour {
|
||||
if (action.packetNum != null) newState = newState.copy(lastPacketNum = action.packetNum)
|
||||
newState
|
||||
}
|
||||
|
||||
else -> state
|
||||
}
|
||||
|
||||
@@ -225,4 +226,4 @@ object SensorRotationBehaviour : UDPConnectionBehaviour {
|
||||
tracker.context.dispatch(TrackerActions.Update { copy(rawRotation = event.data.rotation) })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,4 +144,4 @@ class UDPConnection(
|
||||
return conn
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,18 +9,25 @@ import kotlinx.coroutines.flow.onEach
|
||||
object DefaultVRCConfigBehaviour : VRCConfigBehaviour {
|
||||
override fun reduce(state: VRCConfigState, action: VRCConfigActions) = when (action) {
|
||||
is VRCConfigActions.UpdateValues -> state.copy(currentValues = action.values)
|
||||
|
||||
is VRCConfigActions.ToggleMutedWarning -> {
|
||||
if (action.key !in VRC_VALID_KEYS) state
|
||||
else if (action.key in state.mutedWarnings) state.copy(mutedWarnings = state.mutedWarnings - action.key)
|
||||
else state.copy(mutedWarnings = state.mutedWarnings + action.key)
|
||||
if (action.key !in VRC_VALID_KEYS) {
|
||||
state
|
||||
} else if (action.key in state.mutedWarnings) {
|
||||
state.copy(mutedWarnings = state.mutedWarnings - action.key)
|
||||
} else {
|
||||
state.copy(mutedWarnings = state.mutedWarnings + action.key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun observe(receiver: VRCConfigManager) {
|
||||
receiver.context.state.map { it.mutedWarnings }.distinctUntilChanged().onEach { warnings ->
|
||||
receiver.config.settings.context.dispatch(SettingsActions.Update {
|
||||
copy(mutedVRCWarnings = warnings)
|
||||
})
|
||||
receiver.config.settings.context.dispatch(
|
||||
SettingsActions.Update {
|
||||
copy(mutedVRCWarnings = warnings)
|
||||
},
|
||||
)
|
||||
}.launchIn(receiver.context.scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,8 +94,8 @@ fun computeRecommendedValues(server: VRServer, userHeight: Double): VRCConfigRec
|
||||
return VRCConfigRecommendedValues(
|
||||
legacyMode = false,
|
||||
shoulderTrackingDisabled =
|
||||
(!hasLeftHandWithPosition || !hasRightHandWithPosition || isMissingAnArmTracker) &&
|
||||
((hasLeftHandWithPosition && hasRightHandWithPosition) || isMissingAShoulderTracker),
|
||||
(!hasLeftHandWithPosition || !hasRightHandWithPosition || isMissingAnArmTracker) &&
|
||||
((hasLeftHandWithPosition && hasRightHandWithPosition) || isMissingAShoulderTracker),
|
||||
userHeight = userHeight.toFloat(),
|
||||
calibrationRange = 0.2f,
|
||||
trackerModel = VRCTrackerModel.AXIS,
|
||||
@@ -106,15 +106,14 @@ fun computeRecommendedValues(server: VRServer, userHeight: Double): VRCConfigRec
|
||||
)
|
||||
}
|
||||
|
||||
fun computeValidity(values: VRCConfigValues, recommended: VRCConfigRecommendedValues): VRCConfigValidity =
|
||||
VRCConfigValidity(
|
||||
legacyModeOk = values.legacyMode == recommended.legacyMode,
|
||||
shoulderTrackingOk = values.shoulderTrackingDisabled == recommended.shoulderTrackingDisabled,
|
||||
spineModeOk = recommended.spineMode?.contains(values.spineMode) == true,
|
||||
trackerModelOk = values.trackerModel == recommended.trackerModel,
|
||||
calibrationRangeOk = abs(values.calibrationRange - recommended.calibrationRange) < 0.1f,
|
||||
userHeightOk = abs(recommended.userHeight - values.userHeight) < 0.1f,
|
||||
calibrationVisualsOk = values.calibrationVisuals == recommended.calibrationVisuals,
|
||||
avatarMeasurementTypeOk = values.avatarMeasurementType == recommended.avatarMeasurementType,
|
||||
shoulderWidthCompensationOk = values.shoulderWidthCompensation == recommended.shoulderWidthCompensation,
|
||||
)
|
||||
fun computeValidity(values: VRCConfigValues, recommended: VRCConfigRecommendedValues): VRCConfigValidity = VRCConfigValidity(
|
||||
legacyModeOk = values.legacyMode == recommended.legacyMode,
|
||||
shoulderTrackingOk = values.shoulderTrackingDisabled == recommended.shoulderTrackingDisabled,
|
||||
spineModeOk = recommended.spineMode?.contains(values.spineMode) == true,
|
||||
trackerModelOk = values.trackerModel == recommended.trackerModel,
|
||||
calibrationRangeOk = abs(values.calibrationRange - recommended.calibrationRange) < 0.1f,
|
||||
userHeightOk = abs(recommended.userHeight - values.userHeight) < 0.1f,
|
||||
calibrationVisualsOk = values.calibrationVisuals == recommended.calibrationVisuals,
|
||||
avatarMeasurementTypeOk = values.avatarMeasurementType == recommended.avatarMeasurementType,
|
||||
shoulderWidthCompensationOk = values.shoulderWidthCompensation == recommended.shoulderWidthCompensation,
|
||||
)
|
||||
|
||||
@@ -24,4 +24,4 @@ fun buildTestSerialServer(scope: CoroutineScope) = SerialServer.create(
|
||||
scope = scope,
|
||||
)
|
||||
|
||||
fun buildTestVrServer(scope: CoroutineScope): VRServer = VRServer.create(scope)
|
||||
fun buildTestVrServer(scope: CoroutineScope): VRServer = VRServer.create(scope)
|
||||
|
||||
@@ -3,12 +3,12 @@ package dev.slimevr.firmware
|
||||
import dev.llelievr.espflashkotlin.FlasherSerialInterface
|
||||
import dev.slimevr.VRServer
|
||||
import dev.slimevr.VRServerActions
|
||||
import dev.slimevr.device.Device
|
||||
import dev.slimevr.device.DeviceActions
|
||||
import dev.slimevr.device.DeviceOrigin
|
||||
import dev.slimevr.serial.SerialPortHandle
|
||||
import dev.slimevr.serial.SerialPortInfo
|
||||
import dev.slimevr.serial.SerialServer
|
||||
import dev.slimevr.device.DeviceOrigin
|
||||
import dev.slimevr.device.Device
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -59,9 +59,7 @@ private fun buildSerialServer(
|
||||
// UncompletedCoroutinesError when the test ends.
|
||||
private fun buildVrServer(
|
||||
backgroundScope: kotlinx.coroutines.CoroutineScope,
|
||||
): VRServer {
|
||||
return VRServer.create(backgroundScope)
|
||||
}
|
||||
): VRServer = VRServer.create(backgroundScope)
|
||||
|
||||
class DoSerialFlashTest {
|
||||
|
||||
|
||||
@@ -10,13 +10,12 @@ import solarxr_protocol.data_feed.StartDataFeed
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
private fun testConn(backgroundScope: kotlinx.coroutines.CoroutineScope, onSend: suspend (ByteArray) -> Unit) =
|
||||
SolarXRConnection.create(
|
||||
buildTestVrServer(backgroundScope),
|
||||
onSend = onSend,
|
||||
scope = backgroundScope,
|
||||
behaviours = listOf(DataFeedInitBehaviour),
|
||||
)
|
||||
private fun testConn(backgroundScope: kotlinx.coroutines.CoroutineScope, onSend: suspend (ByteArray) -> Unit) = SolarXRConnection.create(
|
||||
buildTestVrServer(backgroundScope),
|
||||
onSend = onSend,
|
||||
scope = backgroundScope,
|
||||
behaviours = listOf(DataFeedInitBehaviour),
|
||||
)
|
||||
|
||||
private fun config(intervalMs: Int) = DataFeedConfig(minimumTimeSinceLast = intervalMs.toUShort())
|
||||
|
||||
|
||||
@@ -46,4 +46,4 @@ fun main(args: Array<String>) = runBlocking {
|
||||
launch { createIpcServers(server, solarXRBehaviours) }
|
||||
|
||||
Unit
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@ package dev.slimevr.desktop.hid
|
||||
|
||||
import dev.slimevr.AppLogger
|
||||
import dev.slimevr.VRServer
|
||||
import dev.slimevr.hid.HIDReceiver
|
||||
import dev.slimevr.hid.HID_TRACKER_PID
|
||||
import dev.slimevr.hid.HID_TRACKER_RECEIVER_PID
|
||||
import dev.slimevr.hid.HID_TRACKER_RECEIVER_VID
|
||||
import dev.slimevr.hid.HIDReceiver
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
@@ -23,8 +23,7 @@ import org.hid4java.jna.HidDeviceInfoStructure
|
||||
|
||||
private const val HID_POLL_INTERVAL_MS = 3000L
|
||||
|
||||
private fun isCompatibleDevice(vid: Int, pid: Int) =
|
||||
vid == HID_TRACKER_RECEIVER_VID && (pid == HID_TRACKER_RECEIVER_PID || pid == HID_TRACKER_PID)
|
||||
private fun isCompatibleDevice(vid: Int, pid: Int) = vid == HID_TRACKER_RECEIVER_VID && (pid == HID_TRACKER_RECEIVER_PID || pid == HID_TRACKER_PID)
|
||||
|
||||
private val hidSpec = HidServicesSpecification().apply { isAutoStart = false }
|
||||
|
||||
@@ -32,7 +31,7 @@ private val hidSpec = HidServicesSpecification().apply { isAutoStart = false }
|
||||
private val hidServices by lazy { HidManager.getHidServices(hidSpec) }
|
||||
|
||||
private fun enumerateCompatibleDevices(): Map<String, HidDevice> {
|
||||
hidServices // ensure native lib is loaded
|
||||
hidServices // ensure native lib is loaded
|
||||
val root = HidApi.enumerateDevices(0, 0) ?: return emptyMap()
|
||||
val result = mutableMapOf<String, HidDevice>()
|
||||
var info: HidDeviceInfoStructure? = root
|
||||
@@ -56,7 +55,11 @@ fun createDesktopHIDManager(serverContext: VRServer, scope: CoroutineScope) {
|
||||
scope.launch {
|
||||
while (isActive) {
|
||||
val found = withContext(Dispatchers.IO) {
|
||||
try { enumerateCompatibleDevices() } catch (_: Exception) { emptyMap() }
|
||||
try {
|
||||
enumerateCompatibleDevices()
|
||||
} catch (_: Exception) {
|
||||
emptyMap()
|
||||
}
|
||||
}
|
||||
|
||||
// Devices no longer present + jobs that exited on their own (read error)
|
||||
@@ -88,12 +91,19 @@ fun createDesktopHIDManager(serverContext: VRServer, scope: CoroutineScope) {
|
||||
try {
|
||||
while (isActive) {
|
||||
val data = withContext(Dispatchers.IO) {
|
||||
try { hidDevice.readAll(0) } catch (_: Exception) { null }
|
||||
try {
|
||||
hidDevice.readAll(0)
|
||||
} catch (_: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
when {
|
||||
data == null -> return@channelFlow // read error, device gone
|
||||
data == null -> return@channelFlow
|
||||
|
||||
// read error, device gone
|
||||
data.isNotEmpty() -> send(data)
|
||||
else -> delay(1) // no data yet, yield without busy-spinning
|
||||
|
||||
else -> delay(1) // no data yet, yield without busy-spinning
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
|
||||
@@ -38,7 +38,7 @@ suspend fun createUnixSolarXRSocket(server: VRServer, behaviours: List<SolarXRCo
|
||||
server = server,
|
||||
messages = readFramedMessages(channel),
|
||||
send = { bytes -> withContext(Dispatchers.IO) { writeFramed(channel, bytes) } },
|
||||
behaviours = behaviours
|
||||
behaviours = behaviours,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -6,14 +6,14 @@ import dev.slimevr.desktop.platform.Position
|
||||
import dev.slimevr.desktop.platform.ProtobufMessage
|
||||
import dev.slimevr.desktop.platform.TrackerAdded
|
||||
import dev.slimevr.desktop.platform.Version
|
||||
import dev.slimevr.solarxr.SolarXRConnectionBehaviour
|
||||
import dev.slimevr.solarxr.SolarXRConnection
|
||||
import dev.slimevr.solarxr.onSolarXRMessage
|
||||
import dev.slimevr.device.Device
|
||||
import dev.slimevr.device.DeviceActions
|
||||
import dev.slimevr.device.DeviceOrigin
|
||||
import dev.slimevr.tracker.TrackerActions
|
||||
import dev.slimevr.device.Device
|
||||
import dev.slimevr.solarxr.SolarXRConnection
|
||||
import dev.slimevr.solarxr.SolarXRConnectionBehaviour
|
||||
import dev.slimevr.solarxr.onSolarXRMessage
|
||||
import dev.slimevr.tracker.Tracker
|
||||
import dev.slimevr.tracker.TrackerActions
|
||||
import io.github.axisangles.ktmath.Quaternion
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@@ -41,7 +41,7 @@ suspend fun createWindowsSolarXRPipe(server: VRServer, behaviours: List<SolarXRC
|
||||
server = server,
|
||||
messages = readFramedMessages(handle),
|
||||
send = { bytes -> withContext(Dispatchers.IO) { writeFramedPipe(handle, bytes) } },
|
||||
behaviours = behaviours
|
||||
behaviours = behaviours,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,10 @@ import kotlin.io.path.exists
|
||||
|
||||
private const val USER_REG_SUBPATH = "steamapps/compatdata/438100/pfx/user.reg"
|
||||
private val KEY_VALUE_PATTERN = Regex(""""(.+)"=(.+)""")
|
||||
private val HEX_FORMAT = HexFormat { upperCase = false; bytes.byteSeparator = "," }
|
||||
private val HEX_FORMAT = HexFormat {
|
||||
upperCase = false
|
||||
bytes.byteSeparator = ","
|
||||
}
|
||||
|
||||
internal val linuxUserRegPath = System.getenv("HOME")?.let { home ->
|
||||
listOf(
|
||||
@@ -70,8 +73,11 @@ internal suspend fun linuxGetQwordValue(registry: Map<String, String>, key: Stri
|
||||
|
||||
internal suspend fun linuxGetDwordValue(registry: Map<String, String>, key: String): Int? = try {
|
||||
val value = registry[key] ?: return null
|
||||
if (value.startsWith("dword:")) value.substring(6).toInt(16)
|
||||
else throw InvalidObjectException("Expected DWORD but got: $value")
|
||||
if (value.startsWith("dword:")) {
|
||||
value.substring(6).toInt(16)
|
||||
} else {
|
||||
throw InvalidObjectException("Expected DWORD but got: $value")
|
||||
}
|
||||
} catch (e: CancellationException) {
|
||||
throw e
|
||||
} catch (e: Exception) {
|
||||
@@ -92,10 +98,12 @@ internal fun linuxVRCConfigFlow(): Flow<solarxr_protocol.rpc.VRCConfigValues?> =
|
||||
if (keys.isEmpty()) {
|
||||
emit(null)
|
||||
} else {
|
||||
emit(buildVRCConfigValues(
|
||||
intValue = { key -> keys[key]?.let { linuxGetDwordValue(registry, it) } },
|
||||
doubleValue = { key -> keys[key]?.let { linuxGetQwordValue(registry, it) } },
|
||||
))
|
||||
emit(
|
||||
buildVRCConfigValues(
|
||||
intValue = { key -> keys[key]?.let { linuxGetDwordValue(registry, it) } },
|
||||
doubleValue = { key -> keys[key]?.let { linuxGetQwordValue(registry, it) } },
|
||||
),
|
||||
)
|
||||
}
|
||||
delay(3000)
|
||||
// it seems that on linux, steam writes to the reg file is unpredictable.
|
||||
|
||||
@@ -13,27 +13,28 @@ import solarxr_protocol.rpc.VRCTrackerModel
|
||||
|
||||
internal const val VRC_REG_PATH = "Software\\VRChat\\VRChat"
|
||||
|
||||
fun createDesktopVRCConfigManager(config: AppConfig, scope: CoroutineScope): VRCConfigManager =
|
||||
when (CURRENT_PLATFORM) {
|
||||
Platform.WINDOWS -> VRCConfigManager.create(
|
||||
config = config,
|
||||
scope = scope,
|
||||
isSupported = true,
|
||||
values = windowsVRCConfigFlow(),
|
||||
)
|
||||
Platform.LINUX -> VRCConfigManager.create(
|
||||
config = config,
|
||||
scope = scope,
|
||||
isSupported = true,
|
||||
values = linuxVRCConfigFlow(),
|
||||
)
|
||||
else -> VRCConfigManager.create(
|
||||
config = config,
|
||||
scope = scope,
|
||||
isSupported = false,
|
||||
values = emptyFlow(),
|
||||
)
|
||||
}
|
||||
fun createDesktopVRCConfigManager(config: AppConfig, scope: CoroutineScope): VRCConfigManager = when (CURRENT_PLATFORM) {
|
||||
Platform.WINDOWS -> VRCConfigManager.create(
|
||||
config = config,
|
||||
scope = scope,
|
||||
isSupported = true,
|
||||
values = windowsVRCConfigFlow(),
|
||||
)
|
||||
|
||||
Platform.LINUX -> VRCConfigManager.create(
|
||||
config = config,
|
||||
scope = scope,
|
||||
isSupported = true,
|
||||
values = linuxVRCConfigFlow(),
|
||||
)
|
||||
|
||||
else -> VRCConfigManager.create(
|
||||
config = config,
|
||||
scope = scope,
|
||||
isSupported = false,
|
||||
values = emptyFlow(),
|
||||
)
|
||||
}
|
||||
|
||||
internal suspend fun buildVRCConfigValues(
|
||||
intValue: suspend (String) -> Int?,
|
||||
|
||||
Reference in New Issue
Block a user