UNPKG

polygonjs-engine

Version:

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

385 lines (384 loc) 11.6 kB
import {ParamType as ParamType2} from "../../poly/ParamType"; import {ParamEvent as ParamEvent2} from "../../poly/ParamEvent"; import {CoreGraphNode as CoreGraphNode2} from "../../../core/graph/CoreGraphNode"; import {CoreType} from "../../../core/Type"; import {ArrayUtils as ArrayUtils2} from "../../../core/ArrayUtils"; import {ObjectUtils as ObjectUtils2} from "../../../core/ObjectUtils"; const CALLBACK_OPTION = "callback"; const CALLBACK_STRING_OPTION = "callbackString"; const COMPUTE_ON_DIRTY = "computeOnDirty"; const COOK_OPTION = "cook"; const FILE_BROWSE_OPTION = "fileBrowse"; const FILE_TYPE_OPTION = "type"; const EXPRESSION = "expression"; const FOR_ENTITIES = "forEntities"; const LABEL = "label"; const LEVEL = "level"; const MENU = "menu"; const ENTRIES = "entries"; const MULTILINE_OPTION = "multiline"; const LANGUAGE_OPTION = "language"; const NODE_SELECTION = "nodeSelection"; const NODE_SELECTION_CONTEXT = "context"; const NODE_SELECTION_TYPES = "types"; const PARAM_SELECTION = "paramSelection"; const DEPENDENT_ON_FOUND_NODE = "dependentOnFoundNode"; const RANGE_OPTION = "range"; const RANGE_LOCKED_OPTION = "rangeLocked"; const STEP_OPTION = "step"; const SPARE_OPTION = "spare"; const TEXTURE_OPTION = "texture"; const ENV_OPTION = "env"; const HIDDEN_OPTION = "hidden"; const FIELD_OPTION = "field"; const VISIBLE_IF_OPTION = "visibleIf"; const COLOR_CONVERSION = "conversion"; export var StringParamLanguage; (function(StringParamLanguage2) { StringParamLanguage2["TYPESCRIPT"] = "typescript"; })(StringParamLanguage || (StringParamLanguage = {})); export var FileType; (function(FileType2) { FileType2["TEXTURE"] = "texture"; FileType2["GEOMETRY"] = "geometry"; })(FileType || (FileType = {})); export class OptionsController { constructor(_param) { this._param = _param; this._programatic_visible_state = true; this._callbackAllowed = false; this._update_visibility_and_remove_dirty_bound = this.update_visibility_and_remove_dirty.bind(this); this._ui_data_dependency_set = false; } dispose() { this._options[CALLBACK_OPTION] = void 0; this._options[CALLBACK_STRING_OPTION] = void 0; this._visibility_graph_node?.dispose(); } set(options) { this._default_options = options; this._options = ObjectUtils2.cloneDeep(this._default_options); this.post_set_options(); } copy(options_controller) { this._default_options = ObjectUtils2.cloneDeep(options_controller.default()); this._options = ObjectUtils2.cloneDeep(options_controller.current()); this.post_set_options(); } set_option(name, value) { this._options[name] = value; if (this._param.components) { for (let component of this._param.components) { component.options.set_option(name, value); } } } post_set_options() { this._handle_computeOnDirty(); } param() { return this._param; } node() { return this._param.node; } default() { return this._default_options; } current() { return this._options; } has_options_overridden() { return !ObjectUtils2.isEqual(this._options, this._default_options); } overridden_options() { const overriden = {}; const option_names = Object.keys(this._options); for (let option_name of option_names) { if (!ObjectUtils2.isEqual(this._options[option_name], this._default_options[option_name])) { const cloned_option = ObjectUtils2.cloneDeep(this._options[option_name]); Object.assign(overriden, {[option_name]: cloned_option}); } } return overriden; } overridden_option_names() { return Object.keys(this.overridden_options()); } computeOnDirty() { return this._options[COMPUTE_ON_DIRTY] || false; } _handle_computeOnDirty() { if (this.computeOnDirty()) { if (!this._computeOnDirty_callback_added) { this.param().addPostDirtyHook("computeOnDirty", this._compute_param.bind(this)); this._computeOnDirty_callback_added = true; } } } async _compute_param() { await this.param().compute(); } has_callback() { return this._options[CALLBACK_OPTION] != null || this._options[CALLBACK_STRING_OPTION] != null; } allowCallback() { this._callbackAllowed = true; } execute_callback() { if (!this._callbackAllowed) { return; } if (!this.node()) { return; } if (!this.node().scene().loadingController.loaded()) { return; } const callback = this.get_callback(); if (callback != null) { const parent_param = this.param().parent_param; if (parent_param) { parent_param.options.execute_callback(); } else { callback(this.node(), this.param()); } } } get_callback() { if (this.has_callback()) { return this._options[CALLBACK_OPTION] = this._options[CALLBACK_OPTION] || this.create_callback_from_string(); } } create_callback_from_string() { const callbackString = this._options[CALLBACK_STRING_OPTION]; if (callbackString) { const callback_function = new Function("node", "scene", "window", "location", callbackString); return () => { callback_function(this.node(), this.node().scene(), null, null); }; } } color_conversion() { return this._options[COLOR_CONVERSION]; } makes_node_dirty_when_dirty() { let cook_options; if (this.param().parent_param != null) { return false; } let value = true; if ((cook_options = this._options[COOK_OPTION]) != null) { value = cook_options; } return value; } file_browse_option() { return this._options[FILE_BROWSE_OPTION]; } file_browse_allowed() { return this.file_browse_option() != null; } file_browse_type() { const option = this.file_browse_option(); if (option) { return option[FILE_TYPE_OPTION]; } else { return null; } } is_expression_for_entities() { const expr_option = this._options[EXPRESSION]; if (expr_option) { return expr_option[FOR_ENTITIES] || false; } return false; } level() { return this._options[LEVEL] || 0; } has_menu() { return this.menu_options() != null; } menu_options() { return this._options[MENU]; } menu_entries() { const options = this.menu_options(); if (options) { return options[ENTRIES]; } else { return []; } } has_menu_radio() { return this.has_menu(); } is_multiline() { return this._options[MULTILINE_OPTION] === true; } language() { return this._options[LANGUAGE_OPTION]; } is_code() { return this.language() != null; } node_selection_options() { return this._options[NODE_SELECTION]; } node_selection_context() { const options = this.node_selection_options(); if (options) { return options[NODE_SELECTION_CONTEXT]; } } node_selection_types() { const options = this.node_selection_options(); if (options) { return options[NODE_SELECTION_TYPES]; } } dependent_on_found_node() { if (DEPENDENT_ON_FOUND_NODE in this._options) { return this._options[DEPENDENT_ON_FOUND_NODE]; } else { return true; } } is_selecting_param() { return this.param_selection_options() != null; } param_selection_options() { return this._options[PARAM_SELECTION]; } param_selection_type() { const options = this.param_selection_options(); if (options) { const type_or_boolean = options; if (!CoreType.isBoolean(type_or_boolean)) { return type_or_boolean; } } } range() { return this._options[RANGE_OPTION] || [0, 1]; } step() { return this._options[STEP_OPTION]; } range_locked() { return this._options[RANGE_LOCKED_OPTION] || [false, false]; } ensure_in_range(value) { const range = this.range(); if (value >= range[0] && value <= range[1]) { return value; } else { if (value < range[0]) { return this.range_locked()[0] === true ? range[0] : value; } else { return this.range_locked()[1] === true ? range[1] : value; } } } is_spare() { return this._options[SPARE_OPTION] || false; } texture_options() { return this._options[TEXTURE_OPTION]; } texture_as_env() { const texture_options = this.texture_options(); if (texture_options != null) { return texture_options[ENV_OPTION] === true; } return false; } is_hidden() { return this._options[HIDDEN_OPTION] === true || this._programatic_visible_state === false; } is_visible() { return !this.is_hidden(); } set_visible_state(state) { this._options[HIDDEN_OPTION] = !state; this.param().emit(ParamEvent2.VISIBLE_UPDATED); } label() { return this._options[LABEL]; } is_label_hidden() { const type = this.param().type(); return type === ParamType2.BUTTON || type === ParamType2.SEPARATOR || type === ParamType2.BOOLEAN && this.is_field_hidden(); } is_field_hidden() { return this._options[FIELD_OPTION] === false; } ui_data_depends_on_other_params() { return VISIBLE_IF_OPTION in this._options; } visibility_predecessors() { const visibility_options = this._options[VISIBLE_IF_OPTION]; if (!visibility_options) { return []; } let predecessor_names = []; if (CoreType.isArray(visibility_options)) { predecessor_names = ArrayUtils2.uniq(visibility_options.map((options) => Object.keys(options)).flat()); } else { predecessor_names = Object.keys(visibility_options); } const node = this.param().node; return ArrayUtils2.compact(predecessor_names.map((name) => { const param = node.params.get(name); if (param) { return param; } else { console.error(`param ${name} not found as visibility condition for ${this.param().name()} in node ${this.param().node.type()}`); } })); } set_ui_data_dependency() { if (this._ui_data_dependency_set) { return; } this._ui_data_dependency_set = true; const predecessors = this.visibility_predecessors(); if (predecessors.length > 0) { this._visibility_graph_node = new CoreGraphNode2(this.param().scene(), "param_visibility"); for (let predecessor of predecessors) { this._visibility_graph_node.addGraphInput(predecessor); } this._visibility_graph_node.addPostDirtyHook("_update_visibility_and_remove_dirty", this._update_visibility_and_remove_dirty_bound); } } update_visibility_and_remove_dirty() { this.update_visibility(); this.param().removeDirtyState(); } async update_visibility() { const options = this._options[VISIBLE_IF_OPTION]; if (options) { const params = this.visibility_predecessors(); const promises = params.map((p) => { if (p.isDirty()) { return p.compute(); } }); this._programatic_visible_state = false; await Promise.all(promises); if (CoreType.isArray(options)) { for (let options_set of options) { const satisfied_values = params.filter((param) => param.value == options_set[param.name()]); if (satisfied_values.length == params.length) { this._programatic_visible_state = true; } } } else { const satisfied_values = params.filter((param) => param.value == options[param.name()]); this._programatic_visible_state = satisfied_values.length == params.length; } this.param().emit(ParamEvent2.VISIBLE_UPDATED); } } }