Skip to content

Commit c50e257

Browse files
authored
TSL: Improve Fn() warning if not invoked. (#31552)
1 parent ac6a8e0 commit c50e257

File tree

1 file changed

+101
-51
lines changed

1 file changed

+101
-51
lines changed

src/nodes/tsl/TSLCore.js

Lines changed: 101 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,13 @@ const ConvertType = function ( type, cacheMap = null ) {
611611

612612
return ( ...params ) => {
613613

614-
if ( params.length === 0 || ( ! [ 'bool', 'float', 'int', 'uint' ].includes( type ) && params.every( param => typeof param !== 'object' ) ) ) {
614+
if ( params.length === 0 || ( ! [ 'bool', 'float', 'int', 'uint' ].includes( type ) && params.every( param => {
615+
616+
const paramType = typeof param;
617+
618+
return paramType !== 'object' && paramType !== 'function';
619+
620+
} ) ) ) {
615621

616622
params = [ getValueFromType( type, ...params ) ];
617623

@@ -664,37 +670,90 @@ export const nodeProxyIntent = ( NodeClass, scope = null, factor = null, setting
664670

665671
let fnId = 0;
666672

667-
export const Fn = ( jsFunc, layout = null ) => {
673+
class FnNode extends Node {
668674

669-
let nodeType = null;
675+
constructor( jsFunc, layout = null ) {
670676

671-
if ( layout !== null ) {
672-
673-
if ( typeof layout === 'object' ) {
677+
super();
674678

675-
nodeType = layout.return;
679+
let nodeType = null;
676680

677-
} else {
681+
if ( layout !== null ) {
678682

679-
if ( typeof layout === 'string' ) {
683+
if ( typeof layout === 'object' ) {
680684

681-
nodeType = layout;
685+
nodeType = layout.return;
682686

683687
} else {
684688

685-
console.error( 'THREE.TSL: Invalid layout type.' );
689+
if ( typeof layout === 'string' ) {
690+
691+
nodeType = layout;
692+
693+
} else {
694+
695+
console.error( 'THREE.TSL: Invalid layout type.' );
696+
697+
}
698+
699+
layout = null;
700+
701+
}
702+
703+
}
704+
705+
this.shaderNode = new ShaderNode( jsFunc, nodeType );
706+
707+
if ( layout !== null ) {
708+
709+
this.setLayout( layout );
710+
711+
}
712+
713+
this.isFn = true;
714+
715+
}
716+
717+
setLayout( layout ) {
718+
719+
const nodeType = this.shaderNode.nodeType;
720+
721+
if ( typeof layout.inputs !== 'object' ) {
722+
723+
const fullLayout = {
724+
name: 'fn' + fnId ++,
725+
type: nodeType,
726+
inputs: []
727+
};
728+
729+
for ( const name in layout ) {
730+
731+
if ( name === 'return' ) continue;
732+
733+
fullLayout.inputs.push( {
734+
name: name,
735+
type: layout[ name ]
736+
} );
686737

687738
}
688739

689-
layout = null;
740+
layout = fullLayout;
690741

691742
}
692743

744+
this.shaderNode.setLayout( layout );
745+
746+
return this;
747+
693748
}
694749

695-
const shaderNode = new ShaderNode( jsFunc, nodeType );
750+
getNodeType( builder ) {
751+
752+
return this.shaderNode.getNodeType( builder ) || 'float';
753+
754+
}
696755

697-
const fn = ( ...params ) => {
756+
call( ...params ) {
698757

699758
let inputs;
700759

@@ -712,71 +771,62 @@ export const Fn = ( jsFunc, layout = null ) => {
712771

713772
}
714773

715-
const fnCall = shaderNode.call( inputs );
774+
const fnCall = this.shaderNode.call( inputs );
716775

717-
if ( nodeType === 'void' ) fnCall.toStack();
776+
if ( this.shaderNode.nodeType === 'void' ) fnCall.toStack();
718777

719778
return fnCall.toVarIntent();
720779

721-
};
780+
}
722781

723-
fn.shaderNode = shaderNode;
724-
fn.id = shaderNode.id;
782+
once( subBuilds = null ) {
725783

726-
fn.isFn = true;
784+
this.shaderNode.once = true;
785+
this.shaderNode.subBuilds = subBuilds;
727786

728-
fn.getNodeType = ( ...params ) => shaderNode.getNodeType( ...params );
729-
fn.getCacheKey = ( ...params ) => shaderNode.getCacheKey( ...params );
787+
return this;
730788

731-
fn.setLayout = ( layout ) => {
789+
}
732790

733-
shaderNode.setLayout( layout );
791+
generate( builder ) {
734792

735-
return fn;
793+
const type = this.getNodeType( builder );
736794

737-
};
795+
console.warn( 'THREE.TSL: "Fn()" was declared but not invoked. Try calling it like "Fn()( ...params )".' );
738796

739-
fn.once = ( subBuilds = null ) => {
797+
return builder.generateConst( type );
740798

741-
shaderNode.once = true;
742-
shaderNode.subBuilds = subBuilds;
799+
}
743800

744-
return fn;
801+
}
745802

746-
};
803+
export function Fn( jsFunc, layout = null ) {
747804

748-
if ( layout !== null ) {
805+
const instance = new FnNode( jsFunc, layout );
749806

750-
if ( typeof layout.inputs !== 'object' ) {
807+
return new Proxy( () => {}, {
751808

752-
const fullLayout = {
753-
name: 'fn' + fnId ++,
754-
type: nodeType,
755-
inputs: []
756-
};
809+
apply( target, thisArg, params ) {
757810

758-
for ( const name in layout ) {
811+
return instance.call( ...params );
759812

760-
if ( name === 'return' ) continue;
813+
},
761814

762-
fullLayout.inputs.push( {
763-
name: name,
764-
type: layout[ name ]
765-
} );
815+
get( target, prop, receiver ) {
766816

767-
}
817+
return Reflect.get( instance, prop, receiver );
768818

769-
layout = fullLayout;
819+
},
770820

771-
}
821+
set( target, prop, value, receiver ) {
772822

773-
fn.setLayout( layout );
823+
return Reflect.set( instance, prop, value, receiver );
774824

775-
}
825+
}
776826

777-
return fn;
827+
} );
778828

779-
};
829+
}
780830

781831
//
782832

0 commit comments

Comments
 (0)