diff --git a/src/app.ts b/src/app.ts index 1df70c850..01cda33ba 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,7 +1,6 @@ // everything related to canvas, game loop and input import type { - KaboomCtx, Cursor, Key, MouseButton, @@ -19,6 +18,7 @@ import { import { EventHandler, EventController, + overload2, } from "./utils" import GAMEPAD_MAP from "./gamepad.json" @@ -347,70 +347,47 @@ export default (opt: { } // input callbacks - const onKeyDown = ((key, action) => { - if (typeof key === "function") { - return state.events.on("keyDown", key) - } else if (typeof key === "string" && typeof action === "function") { - return state.events.on("keyDown", (k) => k === key && action(key)) - } - }) as KaboomCtx["onKeyDown"] + const onKeyDown = overload2((action: (key: Key) => void) => { + return state.events.on("keyDown", action) + }, (key: Key, action: (key: Key) => void) => { + return state.events.on("keyDown", (k) => k === key && action(key)) + }) - const onKeyPress = ((key, action) => { - if (typeof key === "function") { - return state.events.on("keyPress", key) - } else if (typeof key === "string" && typeof action === "function") { - return state.events.on("keyPress", (k) => k === key && action(key)) - } - }) as KaboomCtx["onKeyPress"] + const onKeyPress = overload2((action: (key: Key) => void) => { + return state.events.on("keyPress", action) + }, (key: Key, action: (key: Key) => void) => { + return state.events.on("keyPress", (k) => k === key && action(key)) + }) - const onKeyPressRepeat = ((key, action) => { - if (typeof key === "function") { - return state.events.on("keyPressRepeat", key) - } else if (typeof key === "string" && typeof action === "function") { - return state.events.on("keyPressRepeat", (k) => k === key && action(key)) - } - }) as KaboomCtx["onKeyPressRepeat"] + const onKeyPressRepeat = overload2((action: (key: Key) => void) => { + return state.events.on("keyPressRepeat", action) + }, (key: Key, action: (key: Key) => void) => { + return state.events.on("keyPressRepeat", (k) => k === key && action(key)) + }) - const onKeyRelease = ((key, action) => { - if (typeof key === "function") { - return state.events.on("keyRelease", key) - } else if (typeof key === "string" && typeof action === "function") { - return state.events.on("keyRelease", (k) => k === key && action(key)) - } - }) as KaboomCtx["onKeyRelease"] - - function onMouseDown( - mouse: MouseButton | ((m: MouseButton) => void), - action?: (m: MouseButton) => void, - ): EventController { - if (typeof mouse === "function") { - return state.events.on("mouseDown", (m) => mouse(m)) - } else { - return state.events.on("mouseDown", (m) => m === mouse && action(m)) - } - } + const onKeyRelease = overload2((action: (key: Key) => void) => { + return state.events.on("keyRelease", action) + }, (key: Key, action: (key: Key) => void) => { + return state.events.on("keyRelease", (k) => k === key && action(key)) + }) - function onMousePress( - mouse: MouseButton | ((m: MouseButton) => void), - action?: (m: MouseButton) => void, - ): EventController { - if (typeof mouse === "function") { - return state.events.on("mousePress", (m) => mouse(m)) - } else { - return state.events.on("mousePress", (m) => m === mouse && action(m)) - } - } + const onMouseDown = overload2((action: (m: MouseButton) => void) => { + return state.events.on("mouseDown", (m) => action(m)) + }, (mouse: MouseButton, action: (m: MouseButton) => void) => { + return state.events.on("mouseDown", (m) => m === mouse && action(m)) + }) - function onMouseRelease( - mouse: MouseButton | ((m: MouseButton) => void), - action?: (m: MouseButton) => void, - ): EventController { - if (typeof mouse === "function") { - return state.events.on("mouseRelease", (m) => mouse(m)) - } else { - return state.events.on("mouseRelease", (m) => m === mouse && action(m)) - } - } + const onMousePress = overload2((action: (m: MouseButton) => void) => { + return state.events.on("mousePress", (m) => action(m)) + }, (mouse: MouseButton, action: (m: MouseButton) => void) => { + return state.events.on("mousePress", (m) => m === mouse && action(m)) + }) + + const onMouseRelease = overload2((action: (m: MouseButton) => void) => { + return state.events.on("mouseRelease", (m) => action(m)) + }, (mouse: MouseButton, action: (m: MouseButton) => void) => { + return state.events.on("mouseRelease", (m) => m === mouse && action(m)) + }) function onMouseMove(f: (pos: Vec2, dpos: Vec2) => void): EventController { return state.events.on("mouseMove", () => f(mousePos(), mouseDeltaPos())) diff --git a/src/utils.ts b/src/utils.ts index bad6fad8c..f70a43f3b 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -178,6 +178,44 @@ export function downloadBlob(filename: string, blob: Blob) { export const isDataURL = (str: string) => str.match(/^data:\w+\/\w+;base64,.+/) export const getExt = (p: string) => p.split(".").pop() +type Func = (...args: any[]) => any + +export function overload2(fn1: A, fn2: B): A & B { + return ((...args) => { + const al = args.length + if (al === fn1.length) return fn1(...args) + if (al === fn2.length) return fn2(...args) + }) as A & B +} + +export function overload3< + A extends Func, + B extends Func, + C extends Func, +>(fn1: A, fn2: B, fn3: C): A & B & C { + return ((...args) => { + const al = args.length + if (al === fn1.length) return fn1(...args) + if (al === fn2.length) return fn2(...args) + if (al === fn3.length) return fn3(...args) + }) as A & B & C +} + +export function overload4< + A extends Func, + B extends Func, + C extends Func, + D extends Func, +>(fn1: A, fn2: B, fn3: C, fn4: D): A & B & C & D { + return ((...args) => { + const al = args.length + if (al === fn1.length) return fn1(...args) + if (al === fn2.length) return fn2(...args) + if (al === fn3.length) return fn3(...args) + if (al === fn4.length) return fn4(...args) + }) as A & B & C & D +} + export const uid = (() => { let id = 0 return () => id++