Explorar o código

TSL: Improve `Fn()` warning if not invoked. (#31552)

sunag hai 11 meses
pai
achega
c50e2574d6
Modificáronse 1 ficheiros con 101 adicións e 51 borrados
  1. 101 51
      src/nodes/tsl/TSLCore.js

+ 101 - 51
src/nodes/tsl/TSLCore.js

@@ -611,7 +611,13 @@ const ConvertType = function ( type, cacheMap = null ) {
 
 	return ( ...params ) => {
 
-		if ( params.length === 0 || ( ! [ 'bool', 'float', 'int', 'uint' ].includes( type ) && params.every( param => typeof param !== 'object' ) ) ) {
+		if ( params.length === 0 || ( ! [ 'bool', 'float', 'int', 'uint' ].includes( type ) && params.every( param => {
+
+			const paramType = typeof param;
+
+			return paramType !== 'object' && paramType !== 'function';
+
+		} ) ) ) {
 
 			params = [ getValueFromType( type, ...params ) ];
 
@@ -664,37 +670,90 @@ export const nodeProxyIntent = ( NodeClass, scope = null, factor = null, setting
 
 let fnId = 0;
 
-export const Fn = ( jsFunc, layout = null ) => {
+class FnNode extends Node {
 
-	let nodeType = null;
+	constructor( jsFunc, layout = null ) {
 
-	if ( layout !== null ) {
-
-		if ( typeof layout === 'object' ) {
+		super();
 
-			nodeType = layout.return;
+		let nodeType = null;
 
-		} else {
+		if ( layout !== null ) {
 
-			if ( typeof layout === 'string' ) {
+			if ( typeof layout === 'object' ) {
 
-				nodeType = layout;
+				nodeType = layout.return;
 
 			} else {
 
-				console.error( 'THREE.TSL: Invalid layout type.' );
+				if ( typeof layout === 'string' ) {
+
+					nodeType = layout;
+
+				} else {
+
+					console.error( 'THREE.TSL: Invalid layout type.' );
+
+				}
+
+				layout = null;
+
+			}
+
+		}
+
+		this.shaderNode = new ShaderNode( jsFunc, nodeType );
+
+		if ( layout !== null ) {
+
+			this.setLayout( layout );
+
+		}
+
+		this.isFn = true;
+
+	}
+
+	setLayout( layout ) {
+
+		const nodeType = this.shaderNode.nodeType;
+
+		if ( typeof layout.inputs !== 'object' ) {
+
+			const fullLayout = {
+				name: 'fn' + fnId ++,
+				type: nodeType,
+				inputs: []
+			};
+
+			for ( const name in layout ) {
+
+				if ( name === 'return' ) continue;
+
+				fullLayout.inputs.push( {
+					name: name,
+					type: layout[ name ]
+				} );
 
 			}
 
-			layout = null;
+			layout = fullLayout;
 
 		}
 
+		this.shaderNode.setLayout( layout );
+
+		return this;
+
 	}
 
-	const shaderNode = new ShaderNode( jsFunc, nodeType );
+	getNodeType( builder ) {
+
+		return this.shaderNode.getNodeType( builder ) || 'float';
+
+	}
 
-	const fn = ( ...params ) => {
+	call( ...params ) {
 
 		let inputs;
 
@@ -712,71 +771,62 @@ export const Fn = ( jsFunc, layout = null ) => {
 
 		}
 
-		const fnCall = shaderNode.call( inputs );
+		const fnCall = this.shaderNode.call( inputs );
 
-		if ( nodeType === 'void' ) fnCall.toStack();
+		if ( this.shaderNode.nodeType === 'void' ) fnCall.toStack();
 
 		return fnCall.toVarIntent();
 
-	};
+	}
 
-	fn.shaderNode = shaderNode;
-	fn.id = shaderNode.id;
+	once( subBuilds = null ) {
 
-	fn.isFn = true;
+		this.shaderNode.once = true;
+		this.shaderNode.subBuilds = subBuilds;
 
-	fn.getNodeType = ( ...params ) => shaderNode.getNodeType( ...params );
-	fn.getCacheKey = ( ...params ) => shaderNode.getCacheKey( ...params );
+		return this;
 
-	fn.setLayout = ( layout ) => {
+	}
 
-		shaderNode.setLayout( layout );
+	generate( builder ) {
 
-		return fn;
+		const type = this.getNodeType( builder );
 
-	};
+		console.warn( 'THREE.TSL: "Fn()" was declared but not invoked. Try calling it like "Fn()( ...params )".' );
 
-	fn.once = ( subBuilds = null ) => {
+		return builder.generateConst( type );
 
-		shaderNode.once = true;
-		shaderNode.subBuilds = subBuilds;
+	}
 
-		return fn;
+}
 
-	};
+export function Fn( jsFunc, layout = null ) {
 
-	if ( layout !== null ) {
+	const instance = new FnNode( jsFunc, layout );
 
-		if ( typeof layout.inputs !== 'object' ) {
+	return new Proxy( () => {}, {
 
-			const fullLayout = {
-				name: 'fn' + fnId ++,
-				type: nodeType,
-				inputs: []
-			};
+		apply( target, thisArg, params ) {
 
-			for ( const name in layout ) {
+			return instance.call( ...params );
 
-				if ( name === 'return' ) continue;
+		},
 
-				fullLayout.inputs.push( {
-					name: name,
-					type: layout[ name ]
-				} );
+		get( target, prop, receiver ) {
 
-			}
+			return Reflect.get( instance, prop, receiver );
 
-			layout = fullLayout;
+		},
 
-		}
+		set( target, prop, value, receiver ) {
 
-		fn.setLayout( layout );
+			return Reflect.set( instance, prop, value, receiver );
 
-	}
+		}
 
-	return fn;
+	} );
 
-};
+}
 
 //
 

粤ICP备19079148号