import { Vector3Like } from "@here/harp-geoutils" ; import { assert } from "@here/harp-utils" ; enum Field { VertexId = 0 , OlderIdx , NewerIdx , X , Y , Z , Count } const Invalid = - 1 ; internal export class VertexCache { private m_cache : number [ ] = [ ] ; private m_vertexCount : number = 0 ; private m_oldestIdx : number = 0 ; private m_newestIdx : number = 0 ; param maxVertexCount constructor ( readonly maxVertexCount ) { this . m_cache . length = this . maxVertexCount * Field . Count ; this . clear ( ) ; } /**
     * Clears the vertex cache.
     */ clear ( ) { this . m_cache . fill ( Invalid ) ; this . m_vertexCount = 0 ; } param vertexId param vertex returns get ( vertexId , vertex ) { const vertexIdx = this . find ( vertexId ) ; if ( vertexIdx === undefined ) { return false ; } this . promoteEntry ( vertexIdx ) ; this . getVertex ( vertexIdx , vertex ) ; return true ; } param vertexId param vertex set ( vertexId , vertex ) { let vertexIdx = Invalid ; if ( this . m_vertexCount < this . maxVertexCount ) { vertexIdx = this . m_vertexCount * Field . Count ; this . m_vertexCount ++ ; } else { vertexIdx = this . m_oldestIdx ; } if ( this . m_vertexCount === 1 ) { this . m_oldestIdx = this . m_newestIdx = vertexIdx ; } else { this . promoteEntry ( vertexIdx ) ; } this . setVertex ( vertexIdx , vertexId , vertex ) ; } private find ( vertexId ) { const size = this . m_cache . length ; for ( let i = 0 ; i < size ; i += Field . Count ) { if ( this . m_cache [ i ] === vertexId ) { return i ; } } return undefined ; } private promoteEntry ( vertexIdx ) { if ( vertexIdx === this . m_newestIdx ) { return ; } const newerIdx = this . getNewerIdx ( vertexIdx ) ; const olderIdx = this . getOlderIdx ( vertexIdx ) ; if ( newerIdx !== Invalid ) { assert ( this . getOlderIdx ( newerIdx ) === vertexIdx ) ; this . setOlderIdx ( newerIdx , olderIdx ) ; } if ( olderIdx !== Invalid ) { assert ( this . getNewerIdx ( olderIdx ) === vertexIdx ) ; this . setNewerIdx ( olderIdx , newerIdx ) ; } if ( vertexIdx === this . m_oldestIdx ) { this . m_oldestIdx = newerIdx ; } this . setNewerIdx ( vertexIdx , Invalid ) ; this . setOlderIdx ( vertexIdx , this . m_newestIdx ) ; assert ( this . m_newestIdx !== Invalid ) ; assert ( this . getNewerIdx ( this . m_newestIdx ) === Invalid ) ; this . setNewerIdx ( this . m_newestIdx , vertexIdx ) ; this . m_newestIdx = vertexIdx ; } private getOlderIdx ( vertexIdx ) { return this . m_cache [ vertexIdx + Field . OlderIdx ] ; } private setOlderIdx ( vertexIdx , olderIdx ) { this . m_cache [ vertexIdx + Field . OlderIdx ] = olderIdx ; } private getNewerIdx ( vertexIdx ) { return this . m_cache [ vertexIdx + Field . NewerIdx ] ; } private setNewerIdx ( vertexIdx , newerIdx ) { this . m_cache [ vertexIdx + Field . NewerIdx ] = newerIdx ; } private getVertex ( vertexIdx , vertex ) { vertex . x = this . m_cache [ vertexIdx + Field . X ] ; vertex . y = this . m_cache [ vertexIdx + Field . Y ] ; vertex . z = this . m_cache [ vertexIdx + Field . Z ] ; } private setVertex ( vertexIdx , vertexId , vertex ) { this . m_cache [ vertexIdx ] = vertexId ; this . m_cache [ vertexIdx + Field . X ] = vertex . x ; this . m_cache [ vertexIdx + Field . Y ] = vertex . y ; this . m_cache [ vertexIdx + Field . Z ] = vertex . z ; } }