UNPKG

shaku

Version:

A simple and effective JavaScript game development framework that knows its place!

121 lines (113 loc) 3.74 kB
/** * A Float32Array that grows automatically. * * |-- copyright and license --| * @module Shaku * @file shaku\src\gfx\draw_batches\dynamic_array.js * @author Ronen Ness (ronenness@gmail.com | http://ronenness.com) * @copyright (c) 2021 Ronen Ness * @license MIT * |-- end copyright and license --| * */ 'use strict'; /** * A polyfill version of 'ArrayBuffer.transfer'. * If native ArrayBuffer.transfer exists, will use it internally. * From: https://reference.codeproject.com/javascript/reference/global_objects/arraybuffer/transfer#Browser_compatibility */ function transferPolyfill (source, dest) { // to handle typed buffers if (source.buffer instanceof ArrayBuffer) { source = source.buffer; } if (dest.buffer instanceof ArrayBuffer) { source = dest.buffer; } // use native if (ArrayBuffer.transfer) { return ArrayBuffer.transfer(source, dest); } // polyfill if(dest.byteLength >= source.byteLength) { var nextOffset = 0; var leftBytes = source.byteLength; var wordSizes = [8, 4, 2, 1]; wordSizes.forEach(function (_wordSize_) { if (leftBytes => _wordSize_) { var done = transferWith(_wordSize_, source, dest, nextOffset, leftBytes); nextOffset = done.nextOffset; leftBytes = done.leftBytes; } }); } function transferWith(wordSize, source, dest, nextOffset, leftBytes) { var ViewClass = Uint8Array; switch (wordSize) { case 8: ViewClass = Float64Array; break; case 4: ViewClass = Float32Array; break; case 2: ViewClass = Uint16Array; break; case 1: ViewClass = Uint8Array; break; default: ViewClass = Uint8Array; break; } var view_source = new ViewClass(source, nextOffset, Math.trunc(leftBytes / wordSize)); var view_dest = new ViewClass(dest, nextOffset, Math.trunc(leftBytes / wordSize)); for(var i=0; i<view_dest.length; i++) { view_dest[i] = view_source[i]; } return { nextOffset : view_source.byteOffset + view_source.byteLength, leftBytes : source.byteLength - (view_source.byteOffset + view_source.byteLength) } } } /** * A float 32 array that grows automatically. */ class DynamicArray { /** * Create the array. * @param {Number} startSize Starting size. * @param {*} type Array type (defaults to Float32Array). */ constructor(startSize, type) { this.type = type || Float32Array; this.buffer = new this.type(startSize); this.index = 0; this._startSize = startSize; } /** * Reset the array back to original size. */ reset(includeSize) { this.index = 0; if (includeSize && this.buffer.length !== this._startSize) { this.buffer = new this.type(this._startSize); } } /** * Push a value into the array and grow it if necessary. * @param {Number} value Value to push. */ push(value) { if (this.index >= this.buffer.length) { let newBuffer = new this.type(this.buffer.length * 2); transferPolyfill(this.buffer, newBuffer); this.buffer = newBuffer; } this.buffer[this.index++] = value; } } // export the dynamic float32 array. module.exports = DynamicArray;