UNPKG

c-structs

Version:
247 lines (245 loc) 6.29 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { c: () => c, p: () => p }); module.exports = __toCommonJS(index_exports); var p = { float32: { size: 4, arrayType: Float32Array, getter: "getFloat32", setter: "setFloat32" }, float64: { size: 8, arrayType: Float64Array, getter: "getFloat64", setter: "setFloat64" }, uint16: { size: 2, arrayType: Uint16Array, getter: "getUint16", setter: "setUint16" }, uint32: { size: 4, arrayType: Uint32Array, getter: "getUint32", setter: "setUint32" }, uint64: { size: 8, arrayType: BigUint64Array, getter: "getBigUint64", setter: "setBigUint64" }, int16: { size: 2, arrayType: Int16Array, getter: "getInt16", setter: "setInt16" }, int32: { size: 4, arrayType: Int32Array, getter: "getInt32", setter: "setInt32" }, int64: { size: 8, arrayType: BigInt64Array, getter: "getBigInt64", setter: "setBigInt64" } }; var c = { // Vector of floats float() { return p.float32; }, float2() { return [p.float32, p.float32]; }, float3() { return [p.float32, p.float32, p.float32]; }, float4() { return [p.float32, p.float32, p.float32, p.float32]; }, uint() { return p.uint32; }, uint2() { return [p.uint32, p.uint32]; }, uint3() { return [p.uint32, p.uint32, p.uint32]; }, uint4() { return [p.uint32, p.uint32, p.uint32, p.uint32]; }, matrix4() { return [ p.float32, p.float32, p.float32, p.float32, p.float32, p.float32, p.float32, p.float32, p.float32, p.float32, p.float32, p.float32, p.float32, p.float32, p.float32, p.float32 ]; }, /** * Create an array descriptor for nested structs. */ array(structDesc, length) { if (typeof structDesc.size !== "number" || typeof structDesc.create !== "function") { throw new Error("c.array: first arg must be a StructDescriptor"); } if (!Number.isInteger(length) || length <= 0) { throw new Error("c.array: length must be a positive integer"); } return { size: structDesc.size * length, create(buffer = new ArrayBuffer(structDesc.size * length), baseOffset = 0) { const arr = []; for (let i = 0; i < length; i++) { arr.push(structDesc.create(buffer, baseOffset + i * structDesc.size)); } Object.defineProperty(arr, "buffer", { get: () => buffer, enumerable: false }); return arr; } }; }, /** * Create a struct descriptor from a schema map. */ struct(schema) { let offset = 0; const fields = []; for (const [name, type] of Object.entries(schema)) { const fieldOffset = offset; let entry; if (Array.isArray(type)) { const elem = type[0]; entry = { kind: "vector", name, elem, length: type.length, offset: fieldOffset }; offset += elem.size * type.length; } else if (type.size && typeof type.create === "function" && Array.isArray(type.create())) { entry = { kind: "array", name, elemDesc: type, length: type.length, offset: fieldOffset }; offset += type.size * type.length; } else if (type.arrayType) { const elem = type; entry = { kind: "scalar", name, desc: elem, offset: fieldOffset }; offset += elem.size; } else if (type.size && typeof type.create === "function") { entry = { kind: "struct", name, desc: type, offset: fieldOffset }; offset += type.size; } else { throw new Error(`Unknown field type for "${name}"`); } fields.push(entry); } const totalSize = offset; return { size: totalSize, create(buffer = new ArrayBuffer(totalSize), baseOffset = 0) { const view = new DataView(buffer); const inst = {}; for (const f of fields) { const abs = baseOffset + f.offset; switch (f.kind) { case "scalar": Object.defineProperty(inst, f.name, { get: () => view[f.desc.getter](abs, true), set: (v) => view[f.desc.setter](abs, v, true), enumerable: true }); break; case "vector": { const Typed = f.elem.arrayType; const ta = new Typed(buffer, abs, f.length); Object.defineProperty(inst, f.name, { get: () => ta, set: (arr) => { for (let i = 0; i < f.length; i++) ta[i] = arr[i]; }, enumerable: true }); break; } case "struct": inst[f.name] = f.desc.create(buffer, abs); break; case "array": inst[f.name] = c.array(f.elemDesc, f.length).create(buffer, abs); break; } } Object.defineProperty(inst, "buffer", { get: () => buffer, enumerable: false }); return inst; } }; } }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { c, p });