@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
162 lines (123 loc) • 3.69 kB
JavaScript
import Entity from "./Entity.js";
/**
*
* @param {Object} template
* @param {Object} [seed]
*/
function populateJsonTemplate(template, seed) {
if (seed === undefined) {
return template;
} else if (template === null) {
return template;
} else {
const templateType = typeof template;
if (templateType === "string") {
if (template.startsWith('$')) {
const varName = template.slice(1);
return seed[varName];
} else {
return template;
}
} else if (templateType === "object") {
if (Array.isArray(template)) {
//populate array
const l = template.length;
const result = [];
for (let i = 0; i < l; i++) {
result[i] = populateJsonTemplate(template[i], seed);
}
return result;
} else {
const result = {};
for (const propertyName in template) {
const templateValue = template[propertyName];
result[propertyName] = populateJsonTemplate(templateValue, seed);
}
return result;
}
} else {
return template;
}
}
}
/**
* Template for instantiating entities
* @class
*/
export class EntityBlueprint {
/**
* @private
* @type {Map<Class, Object>}
*/
#components = new Map();
/**
*
* @param {Array} components
* @returns {EntityBlueprint}
*/
static from(components = []) {
const r = new EntityBlueprint();
for (let i = 0; i < components.length; i++) {
const component = components[i];
r.add(component);
}
return r;
}
/**
*
* @param {Object} component
*/
add(component) {
const constructor = Object.getPrototypeOf(component).constructor;
this.addJSON(constructor, component.toJSON());
}
clear() {
this.#components.clear();
}
/**
* @template T
* @param {Class<T>} klass
* @param {Object} json
*/
addJSON(klass, json) {
this.#components.set(klass, json);
}
/**
*
* @param {Object} json
* @param {ModuleRegistry} registry
*/
fromJSON(json, registry) {
const component_class_names = Object.keys(json);
const component_count = component_class_names.length;
for (let i = 0; i < component_count; i++) {
const componentClassName = component_class_names[i];
const ComponentClass = registry.get(componentClassName);
const component_data = json[componentClassName];
this.addJSON(ComponentClass, component_data);
}
}
/**
* @param {Object} json
* @param {ModuleRegistry} registry
*/
static fromJSON(json, registry) {
const r = new EntityBlueprint();
r.fromJSON(json, registry);
return r;
}
/**
* @param {object} [templateSeed]
* @return {Entity}
*/
build(templateSeed) {
const eb = new Entity();
this.#components.forEach((template, ComponentClass) => {
const component = new ComponentClass();
const json = populateJsonTemplate(template, templateSeed);
component.fromJSON(json);
eb.add(component);
});
return eb;
}
}