UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

157 lines (147 loc) 5.72 kB
/** * processes input events with user-defined typescript. * * */ import {TypedEventNode} from './_Base'; import {EventConnectionPoint, EventConnectionPointType} from '../utils/io/connections/Event'; import {Poly} from '../../Poly'; import {StringParamLanguage} from '../../params/utils/OptionsController'; import {TranspiledFilter} from '../utils/code/controllers/TranspiledFilter'; import {BaseCodeProcessor, buildCodeNodeFunction} from '../../../core/code/FunctionBuilderUtils'; import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig'; import { EventContext } from '../../../core/event/EventContextType'; const DEFAULT_TS = ` export class EventProcessor extends BaseCodeEventProcessor { override initializeProcessor(){ } override processTrigger0(eventContext: EventContext<MouseEvent>){ this.dispatchEventToOutput('output0', eventContext); } override processTrigger1(eventContext: EventContext<MouseEvent>){ this.dispatchEventToOutput('output1', eventContext); } override processTrigger2(eventContext: EventContext<MouseEvent>){ this.dispatchEventToOutput('output2', eventContext); } override processTrigger3(eventContext: EventContext<MouseEvent>){ this.dispatchEventToOutput('output3', eventContext); } override processTrigger4(eventContext: EventContext<MouseEvent>){ this.dispatchEventToOutput('output4', eventContext); } } `; const DEFAULT_JS = DEFAULT_TS.replace(/\:\sEventContext<MouseEvent>/g, '').replace(/override\s/g, ''); export class BaseCodeEventProcessor extends BaseCodeProcessor { constructor(protected override node: CodeEventNode) { super(node); this.initializeProcessor(); } get pv() { return this.node.pv; } get p() { return this.node.p; } get io() { return this.node.io; } initializeProcessor() {} processTrigger0(eventContext: EventContext<Event>) {} processTrigger1(eventContext: EventContext<Event>) {} processTrigger2(eventContext: EventContext<Event>) {} processTrigger3(eventContext: EventContext<Event>) {} processTrigger4(eventContext: EventContext<Event>) {} dispatchEventToOutput(outputName: string, eventContext: EventContext<Event>) { this.node._dispatchEventToOutputFromProcessor(outputName, eventContext); } } class CodeEventParamsConfig extends NodeParamsConfig { codeTypescript = ParamConfig.STRING(DEFAULT_TS, { hideLabel: true, language: StringParamLanguage.TYPESCRIPT, }); codeJavascript = ParamConfig.STRING(DEFAULT_JS, {hidden: true}); } const ParamsConfig = new CodeEventParamsConfig(); export class CodeEventNode extends TypedEventNode<CodeEventParamsConfig> { override paramsConfig = ParamsConfig; // adding BaseCodeEventProcessor seems necessary to have the bundled types include it static BaseCodeEventProcessor = BaseCodeEventProcessor; static override type() { return 'code'; } private _lastCompiledCode: string | undefined; private _processor: BaseCodeEventProcessor | undefined; override initializeNode() { this.io.inputs.setNamedInputConnectionPoints([ new EventConnectionPoint('trigger0', EventConnectionPointType.BASE, this._processTrigger0.bind(this)), new EventConnectionPoint('trigger1', EventConnectionPointType.BASE, this._processTrigger1.bind(this)), new EventConnectionPoint('trigger2', EventConnectionPointType.BASE, this._processTrigger2.bind(this)), new EventConnectionPoint('trigger3', EventConnectionPointType.BASE, this._processTrigger3.bind(this)), new EventConnectionPoint('trigger4', EventConnectionPointType.BASE, this._processTrigger4.bind(this)), ]); this.io.outputs.setNamedOutputConnectionPoints([ new EventConnectionPoint('output0', EventConnectionPointType.BASE), new EventConnectionPoint('output1', EventConnectionPointType.BASE), new EventConnectionPoint('output2', EventConnectionPointType.BASE), new EventConnectionPoint('output3', EventConnectionPointType.BASE), new EventConnectionPoint('output4', EventConnectionPointType.BASE), ]); } private _processTrigger0(event_context: EventContext<Event>) { this._compileIfRequired(); this._processor?.processTrigger0(event_context); } private _processTrigger1(event_context: EventContext<Event>) { this._compileIfRequired(); this._processor?.processTrigger1(event_context); } private _processTrigger2(event_context: EventContext<Event>) { this._compileIfRequired(); this._processor?.processTrigger2(event_context); } private _processTrigger3(event_context: EventContext<Event>) { this._compileIfRequired(); this._processor?.processTrigger3(event_context); } private _processTrigger4(event_context: EventContext<Event>) { this._compileIfRequired(); this._processor?.processTrigger4(event_context); } _dispatchEventToOutputFromProcessor(outputName: string, eventContext: EventContext<Event>) { this.dispatchEventToOutput(outputName, eventContext); } private _compileIfRequired() { if (!this._processor || this._lastCompiledCode != this.pv.codeJavascript) { this._compile(); } } private _compile() { this._processor = undefined; try { const functionBody = `try { ${TranspiledFilter.filter(this.pv.codeJavascript)} } catch(e) { states.error.set(e) }`; const ProcessorClass = buildCodeNodeFunction<BaseCodeEventProcessor>({ BaseCodeProcessor: BaseCodeEventProcessor, BaseCodeProcessorName: 'BaseCodeEventProcessor', node: this, functionBody, }); if (ProcessorClass) { this._processor = new ProcessorClass(this); this._lastCompiledCode = this.pv.codeJavascript; } else { this.states.error.set(`cannot generate function`); Poly.warn(functionBody); } } catch (e) { Poly.warn(e); this.states.error.set(`cannot generate function (${e})`); } } }