UNPKG

molstar

Version:

A comprehensive macromolecular library.

298 lines 11.8 kB
/** * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal <david.sehnal@gmail.com> */ import { OrderedSet } from 'immutable'; import { StateTransform } from '../transform'; import { StateTree } from './immutable'; import { shallowEqual } from '../../mol-util/object'; import { arrayEqual } from '../../mol-util/array'; export { TransientTree }; var TransientTree = /** @class */ (function () { function TransientTree(tree) { this.tree = tree; this.transforms = this.tree.transforms; this.children = this.tree.children; this.dependencies = this.tree.dependencies; this.changedNodes = false; this.changedChildren = false; this.changedDependencies = false; this._childMutations = void 0; this._dependencyMutations = void 0; this._stateUpdates = void 0; } Object.defineProperty(TransientTree.prototype, "childMutations", { get: function () { if (this._childMutations) return this._childMutations; this._childMutations = new Map(); return this._childMutations; }, enumerable: false, configurable: true }); Object.defineProperty(TransientTree.prototype, "dependencyMutations", { get: function () { if (this._dependencyMutations) return this._dependencyMutations; this._dependencyMutations = new Map(); return this._dependencyMutations; }, enumerable: false, configurable: true }); TransientTree.prototype.changeNodes = function () { if (this.changedNodes) return; this.changedNodes = true; this.transforms = this.transforms.asMutable(); }; TransientTree.prototype.changeChildren = function () { if (this.changedChildren) return; this.changedChildren = true; this.children = this.children.asMutable(); }; TransientTree.prototype.changeDependencies = function () { if (this.changedDependencies) return; this.changedDependencies = true; this.dependencies = this.dependencies.asMutable(); }; Object.defineProperty(TransientTree.prototype, "root", { get: function () { return this.transforms.get(StateTransform.RootRef); }, enumerable: false, configurable: true }); TransientTree.prototype.asTransient = function () { return this.asImmutable().asTransient(); }; TransientTree.prototype.addChild = function (parent, child) { this.changeChildren(); if (this.childMutations.has(parent)) { this.childMutations.get(parent).add(child); } else { var set = this.children.get(parent).asMutable(); set.add(child); this.children.set(parent, set); this.childMutations.set(parent, set); } }; TransientTree.prototype.removeChild = function (parent, child) { this.changeChildren(); if (this.childMutations.has(parent)) { this.childMutations.get(parent).remove(child); } else { var set = this.children.get(parent).asMutable(); set.remove(child); this.children.set(parent, set); this.childMutations.set(parent, set); } }; TransientTree.prototype.clearRoot = function () { var parent = StateTransform.RootRef; if (this.children.get(parent).size === 0) return; this.changeChildren(); var set = OrderedSet(); this.children.set(parent, set); this.childMutations.set(parent, set); }; TransientTree.prototype.mutateDependency = function (parent, child, action) { var set = this.dependencyMutations.get(parent); if (!set) { var src = this.dependencies.get(parent); if (!src && action === 'remove') return; this.changeDependencies(); set = src ? src.asMutable() : OrderedSet().asMutable(); this.dependencyMutations.set(parent, set); this.dependencies.set(parent, set); } if (action === 'add') { set.add(child); } else { set.remove(child); } }; TransientTree.prototype.changeParent = function (ref, newParent) { ensurePresent(this.transforms, ref); var old = this.transforms.get(ref); this.removeChild(old.parent, ref); this.addChild(newParent, ref); this.changeNodes(); this.transforms.set(ref, StateTransform.withParent(old, newParent)); }; TransientTree.prototype.add = function (transform) { var ref = transform.ref; if (this.transforms.has(transform.ref)) { var node = this.transforms.get(transform.ref); if (node.parent !== transform.parent) alreadyPresent(transform.ref); } var children = this.children.get(transform.parent); if (!children) parentNotPresent(transform.parent); if (!children.has(transform.ref)) { this.addChild(transform.parent, transform.ref); } if (!this.children.has(transform.ref)) { if (!this.changedChildren) { this.changedChildren = true; this.children = this.children.asMutable(); } this.children.set(transform.ref, OrderedSet()); } this.changeNodes(); this.transforms.set(ref, transform); if (transform.dependsOn) { for (var _i = 0, _a = transform.dependsOn; _i < _a.length; _i++) { var d = _a[_i]; this.mutateDependency(d, ref, 'add'); } } return this; }; /** Calls Transform.definition.params.areEqual if available, otherwise uses shallowEqual to check if the params changed */ TransientTree.prototype.setParams = function (ref, params) { ensurePresent(this.transforms, ref); var transform = this.transforms.get(ref); // TODO: should this be here? if (shallowEqual(transform.params, params)) { return false; } if (!this.changedNodes) { this.changedNodes = true; this.transforms = this.transforms.asMutable(); } this.transforms.set(transform.ref, StateTransform.withParams(transform, params)); return true; }; /** Calls Transform.definition.params.areEqual if available, otherwise uses shallowEqual to check if the params changed */ TransientTree.prototype.setTags = function (ref, tags) { ensurePresent(this.transforms, ref); var transform = this.transforms.get(ref); var withTags = StateTransform.withParams(transform, tags); // TODO: should this be here? if (arrayEqual(transform.tags, withTags.tags)) { return false; } if (!this.changedNodes) { this.changedNodes = true; this.transforms = this.transforms.asMutable(); } this.transforms.set(transform.ref, withTags); return true; }; TransientTree.prototype.assignState = function (ref, state) { ensurePresent(this.transforms, ref); var old = this.transforms.get(ref); if (this._stateUpdates && this._stateUpdates.has(ref)) { StateTransform.assignState(old.state, state); return old; } else { if (!this._stateUpdates) this._stateUpdates = new Set(); this._stateUpdates.add(old.ref); this.changeNodes(); var updated = StateTransform.withState(old, state); this.transforms.set(ref, updated); return updated; } }; TransientTree.prototype.remove = function (ref) { var node = this.transforms.get(ref); if (!node) return []; var st = StateTree.subtreePostOrder(this, node); if (ref === StateTransform.RootRef) { st.pop(); if (st.length === 0) return st; this.clearRoot(); } else { if (st.length === 0) return st; this.removeChild(node.parent, node.ref); } this.changeNodes(); this.changeChildren(); for (var _i = 0, st_1 = st; _i < st_1.length; _i++) { var n = st_1[_i]; this.transforms.delete(n.ref); this.children.delete(n.ref); if (this._childMutations) this._childMutations.delete(n.ref); } var depRemoves = []; for (var _a = 0, st_2 = st; _a < st_2.length; _a++) { var n = st_2[_a]; if (n.dependsOn) { for (var _b = 0, _c = n.dependsOn; _b < _c.length; _b++) { var d = _c[_b]; if (!this.transforms.has(d)) continue; this.mutateDependency(d, n.ref, 'remove'); } } if (this.dependencies.has(n.ref)) { var deps = this.dependencies.get(n.ref).toArray(); this.changeDependencies(); this.dependencies.delete(n.ref); if (this._dependencyMutations) this._dependencyMutations.delete(n.ref); for (var _d = 0, deps_1 = deps; _d < deps_1.length; _d++) { var dep = deps_1[_d]; if (!this.transforms.has(dep)) continue; for (var _e = 0, _f = this.remove(dep); _e < _f.length; _e++) { var del = _f[_e]; depRemoves[depRemoves.length] = del; } } } } for (var _g = 0, depRemoves_1 = depRemoves; _g < depRemoves_1.length; _g++) { var dep = depRemoves_1[_g]; st[st.length] = dep; } return st; }; TransientTree.prototype.asImmutable = function () { if (!this.changedNodes && !this.changedChildren && !this._childMutations) return this.tree; if (this._childMutations) this._childMutations.forEach(fixChildMutations, this.children); if (this._dependencyMutations) this._dependencyMutations.forEach(fixDependencyMutations, this.dependencies); return StateTree.create(this.changedNodes ? this.transforms.asImmutable() : this.transforms, this.changedChildren ? this.children.asImmutable() : this.children, this.changedDependencies ? this.dependencies.asImmutable() : this.dependencies); }; return TransientTree; }()); function fixChildMutations(m, k) { this.set(k, m.asImmutable()); } function fixDependencyMutations(m, k) { if (m.size === 0) this.delete(k); else this.set(k, m.asImmutable()); } function alreadyPresent(ref) { throw new Error("Transform '" + ref + "' is already present in the tree."); } function parentNotPresent(ref) { throw new Error("Parent '" + ref + "' must be present in the tree."); } function ensurePresent(nodes, ref) { if (!nodes.has(ref)) { throw new Error("Node '" + ref + "' is not present in the tree."); } } //# sourceMappingURL=transient.js.map