Refine sensor integration strategy
This commit is contained in:
124
miniprogram/engine/sensor/accelerometerController.ts
Normal file
124
miniprogram/engine/sensor/accelerometerController.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
export interface AccelerometerControllerCallbacks {
|
||||
onSample: (x: number, y: number, z: number) => void
|
||||
onError: (message: string) => void
|
||||
}
|
||||
|
||||
const ACCELEROMETER_START_RETRY_DELAY_MS = 120
|
||||
|
||||
export class AccelerometerController {
|
||||
callbacks: AccelerometerControllerCallbacks
|
||||
listening: boolean
|
||||
starting: boolean
|
||||
accelerometerCallback: ((result: WechatMiniprogram.OnAccelerometerChangeCallbackResult) => void) | null
|
||||
retryTimer: number
|
||||
|
||||
constructor(callbacks: AccelerometerControllerCallbacks) {
|
||||
this.callbacks = callbacks
|
||||
this.listening = false
|
||||
this.starting = false
|
||||
this.accelerometerCallback = null
|
||||
this.retryTimer = 0
|
||||
}
|
||||
|
||||
start(): void {
|
||||
if (this.listening || this.starting) {
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof wx.startAccelerometer !== 'function' || typeof wx.onAccelerometerChange !== 'function') {
|
||||
this.callbacks.onError('当前环境不支持加速度计监听')
|
||||
return
|
||||
}
|
||||
|
||||
this.clearRetryTimer()
|
||||
this.starting = true
|
||||
this.detachCallback()
|
||||
wx.stopAccelerometer({
|
||||
complete: () => {
|
||||
this.startAfterStop(false)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
private startAfterStop(retried: boolean): void {
|
||||
const callback = (result: WechatMiniprogram.OnAccelerometerChangeCallbackResult) => {
|
||||
if (
|
||||
typeof result.x !== 'number'
|
||||
|| typeof result.y !== 'number'
|
||||
|| typeof result.z !== 'number'
|
||||
|| Number.isNaN(result.x)
|
||||
|| Number.isNaN(result.y)
|
||||
|| Number.isNaN(result.z)
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
this.callbacks.onSample(result.x, result.y, result.z)
|
||||
}
|
||||
|
||||
this.accelerometerCallback = callback
|
||||
wx.onAccelerometerChange(callback)
|
||||
wx.startAccelerometer({
|
||||
interval: 'ui',
|
||||
success: () => {
|
||||
this.starting = false
|
||||
this.listening = true
|
||||
},
|
||||
fail: (res) => {
|
||||
const errorMessage = res && res.errMsg ? res.errMsg : 'startAccelerometer failed'
|
||||
if (!retried && errorMessage.indexOf('has enable') >= 0) {
|
||||
this.detachCallback()
|
||||
this.clearRetryTimer()
|
||||
this.retryTimer = setTimeout(() => {
|
||||
this.retryTimer = 0
|
||||
wx.stopAccelerometer({
|
||||
complete: () => {
|
||||
this.startAfterStop(true)
|
||||
},
|
||||
})
|
||||
}, ACCELEROMETER_START_RETRY_DELAY_MS) as unknown as number
|
||||
return
|
||||
}
|
||||
|
||||
this.starting = false
|
||||
this.detachCallback()
|
||||
this.callbacks.onError(errorMessage)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
stop(): void {
|
||||
this.clearRetryTimer()
|
||||
this.detachCallback()
|
||||
wx.stopAccelerometer({
|
||||
complete: () => {},
|
||||
})
|
||||
this.starting = false
|
||||
this.listening = false
|
||||
}
|
||||
|
||||
destroy(): void {
|
||||
this.stop()
|
||||
}
|
||||
|
||||
private clearRetryTimer(): void {
|
||||
if (!this.retryTimer) {
|
||||
return
|
||||
}
|
||||
|
||||
clearTimeout(this.retryTimer)
|
||||
this.retryTimer = 0
|
||||
}
|
||||
|
||||
private detachCallback(): void {
|
||||
if (!this.accelerometerCallback) {
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof wx.offAccelerometerChange === 'function') {
|
||||
wx.offAccelerometerChange(this.accelerometerCallback)
|
||||
}
|
||||
|
||||
this.accelerometerCallback = null
|
||||
}
|
||||
}
|
||||
77
miniprogram/engine/sensor/deviceMotionController.ts
Normal file
77
miniprogram/engine/sensor/deviceMotionController.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
export interface DeviceMotionControllerCallbacks {
|
||||
onSample: (alpha: number | null, beta: number | null, gamma: number | null) => void
|
||||
onError: (message: string) => void
|
||||
}
|
||||
|
||||
export class DeviceMotionController {
|
||||
callbacks: DeviceMotionControllerCallbacks
|
||||
listening: boolean
|
||||
starting: boolean
|
||||
motionCallback: ((result: WechatMiniprogram.OnDeviceMotionChangeCallbackResult) => void) | null
|
||||
|
||||
constructor(callbacks: DeviceMotionControllerCallbacks) {
|
||||
this.callbacks = callbacks
|
||||
this.listening = false
|
||||
this.starting = false
|
||||
this.motionCallback = null
|
||||
}
|
||||
|
||||
start(): void {
|
||||
if (this.listening || this.starting) {
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof wx.startDeviceMotionListening !== 'function' || typeof wx.onDeviceMotionChange !== 'function') {
|
||||
this.callbacks.onError('当前环境不支持设备方向监听')
|
||||
return
|
||||
}
|
||||
|
||||
const callback = (result: WechatMiniprogram.OnDeviceMotionChangeCallbackResult) => {
|
||||
const alpha = typeof result.alpha === 'number' && !Number.isNaN(result.alpha) ? result.alpha : null
|
||||
const beta = typeof result.beta === 'number' && !Number.isNaN(result.beta) ? result.beta : null
|
||||
const gamma = typeof result.gamma === 'number' && !Number.isNaN(result.gamma) ? result.gamma : null
|
||||
this.callbacks.onSample(alpha, beta, gamma)
|
||||
}
|
||||
|
||||
this.motionCallback = callback
|
||||
wx.onDeviceMotionChange(callback)
|
||||
this.starting = true
|
||||
wx.startDeviceMotionListening({
|
||||
interval: 'game',
|
||||
success: () => {
|
||||
this.starting = false
|
||||
this.listening = true
|
||||
},
|
||||
fail: (res) => {
|
||||
this.starting = false
|
||||
this.detachCallback()
|
||||
this.callbacks.onError(res && res.errMsg ? res.errMsg : 'startDeviceMotionListening failed')
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
stop(): void {
|
||||
this.detachCallback()
|
||||
wx.stopDeviceMotionListening({
|
||||
complete: () => {},
|
||||
})
|
||||
this.starting = false
|
||||
this.listening = false
|
||||
}
|
||||
|
||||
destroy(): void {
|
||||
this.stop()
|
||||
}
|
||||
|
||||
private detachCallback(): void {
|
||||
if (!this.motionCallback) {
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof wx.offDeviceMotionChange === 'function') {
|
||||
wx.offDeviceMotionChange(this.motionCallback)
|
||||
}
|
||||
|
||||
this.motionCallback = null
|
||||
}
|
||||
}
|
||||
85
miniprogram/engine/sensor/gyroscopeController.ts
Normal file
85
miniprogram/engine/sensor/gyroscopeController.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
export interface GyroscopeControllerCallbacks {
|
||||
onSample: (x: number, y: number, z: number) => void
|
||||
onError: (message: string) => void
|
||||
}
|
||||
|
||||
export class GyroscopeController {
|
||||
callbacks: GyroscopeControllerCallbacks
|
||||
listening: boolean
|
||||
starting: boolean
|
||||
gyroCallback: ((result: WechatMiniprogram.OnGyroscopeChangeCallbackResult) => void) | null
|
||||
|
||||
constructor(callbacks: GyroscopeControllerCallbacks) {
|
||||
this.callbacks = callbacks
|
||||
this.listening = false
|
||||
this.starting = false
|
||||
this.gyroCallback = null
|
||||
}
|
||||
|
||||
start(): void {
|
||||
if (this.listening || this.starting) {
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof wx.startGyroscope !== 'function' || typeof wx.onGyroscopeChange !== 'function') {
|
||||
this.callbacks.onError('当前环境不支持陀螺仪监听')
|
||||
return
|
||||
}
|
||||
|
||||
const callback = (result: WechatMiniprogram.OnGyroscopeChangeCallbackResult) => {
|
||||
if (
|
||||
typeof result.x !== 'number'
|
||||
|| typeof result.y !== 'number'
|
||||
|| typeof result.z !== 'number'
|
||||
|| Number.isNaN(result.x)
|
||||
|| Number.isNaN(result.y)
|
||||
|| Number.isNaN(result.z)
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
this.callbacks.onSample(result.x, result.y, result.z)
|
||||
}
|
||||
|
||||
this.gyroCallback = callback
|
||||
wx.onGyroscopeChange(callback)
|
||||
this.starting = true
|
||||
wx.startGyroscope({
|
||||
interval: 'game',
|
||||
success: () => {
|
||||
this.starting = false
|
||||
this.listening = true
|
||||
},
|
||||
fail: (res) => {
|
||||
this.starting = false
|
||||
this.detachCallback()
|
||||
this.callbacks.onError(res && res.errMsg ? res.errMsg : 'startGyroscope failed')
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
stop(): void {
|
||||
this.detachCallback()
|
||||
wx.stopGyroscope({
|
||||
complete: () => {},
|
||||
})
|
||||
this.starting = false
|
||||
this.listening = false
|
||||
}
|
||||
|
||||
destroy(): void {
|
||||
this.stop()
|
||||
}
|
||||
|
||||
private detachCallback(): void {
|
||||
if (!this.gyroCallback) {
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof wx.offGyroscopeChange === 'function') {
|
||||
wx.offGyroscopeChange(this.gyroCallback)
|
||||
}
|
||||
|
||||
this.gyroCallback = null
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user