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; } 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; } } const properties = {}; for (const type of sorted) { properties[type] = {}; const get = Components[type].get.bind(Components[type]); properties[type].get = function() { return get(this.id); }; } Object.defineProperties(Entity.prototype, properties); Entity.prototype.toJSON = new Function('', ` return { ${sorted.map((type) => `${type}: this.${type}.toJSON()`).join(', ')} }; `); walk.class = Entity; } return walk.class; } }