silphius/app/ecs/entity-factory.js

71 lines
1.9 KiB
JavaScript
Raw Normal View History

2024-06-10 22:42:30 -05:00
class Node {
children = {};
class;
}
export default class EntityFactory {
$$tries = new Node();
2024-06-15 19:38:49 -05:00
makeClass(componentNames, Components) {
const sorted = componentNames.toSorted();
2024-06-10 22:42:30 -05:00
let walk = this.$$tries;
let i = 0;
while (i < sorted.length) {
if (!walk.children[sorted[i]]) {
walk.children[sorted[i]] = new Node();
}
walk = walk.children[sorted[i]];
i += 1;
}
if (!walk.class) {
class Entity {
2024-06-15 19:38:49 -05:00
static componentNames = sorted;
2024-06-10 22:42:30 -05:00
constructor(id) {
this.id = id;
}
size() {
let size = 0;
2024-06-15 19:38:49 -05:00
for (const componentName of this.constructor.componentNames) {
const instance = Components[componentName];
2024-06-14 01:11:14 -05:00
size += 2 + 4 + instance.constructor.schema.sizeOf(instance.get(this.id));
2024-06-10 22:42:30 -05:00
}
// ID + # of components.
return size + 4 + 2;
}
}
const properties = {};
for (const type of sorted) {
properties[type] = {};
2024-06-15 19:38:49 -05:00
const get = Components[type].get.bind(Components[type]);
2024-06-10 22:42:30 -05:00
properties[type].get = function() {
return get(this.id);
};
}
Object.defineProperties(Entity.prototype, properties);
2024-07-28 18:42:28 -05:00
Entity.prototype.updateAttachments = new Function('update', `
${
sorted
.filter((componentName) => (
Components[componentName].Instance.prototype.updateAttachments
))
.map((type) => `this.${type}.updateAttachments(update)`).join('; ')
}
`);
2024-06-10 22:42:30 -05:00
Entity.prototype.toJSON = new Function('', `
return {
${sorted.map((type) => `${type}: this.${type}.toJSON()`).join(', ')}
};
`);
2024-07-28 18:42:28 -05:00
Entity.prototype.toNet = new Function('recipient', `
2024-07-13 00:33:41 -05:00
return {
2024-07-28 18:42:28 -05:00
${sorted.map((type) => `${type}: this.${type}.toNet(recipient)`).join(', ')}
2024-07-13 00:33:41 -05:00
};
`);
2024-06-10 22:42:30 -05:00
walk.class = Entity;
}
return walk.class;
}
}