diff --git a/gui/public/i18n/en/translation.ftl b/gui/public/i18n/en/translation.ftl index e91247bac8..f05f0d6afd 100644 --- a/gui/public/i18n/en/translation.ftl +++ b/gui/public/i18n/en/translation.ftl @@ -584,6 +584,8 @@ settings-general-tracker_mechanics-trackers_over_usb = Trackers over USB settings-general-tracker_mechanics-trackers_over_usb-description = Enables receiving HID tracker data over USB. Make sure connected trackers have connection over HID enabled! settings-general-tracker_mechanics-trackers_over_usb-enabled-label = Allow HID trackers to connect directly over USB +settings-general-tracker_mechanics-timeout_duration = Timeout duration +settings-general-tracker_mechanics-timeout_duration-description = How long until a tracker is marked as 'disconnected' when the connection is lost. settings-stay_aligned = Stay Aligned settings-stay_aligned-description = Stay Aligned reduces drift by gradually adjusting your trackers to match your relaxed poses. diff --git a/gui/src/components/commons/Input.tsx b/gui/src/components/commons/Input.tsx index ba93fc99b3..8f83084a65 100644 --- a/gui/src/components/commons/Input.tsx +++ b/gui/src/components/commons/Input.tsx @@ -37,6 +37,7 @@ export const InputInside = forwardRef< value, error, variant = 'primary', + ...props }, ref ) { @@ -100,6 +101,7 @@ export const InputInside = forwardRef< value={computedValue} // Do we want that behaviour ? disabled={disabled} ref={ref} + {...props} /> {type === 'password' && (
({ disabled, variant = 'primary', rules, + ...props }: { rules?: UseControllerProps>['rules']; control: Control; @@ -157,6 +160,7 @@ export const Input = ({ onChange={onChange} ref={ref} name={name} + {...props} /> )} /> diff --git a/gui/src/components/settings/pages/GeneralSettings.tsx b/gui/src/components/settings/pages/GeneralSettings.tsx index d9907ce0f2..3e034ce6e6 100644 --- a/gui/src/components/settings/pages/GeneralSettings.tsx +++ b/gui/src/components/settings/pages/GeneralSettings.tsx @@ -15,10 +15,12 @@ import { SteamVRTrackersSettingT, TapDetectionSettingsT, HIDSettingsT, + TimeoutSettingsT, } from 'solarxr-protocol'; import { useConfig } from '@/hooks/config'; import { useWebsocketAPI } from '@/hooks/websocket-api'; import { useLocaleConfig } from '@/i18n/config'; +import { Input } from '@/components/commons/Input'; import { CheckBox } from '@/components/commons/Checkbox'; import { SteamIcon } from '@/components/commons/icon/SteamIcon'; import { WrenchIcon } from '@/components/commons/icon/WrenchIcons'; @@ -108,6 +110,9 @@ export type SettingsForm = { hidSettings: { trackersOverHID: boolean; }; + timeout: { + duration: number; + }; }; const defaultValues: SettingsForm = { @@ -164,6 +169,7 @@ const defaultValues: SettingsForm = { resetsSettings: defaultResetSettings, stayAligned: defaultStayAlignedSettings, hidSettings: { trackersOverHID: false }, + timeout: { duration: 3.0 }, }; const settingsAtom = atom(new SettingsResponseT()); @@ -301,6 +307,10 @@ export function GeneralSettings() { hidSettings.trackersOverHid = values.hidSettings.trackersOverHID; settings.hidSettings = hidSettings; + const timeout = new TimeoutSettingsT(); + timeout.duration = values.timeout.duration; + settings.timeout = timeout; + if (values.resetsSettings) { settings.resetsSettings = loadResetSettings(values.resetsSettings); } @@ -419,6 +429,12 @@ export function GeneralSettings() { }; } + if (settings.timeout) { + formData.timeout = { + duration: settings.timeout.duration, + }; + } + reset({ ...getValues(), ...formData }); }, [settings]); @@ -455,7 +471,10 @@ export function GeneralSettings() { setHandsWarning(false); }} /> -
+ e.preventDefault()} + > } id="steamvr"> <> @@ -733,6 +752,31 @@ export function GeneralSettings() { 'settings-general-tracker_mechanics-trackers_over_usb-enabled-label' )} /> +
+ + {l10n.getString( + 'settings-general-tracker_mechanics-timeout_duration' + )} + +
+ + {l10n.getString( + 'settings-general-tracker_mechanics-timeout_duration-description' + )} + +
+
+
+ +
} id="fksettings"> diff --git a/server/core/src/main/java/dev/slimevr/config/TimeoutConfig.kt b/server/core/src/main/java/dev/slimevr/config/TimeoutConfig.kt new file mode 100644 index 0000000000..2d4c3d6ced --- /dev/null +++ b/server/core/src/main/java/dev/slimevr/config/TimeoutConfig.kt @@ -0,0 +1,22 @@ +package dev.slimevr.config + +import dev.slimevr.VRServer +import dev.slimevr.tracking.trackers.Tracker + +class TimeoutConfig { + // Timeout duration in seconds + var duration = 3.0f + + fun updateTimeoutDuration() { + if (this.duration.isNaN() || this.duration.isInfinite()) { + this.duration = 3.0f + } + if (this.duration < 1f) { + this.duration = 1f + } + if (this.duration > 1000000000000000f) { + this.duration = 1000000000000000f + } + Tracker.DISCONNECT_MS = (this.duration * 1000L).toLong() + Tracker.TIMEOUT_MS + } +} diff --git a/server/core/src/main/java/dev/slimevr/config/VRConfig.kt b/server/core/src/main/java/dev/slimevr/config/VRConfig.kt index 9ef33f5e00..5899065814 100644 --- a/server/core/src/main/java/dev/slimevr/config/VRConfig.kt +++ b/server/core/src/main/java/dev/slimevr/config/VRConfig.kt @@ -19,6 +19,8 @@ class VRConfig { val filters: FiltersConfig = FiltersConfig() + val timeout: TimeoutConfig = TimeoutConfig() + val driftCompensation: DriftCompensationConfig = DriftCompensationConfig() val oscRouter: OSCConfig = OSCConfig() diff --git a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.kt b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.kt index b7d41288af..d5a31452d1 100644 --- a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.kt +++ b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.kt @@ -13,6 +13,7 @@ import dev.slimevr.config.ResetsConfig import dev.slimevr.config.SkeletonConfig import dev.slimevr.config.StayAlignedConfig import dev.slimevr.config.TapDetectionConfig +import dev.slimevr.config.TimeoutConfig import dev.slimevr.config.VMCConfig import dev.slimevr.config.VRCOSCConfig import dev.slimevr.filtering.TrackerFilters.Companion.getByConfigkey @@ -32,6 +33,7 @@ import solarxr_protocol.rpc.SettingsResponse import solarxr_protocol.rpc.StayAlignedSettings import solarxr_protocol.rpc.SteamVRTrackersSetting import solarxr_protocol.rpc.TapDetectionSettings +import solarxr_protocol.rpc.TimeoutSettings import solarxr_protocol.rpc.VMCOSCSettings import solarxr_protocol.rpc.VRCOSCSettings import solarxr_protocol.rpc.settings.LegTweaksSettings @@ -421,7 +423,10 @@ fun createSettingsResponse(fbb: FlatBufferBuilder, server: VRServer): Int { server.configManager.vrConfig.stayAlignedConfig, ), createHIDSettings(fbb, server.configManager.vrConfig.hidConfig), - 0, + createTimeoutSettings( + fbb, + server.configManager.vrConfig.timeout, + ), ) } @@ -457,3 +462,12 @@ fun createHIDSettings( fbb, config.trackersOverHID, ) + +fun createTimeoutSettings( + fbb: FlatBufferBuilder, + timeoutConfig: TimeoutConfig, +): Int = TimeoutSettings + .createTimeoutSettings( + fbb, + timeoutConfig.duration, + ) diff --git a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsHandler.kt b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsHandler.kt index b2aae0599f..08be5b1674 100644 --- a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsHandler.kt +++ b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsHandler.kt @@ -361,6 +361,14 @@ class RPCSettingsHandler(var rpcHandler: RPCHandler, var api: ProtocolAPI) { config.trackersOverHID = requestConfig.trackersOverHid() } + if (req.timeout() != null) { + val timeoutConfig = api.server.configManager + .vrConfig + .timeout + timeoutConfig.duration = req.timeout().duration() + timeoutConfig.updateTimeoutDuration() + } + api.server.configManager.saveConfig() } diff --git a/server/core/src/main/java/dev/slimevr/tracking/trackers/Tracker.kt b/server/core/src/main/java/dev/slimevr/tracking/trackers/Tracker.kt index a3d03ea10b..e98089d3bb 100644 --- a/server/core/src/main/java/dev/slimevr/tracking/trackers/Tracker.kt +++ b/server/core/src/main/java/dev/slimevr/tracking/trackers/Tracker.kt @@ -13,9 +13,6 @@ import io.github.axisangles.ktmath.Quaternion import io.github.axisangles.ktmath.Vector3 import kotlin.properties.Delegates -const val TIMEOUT_MS = 2_000L -const val DISCONNECT_MS = 3_000L + TIMEOUT_MS - /** * Generic tracker class for input and output tracker, * with flags on instantiation. @@ -103,6 +100,11 @@ class Tracker @JvmOverloads constructor( */ val usesSleep: Boolean = false, ) { + companion object { + const val TIMEOUT_MS = 2_000L + var DISCONNECT_MS = 3_000L + TIMEOUT_MS + } + private val timer = BufferedTimer(1f) private var timeAtLastUpdate: Long = System.currentTimeMillis() private var timeScheduledSleep: Long = Long.MAX_VALUE