diff --git a/src/mol-data/util/_spec/chunked-array.spec.ts b/src/mol-data/util/_spec/chunked-array.spec.ts index c611d7575164bf52d912455f2d9401a216c6e025..49d0925fd037b2e1900e834786dc3a475068ae29 100644 --- a/src/mol-data/util/_spec/chunked-array.spec.ts +++ b/src/mol-data/util/_spec/chunked-array.spec.ts @@ -8,14 +8,14 @@ import { ChunkedArray } from '../chunked-array' describe('Chunked Array', () => { it('creation', () => { - const arr = ChunkedArray.create<number>(Array, 2, 2); + const arr = ChunkedArray.create<number, 2>(Array, 2, 2); ChunkedArray.add2(arr, 1, 2); ChunkedArray.add2(arr, 3, 4); expect(ChunkedArray.compact(arr)).toEqual([1, 2, 3, 4]); }); it('initial', () => { - const arr = ChunkedArray.create<number>(Int32Array, 2, 6, new Int32Array([1, 2, 3, 4])); + const arr = ChunkedArray.create(Int32Array, 2, 6, new Int32Array([1, 2, 3, 4])); ChunkedArray.add2(arr, 4, 3); ChunkedArray.add2(arr, 2, 1); ChunkedArray.add2(arr, 5, 6); @@ -23,7 +23,7 @@ describe('Chunked Array', () => { }); it('add many', () => { - const arr = ChunkedArray.create<number>(Array, 2, 2); + const arr = ChunkedArray.create<number, 2>(Array, 2, 2); ChunkedArray.addMany(arr, [1, 2, 3, 4]); expect(ChunkedArray.compact(arr)).toEqual([1, 2, 3, 4]); }); diff --git a/src/mol-data/util/chunked-array.ts b/src/mol-data/util/chunked-array.ts index fdad72464b6057f878cb218ea0ce27cb898c28ff..b2c344b4e23a58684b05dab0036dd0a238f4af77 100644 --- a/src/mol-data/util/chunked-array.ts +++ b/src/mol-data/util/chunked-array.ts @@ -12,9 +12,9 @@ * of elements and no copying is done until ChunkedArray.compact * is called. */ -interface ChunkedArray<T> { +interface ChunkedArray<T, C extends 1 | 2 | 3 | 4 = 1> { ctor: { new (size: number): ArrayLike<T> }, - elementSize: number, + elementSize: C, growBy: number, allocatedSize: number, @@ -29,11 +29,13 @@ interface ChunkedArray<T> { } namespace ChunkedArray { + type Sizes = 1 | 2 | 3 | 4 + export function is(x: any): x is ChunkedArray<any> { return x.creator && x.chunkSize; } - function allocateNext(array: ChunkedArray<any>) { + function allocateNext(array: ChunkedArray<any, any>) { let nextSize = array.growBy * array.elementSize; array.currentSize = nextSize; array.currentIndex = 0; @@ -42,7 +44,7 @@ namespace ChunkedArray { array.chunks[array.chunks.length] = array.currentChunk; } - export function add4<T>(array: ChunkedArray<T>, x: T, y: T, z: T, w: T) { + export function add4<T>(array: ChunkedArray<T, 4>, x: T, y: T, z: T, w: T) { if (array.currentIndex >= array.currentSize) allocateNext(array); const c = array.currentChunk; c[array.currentIndex++] = x; @@ -52,7 +54,7 @@ namespace ChunkedArray { return array.elementCount++; } - export function add3<T>(array: ChunkedArray<T>, x: T, y: T, z: T) { + export function add3<T>(array: ChunkedArray<T, 3>, x: T, y: T, z: T) { if (array.currentIndex >= array.currentSize) allocateNext(array); const c = array.currentChunk; c[array.currentIndex++] = x; @@ -61,7 +63,7 @@ namespace ChunkedArray { return array.elementCount++; } - export function add2<T>(array: ChunkedArray<T>, x: T, y: T) { + export function add2<T>(array: ChunkedArray<T, 2>, x: T, y: T) { if (array.currentIndex >= array.currentSize) allocateNext(array); const c = array.currentChunk; c[array.currentIndex++] = x; @@ -69,13 +71,13 @@ namespace ChunkedArray { return array.elementCount++; } - export function add<T>(array: ChunkedArray<T>, x: T) { + export function add<T>(array: ChunkedArray<T, 1>, x: T) { if (array.currentIndex >= array.currentSize) allocateNext(array); array.currentChunk[array.currentIndex++] = x; return array.elementCount++; } - export function addMany<T>(array: ChunkedArray<T>, data: ArrayLike<T>) { + export function addMany<T>(array: ChunkedArray<T, any>, data: ArrayLike<T>) { const { elementSize } = array; for (let i = 0, _i = data.length; i < _i; i += elementSize) { if (array.currentIndex >= array.currentSize) allocateNext(array); @@ -89,11 +91,11 @@ namespace ChunkedArray { } /** If doNotResizeSingleton = true and the data fit into a single chunk, do not resize it. */ - export function compact<T>(array: ChunkedArray<T>, doNotResizeSingleton = false): ArrayLike<T> { + export function compact<T>(array: ChunkedArray<T, any>, doNotResizeSingleton = false): ArrayLike<T> { return _compact(array, doNotResizeSingleton); } - export function _compact<T>(array: ChunkedArray<T>, doNotResizeSingleton: boolean): ArrayLike<T> { + export function _compact<T>(array: ChunkedArray<T, any>, doNotResizeSingleton: boolean): ArrayLike<T> { const { ctor, chunks, currentIndex } = array; if (!chunks.length) return new ctor(0); @@ -133,13 +135,13 @@ namespace ChunkedArray { return ret; } - export function create<T>(ctor: { new (size: number): ArrayLike<T> }, elementSize: number, chunkSize: number): ChunkedArray<T> + export function create<T, C extends Sizes = 1>(ctor: { new (size: number): ArrayLike<T> }, elementSize: C, chunkSize: number): ChunkedArray<T, C> /** The size of the initial chunk is elementSize * initialCount */ - export function create<T>(ctor: { new (size: number): ArrayLike<T> }, elementSize: number, chunkSize: number, initialCount: number): ChunkedArray<T> + export function create<T, C extends Sizes = 1>(ctor: { new (size: number): ArrayLike<T> }, elementSize: C, chunkSize: number, initialCount: number): ChunkedArray<T, C> /** Use the provided array as the initial chunk. The size of the array must be divisible by the elementSize */ - export function create<T>(ctor: { new (size: number): ArrayLike<T> }, elementSize: number, chunkSize: number, initialChunk: ArrayLike<T>): ChunkedArray<T> - export function create<T>(ctor: { new (size: number): ArrayLike<T> }, elementSize: number, chunkSize: number, initialChunkOrCount?: number | ArrayLike<T>): ChunkedArray<T> { - const ret: ChunkedArray<T> = { + export function create<T, C extends Sizes = 1>(ctor: { new (size: number): ArrayLike<T> }, elementSize: C, chunkSize: number, initialChunk?: ArrayLike<T>): ChunkedArray<T, C> + export function create<T, C extends Sizes = 1>(ctor: { new (size: number): ArrayLike<T> }, elementSize: C, chunkSize: number, initialChunkOrCount?: number | ArrayLike<T>): ChunkedArray<T, C> { + const ret: ChunkedArray<T, C> = { ctor, elementSize, diff --git a/src/mol-geo/util/marching-cubes/algorithm.ts b/src/mol-geo/util/marching-cubes/algorithm.ts index 0eab5c466569cac32f40272e07a5970d93070a40..9b2da47f46353841f2d72eb8c4506f3a5821cf82 100644 --- a/src/mol-geo/util/marching-cubes/algorithm.ts +++ b/src/mol-geo/util/marching-cubes/algorithm.ts @@ -128,9 +128,9 @@ class MarchingCubesState { vertList: number[] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; i: number = 0; j: number = 0; k: number = 0; - vertexBuffer: ChunkedArray<number>; - annotationBuffer: ChunkedArray<number>; - triangleBuffer: ChunkedArray<number>; + vertexBuffer: ChunkedArray<number, 3>; + annotationBuffer: ChunkedArray<number, 1>; + triangleBuffer: ChunkedArray<number, 3>; vertexCount = 0; triangleCount = 0; @@ -198,13 +198,13 @@ class MarchingCubesState { vertexBufferSize = Math.min(262144, Math.max(dX * dY * dZ / 16, 1024) | 0), triangleBufferSize = Math.min(1 << 16, vertexBufferSize * 4); - this.vertexBuffer = ChunkedArray.create<number>(s => new Float32Array(s), 3, vertexBufferSize, + this.vertexBuffer = ChunkedArray.create(Float32Array, 3, vertexBufferSize, params.oldSurface && params.oldSurface.vertexBuffer.ref.value); - this.triangleBuffer = ChunkedArray.create<number>(s => new Uint32Array(s), 3, triangleBufferSize, + this.triangleBuffer = ChunkedArray.create(Uint32Array, 3, triangleBufferSize, params.oldSurface && params.oldSurface.indexBuffer.ref.value); this.annotate = !!params.annotationField; - if (this.annotate) this.annotationBuffer = ChunkedArray.create(s => new Int32Array(s), 1, vertexBufferSize); + if (this.annotate) this.annotationBuffer = ChunkedArray.create(Int32Array, 1, vertexBufferSize); // two layers of vertex indices. Each vertex has 3 edges associated. this.verticesOnEdges = new Int32Array(3 * this.nX * this.nY * 2);