Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/components/logs/logs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export class LogsComponent {
}

async filterGet() {
const config = await this.webusb.getConfig(ConfigIndex.LOG_MASK)
const config = await this.webusb.tryGetConfig(ConfigIndex.LOG_MASK)
this.filterUSB = !!(config.presetIndex & LogMask.USB)
this.filterTouch = !!(config.presetIndex & LogMask.TOUCH)
this.filterWireless = !!(config.presetIndex & LogMask.WIRELESS)
Expand All @@ -75,6 +75,6 @@ export class LogsComponent {
if (this.filterUSB) logMask += LogMask.USB
if (this.filterTouch) logMask += LogMask.TOUCH
if (this.filterWireless) logMask += LogMask.WIRELESS
this.webusb.setConfig(ConfigIndex.LOG_MASK, logMask, [])
this.webusb.trySetConfig(ConfigIndex.LOG_MASK, logMask, [])
}
}
43 changes: 5 additions & 38 deletions src/components/profile/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import { sectionIsGyroAxis, sectionIsHome } from 'lib/ctrl'
import { SectionIndex } from 'lib/ctrl'
import { Device } from 'lib/device'

const MAX_FETCH_ATTEMPTS = 3

@Component({
selector: 'app-profile',
standalone: true,
Expand Down Expand Up @@ -67,45 +65,14 @@ export class ProfileComponent {
}

async tryFetchNames() {
let attempts = 0
while(true) {
try {
const profiles = this.webusb.selectedDevice!.profiles
await profiles.fetchProfileNames()
break
} catch(error) {
attempts += 1
if (attempts <= MAX_FETCH_ATTEMPTS) console.warn(error)
else {
console.error(error)
break
}
}
}
const profiles = this.webusb.selectedDevice!.profiles
await profiles.fetchProfileNames()
}

async tryFetchProfile() {
const log = `tryFetchProfile ${this.profileIndex}`
console.log(log)
let attempts = 0
let success = false
while(true) {
try {
const profiles = this.webusb.selectedDevice!.profiles
await profiles.fetchProfile(this.profileIndex, false)
success = true
break
} catch(error) {
attempts += 1
if (attempts <= MAX_FETCH_ATTEMPTS) console.warn(error)
else {
console.error(error)
break
}
}
}
if (success) console.log(log, 'OK')
else console.log(log, 'FAILED')
console.log('tryFetchProfile', this.profileIndex)
const profiles = this.webusb.selectedDevice!.profiles
await profiles.fetchProfile(this.profileIndex, false)
}

getProfile() {
Expand Down
2 changes: 1 addition & 1 deletion src/components/profile/section.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ export class SectionComponent {
}

save = async () => {
await this.webusb.setSection(this.profileIndex, this.section)
await this.webusb.trySetSection(this.profileIndex, this.section)
}
}

Expand Down
14 changes: 7 additions & 7 deletions src/components/settings/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ export class SettingsComponent {

async load() {
const getConfig = async(index: ConfigIndex) => {
return (await this.webusb.getConfig(index)).presetIndex
return (await this.webusb.tryGetConfig(index)).presetIndex
}
this.longCalibration = !!await getConfig(ConfigIndex.LONG_CALIBRATION)
this.swapGyros = !!await getConfig(ConfigIndex.SWAP_GYROS)
this.invertTouchPolarity = !!await getConfig(ConfigIndex.TOUCH_INVERT_POLARITY)
const gyroUserOffset = await this.webusb.getConfig(ConfigIndex.GYRO_USER_OFFSET)
const gyroUserOffset = await this.webusb.tryGetConfig(ConfigIndex.GYRO_USER_OFFSET)
this.gyroUserOffsetX = gyroUserOffset.values[0]
this.gyroUserOffsetY = gyroUserOffset.values[1]
this.gyroUserOffsetZ = gyroUserOffset.values[2]
Expand All @@ -60,27 +60,27 @@ export class SettingsComponent {
}

async saveLongCalibration() {
await this.webusb.setConfig(ConfigIndex.LONG_CALIBRATION, +this.longCalibration, [])
await this.webusb.trySetConfig(ConfigIndex.LONG_CALIBRATION, +this.longCalibration, [])
}

async saveSwapGyros() {
await this.webusb.setConfig(ConfigIndex.SWAP_GYROS, +this.swapGyros, [])
await this.webusb.trySetConfig(ConfigIndex.SWAP_GYROS, +this.swapGyros, [])
}

async saveInvertTouchPolarity() {
await this.webusb.setConfig(ConfigIndex.TOUCH_INVERT_POLARITY, +this.invertTouchPolarity, [])
await this.webusb.trySetConfig(ConfigIndex.TOUCH_INVERT_POLARITY, +this.invertTouchPolarity, [])
}

async saveGyroUserOffset() {
await this.webusb.setConfig(ConfigIndex.GYRO_USER_OFFSET, 0, [
await this.webusb.trySetConfig(ConfigIndex.GYRO_USER_OFFSET, 0, [
this.gyroUserOffsetX,
this.gyroUserOffsetY,
this.gyroUserOffsetZ,
])
}

async saveThumbstickSmoothSamples() {
await this.webusb.setConfig(ConfigIndex.THUMBSTICK_SMOOTH_SAMPLES, +this.thumbstickSmoothSamples, [])
await this.webusb.trySetConfig(ConfigIndex.THUMBSTICK_SMOOTH_SAMPLES, +this.thumbstickSmoothSamples, [])
}

showDialogHelp(key: string) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/tune/tune.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export class TuneComponent {
}

async getPreset() {
console.log(`getPreset ${ConfigIndex[this.mode.configIndex]}`)
// console.log(`getPreset ${ConfigIndex[this.mode.configIndex]}`)
const tunes = this.webusb.selectedDevice!.tunes
const presetWithValues = await tunes.getPreset(this.mode.configIndex)
if (this.mode.url != 'protocol') {
Expand Down
83 changes: 58 additions & 25 deletions src/lib/device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ import {
const ADDR_IN = 3
const ADDR_OUT = 4
const TIMEOUT = 500
const STATUS_FETCH_MAX_ATTEMPTS = 10
const STATUS_FETCH_DELAY_ATTEMPT = 200

const FETCH_GENERIC_MAX_ATTEMPTS = 5
const FETCH_STATUS_MAX_ATTEMPTS = 10
const FETCH_STATUS_DELAY_ATTEMPT = 250

export class Device {
usbDevice: USBDevice
Expand Down Expand Up @@ -262,29 +264,6 @@ export class Device {
return Promise.race([responsePromise, timeout])
}

async tryGetStatus() {
console.log('tryGetStatus', this.getName())
await delay(100) // Increase the chances device is already connected.
let attempts = 0
while(true) {
try {
if (!this.isConnected) throw Error('tryGetStatus: Device not connected')
if (this.getFirmwareAsString() !== '0.0.0') break
const status = await this.getStatus()
this.handleCtrlStatusShare(status)
break
} catch(error) {
attempts += 1
if (attempts <= STATUS_FETCH_MAX_ATTEMPTS) console.warn(error)
else {
console.error(error)
break
}
await delay(STATUS_FETCH_DELAY_ATTEMPT)
}
}
}

async getConfig(index: ConfigIndex): Promise<PresetWithValues> {
this.pendingConfig = new AsyncSubject()
const ctrlOut = new CtrlConfigGet(index)
Expand Down Expand Up @@ -362,6 +341,60 @@ export class Device {
return Promise.race([responsePromise, timeout])
}

async tryGetStatus() {
console.log('tryGetStatus', this.getName())
await delay(100) // Increase the chances device is already connected.
let attempts = 0
while(true) {
try {
if (!this.isConnected) throw Error('tryGetStatus: Device not connected')
if (this.getFirmwareAsString() !== '0.0.0') break
const status = await this.getStatus()
this.handleCtrlStatusShare(status)
break
} catch(error) {
attempts += 1
if (attempts <= FETCH_STATUS_MAX_ATTEMPTS) console.warn(error)
else {
console.error(error)
break
}
await delay(FETCH_STATUS_DELAY_ATTEMPT)
}
}
}

async tryFetch(func: any) {
let attempts = 0
while(true) {
try {
return await func()
} catch(error) {
attempts += 1
if (attempts <= FETCH_GENERIC_MAX_ATTEMPTS) console.warn(error)
else throw error
}
}
}

async tryGetConfig(index: ConfigIndex) {
console.log('tryGetConfig', ConfigIndex[index])
return this.tryFetch(() => this.getConfig(index))
}

async trySetConfig(index: ConfigIndex, preset: number, values: number[]) {
console.log('tryGetConfig', ConfigIndex[index], preset, values)
return this.tryFetch(() => this.setConfig(index, preset, values))
}

async tryGetSection(profileIndex: number, sectionIndex: SectionIndex) {
return this.tryFetch(() => this.getSection(profileIndex, sectionIndex))
}

async trySetSection(profileIndex: number, section: CtrlSection) {
return this.tryFetch(() => this.setSection(profileIndex, section))
}

}

// Fake wireless device connected to dongle.
Expand Down
24 changes: 12 additions & 12 deletions src/lib/profiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class Profiles {
}

async fetchProfileName(index: number) {
const section = await this.device.getSection(index, SectionIndex.META)
const section = await this.device.tryGetSection(index, SectionIndex.META)
this.profiles[index].meta = section as CtrlSectionMeta
}

Expand All @@ -56,11 +56,11 @@ export class Profiles {
// Replace internal meta properties instead of the whole object, so Angular
// reference to the object is not lost. (Profile name is special because is
// linked in many dynamic UI elements).
const meta = await this.device.getSection(profileIndex, SectionIndex.META) as CtrlSectionMeta
const meta = await this.device.tryGetSection(profileIndex, SectionIndex.META) as CtrlSectionMeta
profile.meta.replaceContentsWith(meta)
// Buttons.
const getButton = async (sectionIndex: SectionIndex) => {
return await this.device.getSection(profileIndex, sectionIndex) as CtrlButton
return await this.device.tryGetSection(profileIndex, sectionIndex) as CtrlButton
}
profile.buttonA = await getButton(SectionIndex.A)
profile.buttonB = await getButton(SectionIndex.B)
Expand Down Expand Up @@ -103,22 +103,22 @@ export class Profiles {
profile.buttonRStickDR = await getButton(SectionIndex.RSTICK_DR)
profile.buttonRStickPush = await getButton(SectionIndex.RSTICK_PUSH)
// Rotary.
const rotaryUp = await this.device.getSection(profileIndex, SectionIndex.ROTARY_UP) as CtrlRotary
const rotaryDown = await this.device.getSection(profileIndex, SectionIndex.ROTARY_DOWN) as CtrlRotary
const rotaryUp = await this.device.tryGetSection(profileIndex, SectionIndex.ROTARY_UP) as CtrlRotary
const rotaryDown = await this.device.tryGetSection(profileIndex, SectionIndex.ROTARY_DOWN) as CtrlRotary
profile.rotaryUp = rotaryUp
profile.rotaryDown = rotaryDown
// Thumbstick mode.
const lStick = await this.device.getSection(profileIndex, SectionIndex.LSTICK_SETTINGS) as CtrlThumbstick
const rStick = await this.device.getSection(profileIndex, SectionIndex.RSTICK_SETTINGS) as CtrlThumbstick
const lStick = await this.device.tryGetSection(profileIndex, SectionIndex.LSTICK_SETTINGS) as CtrlThumbstick
const rStick = await this.device.tryGetSection(profileIndex, SectionIndex.RSTICK_SETTINGS) as CtrlThumbstick
profile.settingsLStick = lStick
profile.settingsRStick = rStick
// Gyro mode.
const gyro = await this.device.getSection(profileIndex, SectionIndex.GYRO_SETTINGS) as CtrlGyro
const gyro = await this.device.tryGetSection(profileIndex, SectionIndex.GYRO_SETTINGS) as CtrlGyro
profile.settingsGyro = gyro
// Gyro Axes.
profile.gyroX = await this.device.getSection(profileIndex, SectionIndex.GYRO_X) as CtrlGyroAxis
profile.gyroY = await this.device.getSection(profileIndex, SectionIndex.GYRO_Y) as CtrlGyroAxis
profile.gyroZ = await this.device.getSection(profileIndex, SectionIndex.GYRO_Z) as CtrlGyroAxis
profile.gyroX = await this.device.tryGetSection(profileIndex, SectionIndex.GYRO_X) as CtrlGyroAxis
profile.gyroY = await this.device.tryGetSection(profileIndex, SectionIndex.GYRO_Y) as CtrlGyroAxis
profile.gyroZ = await this.device.tryGetSection(profileIndex, SectionIndex.GYRO_Z) as CtrlGyroAxis
}

getProfile(profileIndex: number) {
Expand Down Expand Up @@ -157,7 +157,7 @@ export class Profiles {
sections = this.upgradeFrom097to100(sections)
for(let section of sections) {
console.log('Section from blob', section)
await this.device.setSection(profileIndex, section)
await this.device.trySetSection(profileIndex, section)
}
this.fetchProfile(profileIndex, true)
}
Expand Down
4 changes: 2 additions & 2 deletions src/lib/tunes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class Tunes {
}

async fetchPreset(configIndex: number) {
const presetWithValues = await this.device.getConfig(configIndex)
const presetWithValues = await this.device.tryGetConfig(configIndex)
this.presets[configIndex] = presetWithValues
}

Expand All @@ -31,7 +31,7 @@ export class Tunes {

async setPreset(configIndex: number, presetIndex: number, values: number[]) {
this.presets[configIndex] = {presetIndex, values}
return await this.device.setConfig(configIndex, presetIndex, values)
return await this.device.trySetConfig(configIndex, presetIndex, values)
}

async invalidatePresets() {
Expand Down
16 changes: 8 additions & 8 deletions src/services/webusb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,20 +233,20 @@ export class WebusbService {
return await this.selectedDevice!.sendProfileOverwrite(indexTo, indexFrom)
}

async getConfig(index: ConfigIndex): Promise<PresetWithValues> {
return await this.selectedDevice!.getConfig(index)
async tryGetConfig(index: ConfigIndex): Promise<PresetWithValues> {
return await this.selectedDevice!.tryGetConfig(index)
}

async setConfig(index: ConfigIndex, preset: number, values: number[]): Promise<number> {
return await this.selectedDevice!.setConfig(index, preset, values)
async trySetConfig(index: ConfigIndex, preset: number, values: number[]): Promise<number> {
return await this.selectedDevice!.trySetConfig(index, preset, values)
}

async getSection(profileIndex: number, sectionIndex: SectionIndex): Promise<CtrlSection> {
return await this.selectedDevice!.getSection(profileIndex, sectionIndex)
async tryGetSection(profileIndex: number, sectionIndex: SectionIndex): Promise<CtrlSection> {
return await this.selectedDevice!.tryGetSection(profileIndex, sectionIndex)
}

async setSection( profileIndex: number, section: CtrlSection) {
return await this.selectedDevice!.setSection(profileIndex, section)
async trySetSection( profileIndex: number, section: CtrlSection) {
return await this.selectedDevice!.trySetSection(profileIndex, section)
}

getProfiles() {
Expand Down