glre 0.37.0 → 0.38.0
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/index.cjs +32 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +79 -1546
- package/dist/index.js +32 -29
- package/dist/index.js.map +1 -1
- package/dist/native.cjs +32 -29
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.ts +6 -6
- package/dist/native.js +32 -29
- package/dist/native.js.map +1 -1
- package/dist/react.cjs +32 -29
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +32 -29
- package/dist/react.js.map +1 -1
- package/dist/solid.cjs +32 -29
- package/dist/solid.cjs.map +1 -1
- package/dist/solid.d.ts +1 -1
- package/dist/solid.js +32 -29
- package/dist/solid.js.map +1 -1
- package/package.json +1 -1
- package/src/node/node.ts +3 -2
- package/src/node/scope.ts +28 -16
- package/src/node/types.ts +71 -43
- package/src/node/utils/const.ts +2 -1
- package/src/node/utils/index.ts +2 -2
- package/src/node/utils/infer.ts +7 -7
- package/src/node/utils/parse.ts +8 -11
- package/src/node/utils/utils.ts +7 -6
- package/src/types.ts +4 -4
- package/src/utils/program.ts +1 -1
package/package.json
CHANGED
package/src/node/node.ts
CHANGED
|
@@ -14,7 +14,8 @@ export const node = <T extends C>(type: NodeTypes, props?: NodeProps | null, ...
|
|
|
14
14
|
const get = (_: unknown, y: string | Symbol) => {
|
|
15
15
|
if (y === 'type') return type
|
|
16
16
|
if (y === 'props') return props
|
|
17
|
-
if (y === '
|
|
17
|
+
if (y === '__nodeType') return undefined // Will be inferred by TypeScript
|
|
18
|
+
if (y === 'toVar') return toVar.bind(null, x as any)
|
|
18
19
|
if (y === 'isProxy') return true
|
|
19
20
|
if (y === 'toString') return code.bind(null, x)
|
|
20
21
|
if (y === Symbol.toPrimitive) return toPrimitive.bind(null, x)
|
|
@@ -43,7 +44,7 @@ export const node = <T extends C>(type: NodeTypes, props?: NodeProps | null, ...
|
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
// headers with proper type inference
|
|
46
|
-
export const attribute = <T extends C>(x: X
|
|
47
|
+
export const attribute = <T extends C>(x: X<T>, id = getId()) => node<T>('attribute', { id }, x)
|
|
47
48
|
export const constant = <T extends C>(x: X<T>, id = getId()) => node<T>('constant', { id }, x)
|
|
48
49
|
export const uniform = <T extends C>(x: X<T>, id = getId()) => node<T>('uniform', { id }, x)
|
|
49
50
|
export const storage = <T extends C>(x: X<T>, id = getId()) => node<T>('storage', { id }, x)
|
package/src/node/scope.ts
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { getId } from './utils'
|
|
2
2
|
import { conversion, node } from './node'
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
FnLayout,
|
|
5
|
+
FnType,
|
|
6
|
+
NodeProps,
|
|
7
|
+
NodeProxy,
|
|
8
|
+
X,
|
|
9
|
+
Constants,
|
|
10
|
+
Int,
|
|
11
|
+
StructFactory,
|
|
12
|
+
StructNode,
|
|
13
|
+
StructFields,
|
|
14
|
+
} from './types'
|
|
4
15
|
|
|
5
16
|
let scope: NodeProxy | null = null
|
|
6
17
|
let define: NodeProxy | null = null
|
|
@@ -10,16 +21,16 @@ const addToScope = (x: NodeProxy) => {
|
|
|
10
21
|
if (!scope.props.children) scope.props.children = []
|
|
11
22
|
scope.props.children.push(x)
|
|
12
23
|
if (x.type !== 'return' || !define) return
|
|
13
|
-
// define nodes
|
|
14
24
|
const { props } = define
|
|
15
25
|
if (!props.inferFrom) props.inferFrom = []
|
|
16
26
|
props.inferFrom.push(x)
|
|
17
27
|
}
|
|
18
28
|
|
|
19
|
-
export
|
|
29
|
+
export function toVar<T extends StructFields>(x: StructNode<T>, id?: string): StructNode<T>
|
|
30
|
+
export function toVar<T extends Constants>(x: NodeProxy<T>, id?: string): NodeProxy<T> {
|
|
20
31
|
if (!id) id = getId()
|
|
21
32
|
const y = node<T>('variable', { id, inferFrom: [x] })
|
|
22
|
-
const z = node('declare', null, x, y)
|
|
33
|
+
const z = node<T>('declare', null, x as NodeProxy, y)
|
|
23
34
|
addToScope(z)
|
|
24
35
|
return y
|
|
25
36
|
}
|
|
@@ -36,12 +47,12 @@ export const Return = <T extends Constants>(x: X<T>): NodeProxy<T> => {
|
|
|
36
47
|
return y
|
|
37
48
|
}
|
|
38
49
|
|
|
39
|
-
export const struct = <T extends
|
|
40
|
-
return (initialValues:
|
|
50
|
+
export const struct = <T extends StructFields>(fields: T, id = getId()): StructFactory<T> => {
|
|
51
|
+
return (initialValues: StructFields = {}, instanceId = getId()) => {
|
|
41
52
|
const x = node('variable', { id: instanceId, inferFrom: [id] })
|
|
42
53
|
const y = node('struct', { id, fields, initialValues }, x)
|
|
43
54
|
addToScope(y)
|
|
44
|
-
return x
|
|
55
|
+
return x as StructNode<T>
|
|
45
56
|
}
|
|
46
57
|
}
|
|
47
58
|
|
|
@@ -104,32 +115,33 @@ export const Switch = (x: NodeProxy) => {
|
|
|
104
115
|
return ret()
|
|
105
116
|
}
|
|
106
117
|
|
|
107
|
-
export
|
|
108
|
-
fun: (
|
|
118
|
+
export function Fn<T extends NodeProxy | StructNode | void, Args extends any[]>(
|
|
119
|
+
fun: (args: Args) => T,
|
|
109
120
|
defaultId = getId()
|
|
110
|
-
)
|
|
121
|
+
) {
|
|
111
122
|
let layout: FnLayout
|
|
112
|
-
const ret = (...args:
|
|
123
|
+
const ret = (...args: any[]) => {
|
|
113
124
|
const id = layout?.name || defaultId
|
|
114
125
|
const x = node('scope')
|
|
115
126
|
const paramVars: NodeProxy[] = []
|
|
116
127
|
const paramDefs: NodeProps[] = []
|
|
117
|
-
if (layout?.inputs)
|
|
128
|
+
if (layout?.inputs) {
|
|
118
129
|
for (const input of layout.inputs) {
|
|
119
130
|
paramDefs.push({ id: input.name, inferFrom: [conversion(input.type)] })
|
|
120
131
|
}
|
|
121
|
-
else
|
|
132
|
+
} else {
|
|
122
133
|
for (let i = 0; i < args.length; i++) {
|
|
123
134
|
paramDefs.push({ id: `p${i}`, inferFrom: [args[i]] })
|
|
124
135
|
}
|
|
136
|
+
}
|
|
125
137
|
for (const props of paramDefs) paramVars.push(node('variable', props))
|
|
126
|
-
const y = node
|
|
127
|
-
scoped(x, () => fun(paramVars), y)
|
|
138
|
+
const y = node('define', { id, layout }, x, ...args)
|
|
139
|
+
scoped(x, () => fun(paramVars as Args) as any, y)
|
|
128
140
|
return y
|
|
129
141
|
}
|
|
130
142
|
ret.setLayout = (_layout: FnLayout) => {
|
|
131
143
|
layout = _layout
|
|
132
144
|
return ret
|
|
133
145
|
}
|
|
134
|
-
return ret
|
|
146
|
+
return ret as unknown as Args extends readonly unknown[] ? FnType<T, Args> : never
|
|
135
147
|
}
|
package/src/node/types.ts
CHANGED
|
@@ -6,6 +6,9 @@ export type Conversions = (typeof CONVERSIONS)[number]
|
|
|
6
6
|
export type Functions = (typeof FUNCTIONS)[number]
|
|
7
7
|
export type Operators = (typeof OPERATOR_KEYS)[number]
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* scope
|
|
11
|
+
*/
|
|
9
12
|
export interface FnLayout {
|
|
10
13
|
name: string
|
|
11
14
|
type: Constants | 'auto'
|
|
@@ -15,8 +18,13 @@ export interface FnLayout {
|
|
|
15
18
|
}>
|
|
16
19
|
}
|
|
17
20
|
|
|
21
|
+
export interface FnType<T extends NodeProxy | StructNode | void, Args extends any[]> {
|
|
22
|
+
(...args: Args): T extends void ? Void : T
|
|
23
|
+
setLayout(layout: FnLayout): FnType<T, Args>
|
|
24
|
+
}
|
|
25
|
+
|
|
18
26
|
/**
|
|
19
|
-
*
|
|
27
|
+
* node
|
|
20
28
|
*/
|
|
21
29
|
export type NodeTypes =
|
|
22
30
|
// headers
|
|
@@ -48,7 +56,7 @@ export type NodeTypes =
|
|
|
48
56
|
| 'declare'
|
|
49
57
|
| 'return'
|
|
50
58
|
|
|
51
|
-
export interface NodeProps
|
|
59
|
+
export interface NodeProps {
|
|
52
60
|
id?: string
|
|
53
61
|
args?: any[]
|
|
54
62
|
type?: string
|
|
@@ -56,8 +64,8 @@ export interface NodeProps<T extends Record<string, NodeProxy> = {}> {
|
|
|
56
64
|
inferFrom?: any[]
|
|
57
65
|
layout?: FnLayout
|
|
58
66
|
// for struct
|
|
59
|
-
fields?:
|
|
60
|
-
initialValues?:
|
|
67
|
+
fields?: StructFields
|
|
68
|
+
initialValues?: StructFields
|
|
61
69
|
}
|
|
62
70
|
|
|
63
71
|
export interface NodeContext {
|
|
@@ -75,6 +83,7 @@ export interface NodeContext {
|
|
|
75
83
|
vertVaryings: Map<string, string>
|
|
76
84
|
computeInputs: Map<string, string>
|
|
77
85
|
dependencies: Map<string, Set<string>>
|
|
86
|
+
structFields: Map<string, StructFields>
|
|
78
87
|
}
|
|
79
88
|
}
|
|
80
89
|
|
|
@@ -144,6 +153,7 @@ type NodeProxyMethods =
|
|
|
144
153
|
| Conversions
|
|
145
154
|
| Swizzles
|
|
146
155
|
// system property
|
|
156
|
+
| '__nodeType'
|
|
147
157
|
| 'type'
|
|
148
158
|
| 'props'
|
|
149
159
|
| 'isProxy'
|
|
@@ -159,8 +169,9 @@ type ReadNodeProxy = {
|
|
|
159
169
|
}
|
|
160
170
|
|
|
161
171
|
// Internal NodeProxy implementation (renamed from original)
|
|
162
|
-
type NodeProxyImpl<T extends Constants
|
|
172
|
+
type NodeProxyImpl<T extends Constants> = BaseNodeProxy<T> & ReadNodeProxy
|
|
163
173
|
|
|
174
|
+
export type Void = NodeProxyImpl<'void'>
|
|
164
175
|
export type Bool = NodeProxyImpl<'bool'>
|
|
165
176
|
export type UInt = NodeProxyImpl<'uint'>
|
|
166
177
|
export type Int = NodeProxyImpl<'int'>
|
|
@@ -184,8 +195,19 @@ export type Mat4 = NodeProxyImpl<'mat4'>
|
|
|
184
195
|
export type Texture = NodeProxyImpl<'texture'>
|
|
185
196
|
export type Sampler2D = NodeProxyImpl<'sampler2D'>
|
|
186
197
|
export type Struct = NodeProxyImpl<'struct'>
|
|
198
|
+
export type StructFields = Record<string, NodeProxy>
|
|
199
|
+
export type StructNode<T extends StructFields = any> = Omit<Struct, keyof T> & {
|
|
200
|
+
[K in keyof T]: T[K] extends NodeProxy<infer U> ? NodeProxy<U> : never
|
|
201
|
+
} & {
|
|
202
|
+
toVar(id?: string): StructNode<T>
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export interface StructFactory<T extends StructFields> {
|
|
206
|
+
(initialValues?: StructFields, instanceId?: string): StructNode<T>
|
|
207
|
+
}
|
|
187
208
|
|
|
188
209
|
export interface ConstantsToType {
|
|
210
|
+
void: Void
|
|
189
211
|
bool: Bool
|
|
190
212
|
uint: UInt
|
|
191
213
|
int: Int
|
|
@@ -211,14 +233,15 @@ export interface ConstantsToType {
|
|
|
211
233
|
struct: Struct
|
|
212
234
|
}
|
|
213
235
|
|
|
214
|
-
export type NodeProxy<T extends Constants =
|
|
236
|
+
export type NodeProxy<T extends Constants = Constants> = T extends keyof ConstantsToType
|
|
215
237
|
? ConstantsToType[T]
|
|
216
|
-
:
|
|
238
|
+
: BaseNodeProxy<T>
|
|
217
239
|
|
|
218
|
-
export type X<T extends Constants =
|
|
240
|
+
export type X<T extends Constants = Constants> = number | string | boolean | undefined | NodeProxy<T>
|
|
219
241
|
|
|
220
242
|
export interface BaseNodeProxy<T extends Constants> {
|
|
221
243
|
// System properties
|
|
244
|
+
readonly __nodeType?: T
|
|
222
245
|
assign(x: any): NodeProxy<T>
|
|
223
246
|
toVar(name?: string): NodeProxy<T>
|
|
224
247
|
toString(c?: NodeContext): string
|
|
@@ -230,6 +253,11 @@ export interface BaseNodeProxy<T extends Constants> {
|
|
|
230
253
|
// Element access for array/matrix types
|
|
231
254
|
element<Index extends X>(index: Index): NodeProxy<InferArrayElement<T>>
|
|
232
255
|
|
|
256
|
+
// Enhanced member access with type preservation
|
|
257
|
+
member<K extends string>(
|
|
258
|
+
key: K
|
|
259
|
+
): K extends keyof T ? (T[K] extends NodeProxy<infer U> ? NodeProxy<U> : never) : never
|
|
260
|
+
|
|
233
261
|
// Operators methods
|
|
234
262
|
add<U extends Constants>(x: X<U>): NodeProxy<InferOperator<T, U>>
|
|
235
263
|
sub<U extends Constants>(x: X<U>): NodeProxy<InferOperator<T, U>>
|
|
@@ -305,41 +333,41 @@ export interface BaseNodeProxy<T extends Constants> {
|
|
|
305
333
|
* 2.1. const.ts FUNCTIONS
|
|
306
334
|
*/
|
|
307
335
|
// 0. Component-wise functions
|
|
308
|
-
abs(): NodeProxy
|
|
309
|
-
acos(): NodeProxy
|
|
310
|
-
acosh(): NodeProxy
|
|
311
|
-
asin(): NodeProxy
|
|
312
|
-
asinh(): NodeProxy
|
|
313
|
-
atan(): NodeProxy
|
|
314
|
-
atanh(): NodeProxy
|
|
315
|
-
ceil(): NodeProxy
|
|
316
|
-
cos(): NodeProxy
|
|
317
|
-
cosh(): NodeProxy
|
|
318
|
-
degrees(): NodeProxy
|
|
319
|
-
dFdx(): NodeProxy
|
|
320
|
-
dFdy(): NodeProxy
|
|
321
|
-
exp(): NodeProxy
|
|
322
|
-
exp2(): NodeProxy
|
|
323
|
-
floor(): NodeProxy
|
|
324
|
-
fract(): NodeProxy
|
|
325
|
-
fwidth(): NodeProxy
|
|
326
|
-
inverseSqrt(): NodeProxy
|
|
327
|
-
log(): NodeProxy
|
|
328
|
-
log2(): NodeProxy
|
|
329
|
-
negate(): NodeProxy
|
|
330
|
-
normalize(): NodeProxy
|
|
331
|
-
oneMinus(): NodeProxy
|
|
332
|
-
radians(): NodeProxy
|
|
333
|
-
reciprocal(): NodeProxy
|
|
334
|
-
round(): NodeProxy
|
|
335
|
-
saturate(): NodeProxy
|
|
336
|
-
sign(): NodeProxy
|
|
337
|
-
sin(): NodeProxy
|
|
338
|
-
sinh(): NodeProxy
|
|
339
|
-
sqrt(): NodeProxy
|
|
340
|
-
tan(): NodeProxy
|
|
341
|
-
tanh(): NodeProxy
|
|
342
|
-
trunc(): NodeProxy
|
|
336
|
+
abs(): NodeProxy<T>
|
|
337
|
+
acos(): NodeProxy<T>
|
|
338
|
+
acosh(): NodeProxy<T>
|
|
339
|
+
asin(): NodeProxy<T>
|
|
340
|
+
asinh(): NodeProxy<T>
|
|
341
|
+
atan(): NodeProxy<T>
|
|
342
|
+
atanh(): NodeProxy<T>
|
|
343
|
+
ceil(): NodeProxy<T>
|
|
344
|
+
cos(): NodeProxy<T>
|
|
345
|
+
cosh(): NodeProxy<T>
|
|
346
|
+
degrees(): NodeProxy<T>
|
|
347
|
+
dFdx(): NodeProxy<T>
|
|
348
|
+
dFdy(): NodeProxy<T>
|
|
349
|
+
exp(): NodeProxy<T>
|
|
350
|
+
exp2(): NodeProxy<T>
|
|
351
|
+
floor(): NodeProxy<T>
|
|
352
|
+
fract(): NodeProxy<T>
|
|
353
|
+
fwidth(): NodeProxy<T>
|
|
354
|
+
inverseSqrt(): NodeProxy<T>
|
|
355
|
+
log(): NodeProxy<T>
|
|
356
|
+
log2(): NodeProxy<T>
|
|
357
|
+
negate(): NodeProxy<T>
|
|
358
|
+
normalize(): NodeProxy<T>
|
|
359
|
+
oneMinus(): NodeProxy<T>
|
|
360
|
+
radians(): NodeProxy<T>
|
|
361
|
+
reciprocal(): NodeProxy<T>
|
|
362
|
+
round(): NodeProxy<T>
|
|
363
|
+
saturate(): NodeProxy<T>
|
|
364
|
+
sign(): NodeProxy<T>
|
|
365
|
+
sin(): NodeProxy<T>
|
|
366
|
+
sinh(): NodeProxy<T>
|
|
367
|
+
sqrt(): NodeProxy<T>
|
|
368
|
+
tan(): NodeProxy<T>
|
|
369
|
+
tanh(): NodeProxy<T>
|
|
370
|
+
trunc(): NodeProxy<T>
|
|
343
371
|
|
|
344
372
|
// 1. Functions where first argument determines return type
|
|
345
373
|
atan2<U extends Constants>(x: X<U>): NodeProxy<T>
|
package/src/node/utils/const.ts
CHANGED
|
@@ -51,9 +51,10 @@ export const TYPE_MAPPING = {
|
|
|
51
51
|
struct: 'struct',
|
|
52
52
|
} as const
|
|
53
53
|
|
|
54
|
-
export const CONSTANTS = Object.keys(TYPE_MAPPING) as
|
|
54
|
+
export const CONSTANTS = Object.keys(TYPE_MAPPING) as (keyof typeof TYPE_MAPPING)[]
|
|
55
55
|
|
|
56
56
|
export const OPERATORS = {
|
|
57
|
+
not: '', // IGNORED
|
|
57
58
|
add: '+',
|
|
58
59
|
sub: '-',
|
|
59
60
|
mul: '*',
|
package/src/node/utils/index.ts
CHANGED
|
@@ -85,12 +85,12 @@ export const code = <T extends Constants>(target: X<T>, c?: NodeContext | null):
|
|
|
85
85
|
if (type === 'switch') return parseSwitch(c, x, children)
|
|
86
86
|
if (type === 'declare') return parseDeclare(c, x, y)
|
|
87
87
|
if (type === 'define') {
|
|
88
|
-
if (!c.code?.headers.has(id)) c.code?.headers.set(id, parseDefine(c, props,
|
|
88
|
+
if (!c.code?.headers.has(id)) c.code?.headers.set(id, parseDefine(c, props, target))
|
|
89
89
|
return `${id}(${parseArray(children.slice(1), c)})`
|
|
90
90
|
}
|
|
91
91
|
if (type === 'struct') {
|
|
92
92
|
if (!c.code?.headers.has(id)) c.code?.headers.set(id, parseStructHead(c, id, fields))
|
|
93
|
-
return parseStruct(c, id, x.props.id,
|
|
93
|
+
return parseStruct(c, id, x.props.id, initialValues)
|
|
94
94
|
}
|
|
95
95
|
/**
|
|
96
96
|
* headers
|
package/src/node/utils/infer.ts
CHANGED
|
@@ -48,8 +48,8 @@ const inferFromArray = <T extends C>(arr: X<T>[], c: NodeContext) => {
|
|
|
48
48
|
const [x] = arr
|
|
49
49
|
if (is.str(x)) return x as T // for struct
|
|
50
50
|
const ret = infer(x, c)
|
|
51
|
-
for (const x of arr.slice(1))
|
|
52
|
-
|
|
51
|
+
// for (const x of arr.slice(1))
|
|
52
|
+
// if (ret !== infer(x, c)) throw new Error(`glre node system error: defined scope return mismatch`)
|
|
53
53
|
return ret
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -63,7 +63,6 @@ export const inferImpl = <T extends C>(target: NodeProxy<T>, c: NodeContext): T
|
|
|
63
63
|
const [x, y, z] = children
|
|
64
64
|
if (type === 'conversion') return x
|
|
65
65
|
if (type === 'operator') return inferOperator(infer(y, c), infer(z, c), x)
|
|
66
|
-
if (type === 'ternary') return inferOperator(infer(y, c), infer(z, c), 'add')
|
|
67
66
|
if (type === 'builtin') return inferBuiltin(id)
|
|
68
67
|
if (type === 'function') return inferFunction(x) || infer(y, c)
|
|
69
68
|
if (type === 'define') {
|
|
@@ -75,10 +74,11 @@ export const inferImpl = <T extends C>(target: NodeProxy<T>, c: NodeContext): T
|
|
|
75
74
|
if (type === 'member') {
|
|
76
75
|
if (isSwizzle(y)) return inferFromCount(y.length)
|
|
77
76
|
if (isNodeProxy(x)) {
|
|
78
|
-
const
|
|
79
|
-
|
|
77
|
+
const structType = infer(x, c)
|
|
78
|
+
const fields = c.code?.structFields?.get(structType)
|
|
79
|
+
if (fields && fields[y]) return infer(fields[y], c) as T
|
|
80
80
|
}
|
|
81
|
-
return 'float' as T
|
|
81
|
+
return 'float' as T
|
|
82
82
|
}
|
|
83
83
|
if (inferFrom) return inferFromArray(inferFrom, c)
|
|
84
84
|
return infer(x, c) // for uniform and storage gather and scatter
|
|
@@ -92,5 +92,5 @@ export const infer = <T extends C>(target: X<T>, c?: NodeContext | null): T => {
|
|
|
92
92
|
if (c.infers.has(target)) return c.infers.get(target) as T
|
|
93
93
|
const ret = inferImpl(target, c)
|
|
94
94
|
c.infers.set(target, ret)
|
|
95
|
-
return ret
|
|
95
|
+
return ret as T
|
|
96
96
|
}
|
package/src/node/utils/parse.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { code } from '.'
|
|
|
2
2
|
import { infer } from './infer'
|
|
3
3
|
import { getConversions, addDependency } from './utils'
|
|
4
4
|
import { is } from '../../utils/helpers'
|
|
5
|
-
import type { Constants, NodeContext, NodeProps, NodeProxy, X } from '../types'
|
|
5
|
+
import type { Constants, NodeContext, NodeProps, NodeProxy, StructFields, X } from '../types'
|
|
6
6
|
|
|
7
7
|
export const parseArray = (children: X[], c: NodeContext) => {
|
|
8
8
|
return children
|
|
@@ -87,7 +87,8 @@ export const parseDeclare = (c: NodeContext, x: X, y: X) => {
|
|
|
87
87
|
return `var ${varName}: ${wgslType} = ${code(x, c)};`
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
export const parseStructHead = (c: NodeContext, id: string, fields:
|
|
90
|
+
export const parseStructHead = (c: NodeContext, id: string, fields: StructFields = {}) => {
|
|
91
|
+
c.code?.structFields?.set(id, fields)
|
|
91
92
|
const lines: string[] = []
|
|
92
93
|
for (const key in fields) {
|
|
93
94
|
const fieldType = fields[key]
|
|
@@ -99,13 +100,8 @@ export const parseStructHead = (c: NodeContext, id: string, fields: Record<strin
|
|
|
99
100
|
return `struct ${id} {\n ${ret}\n};`
|
|
100
101
|
}
|
|
101
102
|
|
|
102
|
-
export const parseStruct = (
|
|
103
|
-
c
|
|
104
|
-
id: string,
|
|
105
|
-
instanceId = '',
|
|
106
|
-
fields?: Record<string, NodeProxy>,
|
|
107
|
-
initialValues?: Record<string, NodeProxy>
|
|
108
|
-
) => {
|
|
103
|
+
export const parseStruct = (c: NodeContext, id: string, instanceId = '', initialValues?: StructFields) => {
|
|
104
|
+
const fields = c.code?.structFields?.get(id) || {}
|
|
109
105
|
if (c.isWebGL) {
|
|
110
106
|
if (initialValues) {
|
|
111
107
|
const ordered = []
|
|
@@ -124,7 +120,7 @@ export const parseStruct = (
|
|
|
124
120
|
/**
|
|
125
121
|
* define
|
|
126
122
|
*/
|
|
127
|
-
export const parseDefine = (c: NodeContext, props: NodeProps,
|
|
123
|
+
export const parseDefine = (c: NodeContext, props: NodeProps, target: NodeProxy) => {
|
|
128
124
|
const { id, children = [], layout } = props
|
|
129
125
|
const [x, ...args] = children
|
|
130
126
|
const argParams: [name: string, type: string][] = []
|
|
@@ -137,6 +133,8 @@ export const parseDefine = (c: NodeContext, props: NodeProps, returnType: Consta
|
|
|
137
133
|
for (let i = 0; i < args.length; i++) {
|
|
138
134
|
argParams.push([`p${i}`, infer(args[i], c)])
|
|
139
135
|
}
|
|
136
|
+
const scopeCode = code(x, c) // build struct headers before inferring returnType
|
|
137
|
+
const returnType = infer(target, c)
|
|
140
138
|
const ret = []
|
|
141
139
|
if (c?.isWebGL) {
|
|
142
140
|
for (const [paramId, type] of argParams) {
|
|
@@ -152,7 +150,6 @@ export const parseDefine = (c: NodeContext, props: NodeProps, returnType: Consta
|
|
|
152
150
|
ret.push(`fn ${id}(${params}) {`)
|
|
153
151
|
} else ret.push(`fn ${id}(${params}) -> ${getConversions(returnType, c)} {`)
|
|
154
152
|
}
|
|
155
|
-
const scopeCode = code(x, c)
|
|
156
153
|
if (scopeCode) ret.push(scopeCode)
|
|
157
154
|
ret.push('}')
|
|
158
155
|
return ret.join('\n')
|
package/src/node/utils/utils.ts
CHANGED
|
@@ -34,7 +34,7 @@ export const isNodeProxy = <T extends Constants>(x: unknown): x is NodeProxy<T>
|
|
|
34
34
|
|
|
35
35
|
export const isConstants = (type?: unknown): type is Constants => {
|
|
36
36
|
if (!is.str(type)) return false
|
|
37
|
-
return CONSTANTS.includes(type)
|
|
37
|
+
return CONSTANTS.includes(type as any)
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
export const hex2rgb = (hex: number) => {
|
|
@@ -64,7 +64,7 @@ export const getConversions = <T extends Constants>(x: X<T>, c?: NodeContext) =>
|
|
|
64
64
|
return TYPE_MAPPING[x as keyof typeof TYPE_MAPPING] || x // for struct type
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
export const getOperator = (op: X
|
|
67
|
+
export const getOperator = (op: X) => {
|
|
68
68
|
return OPERATORS[op as keyof typeof OPERATORS] || op
|
|
69
69
|
}
|
|
70
70
|
|
|
@@ -86,11 +86,11 @@ export const getEventFun = (c: NodeContext, id: string, isAttribute = false, isT
|
|
|
86
86
|
|
|
87
87
|
export const safeEventCall = <T extends Constants>(x: X<T>, fun: (value: unknown) => void) => {
|
|
88
88
|
if (is.und(x)) return
|
|
89
|
-
if (!isNodeProxy(x)) return fun(x) // for uniform(1)
|
|
89
|
+
if (!isNodeProxy(x)) return fun(x) // for uniform(0) or uniform([0, 1])
|
|
90
90
|
if (x.type !== 'conversion') return
|
|
91
|
-
const
|
|
92
|
-
if (
|
|
93
|
-
fun(
|
|
91
|
+
const args = x.props.children?.slice(1)
|
|
92
|
+
if (is.und(args?.[0])) return // ignore if uniform(vec2())
|
|
93
|
+
fun(args.map((x) => x ?? args[0])) // for uniform(vec2(1)) or uniform(vec2(1, 1))
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
export const initNodeContext = (c: NodeContext) => {
|
|
@@ -103,6 +103,7 @@ export const initNodeContext = (c: NodeContext) => {
|
|
|
103
103
|
vertVaryings: new Map(),
|
|
104
104
|
computeInputs: new Map(),
|
|
105
105
|
dependencies: new Map(),
|
|
106
|
+
structFields: new Map(),
|
|
106
107
|
}
|
|
107
108
|
if (c.isWebGL) return c
|
|
108
109
|
c.code.fragInputs.set('position', '@builtin(position) position: vec4f')
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { EventState, Nested } from 'reev'
|
|
2
2
|
import type { Fun, Queue, Frame } from 'refr'
|
|
3
|
-
import type { NodeProxy, Vec4 } from './node'
|
|
3
|
+
import type { NodeProxy, Vec4, Void } from './node'
|
|
4
4
|
export type { Fun, Queue, Frame }
|
|
5
5
|
|
|
6
6
|
export type GL = EventState<{
|
|
@@ -21,13 +21,13 @@ export type GL = EventState<{
|
|
|
21
21
|
particles: 64 | 256 | 576 | 1024 | 1600 | 2304 | 3136 | 4096 | 4096 | 5184 | 6400 // (8k)^2
|
|
22
22
|
el: HTMLCanvasElement
|
|
23
23
|
vs?: string | Vec4
|
|
24
|
-
cs?: string |
|
|
24
|
+
cs?: string | Void
|
|
25
25
|
fs?: string | Vec4
|
|
26
26
|
vert?: string | Vec4
|
|
27
|
-
comp?: string |
|
|
27
|
+
comp?: string | Void
|
|
28
28
|
frag?: string | Vec4
|
|
29
29
|
vertex?: string | Vec4
|
|
30
|
-
compute?: string |
|
|
30
|
+
compute?: string | Void
|
|
31
31
|
fragment?: string | Vec4
|
|
32
32
|
|
|
33
33
|
/**
|
package/src/utils/program.ts
CHANGED
|
@@ -9,7 +9,7 @@ const createShader = (c: WebGLRenderingContext, source: string, type: number, on
|
|
|
9
9
|
if (c.getShaderParameter(shader, c.COMPILE_STATUS)) return shader
|
|
10
10
|
const error = c.getShaderInfoLog(shader)
|
|
11
11
|
c.deleteShader(shader)
|
|
12
|
-
onError(`Could not compile shader: ${error}`)
|
|
12
|
+
onError(`Could not compile shader: ${error}\n\n↓↓↓generated↓↓↓\n${source}`)
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export const createProgram = (c: WebGLRenderingContext, frag: string, vert: string, gl: GL) => {
|