UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

70 lines (48 loc) 2.17 kB
import { FunctionCompiler } from "../function/FunctionCompiler.js"; import { assert } from "../assert.js"; /** * Builds an encoder/decoder to simplify process of reading/writing various parts of a 32 bit field * @param {number[]} bitCounts * @returns {{encode: function(...number):number, decode: function(value:number, result:number[]):void}} */ export function create32BitCodec(bitCounts) { assert.isArray(bitCounts, 'bitCounts'); assert.lessThanOrEqual(bitCounts.length, 32, `at most 32 groups are supported (1 bit each), instead ${bitCounts} was requested`); const layout = []; const encoderFunctionBody = []; const encoderArguments = []; const decoderFunctionBody = []; let offsetCursor = 0; const group_count = bitCounts.length; for (let i = 0, numVariables = group_count; i < numVariables; i++) { const size = bitCounts[i]; assert.isNonNegativeInteger(size, `size[${i}]`); assert.greaterThan(size, 0, `size[${i}] bust be greater than 0, instead was ${size}`); const offset = offsetCursor; layout.push({ offset, size }); offsetCursor += size; const encoderArgument = 'v' + i; encoderArguments.push(encoderArgument); const bitMask = (Math.pow(2, size) - 1) << offset; encoderFunctionBody.push(`${i > 0 ? '|' : 'return '} ( ( ${encoderArgument} ${offset > 0 ? `<<${offset}` : ''}) & ${bitMask} ) ${i === numVariables - 1 ? ';' : ''}`); decoderFunctionBody.push(`result[${i}] = (value & ${bitMask}) ${offset > 0 ? `>>${offset}` : ''};`); } if (offsetCursor > 32) { throw new Error( `Only up to 32 bits are supported, ${offsetCursor} were required` ); } const encode = FunctionCompiler.INSTANCE.compile({ args: encoderArguments, code: encoderFunctionBody.join('\n') }); const decode = FunctionCompiler.INSTANCE.compile({ args: ['value', 'result'], code: decoderFunctionBody.join('\n') }); return { encode, decode, layout }; }