import { DecodedTile , DecoderOptions , getProjectionName , ITileDecoder , OptionsMap , RequestController , TileInfo , WorkerDecoderProtocol , WorkerServiceProtocol } from "@here/harp-datasource-protocol" ; import { Projection , TileKey } from "@here/harp-geoutils" ; import { ConcurrentWorkerSet } from "./ConcurrentWorkerSet" ; /**
 * Identifier of next decoder worker-service. Used to ensure uniqueness of service ids of decoders
 * dedicated to different datasources.
 */ let nextUniqueServiceId = 0 ; /**
 * Decoder based on [[ConcurrentWorkerSet]].
 *
 * Decodes tiles using workers running in separate contexts (also known as `WebWorkers`):
 * - connection establishment,
 * - sends decode requests,
 * - configuration.
 */ export class WorkerBasedDecoder implements ITileDecoder { private readonly serviceId : string ; private m_serviceCreated : boolean = false ; param workerSet param decoderServiceType constructor ( private readonly workerSet , private readonly decoderServiceType ) { this . workerSet . addReference ( ) ; this . serviceId = `${ this . decoderServiceType }-${ nextUniqueServiceId ++ }` ; } /**
     * Dispose of dedicated tile decoder services in workers and remove reference to underlying
     * [[ConcurrentWorkerSet]].
     */ dispose ( ) { if ( this . m_serviceCreated ) { this . workerSet . broadcastRequest ( WorkerServiceProtocol . WORKER_SERVICE_MANAGER_SERVICE_ID , { type : WorkerServiceProtocol . Requests . DestroyService , targetServiceId : this . serviceId } ) . catch ( ( ) => { } ) ; } this . workerSet . removeReference ( ) ; } /**
     * Connects to [[WorkerServiceManager]]s in underlying [[ConcurrentWorkerSet]] and creates
     * dedicated [[TileDecoderService]]s in all workers to serve decode requests.
     */ async connect ( ) { await this . workerSet . connect ( WorkerServiceProtocol . WORKER_SERVICE_MANAGER_SERVICE_ID ) ; if ( ! this . m_serviceCreated ) { await this . workerSet . broadcastRequest ( WorkerServiceProtocol . WORKER_SERVICE_MANAGER_SERVICE_ID , { type : WorkerServiceProtocol . Requests . CreateService , targetServiceType : this . decoderServiceType , targetServiceId : this . serviceId } ) ; this . m_serviceCreated = true ; } } /**
     * Get  Tile from tile decoder service in worker.
     *
     *  remarks Invokes  {@link @here/harp-datasource-protocol#DecodeTileRequest} on
     * [[TileDecoderService]] running in worker pool.
      decodeTile ( data , tileKey , projection , requestController ? ) { const tileKeyCode = tileKey . mortonCode ( ) ; const message = { type : WorkerDecoderProtocol . Requests . DecodeTileRequest , tileKey : tileKeyCode , data , projection : getProjectionName ( projection ) } ; const transferList = data instanceof ArrayBuffer ? [ data ] : undefined ; return this . workerSet . invokeRequest ( this . serviceId , message , transferList , requestController ) ; } /**
     * Get  {@link @here/harp-datasource-protocol#TileInfo} from tile decoder service in worker.
     *
     *  remarks Invokes  {@link @here/harp-datasource-protocol#TileInfoRequest} * on [[TileDecoderService]] running in worker pool.
      getTileInfo ( data , tileKey , projection , requestController ? ) { const tileKeyCode = tileKey . mortonCode ( ) ; const message = { type : WorkerDecoderProtocol . Requests . TileInfoRequest , tileKey : tileKeyCode , data , projection : getProjectionName ( projection ) } ; const transferList = data instanceof ArrayBuffer ? [ data ] : undefined ; return this . workerSet . invokeRequest ( this . serviceId , message , transferList , requestController ) ; } remarks Broadcasts  {@link @here/harp-datasource-protocol#ConfigurationMessage} * to all [[TileDecoderService]]s running in worker pool.
     *
     *  param options param customOptions configure ( options ? , customOptions ? ) { const message = { service : this . serviceId , type : WorkerDecoderProtocol . DecoderMessageName . Configuration , ... options , options : customOptions } ; this . workerSet . broadcastMessage ( message ) ; } /**
     * The number of workers started for this decoder. The value is `undefined` until the workers
     * have been created.
     */ get workerCount ( ) : number | undefined { return this . workerSet . workerCount ; } }