UNPKG

@polygonjs/polygonjs

Version:

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

105 lines (95 loc) 2.88 kB
import {BaseNodeType} from '../engine/nodes/_Base'; import {BaseParamType} from '../engine/params/_Base'; import {CoreWalker} from './Walker'; import {CoreGraphNodeId} from './graph/CoreGraph'; type NodeOrParam = BaseNodeType | BaseParamType; interface PathElement { path: string; node: NodeOrParam; } interface NamedNode { name: string; node: NodeOrParam; } export class DecomposedPath { private _index = -1; private _pathElements: Array<PathElement | null> = []; private _namedNodes: Array<NamedNode | null> = []; private _graphNodeIds: CoreGraphNodeId[] = []; private _nodeElementByGraphNodeId: Map<CoreGraphNodeId, string> = new Map(); private _absolutePath: string = '/'; constructor() {} reset() { this._index = -1; this._pathElements = []; this._namedNodes = []; this._graphNodeIds = []; this._nodeElementByGraphNodeId.clear(); } addNamedNode(namedNode: NamedNode) { this._index += 1; if (namedNode.name == namedNode.node.name()) { this._namedNodes[this._index] = namedNode; } this._graphNodeIds[this._index] = namedNode.node.graphNodeId(); this._nodeElementByGraphNodeId.set(namedNode.node.graphNodeId(), namedNode.name); this._absolutePath = [this._absolutePath, namedNode.name].join(CoreWalker.SEPARATOR); } addPathElement(pathElement: PathElement) { this._index += 1; this._pathElements[this._index] = pathElement; if (pathElement.node) { this._absolutePath = pathElement.node.path(); } } namedGraphNodes() { return this._namedNodes; } namedNodes(target: BaseNodeType[]) { target.length = 0; for (const namedNode of this._namedNodes) { if (namedNode) { const node = namedNode.node as BaseNodeType; if (node.nameController) { target.push(node); } } } return target; } updateFromNameChange(node: NodeOrParam) { const namedGraphNodeIds = this._namedNodes.map((n) => n?.node.graphNodeId()); if (namedGraphNodeIds.includes(node.graphNodeId())) { this._nodeElementByGraphNodeId.set(node.graphNodeId(), node.name()); } } toPath(): string { const elements = new Array<string>(this._index); for (let i = 0; i <= this._index; i++) { const namedNode = this._namedNodes[i]; if (namedNode) { const nodeName = this._nodeElementByGraphNodeId.get(namedNode.node.graphNodeId()); if (nodeName) { elements[i] = nodeName; } } else { const pathElement = this._pathElements[i]; if (pathElement) { elements[i] = pathElement.path; } } } let joinedPath = elements.join(CoreWalker.SEPARATOR); // if the first character is a letter, we need to prefix with / const firstChar = joinedPath[0]; if (firstChar) { if (!CoreWalker.NON_LETTER_PREFIXES.includes(firstChar)) { joinedPath = `${CoreWalker.SEPARATOR}${joinedPath}`; } } return joinedPath; } toAbsolutePath(): string { return this._absolutePath; } }