@@ -1,4 +1,4 @@
|
||||
import type * as Godot from "godot"
|
||||
import Godot from "godot"
|
||||
import * as React from "react"
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ export type Props<T extends Godot.Node<Godot.NodePathMap>> = {
|
||||
readonly ref?: React.RefObject<T | null>
|
||||
} & {
|
||||
// biome-ignore lint/complexity/noBannedTypes: using Function here is completely fine
|
||||
[K in keyof T as T[K] extends Function ? never : K]?: T[K]
|
||||
[K in keyof T as T[K] extends Function | Godot.Signal ? never : K]?: T[K]
|
||||
}
|
||||
|
||||
export interface Prototype<T extends Godot.Node<Godot.NodePathMap>> {
|
||||
@@ -36,3 +36,28 @@ export const make = <T extends Godot.Node<Godot.NodePathMap>>(
|
||||
),
|
||||
Prototype,
|
||||
)
|
||||
|
||||
export declare namespace useSignal {
|
||||
export type SignalNames<T extends Godot.Node<Godot.NodePathMap>> = {
|
||||
[K in keyof T & string]: T[K] extends Godot.Signal ? K : never
|
||||
}[keyof T & string]
|
||||
|
||||
export type Function<T extends Godot.Node<Godot.NodePathMap>, N extends useSignal.SignalNames<T>> = (
|
||||
T[N] extends Godot.Signal<infer F>
|
||||
? (this: T, ...args: Parameters<F>) => ReturnType<F>
|
||||
: never
|
||||
)
|
||||
}
|
||||
|
||||
export const useSignal = <T extends Godot.Node<Godot.NodePathMap>, N extends useSignal.SignalNames<T>>(
|
||||
ref: React.RefObject<T | null>,
|
||||
name: N,
|
||||
f: useSignal.Function<T, N>,
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: "f" is non-reactive
|
||||
): void => React.useEffect(() => {
|
||||
if (!ref.current) return
|
||||
const signal = ref.current[name] as Godot.Signal
|
||||
const callable = Godot.Callable.create(ref.current, f)
|
||||
signal.connect(callable)
|
||||
return () => { signal.disconnect(callable) }
|
||||
}, [ref.current])
|
||||
|
||||
Reference in New Issue
Block a user