UNPKG

three

Version:

JavaScript 3D library

123 lines (82 loc) 2.22 kB
/** * Data structure for the renderer. It allows defining values * with chained, hierarchical keys. Keys are meant to be * objects since the module internally works with Weak Maps * for performance reasons. * * @private */ class ChainMap { /** * Constructs a new Chain Map. */ constructor() { /** * A map of Weak Maps by their key length. * * @type {Object<number, WeakMap>} */ this.weakMaps = {}; } /** * Returns the Weak Map for the given keys. * * @param {Array<Object>} keys - List of keys. * @return {WeakMap} The weak map. */ _getWeakMap( keys ) { const length = keys.length; let weakMap = this.weakMaps[ length ]; if ( weakMap === undefined ) { weakMap = new WeakMap(); this.weakMaps[ length ] = weakMap; } return weakMap; } /** * Returns the value for the given array of keys. * * @param {Array<Object>} keys - List of keys. * @return {any} The value. Returns `undefined` if no value was found. */ get( keys ) { let map = this._getWeakMap( keys ); for ( let i = 0; i < keys.length - 1; i ++ ) { map = map.get( keys[ i ] ); if ( map === undefined ) return undefined; } return map.get( keys[ keys.length - 1 ] ); } /** * Sets the value for the given keys. * * @param {Array<Object>} keys - List of keys. * @param {any} value - The value to set. * @return {ChainMap} A reference to this Chain Map. */ set( keys, value ) { let map = this._getWeakMap( keys ); for ( let i = 0; i < keys.length - 1; i ++ ) { const key = keys[ i ]; if ( map.has( key ) === false ) map.set( key, new WeakMap() ); map = map.get( key ); } map.set( keys[ keys.length - 1 ], value ); return this; } /** * Deletes a value for the given keys. * * @param {Array<Object>} keys - The keys. * @return {boolean} Returns `true` if the value has been removed successfully and `false` if the value has not be found. */ delete( keys ) { let map = this._getWeakMap( keys ); for ( let i = 0; i < keys.length - 1; i ++ ) { map = map.get( keys[ i ] ); if ( map === undefined ) return false; } return map.delete( keys[ keys.length - 1 ] ); } } export default ChainMap;