@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
184 lines (142 loc) • 4.41 kB
JavaScript
import { assert } from "../core/assert.js";
import { computeSystemName } from "./ecs/computeSystemName.js";
export class EngineConfiguration {
/**
* @private
* @type {System[]}
*/
systems = [];
/**
* @private
* @type {Class<EnginePlugin>[]}
*/
plugins = [];
/**
* Static database
* Can contain tables of structured data that the application often works with.
* Engine startup will load all tables ensuring that data is ready once startup finishes
* Use sparingly, this is not suitable for very large amounts of data as all the data will be in memory and deserialization will stall engine startup
* Example: inventory item table, monster table
* @private
* @readonly
* @type {StaticKnowledgeDataTableDescriptor[]}
*/
knowledge = [];
/**
*
* @type {Map<string,AssetLoader<any>>}
*/
loaders = new Map();
/**
*
* @param {string} type
* @returns {boolean}
*/
hasLoader(type) {
return this.loaders.has(type);
}
/**
* @template T
* @param {string} type
* @param {AssetLoader<T>} loader
*/
addLoader(type, loader) {
if (this.loaders.has(type)) {
return false;
}
this.loaders.set(type, loader);
return true;
}
/**
* @template T
* @param {string} type
* @returns {AssetLoader<T>}
*/
removeLoader(type) {
const assetLoader = this.loaders.get(type);
if (assetLoader !== undefined) {
this.loaders.delete(type);
}
return assetLoader;
}
/**
*
* @param {Class<EnginePlugin>} plugin
* @returns {boolean}
*/
addPlugin(plugin) {
assert.defined(plugin, 'plugin');
this.plugins.push(plugin);
return true;
}
/**
*
* @param {System} system
* @returns {boolean}
*/
addSystem(system) {
assert.defined(system, 'system');
assert.notNull(system, 'system');
assert.equal(system.isSystem, true, "system.isSystem !== true");
this.systems.push(system);
return true;
}
/**
* @param {System} systems
*/
addManySystems(...systems) {
assert.defined(systems, "systems");
assert.isArray(systems, "systems");
systems.forEach(s => this.addSystem(s));
}
/**
*
* @param {StaticKnowledgeDataTableDescriptor} table
* @returns {boolean}
*/
addDataTable(table) {
assert.defined(table,'table');
assert.notNull(table,'table');
this.knowledge.push(table);
return true;
}
/**
*
* @param {Engine} engine
*/
async apply(engine) {
// asset loaders
const loader_promises = [];
this.loaders.forEach((loader, type) => {
loader_promises.push(engine.assetManager.registerLoader(type, loader));
});
await Promise.all(loader_promises);
// Knowledge tables
const knowledgeTableCount = this.knowledge.length;
for (let i = 0; i < knowledgeTableCount; i++) {
const tableDescriptor = this.knowledge[i];
engine.staticKnowledge.add(tableDescriptor.id, tableDescriptor.source, tableDescriptor.table);
}
// Plugins
const plugins = engine.plugins;
const config_plugins = this.plugins;
const pluginCount = config_plugins.length;
for (let i = 0; i < pluginCount; i++) {
const enginePlugin = config_plugins[i];
await plugins.acquire(enginePlugin);
}
console.log(`Loaded ${pluginCount} plugins`);
// Systems
const em = engine.entityManager;
const systemCount = this.systems.length;
for (let i = 0; i < systemCount; i++) {
const system = this.systems[i];
if (engine.entityManager.hasSystem(system.constructor)) {
// system already registered
console.warn(`system '${computeSystemName(system)}' already registered`);
continue;
}
await em.addSystem(system);
}
}
}