@openhps/core
Version:
Open Hybrid Positioning System - Core component
109 lines (103 loc) • 3.53 kB
JavaScript
import TempNode from '../core/TempNode.js';
import { addMethodChaining, nodeArray, nodeObject, nodeObjects, float } from '../tsl/TSLCore.js';
/**
* This module represents the call of a {@link FunctionNode}. Developers are usually not confronted
* with this module since they use the predefined TSL syntax `wgslFn` and `glslFn` which encapsulate
* this logic.
*
* @augments TempNode
*/
class FunctionCallNode extends TempNode {
static get type() {
return 'FunctionCallNode';
}
/**
* Constructs a new function call node.
*
* @param {?FunctionNode} functionNode - The function node.
* @param {Object<string, Node>} [parameters={}] - The parameters for the function call.
*/
constructor(functionNode = null, parameters = {}) {
super();
/**
* The function node.
*
* @type {?FunctionNode}
* @default null
*/
this.functionNode = functionNode;
/**
* The parameters of the function call.
*
* @type {Object<string, Node>}
* @default {}
*/
this.parameters = parameters;
}
/**
* Sets the parameters of the function call node.
*
* @param {Object<string, Node>} parameters - The parameters to set.
* @return {FunctionCallNode} A reference to this node.
*/
setParameters(parameters) {
this.parameters = parameters;
return this;
}
/**
* Returns the parameters of the function call node.
*
* @return {Object<string, Node>} The parameters of this node.
*/
getParameters() {
return this.parameters;
}
getNodeType(builder) {
return this.functionNode.getNodeType(builder);
}
generate(builder) {
const params = [];
const functionNode = this.functionNode;
const inputs = functionNode.getInputs(builder);
const parameters = this.parameters;
const generateInput = (node, inputNode) => {
const type = inputNode.type;
const pointer = type === 'pointer';
let output;
if (pointer) output = '&' + node.build(builder);else output = node.build(builder, type);
return output;
};
if (Array.isArray(parameters)) {
if (parameters.length > inputs.length) {
console.error('THREE.TSL: The number of provided parameters exceeds the expected number of inputs in \'Fn()\'.');
parameters.length = inputs.length;
} else if (parameters.length < inputs.length) {
console.error('THREE.TSL: The number of provided parameters is less than the expected number of inputs in \'Fn()\'.');
while (parameters.length < inputs.length) {
parameters.push(float(0));
}
}
for (let i = 0; i < parameters.length; i++) {
params.push(generateInput(parameters[i], inputs[i]));
}
} else {
for (const inputNode of inputs) {
const node = parameters[inputNode.name];
if (node !== undefined) {
params.push(generateInput(node, inputNode));
} else {
console.error(`THREE.TSL: Input '${inputNode.name}' not found in \'Fn()\'.`);
params.push(generateInput(float(0), inputNode));
}
}
}
const functionName = functionNode.build(builder, 'property');
return `${functionName}( ${params.join(', ')} )`;
}
}
export default FunctionCallNode;
export const call = (func, ...params) => {
params = params.length > 1 || params[0] && params[0].isNode === true ? nodeArray(params) : nodeObjects(params[0]);
return nodeObject(new FunctionCallNode(nodeObject(func), params));
};
addMethodChaining('call', call);