silphius/app/ecs/schema.js
2024-07-23 10:10:32 -05:00

67 lines
1.6 KiB
JavaScript

export default class Schema {
static $$types = {};
specification;
constructor(specification) {
this.specification = this.constructor.normalize(specification);
}
static defaultValue({$, concrete}) {
if (concrete.defaultValue) {
return concrete.defaultValue;
}
return $.defaultValue(concrete);
}
defaultValue() {
return this.constructor.defaultValue(this.specification);
}
static deserialize(view, offset, {$, concrete}) {
return $.deserialize(view, offset, concrete);
}
deserialize(view, offset = 0) {
return this.constructor.deserialize(view, {value: offset}, this.specification);
}
static normalize({type, ...rest}) {
const $$type = this.$$types[type];
if (!$$type) {
throw new TypeError(`unregistered schema type '${type}'`);
}
return {
$: this.$$types[type],
concrete: $$type.normalize ? $$type.normalize(rest) : rest,
};
}
static serialize(source, view, offset, {$, concrete}) {
return $.serialize(source, view, offset, concrete);
}
serialize(source, view, offset = 0) {
this.constructor.serialize(source, view, offset, this.specification);
}
static sizeOf(instance, {$, concrete}) {
return $.sizeOf(instance, concrete);
}
sizeOf(instance) {
return this.constructor.sizeOf(instance, this.specification);
}
static size({$, concrete}) {
return $.staticSizeOf(concrete);
}
}
const imports = import.meta.glob('./schema-types/*.js', {eager: true, import: 'default'});
for (const path in imports) {
Schema.$$types[path.replace(/.\/schema-types\/(.*)\.js/, '$1')] = imports[path](Schema);
}