Skip to content

Commit

Permalink
Merge pull request #72 from inputlabs/webusb-better-async
Browse files Browse the repository at this point in the history
Max re-fetch attempts, Detect device change
  • Loading branch information
marcos-diaz authored Feb 7, 2025
2 parents ecd0713 + 601ecc5 commit b45bb1c
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 25 deletions.
6 changes: 3 additions & 3 deletions src/components/profile/profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
<div class='icon'>
<span class='material'>settings_remote</span>
</div>
<div>Select wireless connected</div>
<div>device to modify profiles</div>
<div>Select a wireless device</div>
<div>to modify profiles</div>
</div>

<div class="template" *ngIf='webusb.isController()'>
<div class="template" *ngIf='webusb.isConnectedRaw() && webusb.isController()'>
<div class="crop_h">
<div class='crop_v'>
<!-- BUTTONS -->
Expand Down
77 changes: 60 additions & 17 deletions src/components/profile/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ import { CtrlSection, CtrlSectionMeta, CtrlButton, CtrlRotary, CtrlGyroAxis } fr
import { ThumbstickMode, GyroMode } from 'lib/ctrl'
import { sectionIsGyroAxis, sectionIsHome } from 'lib/ctrl'
import { SectionIndex } from 'lib/ctrl'
import { Device } from 'lib/device'
import { Profiles } from 'lib/profiles'
import { delay } from 'lib/delay'

const MAX_FETCH_ATTEMPTS = 3

@Component({
selector: 'app-profile',
standalone: true,
Expand All @@ -28,7 +31,7 @@ import { delay } from 'lib/delay'
styleUrls: ['./profile.sass']
})
export class ProfileComponent {
profiles: Profiles
device?: Device
profileIndex: number = 0
selected: CtrlSection = new CtrlSectionMeta(0, SectionIndex.META, '', 0, 0, 0, 0)
// Template aliases.
Expand All @@ -42,11 +45,25 @@ export class ProfileComponent {
activatedRoute.data.subscribe((data) => {
this.profileIndex = data['index']
})
this.profiles = this.webusb.selectedDevice!.profiles
}

ngAfterViewInit() {
this.init()
// ngAfterViewInit() {
// this.init()
// }

ngAfterViewChecked() {
// Refresh data if device changes.
if (!this.webusb.selectedDevice) return
if (!this.webusb.isController()) return
if (!this.device) {
this.device = this.webusb.selectedDevice!
this.init()
return
}
if (this.device != this.webusb.selectedDevice) {
this.device = this.webusb.selectedDevice!
this.init()
}
}

async init() {
Expand All @@ -55,43 +72,69 @@ export class ProfileComponent {
await delay(100)
}
// Fetch profile names, retry if it fails.
await this.tryFetchNames()
// Selected early to avoid flickering.
this.setSelectedMeta()
// Fetch profile sections, retry if it fails.
await this.tryFetchProfile()
// Selected again to connect Angular 2-way binding correctly.
this.setSelectedMeta()
}

async tryFetchNames() {
let attempts = 0
while(true) {
try {
await this.profiles.fetchProfileNames()
const profiles = this.webusb.selectedDevice!.profiles
await profiles.fetchProfileNames()
break
} catch(error) {
console.warn(error)
attempts += 1
if (attempts <= MAX_FETCH_ATTEMPTS) console.warn(error)
else {
console.error(error)
break
}
}
}
// Selected early to avoid flickering.
this.setSelectedMeta()
// Fetch profile sections, retry if it fails.
}

async tryFetchProfile() {
let attempts = 0
while(true) {
try {
await this.profiles.fetchProfile(this.profileIndex, false)
const profiles = this.webusb.selectedDevice!.profiles
await profiles.fetchProfile(this.profileIndex, false)
break
} catch(error) {
console.warn(error)
attempts += 1
if (attempts <= MAX_FETCH_ATTEMPTS) console.warn(error)
else {
console.error(error)
break
}
}
}
// Selected again to connect Angular 2-way binding correctly.
this.setSelectedMeta()
}

getProfile() {
return this.webusb.selectedDevice!.profiles.getProfile(this.profileIndex)
}

setSelected(section: CtrlSection) {
this.selected = section
}

setSelectedMeta() {
this.selected = this.profiles.getProfile(this.profileIndex).meta
this.selected = this.getProfile().meta
}

setSelectedThumbstick() {
this.selected = this.profiles.getProfile(this.profileIndex).thumbstick
this.selected = this.getProfile().thumbstick
}

setSelectedGyro() {
this.selected = this.profiles.getProfile(this.profileIndex).gyro
this.selected = this.getProfile().gyro
}

getSelected() {
Expand Down Expand Up @@ -119,7 +162,7 @@ export class ProfileComponent {
}

getMappings() {
const profile = this.profiles.profiles[this.profileIndex]
const profile = this.getProfile()
const thumbstick = profile.thumbstick
const gyro = profile.gyro
const rotaryUp = this.getMapping(profile.rotaryUp)
Expand Down
2 changes: 1 addition & 1 deletion src/components/sidebar/sidebar.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
</a>
</div>

<div *ngIf='this.isProfiles() && webusb.isController()'>
<div *ngIf='this.isProfiles()'>
<a routerLink='profiles/0' routerLinkActive='active'>
<app-led [colorOff]='ledColorOff' [dotsize]='16' [on]='getProfileLed(0)'/>
<div>{{getProfileName(0)}}</div>
Expand Down
1 change: 1 addition & 0 deletions src/components/sidebar/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export class SidebarComponent {
}

getProfileName(index: number) {
if (!this.webusb.isController()) return ''
let profiles = this.webusb.getProfiles()
if (!profiles) return ''
return profiles.getProfile(index).meta.name
Expand Down
9 changes: 5 additions & 4 deletions src/lib/device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {

const ADDR_IN = 3
const ADDR_OUT = 4
const TIMEOUT = 500

export class Device {
usbDevice: USBDevice
Expand Down Expand Up @@ -189,7 +190,7 @@ export class Device {
})
})
const timeoutMessage = `Timeout in getConfig ${ConfigIndex[index]}`
const timeout = timeoutPromise(200, timeoutMessage) as Promise<PresetWithValues>
const timeout = timeoutPromise(TIMEOUT, timeoutMessage) as Promise<PresetWithValues>
return Promise.race([responsePromise, timeout])
}

Expand All @@ -205,7 +206,7 @@ export class Device {
})
})
const timeoutMessage = `Timeout in setConfig ${ConfigIndex[index]}`
const timeout = timeoutPromise(200, timeoutMessage) as Promise<number>
const timeout = timeoutPromise(TIMEOUT, timeoutMessage) as Promise<number>
return Promise.race([responsePromise, timeout])
}

Expand All @@ -224,7 +225,7 @@ export class Device {
})
})
const timeoutMessage = `Timeout in getSection ${SectionIndex[sectionIndex]}`
const timeout = timeoutPromise(200, timeoutMessage) as Promise<CtrlSection>
const timeout = timeoutPromise(TIMEOUT, timeoutMessage) as Promise<CtrlSection>
return Promise.race([responsePromise, timeout])
}

Expand All @@ -243,7 +244,7 @@ export class Device {
})
})
const timeoutMessage = `Timeout in setSection`
const timeout = timeoutPromise(200, timeoutMessage)
const timeout = timeoutPromise(TIMEOUT, timeoutMessage)
return Promise.race([responsePromise, timeout])
}

Expand Down

0 comments on commit b45bb1c

Please sign in to comment.