import Check from "../Core/Check.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; import destroyObject from "../Core/destroyObject.js"; import PrimitiveCollection from "./PrimitiveCollection.js"; /** * A primitive collection for helping maintain the order or ground primitives based on a z-index * * @private */ function OrderedGroundPrimitiveCollection() { this._length = 0; this._collections = {}; this._collectionsArray = []; this.show = true; } Object.defineProperties(OrderedGroundPrimitiveCollection.prototype, { /** * Gets the number of primitives in the collection. * * @memberof OrderedGroundPrimitiveCollection.prototype * * @type {Number} * @readonly */ length: { get: function () { return this._length; }, }, }); /** * Adds a primitive to the collection. * * @param {GroundPrimitive} primitive The primitive to add. * @param {Number} [zIndex = 0] The index of the primitive * @returns {GroundPrimitive} The primitive added to the collection. */ OrderedGroundPrimitiveCollection.prototype.add = function (primitive, zIndex) { //>>includeStart('debug', pragmas.debug); Check.defined("primitive", primitive); if (defined(zIndex)) { Check.typeOf.number("zIndex", zIndex); } //>>includeEnd('debug'); zIndex = defaultValue(zIndex, 0); let collection = this._collections[zIndex]; if (!defined(collection)) { collection = new PrimitiveCollection({ destroyPrimitives: false }); collection._zIndex = zIndex; this._collections[zIndex] = collection; const array = this._collectionsArray; let i = 0; while (i < array.length && array[i]._zIndex < zIndex) { i++; } array.splice(i, 0, collection); } collection.add(primitive); this._length++; primitive._zIndex = zIndex; return primitive; }; /** * Adjusts the z-index * @param {GroundPrimitive} primitive * @param {Number} zIndex */ OrderedGroundPrimitiveCollection.prototype.set = function (primitive, zIndex) { //>>includeStart('debug', pragmas.debug); Check.defined("primitive", primitive); Check.typeOf.number("zIndex", zIndex); //>>includeEnd('debug'); if (zIndex === primitive._zIndex) { return primitive; } this.remove(primitive, true); this.add(primitive, zIndex); return primitive; }; /** * Removes a primitive from the collection. * * @param {Object} primitive The primitive to remove. * @param {Boolean} [doNotDestroy = false] * @returns {Boolean} true if the primitive was removed; false if the primitive is undefined or was not found in the collection. */ OrderedGroundPrimitiveCollection.prototype.remove = function ( primitive, doNotDestroy ) { if (this.contains(primitive)) { const index = primitive._zIndex; const collection = this._collections[index]; let result; if (doNotDestroy) { result = collection.remove(primitive); } else { result = collection.removeAndDestroy(primitive); } if (result) { this._length--; } if (collection.length === 0) { this._collectionsArray.splice( this._collectionsArray.indexOf(collection), 1 ); this._collections[index] = undefined; collection.destroy(); } return result; } return false; }; /** * Removes all primitives in the collection. * * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. * * @see OrderedGroundPrimitiveCollection#destroyPrimitives */ OrderedGroundPrimitiveCollection.prototype.removeAll = function () { const collections = this._collectionsArray; for (let i = 0; i < collections.length; i++) { const collection = collections[i]; collection.destroyPrimitives = true; collection.destroy(); } this._collections = {}; this._collectionsArray = []; this._length = 0; }; /** * Determines if this collection contains a primitive. * * @param {Object} primitive The primitive to check for. * @returns {Boolean} true if the primitive is in the collection; false if the primitive is undefined or was not found in the collection. */ OrderedGroundPrimitiveCollection.prototype.contains = function (primitive) { if (!defined(primitive)) { return false; } const collection = this._collections[primitive._zIndex]; return defined(collection) && collection.contains(primitive); }; /** * @private */ OrderedGroundPrimitiveCollection.prototype.update = function (frameState) { if (!this.show) { return; } const collections = this._collectionsArray; for (let i = 0; i < collections.length; i++) { collections[i].update(frameState); } }; /** * Returns true if this object was destroyed; otherwise, false. *

* If this object was destroyed, it should not be used; calling any function other than * isDestroyed will result in a {@link DeveloperError} exception. * * @returns {Boolean} True if this object was destroyed; otherwise, false. * * @see OrderedGroundPrimitiveCollection#destroy */ OrderedGroundPrimitiveCollection.prototype.isDestroyed = function () { return false; }; /** * Destroys the WebGL resources held by each primitive in this collection. Explicitly destroying this * collection allows for deterministic release of WebGL resources, instead of relying on the garbage * collector to destroy this collection. *

* Since destroying a collection destroys all the contained primitives, only destroy a collection * when you are sure no other code is still using any of the contained primitives. *

* Once this collection is destroyed, it should not be used; calling any function other than * isDestroyed will result in a {@link DeveloperError} exception. Therefore, * assign the return value (undefined) to the object as done in the example. * * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. * * * @example * primitives = primitives && primitives.destroy(); * * @see OrderedGroundPrimitiveCollection#isDestroyed */ OrderedGroundPrimitiveCollection.prototype.destroy = function () { this.removeAll(); return destroyObject(this); }; export default OrderedGroundPrimitiveCollection;