@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
167 lines (153 loc) • 5.67 kB
text/typescript
/**
* sends a trigger when an object attribute has been updated
*
*
*/
import {TRIGGER_CONNECTION_NAME, TypedJsNode} from './_Base';
import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig';
import {
JsConnectionPoint,
JsConnectionPointType,
JS_CONNECTION_POINT_IN_NODE_DEF,
ParamConvertibleJsType,
PARAM_CONVERTIBLE_JS_CONNECTION_POINT_TYPES,
} from '../utils/io/connections/Js';
import {JsType} from '../../poly/registers/nodes/types/Js';
import {inputObject3D} from './_BaseObject3D';
import {JsLinesCollectionController} from './code/utils/JsLinesCollectionController';
import {WatchedValueJsDefinition} from './utils/JsDefinition';
import {Poly} from '../../Poly';
import {nodeMethodName} from './code/assemblers/actor/ActorAssemblerUtils';
import {createVariable} from './code/assemblers/_BaseJsPersistedConfigUtils';
import {StringParam} from '../../params/String';
enum OnObjectAttributeUpdateInputName {
attribName = 'attribName',
}
const CONNECTION_OPTIONS = JS_CONNECTION_POINT_IN_NODE_DEF;
class OnObjectAttributeUpdateJsParamsConfig extends NodeParamsConfig {
/** @param type */
type = ParamConfig.INTEGER(PARAM_CONVERTIBLE_JS_CONNECTION_POINT_TYPES.indexOf(JsConnectionPointType.FLOAT), {
menu: {
entries: PARAM_CONVERTIBLE_JS_CONNECTION_POINT_TYPES.map((name, i) => {
return {name: name, value: i};
}),
},
});
}
const ParamsConfig = new OnObjectAttributeUpdateJsParamsConfig();
export class OnObjectAttributeUpdateJsNode extends TypedJsNode<OnObjectAttributeUpdateJsParamsConfig> {
override readonly paramsConfig = ParamsConfig;
static override type() {
return JsType.ON_OBJECT_ATTRIBUTE_UPDATE;
}
override isTriggering() {
return true;
}
static readonly OUTPUT_NEW_VAL = 'newValue';
static readonly OUTPUT_PREV_VAL = 'previousValue';
override initializeNode() {
this.io.connection_points.spare_params.setInputlessParamNames(['type']);
this.io.inputs.setNamedInputConnectionPoints([
new JsConnectionPoint(JsConnectionPointType.OBJECT_3D, JsConnectionPointType.OBJECT_3D, CONNECTION_OPTIONS),
new JsConnectionPoint(
OnObjectAttributeUpdateInputName.attribName,
JsConnectionPointType.STRING,
CONNECTION_OPTIONS
),
]);
this.io.outputs.setNamedOutputConnectionPoints([
new JsConnectionPoint(TRIGGER_CONNECTION_NAME, JsConnectionPointType.TRIGGER, CONNECTION_OPTIONS),
]);
this.io.connection_points.set_expected_input_types_function(() => []);
this.io.connection_points.set_output_name_function(
(index: number) =>
[
TRIGGER_CONNECTION_NAME,
OnObjectAttributeUpdateJsNode.OUTPUT_NEW_VAL,
OnObjectAttributeUpdateJsNode.OUTPUT_PREV_VAL,
][index]
);
this.io.connection_points.set_expected_output_types_function(() => [
JsConnectionPointType.TRIGGER,
...this._currentConnectionType(),
]);
}
private _currentConnectionType() {
if (this.pv.type == null) {
console.warn(`${this.type()} actor node type not valid`);
}
const connectionType = PARAM_CONVERTIBLE_JS_CONNECTION_POINT_TYPES[this.pv.type];
if (connectionType == null) {
console.warn(`${this.type()} actor node type not valid`);
}
return [connectionType, connectionType];
}
setAttribType(type: ParamConvertibleJsType) {
this.p.type.set(PARAM_CONVERTIBLE_JS_CONNECTION_POINT_TYPES.indexOf(type));
}
attribType(): JsConnectionPointType {
return PARAM_CONVERTIBLE_JS_CONNECTION_POINT_TYPES[this.pv.type];
}
setAttribName(attribName: string) {
(this.params.get(OnObjectAttributeUpdateInputName.attribName) as StringParam).set(attribName);
}
attributeName() {
return (this.params.get(OnObjectAttributeUpdateInputName.attribName) as StringParam).value;
}
override setLines(linesController: JsLinesCollectionController) {
const type = this.attribType();
const object3D = inputObject3D(this, linesController);
const attribName = this.variableForInput(linesController, OnObjectAttributeUpdateInputName.attribName);
// outputs
const usedOutputNames = this.io.outputs.used_output_names();
const _val = (
propertyName: string,
functionName: 'getObjectAttributeAutoDefault' | 'getObjectAttributePrevious',
type: JsConnectionPointType
) => {
if (!usedOutputNames.includes(propertyName)) {
return;
}
const func = Poly.namedFunctionsRegister.getFunction(functionName, this, linesController);
const varName = this.jsVarName(propertyName);
const variable = createVariable(type);
if (variable) {
linesController.addVariable(this, variable);
}
linesController.addBodyOrComputed(this, [
{
dataType: type,
varName,
value: func.asString(object3D, attribName, `'${type}'`),
},
]);
};
_val(OnObjectAttributeUpdateJsNode.OUTPUT_NEW_VAL, 'getObjectAttributeAutoDefault', type);
_val(OnObjectAttributeUpdateJsNode.OUTPUT_PREV_VAL, 'getObjectAttributePrevious', type);
}
override setTriggeringLines(linesController: JsLinesCollectionController, triggeredMethods: string) {
const type = this.attribType();
const object3D = inputObject3D(this, linesController);
const attribName = this.variableForInput(linesController, OnObjectAttributeUpdateInputName.attribName);
const getObjectAttributeRef = Poly.namedFunctionsRegister.getFunction(
'getObjectAttributeRef',
this,
linesController
);
linesController.addDefinitions(this, [
new WatchedValueJsDefinition(
this,
linesController,
type,
getObjectAttributeRef.asString(object3D, attribName, `'${type}'`),
`this.${nodeMethodName(this)}()`,
{
deep: true,
}
),
]);
linesController.addTriggeringLines(this, [triggeredMethods], {
gatherable: false,
});
}
}