class Node { children = {}; class; } export default class EntityFactory { $$tries = new Node(); makeClass(componentNames, Components) { const sorted = componentNames.toSorted(); 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 { static componentNames = sorted; constructor(id) { this.id = id; for (const type of sorted) { this[type] = Components[type].get(id); } } size() { let size = 0; for (const componentName of this.constructor.componentNames) { const instance = Components[componentName]; size += 2 + 4 + instance.constructor.schema.sizeOf(instance.get(this.id)); } // ID + # of components. return size + 4 + 2; } } Entity.prototype.updateAttachments = new Function('update', ` ${ sorted .filter((componentName) => ( Components[componentName].Instance.prototype.updateAttachments )) .map((type) => `this.${type}.updateAttachments(update)`).join('; ') } `); Entity.prototype.toJSON = new Function('', ` return { ${sorted.map((type) => `${type}: this.${type}.toJSON()`).join(', ')} }; `); Entity.prototype.toNet = new Function('recipient', ` return { ${sorted.map((type) => `${type}: this.${type}.toNet(recipient)`).join(', ')} }; `); walk.class = Entity; } return walk.class; } }