glre 0.48.0 → 0.49.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -18
- package/dist/addons.d.ts +57 -53
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +57 -53
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/native.d.ts +57 -53
- package/dist/node.cjs +15 -15
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.ts +60 -56
- package/dist/node.js +15 -15
- package/dist/node.js.map +1 -1
- package/dist/react.d.ts +57 -53
- package/dist/solid.d.ts +57 -53
- package/package.json +1 -1
- package/src/index.ts +4 -1
- package/src/node/create.ts +10 -9
- package/src/node/scope.ts +3 -15
- package/src/node/types.ts +20 -43
- package/src/node/utils/const.ts +27 -10
- package/src/node/utils/index.ts +15 -8
- package/src/node/utils/infer.ts +17 -10
package/dist/react.d.ts
CHANGED
|
@@ -29,8 +29,54 @@ declare const TYPE_MAPPING: {
|
|
|
29
29
|
readonly struct: "struct";
|
|
30
30
|
};
|
|
31
31
|
declare const CONSTANTS: (keyof typeof TYPE_MAPPING)[];
|
|
32
|
+
declare const SWIZZLE_BASE_MAP: {
|
|
33
|
+
readonly float: "float";
|
|
34
|
+
readonly vec2: "float";
|
|
35
|
+
readonly vec3: "float";
|
|
36
|
+
readonly vec4: "float";
|
|
37
|
+
readonly int: "int";
|
|
38
|
+
readonly ivec2: "int";
|
|
39
|
+
readonly ivec3: "int";
|
|
40
|
+
readonly ivec4: "int";
|
|
41
|
+
readonly uint: "uint";
|
|
42
|
+
readonly uvec2: "uint";
|
|
43
|
+
readonly uvec3: "uint";
|
|
44
|
+
readonly uvec4: "uint";
|
|
45
|
+
readonly bool: "bool";
|
|
46
|
+
readonly bvec2: "bool";
|
|
47
|
+
readonly bvec3: "bool";
|
|
48
|
+
readonly bvec4: "bool";
|
|
49
|
+
};
|
|
50
|
+
declare const SWIZZLE_RESULT_MAP: {
|
|
51
|
+
float: {
|
|
52
|
+
readonly 1: "float";
|
|
53
|
+
readonly 2: "vec2";
|
|
54
|
+
readonly 3: "vec3";
|
|
55
|
+
readonly 4: "vec4";
|
|
56
|
+
readonly 9: "mat3";
|
|
57
|
+
readonly 16: "mat4";
|
|
58
|
+
};
|
|
59
|
+
int: {
|
|
60
|
+
readonly 1: "int";
|
|
61
|
+
readonly 2: "ivec2";
|
|
62
|
+
readonly 3: "ivec3";
|
|
63
|
+
readonly 4: "ivec4";
|
|
64
|
+
};
|
|
65
|
+
uint: {
|
|
66
|
+
readonly 1: "uint";
|
|
67
|
+
readonly 2: "uvec2";
|
|
68
|
+
readonly 3: "uvec3";
|
|
69
|
+
readonly 4: "uvec4";
|
|
70
|
+
};
|
|
71
|
+
bool: {
|
|
72
|
+
readonly 1: "bool";
|
|
73
|
+
readonly 2: "bvec2";
|
|
74
|
+
readonly 3: "bvec3";
|
|
75
|
+
readonly 4: "bvec4";
|
|
76
|
+
};
|
|
77
|
+
};
|
|
32
78
|
declare const OPERATORS: {
|
|
33
|
-
readonly not: "";
|
|
79
|
+
readonly not: "!";
|
|
34
80
|
readonly add: "+";
|
|
35
81
|
readonly sub: "-";
|
|
36
82
|
readonly mul: "*";
|
|
@@ -78,7 +124,7 @@ type Operators = (typeof OPERATOR_KEYS)[number];
|
|
|
78
124
|
*/
|
|
79
125
|
interface FnLayout {
|
|
80
126
|
name: string;
|
|
81
|
-
type
|
|
127
|
+
type?: C | 'auto';
|
|
82
128
|
inputs?: Array<{
|
|
83
129
|
name: string;
|
|
84
130
|
type: C | 'auto';
|
|
@@ -117,6 +163,15 @@ interface NodeContext {
|
|
|
117
163
|
structStructFields: Map<string, StructFields>;
|
|
118
164
|
};
|
|
119
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* swizzle
|
|
168
|
+
*/
|
|
169
|
+
type _SwizzleLength<A extends string> = A extends `${infer _}${infer A}` ? A extends '' ? 1 : A extends `${infer _}${infer B}` ? B extends '' ? 2 : B extends `${infer _}${infer C}` ? C extends '' ? 3 : 4 : never : never : never;
|
|
170
|
+
type _SwizzleBaseMap = typeof SWIZZLE_BASE_MAP;
|
|
171
|
+
type _SwizzleResultMap = typeof SWIZZLE_RESULT_MAP;
|
|
172
|
+
type _SwizzleBase<T extends C> = T extends keyof _SwizzleBaseMap ? _SwizzleBaseMap[T] : never;
|
|
173
|
+
type _SwizzleResult<T extends C, L extends 1 | 2 | 3 | 4> = _SwizzleResultMap[_SwizzleBase<T>][L];
|
|
174
|
+
type InferSwizzleType<T extends C, S extends string> = _SwizzleLength<S> extends infer L extends 1 | 2 | 3 | 4 ? _SwizzleResult<_SwizzleBase<T>, L> : never;
|
|
120
175
|
/**
|
|
121
176
|
* infer
|
|
122
177
|
*/
|
|
@@ -127,57 +182,6 @@ type ExtractPairs<T> = T extends readonly [infer L, infer R, string] ? [L, R] |
|
|
|
127
182
|
type OperatorTypeRules = ExtractPairs<_OperatorTypeRulesMap[number]>;
|
|
128
183
|
type IsInRules<L extends C, R extends C> = [L, R] extends OperatorTypeRules ? 1 : 0;
|
|
129
184
|
type ValidateOperator<L extends C, R extends C> = L extends R ? 1 : IsInRules<L, R>;
|
|
130
|
-
/**
|
|
131
|
-
* swizzle
|
|
132
|
-
*/
|
|
133
|
-
type _SwizzleLength<A extends string> = A extends `${infer _}${infer A}` ? A extends '' ? 1 : A extends `${infer _}${infer B}` ? B extends '' ? 2 : B extends `${infer _}${infer C}` ? C extends '' ? 3 : 4 : never : never : never;
|
|
134
|
-
type _SwizzleBaseMap = {
|
|
135
|
-
float: 'float';
|
|
136
|
-
vec2: 'float';
|
|
137
|
-
vec3: 'float';
|
|
138
|
-
vec4: 'float';
|
|
139
|
-
int: 'int';
|
|
140
|
-
ivec2: 'int';
|
|
141
|
-
ivec3: 'int';
|
|
142
|
-
ivec4: 'int';
|
|
143
|
-
uint: 'uint';
|
|
144
|
-
uvec2: 'uint';
|
|
145
|
-
uvec3: 'uint';
|
|
146
|
-
uvec4: 'uint';
|
|
147
|
-
bool: 'bool';
|
|
148
|
-
bvec2: 'bool';
|
|
149
|
-
bvec3: 'bool';
|
|
150
|
-
bvec4: 'bool';
|
|
151
|
-
};
|
|
152
|
-
type _SwizzleResultMap = {
|
|
153
|
-
float: {
|
|
154
|
-
1: 'float';
|
|
155
|
-
2: 'vec2';
|
|
156
|
-
3: 'vec3';
|
|
157
|
-
4: 'vec4';
|
|
158
|
-
};
|
|
159
|
-
int: {
|
|
160
|
-
1: 'int';
|
|
161
|
-
2: 'ivec2';
|
|
162
|
-
3: 'ivec3';
|
|
163
|
-
4: 'ivec4';
|
|
164
|
-
};
|
|
165
|
-
uint: {
|
|
166
|
-
1: 'uint';
|
|
167
|
-
2: 'uvec2';
|
|
168
|
-
3: 'uvec3';
|
|
169
|
-
4: 'uvec4';
|
|
170
|
-
};
|
|
171
|
-
bool: {
|
|
172
|
-
1: 'bool';
|
|
173
|
-
2: 'bvec2';
|
|
174
|
-
3: 'bvec3';
|
|
175
|
-
4: 'bvec4';
|
|
176
|
-
};
|
|
177
|
-
};
|
|
178
|
-
type _SwizzleBase<T extends C> = T extends keyof _SwizzleBaseMap ? _SwizzleBaseMap[T] : never;
|
|
179
|
-
type _SwizzleResult<T extends C, L extends 1 | 2 | 3 | 4> = _SwizzleResultMap[_SwizzleBase<T>][L];
|
|
180
|
-
type InferSwizzleType<T extends C, S extends string> = _SwizzleLength<S> extends infer L extends 1 | 2 | 3 | 4 ? _SwizzleResult<_SwizzleBase<T>, L> : never;
|
|
181
185
|
/**
|
|
182
186
|
* Swizzles
|
|
183
187
|
*/
|
package/dist/solid.d.ts
CHANGED
|
@@ -29,8 +29,54 @@ declare const TYPE_MAPPING: {
|
|
|
29
29
|
readonly struct: "struct";
|
|
30
30
|
};
|
|
31
31
|
declare const CONSTANTS: (keyof typeof TYPE_MAPPING)[];
|
|
32
|
+
declare const SWIZZLE_BASE_MAP: {
|
|
33
|
+
readonly float: "float";
|
|
34
|
+
readonly vec2: "float";
|
|
35
|
+
readonly vec3: "float";
|
|
36
|
+
readonly vec4: "float";
|
|
37
|
+
readonly int: "int";
|
|
38
|
+
readonly ivec2: "int";
|
|
39
|
+
readonly ivec3: "int";
|
|
40
|
+
readonly ivec4: "int";
|
|
41
|
+
readonly uint: "uint";
|
|
42
|
+
readonly uvec2: "uint";
|
|
43
|
+
readonly uvec3: "uint";
|
|
44
|
+
readonly uvec4: "uint";
|
|
45
|
+
readonly bool: "bool";
|
|
46
|
+
readonly bvec2: "bool";
|
|
47
|
+
readonly bvec3: "bool";
|
|
48
|
+
readonly bvec4: "bool";
|
|
49
|
+
};
|
|
50
|
+
declare const SWIZZLE_RESULT_MAP: {
|
|
51
|
+
float: {
|
|
52
|
+
readonly 1: "float";
|
|
53
|
+
readonly 2: "vec2";
|
|
54
|
+
readonly 3: "vec3";
|
|
55
|
+
readonly 4: "vec4";
|
|
56
|
+
readonly 9: "mat3";
|
|
57
|
+
readonly 16: "mat4";
|
|
58
|
+
};
|
|
59
|
+
int: {
|
|
60
|
+
readonly 1: "int";
|
|
61
|
+
readonly 2: "ivec2";
|
|
62
|
+
readonly 3: "ivec3";
|
|
63
|
+
readonly 4: "ivec4";
|
|
64
|
+
};
|
|
65
|
+
uint: {
|
|
66
|
+
readonly 1: "uint";
|
|
67
|
+
readonly 2: "uvec2";
|
|
68
|
+
readonly 3: "uvec3";
|
|
69
|
+
readonly 4: "uvec4";
|
|
70
|
+
};
|
|
71
|
+
bool: {
|
|
72
|
+
readonly 1: "bool";
|
|
73
|
+
readonly 2: "bvec2";
|
|
74
|
+
readonly 3: "bvec3";
|
|
75
|
+
readonly 4: "bvec4";
|
|
76
|
+
};
|
|
77
|
+
};
|
|
32
78
|
declare const OPERATORS: {
|
|
33
|
-
readonly not: "";
|
|
79
|
+
readonly not: "!";
|
|
34
80
|
readonly add: "+";
|
|
35
81
|
readonly sub: "-";
|
|
36
82
|
readonly mul: "*";
|
|
@@ -78,7 +124,7 @@ type Operators = (typeof OPERATOR_KEYS)[number];
|
|
|
78
124
|
*/
|
|
79
125
|
interface FnLayout {
|
|
80
126
|
name: string;
|
|
81
|
-
type
|
|
127
|
+
type?: C | 'auto';
|
|
82
128
|
inputs?: Array<{
|
|
83
129
|
name: string;
|
|
84
130
|
type: C | 'auto';
|
|
@@ -117,6 +163,15 @@ interface NodeContext {
|
|
|
117
163
|
structStructFields: Map<string, StructFields>;
|
|
118
164
|
};
|
|
119
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* swizzle
|
|
168
|
+
*/
|
|
169
|
+
type _SwizzleLength<A extends string> = A extends `${infer _}${infer A}` ? A extends '' ? 1 : A extends `${infer _}${infer B}` ? B extends '' ? 2 : B extends `${infer _}${infer C}` ? C extends '' ? 3 : 4 : never : never : never;
|
|
170
|
+
type _SwizzleBaseMap = typeof SWIZZLE_BASE_MAP;
|
|
171
|
+
type _SwizzleResultMap = typeof SWIZZLE_RESULT_MAP;
|
|
172
|
+
type _SwizzleBase<T extends C> = T extends keyof _SwizzleBaseMap ? _SwizzleBaseMap[T] : never;
|
|
173
|
+
type _SwizzleResult<T extends C, L extends 1 | 2 | 3 | 4> = _SwizzleResultMap[_SwizzleBase<T>][L];
|
|
174
|
+
type InferSwizzleType<T extends C, S extends string> = _SwizzleLength<S> extends infer L extends 1 | 2 | 3 | 4 ? _SwizzleResult<_SwizzleBase<T>, L> : never;
|
|
120
175
|
/**
|
|
121
176
|
* infer
|
|
122
177
|
*/
|
|
@@ -127,57 +182,6 @@ type ExtractPairs<T> = T extends readonly [infer L, infer R, string] ? [L, R] |
|
|
|
127
182
|
type OperatorTypeRules = ExtractPairs<_OperatorTypeRulesMap[number]>;
|
|
128
183
|
type IsInRules<L extends C, R extends C> = [L, R] extends OperatorTypeRules ? 1 : 0;
|
|
129
184
|
type ValidateOperator<L extends C, R extends C> = L extends R ? 1 : IsInRules<L, R>;
|
|
130
|
-
/**
|
|
131
|
-
* swizzle
|
|
132
|
-
*/
|
|
133
|
-
type _SwizzleLength<A extends string> = A extends `${infer _}${infer A}` ? A extends '' ? 1 : A extends `${infer _}${infer B}` ? B extends '' ? 2 : B extends `${infer _}${infer C}` ? C extends '' ? 3 : 4 : never : never : never;
|
|
134
|
-
type _SwizzleBaseMap = {
|
|
135
|
-
float: 'float';
|
|
136
|
-
vec2: 'float';
|
|
137
|
-
vec3: 'float';
|
|
138
|
-
vec4: 'float';
|
|
139
|
-
int: 'int';
|
|
140
|
-
ivec2: 'int';
|
|
141
|
-
ivec3: 'int';
|
|
142
|
-
ivec4: 'int';
|
|
143
|
-
uint: 'uint';
|
|
144
|
-
uvec2: 'uint';
|
|
145
|
-
uvec3: 'uint';
|
|
146
|
-
uvec4: 'uint';
|
|
147
|
-
bool: 'bool';
|
|
148
|
-
bvec2: 'bool';
|
|
149
|
-
bvec3: 'bool';
|
|
150
|
-
bvec4: 'bool';
|
|
151
|
-
};
|
|
152
|
-
type _SwizzleResultMap = {
|
|
153
|
-
float: {
|
|
154
|
-
1: 'float';
|
|
155
|
-
2: 'vec2';
|
|
156
|
-
3: 'vec3';
|
|
157
|
-
4: 'vec4';
|
|
158
|
-
};
|
|
159
|
-
int: {
|
|
160
|
-
1: 'int';
|
|
161
|
-
2: 'ivec2';
|
|
162
|
-
3: 'ivec3';
|
|
163
|
-
4: 'ivec4';
|
|
164
|
-
};
|
|
165
|
-
uint: {
|
|
166
|
-
1: 'uint';
|
|
167
|
-
2: 'uvec2';
|
|
168
|
-
3: 'uvec3';
|
|
169
|
-
4: 'uvec4';
|
|
170
|
-
};
|
|
171
|
-
bool: {
|
|
172
|
-
1: 'bool';
|
|
173
|
-
2: 'bvec2';
|
|
174
|
-
3: 'bvec3';
|
|
175
|
-
4: 'bvec4';
|
|
176
|
-
};
|
|
177
|
-
};
|
|
178
|
-
type _SwizzleBase<T extends C> = T extends keyof _SwizzleBaseMap ? _SwizzleBaseMap[T] : never;
|
|
179
|
-
type _SwizzleResult<T extends C, L extends 1 | 2 | 3 | 4> = _SwizzleResultMap[_SwizzleBase<T>][L];
|
|
180
|
-
type InferSwizzleType<T extends C, S extends string> = _SwizzleLength<S> extends infer L extends 1 | 2 | 3 | 4 ? _SwizzleResult<_SwizzleBase<T>, L> : never;
|
|
181
185
|
/**
|
|
182
186
|
* Swizzles
|
|
183
187
|
*/
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -54,7 +54,10 @@ export const createGL = (...args: Partial<GL>[]) => {
|
|
|
54
54
|
gl('mount', async (el: HTMLCanvasElement) => {
|
|
55
55
|
gl.el = findElement(gl) || el || args.map(findElement).find(Boolean)
|
|
56
56
|
const isAppend = !gl.el // Check first: canvas may unmount during WebGPU async processing
|
|
57
|
-
if (isAppend && !gl.isNative)
|
|
57
|
+
if (isAppend && !gl.isNative) {
|
|
58
|
+
gl.el = document.createElement('canvas')
|
|
59
|
+
Object.assign(gl.el.style, { top: 0, left: 0, position: 'fixed' })
|
|
60
|
+
}
|
|
58
61
|
for (let i = 0; i < args.length; i++) {
|
|
59
62
|
const arg = args[i]
|
|
60
63
|
gl.fs = arg.fs || arg.frag || arg.fragment || undefined
|
package/src/node/create.ts
CHANGED
|
@@ -8,9 +8,9 @@ const toPrimitive = (x: Y, hint: string) => {
|
|
|
8
8
|
if (hint === 'string') return code(x as any, null)
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
export const create = <T extends C>(type: NodeTypes, props?: NodeProps | null, ...
|
|
11
|
+
export const create = <T extends C>(type: NodeTypes, props?: NodeProps | null, ...children: Y[]) => {
|
|
12
12
|
if (!props) props = {}
|
|
13
|
-
if (
|
|
13
|
+
if (children.length) props.children = children
|
|
14
14
|
const listeners = new Set<(value: any) => void>()
|
|
15
15
|
const get = (_: unknown, key: string | Symbol) => {
|
|
16
16
|
if (key === 'type') return type
|
|
@@ -30,20 +30,21 @@ export const create = <T extends C>(type: NodeTypes, props?: NodeProps | null, .
|
|
|
30
30
|
if (key === 'variable') return (id = getId()) => variable(id)
|
|
31
31
|
if (key === 'builtin') return (id = getId()) => builtin(id)
|
|
32
32
|
if (key === 'vertexStage') return (id = getId()) => vertexStage(x, id)
|
|
33
|
-
if (key === 'element') return (
|
|
34
|
-
if (key === 'member') return (
|
|
33
|
+
if (key === 'element') return (y: Y) => (type === 'storage' ? gather(x, y) : element(x, y))
|
|
34
|
+
if (key === 'member') return (y: Y) => member(x, y)
|
|
35
35
|
if (key === 'assign') return assign.bind(null, x, x.type === 'gather')
|
|
36
36
|
if (key === 'select') return select.bind(null, x)
|
|
37
37
|
if (isOperator(key)) {
|
|
38
|
-
|
|
38
|
+
if (key.endsWith('Assign')) return (...y: Y[]) => addToScope(operator(key, x, ...y))
|
|
39
|
+
return (...y: Y[]) => operator(key, x, ...y)
|
|
39
40
|
}
|
|
40
|
-
if (isFunction(key)) return (...
|
|
41
|
+
if (isFunction(key)) return (...y: Y[]) => function_(key, x, ...y)
|
|
41
42
|
if (isConversion(key)) return () => conversion(getConstant(key), x)
|
|
42
43
|
if (is.str(key)) return isArrayAccess(key) ? element(x, key) : member(x, key)
|
|
43
44
|
}
|
|
44
|
-
const set = (_: unknown, key: string,
|
|
45
|
-
if (key === 'value') listeners.forEach((fun) => fun(
|
|
46
|
-
if (is.str(key)) member(x, key).assign(
|
|
45
|
+
const set = (_: unknown, key: string, y: Y) => {
|
|
46
|
+
if (key === 'value') listeners.forEach((fun) => fun(y))
|
|
47
|
+
if (is.str(key)) member(x, key).assign(y)
|
|
47
48
|
return true
|
|
48
49
|
}
|
|
49
50
|
const x = new Proxy({}, { get, set }) as unknown as X<T>
|
package/src/node/scope.ts
CHANGED
|
@@ -1,23 +1,12 @@
|
|
|
1
1
|
import { conversion, create } from './create'
|
|
2
|
-
import type {
|
|
3
|
-
FnLayout,
|
|
4
|
-
FnType,
|
|
5
|
-
Constants as C,
|
|
6
|
-
Int,
|
|
7
|
-
NodeProps,
|
|
8
|
-
Struct,
|
|
9
|
-
StructFactory,
|
|
10
|
-
StructFields,
|
|
11
|
-
X,
|
|
12
|
-
Y,
|
|
13
|
-
} from './types'
|
|
14
2
|
import { getId } from './utils'
|
|
3
|
+
import type { FnLayout, FnType, Constants as C, Int, NodeProps, Struct, StructFactory, StructFields, X, Y } from './types'
|
|
15
4
|
|
|
16
5
|
let scope: X | null = null
|
|
17
6
|
let define: X | null = null
|
|
18
7
|
|
|
19
8
|
export const addToScope = <T extends C>(x: X<T>) => {
|
|
20
|
-
if (!scope) return
|
|
9
|
+
if (!scope) return x
|
|
21
10
|
if (!scope.props.children) scope.props.children = []
|
|
22
11
|
scope.props.children.push(x)
|
|
23
12
|
if (x.type !== 'return' || !define) return x
|
|
@@ -133,8 +122,7 @@ export function Fn<T extends X | Struct | void, Args extends any[]>(fun: (args:
|
|
|
133
122
|
else
|
|
134
123
|
paramDefs.push({
|
|
135
124
|
id: input.name,
|
|
136
|
-
inferFrom:
|
|
137
|
-
input.type === 'auto' ? [args[i]] : [conversion(input.type, args[i])],
|
|
125
|
+
inferFrom: input.type === 'auto' ? [args[i]] : [conversion(input.type, args[i])],
|
|
138
126
|
})
|
|
139
127
|
}
|
|
140
128
|
for (const props of paramDefs) paramVars.push(create('variable', props))
|
package/src/node/types.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CONSTANTS, CONVERSIONS, FUNCTIONS, OPERATOR_KEYS, OPERATOR_TYPE_RULES } from './utils/const'
|
|
1
|
+
import { CONSTANTS, CONVERSIONS, FUNCTIONS, OPERATOR_KEYS, OPERATOR_TYPE_RULES, SWIZZLE_BASE_MAP, SWIZZLE_RESULT_MAP } from './utils/const'
|
|
2
2
|
import type { GL } from '../types'
|
|
3
3
|
|
|
4
4
|
export type Constants = (typeof CONSTANTS)[number] | 'void'
|
|
@@ -11,7 +11,7 @@ export type Operators = (typeof OPERATOR_KEYS)[number]
|
|
|
11
11
|
*/
|
|
12
12
|
export interface FnLayout {
|
|
13
13
|
name: string
|
|
14
|
-
type
|
|
14
|
+
type?: C | 'auto'
|
|
15
15
|
inputs?: Array<{
|
|
16
16
|
name: string
|
|
17
17
|
type: C | 'auto'
|
|
@@ -97,6 +97,24 @@ export interface NodeContext {
|
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
/**
|
|
101
|
+
* swizzle
|
|
102
|
+
*/
|
|
103
|
+
// Optimized string length using direct pattern matching
|
|
104
|
+
// prettier-ignore
|
|
105
|
+
type _SwizzleLength<A extends string> =
|
|
106
|
+
A extends `${infer _}${infer A}` ? A extends '' ? 1 :
|
|
107
|
+
A extends `${infer _}${infer B}` ? B extends '' ? 2 :
|
|
108
|
+
B extends `${infer _}${infer C}` ? C extends '' ? 3 :
|
|
109
|
+
4 : never : never : never
|
|
110
|
+
|
|
111
|
+
// Unified logic with infer.ts inferSwizzleType
|
|
112
|
+
type _SwizzleBaseMap = typeof SWIZZLE_BASE_MAP
|
|
113
|
+
type _SwizzleResultMap = typeof SWIZZLE_RESULT_MAP
|
|
114
|
+
type _SwizzleBase<T extends C> = T extends keyof _SwizzleBaseMap ? _SwizzleBaseMap[T] : never
|
|
115
|
+
type _SwizzleResult<T extends C, L extends 1 | 2 | 3 | 4> = _SwizzleResultMap[_SwizzleBase<T>][L]
|
|
116
|
+
type InferSwizzleType<T extends C, S extends string> = _SwizzleLength<S> extends infer L extends 1 | 2 | 3 | 4 ? _SwizzleResult<_SwizzleBase<T>, L> : never
|
|
117
|
+
|
|
100
118
|
/**
|
|
101
119
|
* infer
|
|
102
120
|
*/
|
|
@@ -130,47 +148,6 @@ type OperatorTypeRules = ExtractPairs<_OperatorTypeRulesMap[number]>
|
|
|
130
148
|
type IsInRules<L extends C, R extends C> = [L, R] extends OperatorTypeRules ? 1 : 0
|
|
131
149
|
type ValidateOperator<L extends C, R extends C> = L extends R ? 1 : IsInRules<L, R>
|
|
132
150
|
|
|
133
|
-
/**
|
|
134
|
-
* swizzle
|
|
135
|
-
*/
|
|
136
|
-
// Optimized string length using direct pattern matching
|
|
137
|
-
// prettier-ignore
|
|
138
|
-
type _SwizzleLength<A extends string> =
|
|
139
|
-
A extends `${infer _}${infer A}` ? A extends '' ? 1 :
|
|
140
|
-
A extends `${infer _}${infer B}` ? B extends '' ? 2 :
|
|
141
|
-
B extends `${infer _}${infer C}` ? C extends '' ? 3 :
|
|
142
|
-
4 : never : never : never
|
|
143
|
-
|
|
144
|
-
type _SwizzleBaseMap = {
|
|
145
|
-
float: 'float'
|
|
146
|
-
vec2: 'float'
|
|
147
|
-
vec3: 'float'
|
|
148
|
-
vec4: 'float'
|
|
149
|
-
int: 'int'
|
|
150
|
-
ivec2: 'int'
|
|
151
|
-
ivec3: 'int'
|
|
152
|
-
ivec4: 'int'
|
|
153
|
-
uint: 'uint'
|
|
154
|
-
uvec2: 'uint'
|
|
155
|
-
uvec3: 'uint'
|
|
156
|
-
uvec4: 'uint'
|
|
157
|
-
bool: 'bool'
|
|
158
|
-
bvec2: 'bool'
|
|
159
|
-
bvec3: 'bool'
|
|
160
|
-
bvec4: 'bool'
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
type _SwizzleResultMap = {
|
|
164
|
-
float: { 1: 'float'; 2: 'vec2'; 3: 'vec3'; 4: 'vec4' }
|
|
165
|
-
int: { 1: 'int'; 2: 'ivec2'; 3: 'ivec3'; 4: 'ivec4' }
|
|
166
|
-
uint: { 1: 'uint'; 2: 'uvec2'; 3: 'uvec3'; 4: 'uvec4' }
|
|
167
|
-
bool: { 1: 'bool'; 2: 'bvec2'; 3: 'bvec3'; 4: 'bvec4' }
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
type _SwizzleBase<T extends C> = T extends keyof _SwizzleBaseMap ? _SwizzleBaseMap[T] : never
|
|
171
|
-
type _SwizzleResult<T extends C, L extends 1 | 2 | 3 | 4> = _SwizzleResultMap[_SwizzleBase<T>][L]
|
|
172
|
-
type InferSwizzleType<T extends C, S extends string> = _SwizzleLength<S> extends infer L extends 1 | 2 | 3 | 4 ? _SwizzleResult<_SwizzleBase<T>, L> : never
|
|
173
|
-
|
|
174
151
|
/**
|
|
175
152
|
* Swizzles
|
|
176
153
|
*/
|
package/src/node/utils/const.ts
CHANGED
|
@@ -32,8 +32,34 @@ export const TYPE_MAPPING = {
|
|
|
32
32
|
|
|
33
33
|
export const CONSTANTS = Object.keys(TYPE_MAPPING) as (keyof typeof TYPE_MAPPING)[]
|
|
34
34
|
|
|
35
|
+
export const SWIZZLE_BASE_MAP = {
|
|
36
|
+
float: 'float',
|
|
37
|
+
vec2: 'float',
|
|
38
|
+
vec3: 'float',
|
|
39
|
+
vec4: 'float',
|
|
40
|
+
int: 'int',
|
|
41
|
+
ivec2: 'int',
|
|
42
|
+
ivec3: 'int',
|
|
43
|
+
ivec4: 'int',
|
|
44
|
+
uint: 'uint',
|
|
45
|
+
uvec2: 'uint',
|
|
46
|
+
uvec3: 'uint',
|
|
47
|
+
uvec4: 'uint',
|
|
48
|
+
bool: 'bool',
|
|
49
|
+
bvec2: 'bool',
|
|
50
|
+
bvec3: 'bool',
|
|
51
|
+
bvec4: 'bool',
|
|
52
|
+
} as const
|
|
53
|
+
|
|
54
|
+
export const SWIZZLE_RESULT_MAP = {
|
|
55
|
+
float: { 1: 'float', 2: 'vec2', 3: 'vec3', 4: 'vec4', 9: 'mat3', 16: 'mat4' } as const,
|
|
56
|
+
int: { 1: 'int', 2: 'ivec2', 3: 'ivec3', 4: 'ivec4' } as const,
|
|
57
|
+
uint: { 1: 'uint', 2: 'uvec2', 3: 'uvec3', 4: 'uvec4' } as const,
|
|
58
|
+
bool: { 1: 'bool', 2: 'bvec2', 3: 'bvec3', 4: 'bvec4' } as const,
|
|
59
|
+
}
|
|
60
|
+
|
|
35
61
|
export const OPERATORS = {
|
|
36
|
-
not: '',
|
|
62
|
+
not: '!',
|
|
37
63
|
add: '+',
|
|
38
64
|
sub: '-',
|
|
39
65
|
mul: '*',
|
|
@@ -66,15 +92,6 @@ export const OPERATORS = {
|
|
|
66
92
|
|
|
67
93
|
export const OPERATOR_KEYS = Object.keys(OPERATORS) as (keyof typeof OPERATORS)[]
|
|
68
94
|
|
|
69
|
-
export const COMPONENT_COUNT_TO_TYPE = {
|
|
70
|
-
1: 'float',
|
|
71
|
-
2: 'vec2',
|
|
72
|
-
3: 'vec3',
|
|
73
|
-
4: 'vec4',
|
|
74
|
-
9: 'mat3',
|
|
75
|
-
16: 'mat4',
|
|
76
|
-
} as const
|
|
77
|
-
|
|
78
95
|
export const BUILTIN_TYPES = {
|
|
79
96
|
// WGSL builtin variables
|
|
80
97
|
position: 'vec4',
|
package/src/node/utils/index.ts
CHANGED
|
@@ -7,18 +7,20 @@ import type { Constants as C, NodeContext, Y } from '../types'
|
|
|
7
7
|
|
|
8
8
|
export * from './utils'
|
|
9
9
|
|
|
10
|
+
const parseNumber = (target = 0) => {
|
|
11
|
+
const ret = `${target}`
|
|
12
|
+
if (ret.includes('.')) return ret
|
|
13
|
+
// Check if this number should be an integer based on the inferred type
|
|
14
|
+
// For now, keep the original behavior to maintain compatibility
|
|
15
|
+
return ret + '.0'
|
|
16
|
+
}
|
|
17
|
+
|
|
10
18
|
export const code = <T extends C>(target: Y<T>, c?: NodeContext | null): string => {
|
|
11
19
|
if (!c) c = {}
|
|
12
20
|
initNodeContext(c)
|
|
13
21
|
if (is.arr(target)) return parseArray(target, c)
|
|
14
22
|
if (is.str(target)) return target
|
|
15
|
-
if (is.num(target))
|
|
16
|
-
const ret = `${target}`
|
|
17
|
-
if (ret.includes('.')) return ret
|
|
18
|
-
// Check if this number should be an integer based on the inferred type
|
|
19
|
-
// For now, keep the original behavior to maintain compatibility
|
|
20
|
-
return ret + '.0'
|
|
21
|
-
}
|
|
23
|
+
if (is.num(target)) return parseNumber(target)
|
|
22
24
|
if (is.bol(target)) return target ? 'true' : 'false'
|
|
23
25
|
if (!target) return ''
|
|
24
26
|
if (!isX(target)) return ''
|
|
@@ -42,7 +44,12 @@ export const code = <T extends C>(target: Y<T>, c?: NodeContext | null): string
|
|
|
42
44
|
: `${code(storageNode, c)}[${code(indexNode, c)}] = ${code(y, c)};`
|
|
43
45
|
}
|
|
44
46
|
if (type === 'ternary') return c.isWebGL ? `(${code(z, c)} ? ${code(x, c)} : ${code(y, c)})` : `select(${code(x, c)}, ${code(y, c)}, ${code(z, c)})`
|
|
45
|
-
if (type === 'conversion')
|
|
47
|
+
if (type === 'conversion') {
|
|
48
|
+
if (x === 'float') if (is.num(y)) return parseNumber(y) // no conversion needed, e.g., float(1.0) → 1.0
|
|
49
|
+
if (x === 'bool') if (is.bol(y)) return y ? 'true' : 'false'
|
|
50
|
+
if (x === 'int') if (is.num(y)) return `${y << 0}`
|
|
51
|
+
return `${getConversions(x, c)}(${parseArray(children.slice(1), c)})`
|
|
52
|
+
}
|
|
46
53
|
if (type === 'operator') {
|
|
47
54
|
if (x === 'not' || x === 'bitNot') return `!${code(y, c)}`
|
|
48
55
|
if (x === 'mod') return code(mod(y, z), c)
|
package/src/node/utils/infer.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isConstants, isElement, isX, isSwizzle } from './utils'
|
|
2
|
-
import { BUILTIN_TYPES,
|
|
2
|
+
import { BUILTIN_TYPES, FUNCTION_RETURN_TYPES, getOperatorResultType, SWIZZLE_BASE_MAP, SWIZZLE_RESULT_MAP, validateOperatorTypes } from './const'
|
|
3
3
|
import { is, getStride, isFloat32 } from '../../helpers'
|
|
4
4
|
import type { Constants as C, NodeContext, X, Y } from '../types'
|
|
5
5
|
|
|
@@ -7,7 +7,14 @@ const inferBuiltin = <T extends C>(id: string | undefined) => {
|
|
|
7
7
|
return BUILTIN_TYPES[id as keyof typeof BUILTIN_TYPES] as T
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
// Unified logic with types.ts inferArrayElement type
|
|
11
|
+
const inferSwizzleType = <T extends C>(L: T, len: 1 | 2 | 3 | 4): T => {
|
|
12
|
+
return SWIZZLE_RESULT_MAP[SWIZZLE_BASE_MAP[L as 'float']][len] as T
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Unified logic with types.ts InferOperator type
|
|
10
16
|
const inferOperator = <T extends C>(L: T, R: T, op: string): T => {
|
|
17
|
+
if (op === 'not') return 'bool' as T // 'not' operator's right side is none, causing a warning in the next validator
|
|
11
18
|
if (!validateOperatorTypes(L, R, op)) console.warn(`GLRE Type Warning: Invalid operator '${op}' between types '${L}' and '${R}'`)
|
|
12
19
|
return getOperatorResultType(L, R, op) as T
|
|
13
20
|
}
|
|
@@ -15,15 +22,15 @@ const inferOperator = <T extends C>(L: T, R: T, op: string): T => {
|
|
|
15
22
|
export const inferPrimitiveType = <T extends C>(x: Y<T>) => {
|
|
16
23
|
if (is.bol(x)) return 'bool' as T
|
|
17
24
|
if (is.str(x)) return 'texture' as T
|
|
18
|
-
if (is.num(x)) return 'float' as T // @TODO FIX:
|
|
19
|
-
if (is.arr(x) || isFloat32(x)) return
|
|
25
|
+
if (is.num(x)) return 'float' as T // @TODO FIX: Number.isInteger(x) ? 'int' : 'float'
|
|
26
|
+
if (is.arr(x) || isFloat32(x)) return SWIZZLE_RESULT_MAP.float[x.length as 1 | 2 | 3 | 4 | 9 | 16] as T
|
|
20
27
|
if (isElement(x)) return 'texture' as T
|
|
21
28
|
return 'void' as T
|
|
22
29
|
}
|
|
23
30
|
|
|
24
31
|
const inferFromCount = <T extends C>(count: number, error = console.warn, id = '') => {
|
|
25
|
-
const ret =
|
|
26
|
-
if (!ret)
|
|
32
|
+
const ret = SWIZZLE_RESULT_MAP.float[count as 1 | 2 | 3 | 4 | 9 | 16] as T
|
|
33
|
+
if (!ret) error(`glre node system error: Cannot infer ${id ? `${id} ` : ''} type from array length ${count}. Check your data size. Supported: 1(float), 2(vec2), 3(vec3), 4(vec4), 9(mat3), 16(mat4)`)
|
|
27
34
|
return ret
|
|
28
35
|
}
|
|
29
36
|
|
|
@@ -62,13 +69,13 @@ export const inferImpl = <T extends C>(target: X<T>, c: NodeContext): T => {
|
|
|
62
69
|
}
|
|
63
70
|
|
|
64
71
|
if (type === 'member') {
|
|
65
|
-
|
|
66
|
-
if (
|
|
67
|
-
const
|
|
68
|
-
const fields = c.code?.structStructFields?.get(structType)
|
|
72
|
+
const constant = infer(x, c) // Check if struct first to avoid field/swizzle clash, e.g. Struct({ x: float(), y: float() })
|
|
73
|
+
if (!isConstants(constant)) {
|
|
74
|
+
const fields = c.code?.structStructFields?.get(constant)
|
|
69
75
|
if (fields && fields[y]) return infer(fields[y], c) as T
|
|
70
76
|
}
|
|
71
|
-
return
|
|
77
|
+
if (isSwizzle(y)) return inferSwizzleType(constant, y.length as 1 | 2 | 3 | 4) as T
|
|
78
|
+
return 'float' as T // throw Error
|
|
72
79
|
}
|
|
73
80
|
if (inferFrom) return inferFromArray(inferFrom, c)
|
|
74
81
|
return x ? infer(x, c) : ('void' as T) // for uniform and storage gather and scatter
|