@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
70 lines (48 loc) • 2.17 kB
JavaScript
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
};
}