96 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			96 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | import Node, { addNodeClass } from '../core/Node.js'; | ||
|  | import { nodeProxy } from '../shadernode/ShaderNode.js'; | ||
|  | 
 | ||
|  | class FunctionOverloadingNode extends Node { | ||
|  | 
 | ||
|  | 	constructor( functionNodes = [], ...parametersNodes ) { | ||
|  | 
 | ||
|  | 		super(); | ||
|  | 
 | ||
|  | 		this.functionNodes = functionNodes; | ||
|  | 		this.parametersNodes = parametersNodes; | ||
|  | 
 | ||
|  | 		this._candidateFnCall = null; | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	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; | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | export default FunctionOverloadingNode; | ||
|  | 
 | ||
|  | const overloadingBaseFn = nodeProxy( FunctionOverloadingNode ); | ||
|  | 
 | ||
|  | export const overloadingFn = ( functionNodes ) => ( ...params ) => overloadingBaseFn( functionNodes, ...params ); | ||
|  | 
 | ||
|  | addNodeClass( 'FunctionOverloadingNode', FunctionOverloadingNode ); |