diff --git a/server/core/src/main/java/dev/slimevr/solarxr/datafeed.kt b/server/core/src/main/java/dev/slimevr/solarxr/datafeed.kt index 25358d3ea..ae4a8a49e 100644 --- a/server/core/src/main/java/dev/slimevr/solarxr/datafeed.kt +++ b/server/core/src/main/java/dev/slimevr/solarxr/datafeed.kt @@ -25,6 +25,7 @@ import solarxr_protocol.datatypes.TrackerId import solarxr_protocol.datatypes.hardware_info.HardwareInfo import solarxr_protocol.datatypes.hardware_info.HardwareStatus import solarxr_protocol.datatypes.math.Quat +import solarxr_protocol.datatypes.math.Vec3f import java.nio.ByteBuffer private fun createTracker(device: DeviceState, tracker: TrackerState, trackerMask: TrackerDataMask): TrackerData = TrackerData( @@ -34,6 +35,7 @@ private fun createTracker(device: DeviceState, tracker: TrackerState, trackerMas ), status = if (trackerMask.status == true) device.status else null, rotation = if (trackerMask.rotation == true) tracker.rawRotation.let { Quat(it.x, it.y, it.z, it.w) } else null, + position = if (trackerMask.position == true && tracker.position != null) tracker.position.let { Vec3f(it.x, it.y, it.z) } else null, info = if (trackerMask.info == true) { TrackerInfo( imuType = tracker.sensorType, @@ -43,6 +45,7 @@ private fun createTracker(device: DeviceState, tracker: TrackerState, trackerMas } else { null }, + tps = if (trackerMask.tps == true) tracker.tps else null, ) private fun createDevice( @@ -56,8 +59,7 @@ private fun createDevice( id = DeviceId(device.id.toUByte()), hardwareStatus = HardwareStatus( batteryVoltage = device.batteryVoltage, - batteryPctEstimate = device.batteryLevel.toUInt() - .toUByte(), + batteryPctEstimate = (device.batteryLevel * 100).toUInt().toUByte(), ping = device.ping?.toUShort(), ), hardwareInfo = HardwareInfo( diff --git a/server/core/src/main/java/dev/slimevr/tracker/behaviours.kt b/server/core/src/main/java/dev/slimevr/tracker/behaviours.kt index 7d4285115..3030e881e 100644 --- a/server/core/src/main/java/dev/slimevr/tracker/behaviours.kt +++ b/server/core/src/main/java/dev/slimevr/tracker/behaviours.kt @@ -1,14 +1,33 @@ package dev.slimevr.tracker +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.distinctUntilChangedBy import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch +import kotlin.concurrent.atomics.AtomicInt +import kotlin.concurrent.atomics.ExperimentalAtomicApi +import kotlin.concurrent.atomics.incrementAndFetch -object TrackerInfosBehaviour : TrackerBehaviour { +object TrackerBasicBehaviour : TrackerBehaviour { override fun reduce(state: TrackerState, action: TrackerActions) = if (action is TrackerActions.Update) action.transform(state) else state +} +object TrackerTPSBehaviour : TrackerBehaviour { + @OptIn(ExperimentalAtomicApi::class) override fun observe(receiver: TrackerContext) { - receiver.state.onEach { -// AppLogger.tracker.info("Tracker state changed {State}", it) + val count = AtomicInt(0) + + receiver.state.distinctUntilChangedBy { it.rawRotation }.onEach { + count.incrementAndFetch() }.launchIn(receiver.scope) + + receiver.scope.launch { + while (isActive) { + delay(1000) + receiver.dispatch(TrackerActions.Update { copy(tps = count.exchange(0).toUShort()) }) + } + } } } diff --git a/server/core/src/main/java/dev/slimevr/tracker/module.kt b/server/core/src/main/java/dev/slimevr/tracker/module.kt index dacfd39b7..68d4ec682 100644 --- a/server/core/src/main/java/dev/slimevr/tracker/module.kt +++ b/server/core/src/main/java/dev/slimevr/tracker/module.kt @@ -21,7 +21,8 @@ data class TrackerState( val rawRotation: Quaternion, val deviceId: Int, val origin: DeviceOrigin, - val position: Vector3? + val tps: UShort, + val position: Vector3?, ) sealed interface TrackerActions { @@ -53,10 +54,11 @@ class Tracker( deviceId = deviceId, customName = null, sensorType = sensorType, - position = null + position = null, + tps = 0u, ) - val behaviours = listOf(TrackerInfosBehaviour) + val behaviours = listOf(TrackerBasicBehaviour, TrackerTPSBehaviour) val context = Context.create(initialState = trackerState, scope = scope, behaviours = behaviours) behaviours.forEach { it.observe(context) } return Tracker(context = context)