import { clone, ImageryLayer, GlobeSurfaceTile, TerrainState, Texture, } from "@cesium/engine"; function TerrainTileProcessor( frameState, terrainProvider, imageryLayerCollection ) { this.frameState = frameState; this.terrainProvider = terrainProvider; this.imageryLayerCollection = imageryLayerCollection; } // Processes the given list of tiles until all terrain and imagery states stop changing. TerrainTileProcessor.prototype.process = function (tiles, maxIterations) { const that = this; function getState(tile) { return [ tile.state, tile.data ? tile.data.terrainState : undefined, tile.data && tile.data.imagery ? tile.data.imagery.map(function (imagery) { return [ imagery.readyImagery ? imagery.readyImagery.state : undefined, imagery.loadingImagery ? imagery.loadingImagery.state : undefined, ]; }) : [], ]; } function statesAreSame(a, b) { if (a.length !== b.length) { return false; } let same = true; for (let i = 0; i < a.length; ++i) { if (Array.isArray(a[i]) && Array.isArray(b[i])) { same = same && statesAreSame(a[i], b[i]); } else if (Array.isArray(a[i]) || Array.isArray(b[i])) { same = false; } else { same = same && a[i] === b[i]; } } return same; } return new Promise((resolve) => { let iterations = 0; function next() { ++iterations; ++that.frameState.frameNumber; // Keep going until all terrain and imagery provider are ready and states are no longer changing. let changed = false; tiles.forEach(function (tile) { const beforeState = getState(tile); GlobeSurfaceTile.processStateMachine( tile, that.frameState, that.terrainProvider, that.imageryLayerCollection ); const afterState = getState(tile); changed = changed || tile.data.terrainState === TerrainState.RECEIVING || tile.data.terrainState === TerrainState.TRANSFORMING || !statesAreSame(beforeState, afterState); }); if (!changed || iterations >= maxIterations) { resolve(iterations); } else { setTimeout(next, 0); } } next(); }); }; TerrainTileProcessor.prototype.mockWebGL = function () { spyOn(GlobeSurfaceTile, "_createVertexArrayForMesh").and.callFake( function () { const vertexArray = jasmine.createSpyObj("VertexArray", [ "destroy", "isDestroyed", ]); return vertexArray; } ); spyOn(ImageryLayer.prototype, "_createTextureWebGL").and.callFake(function ( context, imagery ) { const texture = jasmine.createSpyObj("Texture", ["destroy"]); texture.width = imagery.image.width; texture.height = imagery.image.height; return texture; }); spyOn(ImageryLayer.prototype, "_finalizeReprojectTexture"); spyOn(Texture, "create").and.callFake(function (options) { const result = clone(options); result.destroy = function () {}; return result; }); }; export default TerrainTileProcessor;