@loaders.gl/tiles
Version:
Common components for different tiles loaders.
151 lines (150 loc) • 3.94 kB
JavaScript
// This file is derived from the Cesium code base under Apache 2 license
// See LICENSE.md and https://github.com/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md
import { assert } from '@loaders.gl/loader-utils';
/**
* A wrapper around arrays so that the internal length of the array can be manually managed.
*
* @alias ManagedArray
* @constructor
* @private
*
* @param {Number} [length=0] The initial length of the array.
*/
export class ManagedArray {
_map = new Map();
_array;
_length;
constructor(length = 0) {
this._array = new Array(length);
this._length = length;
}
/**
* Gets or sets the length of the array.
* If the set length is greater than the length of the internal array, the internal array is resized.
*
* @memberof ManagedArray.prototype
* @type Number
*/
get length() {
return this._length;
}
set length(length) {
this._length = length;
if (length > this._array.length) {
this._array.length = length;
}
}
/**
* Gets the internal array.
*
* @memberof ManagedArray.prototype
* @type Array
* @readonly
*/
get values() {
return this._array;
}
/**
* Gets the element at an index.
*
* @param {Number} index The index to get.
*/
get(index) {
assert(index < this._array.length);
return this._array[index];
}
/**
* Sets the element at an index. Resizes the array if index is greater than the length of the array.
*
* @param {Number} index The index to set.
* @param {*} element The element to set at index.
*/
set(index, element) {
assert(index >= 0);
if (index >= this.length) {
this.length = index + 1;
}
if (this._map.has(this._array[index])) {
this._map.delete(this._array[index]);
}
this._array[index] = element;
this._map.set(element, index);
}
delete(element) {
const index = this._map.get(element);
if (index >= 0) {
this._array.splice(index, 1);
this._map.delete(element);
this.length--;
}
}
/**
* Returns the last element in the array without modifying the array.
*
* @returns {*} The last element in the array.
*/
peek() {
return this._array[this._length - 1];
}
/**
* Push an element into the array.
*
* @param {*} element The element to push.
*/
push(element) {
if (!this._map.has(element)) {
const index = this.length++;
this._array[index] = element;
this._map.set(element, index);
}
}
/**
* Pop an element from the array.
*
* @returns {*} The last element in the array.
*/
pop() {
const element = this._array[--this.length];
this._map.delete(element);
return element;
}
/**
* Resize the internal array if length > _array.length.
*
* @param {Number} length The length.
*/
reserve(length) {
assert(length >= 0);
if (length > this._array.length) {
this._array.length = length;
}
}
/**
* Resize the array.
*
* @param {Number} length The length.
*/
resize(length) {
assert(length >= 0);
this.length = length;
}
/**
* Trim the internal array to the specified length. Defaults to the current length.
*
* @param {Number} [length] The length.
*/
trim(length) {
if (length === null || length === undefined) {
length = this.length;
}
this._array.length = length;
}
reset() {
this._array = [];
this._map = new Map();
this._length = 0;
}
find(target) {
return this._map.has(target);
}
}