import ConstNode from "../core/ConstNode.js"; import Node from "../core/Node.js"; import NodeBuilder from "../core/NodeBuilder.js"; import StackNode from "../core/StackNode.js"; export interface NodeElements { toGlobal: (node: Node) => Node; append: typeof append; toColor: typeof color; toFloat: typeof float; toInt: typeof int; toUint: typeof uint; toBool: typeof bool; toVec2: typeof vec2; toIvec2: typeof ivec2; toUvec2: typeof uvec2; toBvec2: typeof bvec2; toVec3: typeof vec3; toIvec3: typeof ivec3; toUvec3: typeof uvec3; toBvec3: typeof bvec3; toVec4: typeof vec4; toIvec4: typeof ivec4; toUvec4: typeof uvec4; toBvec4: typeof bvec4; toMat2: typeof mat2; toMat3: typeof mat3; toMat4: typeof mat4; element: typeof element; convert: typeof convert; } export function addMethodChaining(name: string, nodeElement: unknown): void; export type SwizzleCharacter = "x" | "y" | "z" | "w" | "r" | "g" | "b" | "a" | "s" | "t" | "p" | "q"; export type SwizzleOption = Exclude< | `${SwizzleCharacter}` | `${SwizzleCharacter}${SwizzleCharacter}` | `${SwizzleCharacter}${SwizzleCharacter}${SwizzleCharacter}` | `${SwizzleCharacter}${SwizzleCharacter}${SwizzleCharacter}${SwizzleCharacter}`, "abs" | "sqrt" >; export type Swizzable = & T & { [Key in SwizzleOption | number]: ShaderNodeObject; } & { [Key in SwizzleOption as `flip${Uppercase}`]: () => ShaderNodeObject; }; export type ShaderNodeObject = & T & { [Key in keyof NodeElements]: T extends { [K in Key]: infer M } ? M : NodeElements[Key] extends (node: T, ...args: infer Args) => infer R ? (...args: Args) => R : never; } & { [Key in keyof NodeElements as `${Key}Assign`]: T extends { [K in Key]: infer M } ? M : NodeElements[Key] extends (node: T, ...args: infer Args) => unknown ? (...args: Args) => ShaderNodeObject : never; } & Swizzable; /** anything that can be passed to {@link nodeObject} and returns a proxy */ export type NodeRepresentation = number | boolean | Node | ShaderNodeObject; /** anything that can be passed to {@link nodeObject} */ export type NodeObjectOption = NodeRepresentation | string; // same logic as in ShaderNodeObject: number,boolean,node->ShaderNodeObject, otherwise do nothing export type NodeObject = T extends Node ? ShaderNodeObject : T extends number | boolean ? ShaderNodeObject> : T; // opposite of NodeObject: node -> node|ShaderNodeObject|boolean|number, otherwise do nothing type Proxied = T extends Node ? NodeRepresentation : T; // https://github.com/microsoft/TypeScript/issues/42435#issuecomment-765557874 export type ProxiedTuple = [...{ [index in keyof T]: Proxied }]; export type ProxiedObject = { [index in keyof T]: Proxied }; type RemoveTail = T extends [unknown, ...infer X] ? X : []; type RemoveHeadAndTail = T extends [unknown, ...infer X, unknown] ? X : []; /** * Temporary type to save signatures of 4 constructors. Each element may be tuple or undefined. * * We use an object instead of tuple or union as it makes stuff easier, especially in Typescript 4.0. */ interface Construtors< A extends undefined | [...unknown[]], B extends undefined | [...unknown[]], C extends undefined | [...unknown[]], D extends undefined | [...unknown[]], > { a: A; b: B; c: C; d: D; } /** * Returns all constructors * * * */ type OverloadedConstructorsOf = T extends { new(...args: infer A1): unknown; new(...args: infer A2): unknown; new(...args: infer A3): unknown; new(...args: infer A4): unknown; } ? Construtors : T extends { new(...args: infer A1): unknown; new(...args: infer A2): unknown; new(...args: infer A3): unknown; } ? Construtors : T extends { new(...args: infer A1): unknown; new(...args: infer A2): unknown; } ? Construtors : T extends new(...args: infer A) => unknown ? Construtors : Construtors; type AnyConstructors = Construtors; /** * Returns all constructors where the first paramter is assignable to given "scope" */ // eslint-disable-next-line @typescript-eslint/consistent-type-definitions type FilterConstructorsByScope = { a: S extends T["a"][0] ? T["a"] : undefined; b: S extends T["b"][0] ? T["b"] : undefined; c: S extends T["c"][0] ? T["c"] : undefined; d: S extends T["d"][0] ? T["d"] : undefined; }; /** * "flattens" the tuple into an union type */ type ConstructorUnion = | Exclude | Exclude | Exclude | Exclude; /** * Extract list of possible scopes - union of the first paramter * of all constructors, should it be string */ type ExtractScopes = | (T["a"][0] extends string ? T["a"][0] : never) | (T["b"][0] extends string ? T["b"][0] : never) | (T["c"][0] extends string ? T["c"][0] : never) | (T["d"][0] extends string ? T["d"][0] : never); type GetConstructorsByScope = ConstructorUnion, S>>; type GetConstructors = ConstructorUnion>; type GetPossibleScopes = ExtractScopes>; export type ConvertType = (...params: unknown[]) => ShaderNodeObject; type NodeArray = { [index in keyof T]: NodeObject }; type NodeObjects = { [key in keyof T]: T[key] extends NodeObjectOption ? NodeObject : T[key] }; type ConstructedNode = T extends new(...args: any[]) => infer R ? (R extends Node ? R : never) : never; export type NodeOrType = Node | string; export const getConstNodeType: (value: NodeOrType) => string | null; export class ShaderNode { constructor(jsFunc: (inputs: NodeObjects, builder: NodeBuilder) => NodeRepresentation); call: ( inputs: { [key in keyof T]: T[key] extends NodeRepresentation ? ShaderNodeObject | Node : T[key] }, builder?: NodeBuilder, ) => ShaderNodeObject; } export function nodeObject(obj: T): NodeObject; export function nodeObjects(obj: T): NodeObjects; export function nodeArray(obj: readonly [...T]): NodeArray; export function nodeProxy( nodeClass: T, ): (...params: ProxiedTuple>) => ShaderNodeObject>; export function nodeProxy>( nodeClass: T, scope: S, ): (...params: ProxiedTuple>>) => ShaderNodeObject>; export function nodeProxy>( nodeClass: T, scope: S, factor: NodeObjectOption, ): (...params: ProxiedTuple>>) => ShaderNodeObject>; export function nodeImmutable( nodeClass: T, ...params: ProxiedTuple> ): ShaderNodeObject>; export function Fn>(jsFunc: () => R): () => R; export function Fn>( jsFunc: (args: T) => R, ): (...args: ProxiedTuple) => R; export function Fn>( jsFunc: (args: T) => R, ): (args: ProxiedObject) => R; /** * @deprecated tslFn() has been renamed to Fn() */ export function tslFn>(jsFunc: () => R): () => R; /** * @deprecated tslFn() has been renamed to Fn() */ export function tslFn>( jsFunc: (args: T) => R, ): (...args: ProxiedTuple) => R; /** * @deprecated tslFn() has been renamed to Fn() */ export function tslFn>( jsFunc: (args: T) => R, ): (args: ProxiedObject) => R; export const setCurrentStack: (stack: StackNode | null) => void; export const getCurrentStack: () => StackNode | null; export const If: (boolNode: Node, method: () => void) => StackNode; export function append(node: Node): Node; export const color: ConvertType; export const float: ConvertType; export const int: ConvertType; export const uint: ConvertType; export const bool: ConvertType; export const vec2: ConvertType; export const ivec2: ConvertType; export const uvec2: ConvertType; export const bvec2: ConvertType; export const vec3: ConvertType; export const ivec3: ConvertType; export const uvec3: ConvertType; export const bvec3: ConvertType; export const vec4: ConvertType; export const ivec4: ConvertType; export const uvec4: ConvertType; export const bvec4: ConvertType; export const mat2: ConvertType; export const mat3: ConvertType; export const mat4: ConvertType; export const string: (value?: string) => ShaderNodeObject>; export const arrayBuffer: (value: ArrayBuffer) => ShaderNodeObject>; export const element: (node: NodeRepresentation, indexNode: NodeRepresentation) => ShaderNodeObject; export const convert: (node: NodeRepresentation, types: string) => ShaderNodeObject;