@openhps/core
Version:
Open Hybrid Positioning System - Core component
119 lines (111 loc) • 3.44 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.overloadingFn = exports.default = void 0;
var _Node = _interopRequireDefault(require("../core/Node.js"));
var _TSLCore = require("../tsl/TSLCore.js");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* This class allows to define multiple overloaded versions
* of the same function. Depending on the parameters of the function
* call, the node picks the best-fit overloaded version.
*
* @augments Node
*/
class FunctionOverloadingNode extends _Node.default {
static get type() {
return 'FunctionOverloadingNode';
}
/**
* Constructs a new function overloading node.
*
* @param {Array<Function>} functionNodes - Array of `Fn` function definitions.
* @param {...Node} parametersNodes - A list of parameter nodes.
*/
constructor(functionNodes = [], ...parametersNodes) {
super();
/**
* Array of `Fn` function definitions.
*
* @type {Array<Function>}
*/
this.functionNodes = functionNodes;
/**
* A list of parameter nodes.
*
* @type {Array<Node>}
*/
this.parametersNodes = parametersNodes;
/**
* The selected overloaded function call.
*
* @private
* @type {ShaderCallNodeInternal}
*/
this._candidateFnCall = null;
/**
* This node is marked as global.
*
* @type {boolean}
* @default true
*/
this.global = true;
}
/**
* This method is overwritten since the node type is inferred from
* the function's return type.
*
* @param {NodeBuilder} builder - The current node builder.
* @return {string} The node type.
*/
getNodeType() {
return this.functionNodes[0].shaderNode.layout.type;
}
setup(builder) {
const params = this.parametersNodes;
let candidateFnCall = this._candidateFnCall;
if (candidateFnCall === null) {
let candidateFn = null;
let candidateScore = -1;
for (const functionNode of this.functionNodes) {
const shaderNode = functionNode.shaderNode;
const layout = shaderNode.layout;
if (layout === null) {
throw new Error('FunctionOverloadingNode: FunctionNode must be a layout.');
}
const inputs = layout.inputs;
if (params.length === inputs.length) {
let score = 0;
for (let i = 0; i < params.length; i++) {
const param = params[i];
const input = inputs[i];
if (param.getNodeType(builder) === input.type) {
score++;
} else {
score = 0;
}
}
if (score > candidateScore) {
candidateFn = functionNode;
candidateScore = score;
}
}
}
this._candidateFnCall = candidateFnCall = candidateFn(...params);
}
return candidateFnCall;
}
}
var _default = exports.default = FunctionOverloadingNode;
const overloadingBaseFn = /*@__PURE__*/(0, _TSLCore.nodeProxy)(FunctionOverloadingNode);
/**
* TSL function for creating a function overloading node.
*
* @tsl
* @function
* @param {Array<Function>} functionNodes - Array of `Fn` function definitions.
* @returns {FunctionOverloadingNode}
*/
const overloadingFn = functionNodes => (...params) => overloadingBaseFn(functionNodes, ...params);
exports.overloadingFn = overloadingFn;