Skip to content

Commit 6af0ab5

Browse files
committed
Add hookTypes
1 parent af60d1b commit 6af0ab5

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed

src/webgl/p5.Shader.js

+73
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,79 @@ class Shader {
5252
};
5353
}
5454

55+
hookTypes(hookName) {
56+
let fullSrc = this._vertSrc;
57+
let body = this.hooks.vertex[hookName];
58+
if (!body) {
59+
body = this.hooks.fragment[hookName];
60+
fullSrc = this._fragSrc;
61+
}
62+
if (!body) {
63+
throw new Error(`Can't find hook ${hookName}!`);
64+
}
65+
const nameParts = hookName.split(/\s+/g);
66+
const functionName = nameParts.pop();
67+
const returnType = nameParts.pop();
68+
const returnQualifiers = [...nameParts];
69+
70+
const parameterMatch = /\(([^\)]*)\)/.exec(body);
71+
if (!parameterMatch) {
72+
throw new Error(`Couldn't find function parameters in hook body:\n${body}`);
73+
}
74+
75+
const structProperties = structName => {
76+
const structDefMatch = new RegExp(`struct\\s+${structName}\\s*\{([^\}]*)\}`).exec(fullSrc);
77+
if (!structDefMatch) return undefined;
78+
79+
const properties = [];
80+
for (const defSrc of structDefMatch[1].split(';')) {
81+
// E.g. `int var1, var2;` or `MyStruct prop;`
82+
const parts = defSrc.trim().split(/\s+|,/g);
83+
const typeName = parts.shift();
84+
const names = [...parts];
85+
const typeProperties = structProperties(typeName);
86+
for (const name of names) {
87+
properties.push({
88+
name,
89+
type: {
90+
typeName,
91+
qualifiers: [],
92+
properties: typeProperties,
93+
},
94+
});
95+
}
96+
}
97+
return properties;
98+
};
99+
100+
const parameters = parameterMatch[1].split(',').map(paramString => {
101+
// e.g. `int prop` or `in sampler2D prop` or `const float prop`
102+
const parts = paramString.trim().split(/\s+/g);
103+
const name = parts.pop();
104+
const typeName = parts.pop();
105+
const qualifiers = [...parts];
106+
const properties = structProperties(typeName);
107+
return {
108+
name,
109+
type: {
110+
typeName,
111+
qualifiers,
112+
properties,
113+
}
114+
}
115+
});
116+
117+
return {
118+
name: functionName,
119+
returnType: {
120+
typeName: returnType,
121+
qualifiers: returnQualifiers,
122+
properties: structProperties(returnType)
123+
},
124+
parameters
125+
};
126+
}
127+
55128
shaderSrc(src, shaderType) {
56129
const main = 'void main';
57130
let [preMain, postMain] = src.split(main);

test/unit/webgl/p5.Shader.js

+57
Original file line numberDiff line numberDiff line change
@@ -334,4 +334,61 @@ suite('p5.Shader', function() {
334334
});
335335
});
336336
});
337+
338+
suite('hookTypes', function() {
339+
test('Produces expected types on baseFilterShader()', function() {
340+
const types = myp5.baseFilterShader().hookTypes('vec4 getColor');
341+
assert.deepEqual(types, {
342+
name: 'getColor',
343+
returnType: {
344+
typeName: 'vec4',
345+
qualifiers: [],
346+
properties: undefined,
347+
},
348+
parameters: [
349+
{
350+
name: 'inputs',
351+
type: {
352+
typeName: 'FilterInputs',
353+
qualifiers: [],
354+
properties: [
355+
{
356+
name: 'texCoord',
357+
type: {
358+
typeName: 'vec2',
359+
qualifiers: [],
360+
properties: undefined,
361+
}
362+
},
363+
{
364+
name: 'canvasSize',
365+
type: {
366+
typeName: 'vec2',
367+
qualifiers: [],
368+
properties: undefined,
369+
}
370+
},
371+
{
372+
name: 'texelSize',
373+
type: {
374+
typeName: 'vec2',
375+
qualifiers: [],
376+
properties: undefined,
377+
}
378+
},
379+
],
380+
}
381+
},
382+
{
383+
name: 'content',
384+
type: {
385+
typeName: 'sampler2D',
386+
qualifiers: ['in'],
387+
properties: undefined,
388+
}
389+
}
390+
]
391+
});
392+
});
393+
});
337394
});

0 commit comments

Comments
 (0)