silphius/app/ecs/serializer.js
2024-06-10 22:45:09 -05:00

62 lines
1.7 KiB
JavaScript

import Schema from './schema.js';
export default class Serializer {
constructor(schema) {
this.schema = schema instanceof Schema ? schema : new Schema(schema);
}
decode(view, destination, offset = 0) {
let cursor = offset;
for (const [key, {type}] of this.schema) {
const viewGetMethod = Schema.viewGetMethods[type];
let value;
if (viewGetMethod) {
value = view[viewGetMethod](cursor, true);
cursor += Schema.sizeOfType(type);
}
else {
switch (type) {
case 'string': {
const length = view.getUint32(cursor, true);
cursor += 4;
const {buffer, byteOffset} = view;
const decoder = new TextDecoder();
value = decoder.decode(new DataView(buffer, byteOffset + cursor, length));
cursor += length;
break;
}
}
}
destination[key] = value;
}
}
encode(source, view, offset = 0) {
let cursor = offset;
for (const [key, {type}] of this.schema) {
const viewSetMethod = Schema.viewSetMethods[type];
if (viewSetMethod) {
view[viewSetMethod](cursor, source[key], true);
cursor += Schema.sizeOfType(type);
}
else {
switch (type) {
case 'string': {
const lengthOffset = cursor;
cursor += 4;
const encoder = new TextEncoder();
const bytes = encoder.encode(source[key]);
for (let i = 0; i < bytes.length; ++i) {
view.setUint8(cursor++, bytes[i]);
}
view.setUint32(lengthOffset, bytes.length, true);
break;
}
}
}
}
}
}