Skip to content

Commit 189214e

Browse files
committed
TSL: Function Overloading
1 parent 28d1942 commit 189214e

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

examples/jsm/nodes/Nodes.js

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export { default as ArrayElementNode } from './utils/ArrayElementNode.js';
4949
export { default as ConvertNode } from './utils/ConvertNode.js';
5050
export { default as DiscardNode, discard } from './utils/DiscardNode.js';
5151
export { default as EquirectUVNode, equirectUV } from './utils/EquirectUVNode.js';
52+
export { default as FunctionOverloadingNode, overloadingFn } from './utils/FunctionOverloadingNode.js';
5253
export { default as JoinNode } from './utils/JoinNode.js';
5354
export { default as LoopNode, loop } from './utils/LoopNode.js';
5455
export { default as MatcapUVNode, matcapUV } from './utils/MatcapUVNode.js';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import Node, { addNodeClass } from '../core/Node.js';
2+
import { nodeProxy } from '../shadernode/ShaderNode.js';
3+
4+
class FunctionOverloadingNode extends Node {
5+
6+
constructor( functionNodes = [], ...parametersNodes ) {
7+
8+
super();
9+
10+
this.functionNodes = functionNodes;
11+
this.parametersNodes = parametersNodes;
12+
13+
this._candidateFnCall = null;
14+
15+
}
16+
17+
getNodeType() {
18+
19+
return this.functionNodes[ 0 ].shaderNode.layout.type;
20+
21+
}
22+
23+
setup( builder ) {
24+
25+
const params = this.parametersNodes;
26+
27+
let candidateFnCall = this._candidateFnCall;
28+
29+
if ( candidateFnCall === null ) {
30+
31+
let candidateFn = null;
32+
let candidateScore = - 1;
33+
34+
for ( const functionNode of this.functionNodes ) {
35+
36+
const shaderNode = functionNode.shaderNode;
37+
const layout = shaderNode.layout;
38+
39+
if ( layout === null ) {
40+
41+
throw new Error( 'FunctionOverloadingNode: FunctionNode must be a layout.' );
42+
43+
}
44+
45+
const inputs = layout.inputs;
46+
47+
if ( params.length === inputs.length ) {
48+
49+
let score = 0;
50+
51+
for ( let i = 0; i < params.length; i ++ ) {
52+
53+
const param = params[ i ];
54+
const input = inputs[ i ];
55+
56+
if ( param.getNodeType( builder ) === input.type ) {
57+
58+
score ++;
59+
60+
} else {
61+
62+
score = 0;
63+
64+
}
65+
66+
}
67+
68+
if ( score > candidateScore ) {
69+
70+
candidateFn = functionNode;
71+
candidateScore = score;
72+
73+
}
74+
75+
}
76+
77+
}
78+
79+
this._candidateFnCall = candidateFnCall = candidateFn( ...params );
80+
81+
}
82+
83+
return candidateFnCall;
84+
85+
}
86+
87+
}
88+
89+
export default FunctionOverloadingNode;
90+
91+
const overloadingBaseFn = nodeProxy( FunctionOverloadingNode );
92+
93+
export const overloadingFn = ( functionNodes ) => ( ...params ) => overloadingBaseFn( functionNodes, ...params );
94+
95+
addNodeClass( 'FunctionOverloadingNode', FunctionOverloadingNode );

0 commit comments

Comments
 (0)