silphius/app/ecs/base.js

94 lines
1.9 KiB
JavaScript
Raw Normal View History

2024-06-10 22:42:30 -05:00
export default class Base {
map = [];
pool = [];
static schema;
allocateMany(count) {
const results = [];
while (count-- > 0 && this.pool.length > 0) {
results.push(this.pool.pop());
}
return results;
}
create(entity, values) {
this.createMany([[entity, values]]);
}
destroy(entity) {
this.destroyMany([entity]);
}
destroyMany(entities) {
this.freeMany(
entities
.map((entity) => {
if ('undefined' !== typeof this.map[entity]) {
return this.map[entity];
}
throw new Error(`can't free for non-existent entity ${entity}`);
}),
);
for (let i = 0; i < entities.length; i++) {
this.map[entities[i]] = undefined;
}
}
static filterDefaults(instance) {
const json = {};
for (const [i, {defaultValue}] of this.schema) {
if (i in instance && instance[i] !== defaultValue) {
json[i] = instance[i];
}
}
return json;
}
freeMany(indices) {
for (let i = 0; i < indices.length; ++i) {
this.pool.push(indices[i]);
}
}
insertMany(entities) {
const creating = [];
for (let i = 0; i < entities.length; i++) {
const [entity, values] = entities[i];
if (!this.get(entity)) {
creating.push([entity, values]);
}
else {
const instance = this.get(entity);
for (const i in values) {
instance[i] = values[i];
}
}
}
this.createMany(creating);
}
// eslint-disable-next-line no-unused-vars
markChange(entity, components) {}
mergeDiff(original, update) {
return {...original, ...update};
}
sizeOf(entity) {
return this.constructor.schema.sizeOf(this.get(entity));
}
static wrap(name, ecs) {
class WrappedComponent extends this {
markChange(entity, key, value) {
ecs.markChange(entity, {[name]: {[key]: value}})
}
}
return new WrappedComponent();
}
}