polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
114 lines (103 loc) • 5.04 kB
text/typescript
import {JsonExportDispatcher} from '../../../io/json/export/Dispatcher';
import {ParamJsonExporterData} from '../../utils/io/IOController';
import {ParamsUpdateOptions} from '../../utils/params/ParamsController';
import {ParamOptions} from '../../../params/utils/OptionsController';
import {ParamType} from '../../../poly/ParamType';
import {JsAssemblerControllerType, AssemblerControllerNode} from './Controller';
import {ParamInitValueSerialized} from '../../../params/types/ParamInitValueSerialized';
import {ArrayUtils} from '../../../../core/ArrayUtils';
import {ObjectUtils} from '../../../../core/ObjectUtils';
/*
Create spare params on mat nodes
*/
export class JsAssemblerNodeSpareParamsController {
private _deleted_params_data: Map<string, ParamJsonExporterData<ParamType>> = new Map();
private _created_spare_param_names: string[] = [];
private _raw_input_serialized_by_param_name: Map<string, ParamInitValueSerialized> = new Map();
private _init_value_serialized_by_param_name: Map<string, ParamInitValueSerialized> = new Map();
constructor(private _controller: JsAssemblerControllerType, private _node: AssemblerControllerNode) {}
get assembler() {
return this._controller.assembler;
}
create_spare_parameters() {
// const current_spare_param_names: string[] = this.node.params.spare_names;
const params_update_options: ParamsUpdateOptions = {};
const param_configs = this.assembler.param_configs();
const assembler_param_names = param_configs.map((c) => c.name());
const spare_param_names_to_add = ObjectUtils.clone(assembler_param_names);
const validation_result = this._validate_names(spare_param_names_to_add);
if (validation_result == false) {
return;
}
// spare_param_names_to_remove is composed of previously created params, but also spare params with the same name, which may be created when loading the scene
const spare_param_names_to_remove = ObjectUtils.clone(this._created_spare_param_names).concat(
spare_param_names_to_add
);
// keep track of raw_inputs so we can restore them
spare_param_names_to_remove.forEach((param_name) => {
// store the param data, in case it gets recreated later
// this allows expressions to be kept in memory
const param = this._node.params.get(param_name);
if (param) {
this._raw_input_serialized_by_param_name.set(param.name(), param.raw_input_serialized);
this._init_value_serialized_by_param_name.set(param.name(), param.default_value_serialized);
const param_exporter = JsonExportDispatcher.dispatch_param(param);
if (param_exporter.required()) {
const params_data = param_exporter.data();
this._deleted_params_data.set(param.name(), params_data);
}
}
params_update_options.names_to_delete = params_update_options.names_to_delete || [];
params_update_options.names_to_delete.push(param_name);
});
// this.within_param_folder('spare_params', () => {
for (let param_config of param_configs) {
if (spare_param_names_to_add.indexOf(param_config.name()) >= 0) {
const config_options = ObjectUtils.clone(param_config.param_options);
const default_options: ParamOptions = {
spare: true,
computeOnDirty: true,
cook: false, // it should update the uniforms only via its callback
};
const options = ObjectUtils.merge(config_options, default_options);
// set init_value and raw_input to the previous param's
let init_value = this._init_value_serialized_by_param_name.get(param_config.name());
if (init_value == null) {
init_value = param_config.default_value as any;
}
let raw_input = this._raw_input_serialized_by_param_name.get(param_config.name());
if (raw_input == null) {
raw_input = param_config.default_value as any;
}
params_update_options.to_add = params_update_options.to_add || [];
params_update_options.to_add.push({
name: param_config.name(),
type: param_config.type(),
init_value: init_value as any,
raw_input: raw_input as any,
options: options,
});
}
}
this._node.params.update_params(params_update_options);
this._created_spare_param_names = params_update_options.to_add?.map((o) => o.name) || [];
}
// TODO: handle the case where a param created by user already exists.
// we may then change the name of the new spare param.
private _validate_names(spare_param_names_to_add: string[]): boolean {
// check that param_names_to_add does not include any currently existing param names (that are not spare)
const current_param_names = ObjectUtils.clone(this._node.params.non_spare_names);
const spare_params_with_same_name_as_params = ArrayUtils.intersection(
spare_param_names_to_add,
current_param_names
);
if (spare_params_with_same_name_as_params.length > 0) {
const error_message = `${this._node.fullPath()} attempts to create spare params called '${spare_params_with_same_name_as_params.join(
', '
)}' with same name as params`;
this._node.states.error.set(error_message);
return false;
}
return true;
}
}