Skip to content

Commit de9a478

Browse files
authored
Refactor Input System [AARD-1997] (#1219)
2 parents d2d2aca + 7e04477 commit de9a478

24 files changed

+933
-496
lines changed

fission/src/systems/input/DefaultInputs.ts

Lines changed: 163 additions & 284 deletions
Large diffs are not rendered by default.

fission/src/systems/input/InputSchemeManager.ts

Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,28 @@
11
import { random } from "@/util/Random"
22
import PreferencesSystem from "../preferences/PreferencesSystem"
33
import DefaultInputs from "./DefaultInputs"
4-
import InputSystem, { AxisInput, ButtonInput, Input } from "./InputSystem"
4+
import InputSystem, { AxisInput, ButtonInput, Input, KeyDescriptor } from "./InputSystem"
5+
import { DriveType } from "@/systems/simulation/behavior/Behavior.ts"
6+
import SynthesisBrain from "@/systems/simulation/synthesis_brain/SynthesisBrain.ts"
57

68
export type InputScheme = {
79
schemeName: string
810
descriptiveName: string
911
customized: boolean
1012
usesGamepad: boolean
1113
usesTouchControls: boolean
14+
supportedDrivetrains: DriveType[]
1215
inputs: Input[]
1316
}
1417

18+
export enum InputSchemeUseType {
19+
IN_USE, // bound to a robot
20+
CONFLICT, // has keys overlapping with a bound scheme
21+
AVAILABLE, // no overlap and not bound
22+
}
23+
24+
export type InputSchemeAvailability = { scheme: InputScheme; status: InputSchemeUseType; conflicts_with_names?: string }
25+
1526
class InputSchemeManager {
1627
// References to the current custom schemes to avoid parsing every time they are requested
1728
private static _customSchemes: InputScheme[] | undefined
@@ -85,31 +96,72 @@ class InputSchemeManager {
8596

8697
// Add default schemes if they have not been customized
8798
this.defaultInputSchemes.forEach(defaultScheme => {
88-
if (
89-
allSchemes.some(s => {
90-
return s.schemeName === defaultScheme.schemeName
91-
})
92-
)
93-
return
94-
99+
if (allSchemes.some(s => s.schemeName === defaultScheme.schemeName)) return
95100
allSchemes.push(defaultScheme)
96101
})
97102

98103
return allSchemes
99104
}
100105

101106
/** Creates an array of every input scheme that is not currently in use by a robot */
102-
public static get availableInputSchemes(): InputScheme[] {
107+
private static get _availableInputSchemes(): InputSchemeAvailability[] {
103108
const allSchemes = this.allInputSchemes
104109

105-
// Remove schemes that are in use
106-
const schemesInUse = Array.from(InputSystem.brainIndexSchemeMap.values())
107-
return allSchemes.filter(scheme => !schemesInUse.includes(scheme))
110+
// Remove schemes that have conflicts
111+
const usedKeyMap = new Map<KeyDescriptor, string[]>()
112+
const result: Record<string, InputSchemeAvailability> = {}
113+
for (const scheme of InputSystem.brainIndexSchemeMap.values()) {
114+
result[scheme.schemeName] = { scheme, status: InputSchemeUseType.IN_USE }
115+
scheme?.inputs?.forEach(input => {
116+
input.keysUsed
117+
.filter(key => key != null)
118+
.forEach(key => {
119+
const entry = usedKeyMap.get(key)
120+
if (entry != null) {
121+
entry.push(scheme.schemeName)
122+
} else {
123+
usedKeyMap.set(key, [scheme.schemeName])
124+
}
125+
})
126+
})
127+
}
128+
129+
allSchemes.forEach(scheme => {
130+
const conflictingSchemes = scheme.inputs.flatMap(input =>
131+
input.keysUsed.flatMap(key => usedKeyMap.get(key) ?? [])
132+
)
133+
console.log(conflictingSchemes)
134+
if (conflictingSchemes.length > 0) {
135+
result[scheme.schemeName] ??= {
136+
scheme,
137+
status: InputSchemeUseType.CONFLICT,
138+
conflicts_with_names: [...new Set(conflictingSchemes)].join(", "),
139+
}
140+
} else {
141+
result[scheme.schemeName] = { scheme, status: InputSchemeUseType.AVAILABLE }
142+
}
143+
})
144+
return Object.values(result)
145+
}
146+
147+
/** Creates an array of every input scheme that is not currently in use by a robot */
148+
public static availableInputSchemesByType(driveType?: DriveType): InputSchemeAvailability[] {
149+
const allSchemes = this._availableInputSchemes
150+
if (driveType == null) {
151+
return allSchemes
152+
}
153+
return allSchemes.filter(entry => entry.scheme.supportedDrivetrains.includes(driveType))
154+
}
155+
156+
/** Creates an array of every input scheme that is not currently in use by a robot */
157+
public static availableInputSchemesByBrain(brainIndex: number): InputSchemeAvailability[] {
158+
const driveType = SynthesisBrain.brainIndexMap.get(brainIndex)?.driveType
159+
return this.availableInputSchemesByType(driveType)
108160
}
109161

110162
/** @returns a random available robot name */
111163
public static get randomAvailableName(): string {
112-
const usedNames = this.availableInputSchemes.map(s => s.schemeName)
164+
const usedNames = this.allInputSchemes.map(s => s.schemeName)
113165

114166
const randomName = () => {
115167
const index = Math.floor(random() * DefaultInputs.NAMES.length)

0 commit comments

Comments
 (0)