Add mock GPS simulator and configurable location sources
This commit is contained in:
@@ -121,6 +121,13 @@ export interface MapEngineViewState {
|
||||
statusText: string
|
||||
gpsTracking: boolean
|
||||
gpsTrackingText: string
|
||||
locationSourceMode: 'real' | 'mock'
|
||||
locationSourceText: string
|
||||
mockBridgeConnected: boolean
|
||||
mockBridgeStatusText: string
|
||||
mockBridgeUrlText: string
|
||||
mockCoordText: string
|
||||
mockSpeedText: string
|
||||
gpsCoordText: string
|
||||
heartRateConnected: boolean
|
||||
heartRateStatusText: string
|
||||
@@ -209,6 +216,13 @@ const VIEW_SYNC_KEYS: Array<keyof MapEngineViewState> = [
|
||||
'statusText',
|
||||
'gpsTracking',
|
||||
'gpsTrackingText',
|
||||
'locationSourceMode',
|
||||
'locationSourceText',
|
||||
'mockBridgeConnected',
|
||||
'mockBridgeStatusText',
|
||||
'mockBridgeUrlText',
|
||||
'mockCoordText',
|
||||
'mockSpeedText',
|
||||
'gpsCoordText',
|
||||
'heartRateConnected',
|
||||
'heartRateStatusText',
|
||||
@@ -582,15 +596,20 @@ export class MapEngine {
|
||||
this.setState({
|
||||
gpsTracking: this.locationController.listening,
|
||||
gpsTrackingText: message,
|
||||
...this.getLocationControllerViewPatch(),
|
||||
}, true)
|
||||
},
|
||||
onError: (message) => {
|
||||
this.setState({
|
||||
gpsTracking: false,
|
||||
gpsTracking: this.locationController.listening,
|
||||
gpsTrackingText: message,
|
||||
...this.getLocationControllerViewPatch(),
|
||||
statusText: `${message} (${this.buildVersion})`,
|
||||
}, true)
|
||||
},
|
||||
onDebugStateChange: () => {
|
||||
this.setState(this.getLocationControllerViewPatch(), true)
|
||||
},
|
||||
})
|
||||
this.heartRateController = new HeartRateController({
|
||||
onHeartRate: (bpm) => {
|
||||
@@ -716,6 +735,13 @@ export class MapEngine {
|
||||
statusText: `单 WebGL 管线已就绪,等待传感器接入 (${this.buildVersion})`,
|
||||
gpsTracking: false,
|
||||
gpsTrackingText: '持续定位待启动',
|
||||
locationSourceMode: 'real',
|
||||
locationSourceText: '真实定位',
|
||||
mockBridgeConnected: false,
|
||||
mockBridgeStatusText: '未连接',
|
||||
mockBridgeUrlText: 'wss://gs.gotomars.xyz/mock-gps',
|
||||
mockCoordText: '--',
|
||||
mockSpeedText: '--',
|
||||
gpsCoordText: '--',
|
||||
heartRateConnected: false,
|
||||
heartRateStatusText: '心率带未连接',
|
||||
@@ -833,6 +859,20 @@ export class MapEngine {
|
||||
return this.gamePresentation.hud.hudTargetControlId
|
||||
}
|
||||
|
||||
getLocationControllerViewPatch(): Partial<MapEngineViewState> {
|
||||
const debugState = this.locationController.getDebugState()
|
||||
return {
|
||||
gpsTracking: debugState.listening,
|
||||
locationSourceMode: debugState.sourceMode,
|
||||
locationSourceText: debugState.sourceModeText,
|
||||
mockBridgeConnected: debugState.mockBridgeConnected,
|
||||
mockBridgeStatusText: debugState.mockBridgeStatusText,
|
||||
mockBridgeUrlText: debugState.mockBridgeUrlText,
|
||||
mockCoordText: debugState.mockCoordText,
|
||||
mockSpeedText: debugState.mockSpeedText,
|
||||
}
|
||||
}
|
||||
|
||||
getGameModeText(): string {
|
||||
return this.gameMode === 'score-o' ? '积分赛' : '顺序赛'
|
||||
}
|
||||
@@ -1272,6 +1312,26 @@ export class MapEngine {
|
||||
this.locationController.start()
|
||||
}
|
||||
|
||||
handleSetRealLocationMode(): void {
|
||||
this.locationController.setSourceMode('real')
|
||||
}
|
||||
|
||||
handleSetMockLocationMode(): void {
|
||||
this.locationController.setSourceMode('mock')
|
||||
}
|
||||
|
||||
handleConnectMockLocationBridge(): void {
|
||||
this.locationController.connectMockBridge()
|
||||
}
|
||||
|
||||
handleDisconnectMockLocationBridge(): void {
|
||||
this.locationController.disconnectMockBridge()
|
||||
}
|
||||
|
||||
handleSetMockLocationBridgeUrl(url: string): void {
|
||||
this.locationController.setMockBridgeUrl(url)
|
||||
}
|
||||
|
||||
handleSetGameMode(nextMode: 'classic-sequential' | 'score-o'): void {
|
||||
if (this.gameMode === nextMode) {
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user