class Node { children = {}; class; } export default class EntityFactory { $$tries = new Node(); makeClass(types, Types) { const sorted = types.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 types = sorted; constructor(id) { this.id = id; } size() { let size = 0; for (const component of this.constructor.types) { const instance = Types[component]; size += 2 + 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 = Types[type].get.bind(Types[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; } }