@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
98 lines (77 loc) • 3.99 kB
JavaScript
import { System } from "./System.js";
/**
* Utility method for making sure that the system is properly constructed, used internally by the engine itself
* @param {System} system
* @throws {Error} if the system fails validation
*/
export function system_validate_class(system) {
if (system === undefined) {
throw new Error("System is undefined");
}
if (system === null) {
throw new Error("System is null");
}
if (!(system instanceof System)) {
throw new TypeError("System does not inherit from \"System\" class");
}
if (typeof system.add === "function") {
throw new Error(`uses deprecated 'add' method, should use 'link' instead`);
}
if (typeof system.remove === "function") {
throw new Error(`uses deprecated 'remove' method, should use 'unlink' instead`);
}
// validate 'components_used' section
const components_used = system.components_used;
const components_used_count = components_used.length;
for (let i = 0; i < components_used_count; i++) {
const spec = components_used[i];
if (spec === undefined || spec === null || spec.isResourceAccessSpecification !== true) {
throw new Error(`Invalid access specification[${i}], expected an instance of ResourceAccessSpecification, but got something else`);
}
if (spec.resource === null) {
throw new Error(`No component specified for element [${i}]`);
}
if (spec.access === 0) {
throw new Error('No access modifiers specified, must have at least one (such as Read, Write, Create)');
}
// backtrace to make sure there are no duplicates
for (let j = 0; j < i - 1; j++) {
const spec_other = components_used[j];
if (spec_other.resource === spec.resource) {
throw new Error(`Duplicate specification of component [${j}] and [${i}]`);
}
}
}
//validate dependencies
const dependencies = system.dependencies;
const numDependencies = dependencies.length;
if (numDependencies < 1) {
throw new Error(`A system must declare at least one dependency`);
}
if (numDependencies > 1) {
//check for duplicates
for (let i = 0; i < numDependencies; i++) {
const dependencyA = dependencies[i];
for (let j = i + 1; j < numDependencies; j++) {
if (dependencyA === dependencies[j]) {
throw new Error(`Detected duplicate dependency: ${dependencyA.constructor.typeName}`);
}
}
}
}
// deprecation check
if(system.startup !== System.prototype.startup && system.startup.length > 1) {
throw new Error(`'startup' method declares ${system.startup.length} arguments, callbacks have been deprecated in meep 2.128.0, use promises instead`);
}
// deprecation check
if(system.shutdown !== System.prototype.shutdown && system.shutdown.length > 1) {
throw new Error(`'shutdown' method declares ${system.shutdown.length} arguments, callbacks have been deprecated in meep 2.128.0, use promises instead`);
}
const linkArgumentCount = numDependencies + 1;
if (system.link !== System.prototype.link && system.link.length !== linkArgumentCount && system.__validation_ignore_link_argument_count !== true) {
throw new Error(`'link' method declares ${system.link.length} instead of expected ${linkArgumentCount} based on it's ${numDependencies} dependencies`);
}
if (system.unlink !== System.prototype.unlink && system.unlink.length !== linkArgumentCount && system.__validation_ignore_link_argument_count !== true) {
throw new Error(`'unlink' method declares ${system.unlink.length} instead of expected ${linkArgumentCount} based on it's ${numDependencies} dependencies`);
}
}