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/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: C | 'auto';
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: C | 'auto';
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glre",
3
- "version": "0.48.0",
3
+ "version": "0.49.1",
4
4
  "author": "tseijp",
5
5
  "license": "MIT",
6
6
  "private": false,
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) gl.el = document.createElement('canvas')
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
@@ -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, ...args: Y[]) => {
11
+ export const create = <T extends C>(type: NodeTypes, props?: NodeProps | null, ...children: Y[]) => {
12
12
  if (!props) props = {}
13
- if (args.length) props.children = args
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 (arg: Y) => (type === 'storage' ? gather(x, arg) : element(x, arg))
34
- if (key === 'member') return (arg: Y) => member(x, arg)
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
- return key.endsWith('Assign') ? (...args: Y[]) => addToScope(operator(key, x, ...args)) : (...args: Y[]) => operator(key, x, ...args)
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 (...args: Y[]) => function_(key, x, ...args)
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, arg: Y) => {
45
- if (key === 'value') listeners.forEach((fun) => fun(arg))
46
- if (is.str(key)) member(x, key).assign(arg)
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: C | 'auto'
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
  */
@@ -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: '', // IGNORED
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',
@@ -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') return `${getConversions(x, c)}(${parseArray(children.slice(1), c)})`
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)
@@ -1,5 +1,5 @@
1
1
  import { isConstants, isElement, isX, isSwizzle } from './utils'
2
- import { BUILTIN_TYPES, COMPONENT_COUNT_TO_TYPE, FUNCTION_RETURN_TYPES, getOperatorResultType, validateOperatorTypes } from './const'
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: Number.isInteger(x) ? 'int' : 'float'
19
- if (is.arr(x) || isFloat32(x)) return COMPONENT_COUNT_TO_TYPE[x.length as keyof typeof COMPONENT_COUNT_TO_TYPE] as T
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 = COMPONENT_COUNT_TO_TYPE[count as keyof typeof COMPONENT_COUNT_TO_TYPE] as T
26
- if (!ret) console.warn(`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)`)
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
- if (isSwizzle(y)) return inferFromCount(y.length, c.gl?.error, id)
66
- if (isX(x)) {
67
- const structType = infer(x, c)
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 'float' as T
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