polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
385 lines (384 loc) • 11.6 kB
JavaScript
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);
}
}
}