@benev/nubs
Version:
user-input system for web games
74 lines (62 loc) • 1.89 kB
text/typescript
import {StateGetter, StateSetter} from "@chasemoskal/magical/x/view/types.js"
import {Waiting} from "../types/waiting.js"
import {NubCauseEvent} from "../../../../../events/cause.js"
import {Bindings} from "../../../../context/bindings/types/bindings.js"
import {compareStringArrays} from "../../../../../tools/compare-string-arrays.js"
export function controlKeybindAssignments({
getMode,
getWaiting,
setWaiting,
getShowDialog,
setShowDialog,
setKeysPressed,
getKeysPressed,
getBindingsDraft,
setBindingsDraft,
}: {
getMode: () => string
getBindingsDraft: () => Bindings
setBindingsDraft: (b: Bindings) => void
getShowDialog: StateGetter<boolean>
setShowDialog: StateSetter<boolean>
getKeysPressed: StateGetter<string[]>
setKeysPressed: StateSetter<string[]>
getWaiting: StateGetter<Waiting | undefined>
setWaiting: StateSetter<undefined | Waiting>
}) {
const key_set = new Set<string>()
return (event: NubCauseEvent) => {
const waiting = getWaiting()
const is_dialog_shown = getShowDialog()
if (waiting && event.detail.kind === "key") {
const {cause, pressed} = event.detail
const {effect, keyIndex} = waiting
if (pressed) {
const isEscapeKey = cause === "Escape"
if (is_dialog_shown) {
if (isEscapeKey) {
setShowDialog(false)
setWaiting(undefined)
key_set.clear()
}
else {
key_set.add(cause)
setKeysPressed(Array.from(key_set))
}
}
const mode = getMode()
const bindings = getBindingsDraft()
const combo_cause = getKeysPressed()
const keybinds = bindings.modes[mode].key[effect]
const redundant = keybinds.some(c => compareStringArrays(c, combo_cause))
if (!redundant) {
if (isEscapeKey)
keybinds.splice(keyIndex, 1)
else
keybinds[keyIndex] = combo_cause
setBindingsDraft(bindings)
}
}
}
}
}