# Serpentity
-Serpentity is a simple entity framework inspired by [Ash][ash].
+Serpentity is a simple entity framework inspired by Ash.
Usage:
- require('serpentity');
+ let Serpentity = require('serpentity');
+
+or:
+
+ <script src="/node_modules/serpentity/dist/serpentity.js"></script>
## Instantiating an engine
- var engine = Serpentity();
+ let engine = Serpentity();
Add entities or systems, systems are added with a priority (the smaller
the number, the earlier it will be called):
Entities are the basic object of Serpentity, and they do nothing.
- var entity = new Serpentity.Entity();
+ let entity = new Serpentity.Entity();
All the behavior is added through components
Components define data that we can add to an entity. This data will
eventually be consumed by "Systems"
- Class("PositionComponent").inherits(Serpentity.Component)({
- prototype : {
- x : 0,
- y : 0
- }
- });
+ let PositionComponent = class PositionComponent extends Serpentity.Component {
+ constructor (config) {
+ super(config);
+
+ this.x = this.x || 0;
+ this.y = this.y || 0;
+ }
+ };
-You can add components to entities by using the addComponent method:
+You can add components to entities by using the add method:
entity.addComponent(new PositionComponent());
Nodes are sets of components that you define, so your system can require
entities that always follow the API defined in the node.
- Class("MovementNode").inherits(Serpentity.Node)({
- types : {
- position : PositionComponent,
- motion : MotionComponent
- }
- });
+ let MovementNode = class MovementNode extends Serpentity.Node;
+ MovementNode.position = PositionComponent;
+ MovementNode.motion = MotionComponent;
You can then request an array of all the nodes representing entities
that comply with that API
Systems are called on every update, and they use components through nodes.
- Class("TestSystem").inherits(Serpentity.System)({
- prototype : {
- added : function added(engine){
- this.nodeList = engine.getNodes(MovementNode);
- },
- removed : function removed(engine){
- this.nodeList = undefined;
- }
- update : function update(dt){
- this.nodeList.forEach(function (node) {
- console.log("Current position is: " + node.position.x + "," + node.position.y);
- });
- }
+ let TestSystem = class TestSystem extends Serpentity.System {
+ added (engine){
+ this.nodeList = engine.getNodes(MovementNode);
+ },
+ removed (engine){
+ this.nodeList = undefined;
+ }
+ update (dt){
+ let node;
+ for (node of this.nodeList) {
+ console.log(`Current position is: ${node.position.x},${node.position.y}`);
}
- });
+ }
+ };
## That's it
Just run `engine.update(dt)` in your game loop :D
-## Checking it in the frontend (dev).
-
-You can link the bower package to test it out locally.
-Spawn a python server (`python -m SimpleHTTPServer`) to see
-the test page in `http://localhost:8000/browser_test/`
-
-
## TO-DO
-* Removing components
-* Implement the ashteroids demo (Serpentoids)
-* Actually check performance
+* Minimize code (Uglify does not support ES6 yet)
+* Check Performance
[ash]: http://www.ashframework.org/
+++ /dev/null
-#!/usr/bin/env node
-
-require("colors");
-require("serpentity");
-
-/////////////////
-// Load the stuff
-/////////////////
-console.log("\n## Loading".bold.black)
-console.log("Serpentity: " + (typeof Serpentity !== "undefined" ? "LOAD OK".green : "FAIL".red));
-console.log("Serpentity.Entity: " + (typeof Serpentity !== "undefined" && Serpentity.Entity ? "LOAD OK".green : "FAIL".red));
-console.log("Serpentity.Component: " + (typeof Serpentity !== "undefined" && Serpentity.Component ? "LOAD OK".green : "FAIL".red));
-console.log("Serpentity.System: " + (typeof Serpentity !== "undefined" && Serpentity.System ? "LOAD OK".green : "FAIL".red));
-console.log("Serpentity.Node: " + (typeof Serpentity !== "undefined" && Serpentity.Node ? "LOAD OK".green : "FAIL".red));
-console.log("Serpentity.NodeCollection: " + (typeof Serpentity !== "undefined" && Serpentity.NodeCollection ? "LOAD OK".green : "FAIL".red));
-
-//////////////////////
-// Create test classes
-//////////////////////
-console.log("\n## Creating Test Classes".bold.black);
-Class("TestSystem").inherits(Serpentity.System)({
- prototype : {
- added : function added(engine) {
- this.testNodes = engine.getNodes(TestNode);
- console.log("System added callback: " + "EXEC OK".green);
- },
-
- removed : function removed(engine) {
- this.testNodes = null;
- console.log("System removed callback: " + "EXEC OK".green);
- },
-
- update : function update(dt) {
- this.testNodes.forEach(function (node) {
- console.log("Running Node: " + (node.test.testMessage === "test" ? "SYSTEM OK".green : "FAIL".RED));
- });
- console.log("System update callback: " + "EXEC OK".green);
- }
- }
-});
-var testSystem = new TestSystem();
-
-Class("LowProTestSystem").inherits(Serpentity.System)({
- prototype : {
- added : function added(engine) {
- this.testNodes = engine.getNodes(TestNode);
- console.log("System added callback: " + "EXEC OK".green);
- },
-
- removed : function removed(engine) {
- this.testNodes = null;
- console.log("System removed callback: " + "EXEC OK".green);
- },
-
- update : function update(dt) {
- this.testNodes.forEach(function (node) {
- console.log("Running Low Priority Node: " + (node.test.testMessage === "test" ? "SYSTEM OK".green : "FAIL".RED));
- });
- console.log("System update callback: " + "EXEC OK".green);
- }
- }
-});
-var lowProTestSystem = new LowProTestSystem();
-console.log("LowProTestSystem: " + "CREATE OK".green)
-
-Class("MidProTestSystem").inherits(Serpentity.System)({
- prototype : {
- added : function added(engine) {
- this.testNodes = engine.getNodes(TestNode);
- console.log("System added callback: " + "EXEC OK".green);
- },
-
- removed : function removed(engine) {
- this.testNodes = null;
- console.log("System removed callback: " + "EXEC OK".green);
- },
-
- update : function update(dt) {
- this.testNodes.forEach(function (node) {
- console.log("Running Mid Priority Node: " + (node.test.testMessage === "test" ? "SYSTEM OK".green : "FAIL".RED));
- });
- console.log("System update callback: " + "EXEC OK".green);
- }
- }
-});
-var midProTestSystem = new MidProTestSystem();
-console.log("MidProTestSystem: " + "CREATE OK".green)
-
-
-Class("TestComponent").inherits(Serpentity.Component)({
- prototype : {
- testMessage : "test"
- }
-});
-console.log("TestComponent: " + "CREATE OK".green)
-
-Class("TestNode").inherits(Serpentity.Node)({
- types : {
- test : TestComponent
- }
-});
-console.log("TestNode: " + "CREATE OK".green)
-
-
-console.log("\n## Adding system to the engine".bold.black)
-
-var engine = new Serpentity();
-console.log("engine: " + "CREATE OK".green)
-
-engine.addSystem(testSystem, 0);
-
-console.log("\n## Running update without any entities".bold.black)
-engine.update(10);
-
-console.log("\n## Adding system to the engine and updating".bold.black)
-var entity = new Serpentity.Entity();
-entity.addComponent(new TestComponent());
-engine.addEntity(entity);
-engine.update(10);
-
-console.log("\n## Adding Low Priority System".bold.black)
-engine.addSystem(lowProTestSystem, 10);
-engine.update(10);
-
-console.log("\n## Adding Mid Priority System".bold.black)
-engine.addSystem(midProTestSystem, 5);
-engine.update(10);
-
-console.log("\n## Removing the system and readding".bold.black)
-engine.removeSystem(testSystem);
-engine.update(10);
-engine.addSystem(testSystem, 0);
-engine.update(10);
-
-console.log("\n## Adding a second entity".bold.black)
-var entity = new Serpentity.Entity();
-entity.addComponent(new TestComponent());
-engine.addEntity(entity);
-engine.update(10);
-
-console.log("\n## Removing entity".bold.black)
-engine.removeEntity(entity)
-engine.update(10);
-
-console.log("\n## Removing system".bold.black)
-engine.removeSystem(testSystem)
-engine.update(10);
+++ /dev/null
-{
- "name": "serpentity",
- "version": "0.1.7",
- "homepage": "https://github.com/rbdr/serpentity",
- "authors": [
- "Ben Beltran <ben@nsovocal.com>"
- ],
- "description": "A simple entity framework inspired by ash",
- "main": [
- "./dist/serpentity.js"
- ],
- "keywords": [
- "entity",
- "serpentity"
- ],
- "license": "MIT",
- "ignore": [
- "**/.*",
- "node_modules",
- "bower_components",
- "test",
- "tests",
- "bin",
- "browser_test",
- "LICENSE",
- "bower.json",
- "README.md",
- "gulpfile.js",
- "package.json",
- "lib"
- ],
- "dependencies": {
- "neon": "*"
- }
-}
+++ /dev/null
-<!DOCTYPE html>
-<html>
- <head>
- <title>Serpentity Browser Test</title>
- <script src="/bower_components/neon/neon.js"></script>
- <script src="/bower_components/serpentity/dist/serpentity.js"></script>
- <script type="application/javascript">
- /////////////////
- // Load the stuff
- /////////////////
- console.log("\n## Loading")
- console.log("Serpentity: " + (typeof Serpentity !== "undefined" ? "LOAD OK" : "FAIL"));
- console.log("Serpentity.Entity: " + (typeof Serpentity !== "undefined" && Serpentity.Entity ? "LOAD OK" : "FAIL"));
- console.log("Serpentity.Component: " + (typeof Serpentity !== "undefined" && Serpentity.Component ? "LOAD OK" : "FAIL"));
- console.log("Serpentity.System: " + (typeof Serpentity !== "undefined" && Serpentity.System ? "LOAD OK" : "FAIL"));
- console.log("Serpentity.Node: " + (typeof Serpentity !== "undefined" && Serpentity.Node ? "LOAD OK" : "FAIL"));
- console.log("Serpentity.NodeCollection: " + (typeof Serpentity !== "undefined" && Serpentity.NodeCollection ? "LOAD OK" : "FAIL"));
-
- //////////////////////
- // Create test classes
- //////////////////////
- console.log("\n## Creating Test Classes");
- Class("TestSystem").inherits(Serpentity.System)({
- prototype : {
- added : function added(engine) {
- this.testNodes = engine.getNodes(TestNode);
- console.log("System added callback: " + "EXEC OK");
- },
-
- removed : function removed(engine) {
- this.testNodes = null;
- console.log("System removed callback: " + "EXEC OK");
- },
-
- update : function update(dt) {
- this.testNodes.forEach(function (node) {
- console.log("Running Node: " + (node.test.testMessage === "test" ? "SYSTEM OK" : "FAIL"));
- });
- console.log("System update callback: " + "EXEC OK");
- }
- }
- });
- var testSystem = new TestSystem();
-
- Class("LowProTestSystem").inherits(Serpentity.System)({
- prototype : {
- added : function added(engine) {
- this.testNodes = engine.getNodes(TestNode);
- console.log("System added callback: " + "EXEC OK");
- },
-
- removed : function removed(engine) {
- this.testNodes = null;
- console.log("System removed callback: " + "EXEC OK");
- },
-
- update : function update(dt) {
- this.testNodes.forEach(function (node) {
- console.log("Running Low Priority Node: " + (node.test.testMessage === "test" ? "SYSTEM OK" : "FAIL"));
- });
- console.log("System update callback: " + "EXEC OK");
- }
- }
- });
- var lowProTestSystem = new LowProTestSystem();
- console.log("LowProTestSystem: " + "CREATE OK")
-
- Class("MidProTestSystem").inherits(Serpentity.System)({
- prototype : {
- added : function added(engine) {
- this.testNodes = engine.getNodes(TestNode);
- console.log("System added callback: " + "EXEC OK");
- },
-
- removed : function removed(engine) {
- this.testNodes = null;
- console.log("System removed callback: " + "EXEC OK");
- },
-
- update : function update(dt) {
- this.testNodes.forEach(function (node) {
- console.log("Running Mid Priority Node: " + (node.test.testMessage === "test" ? "SYSTEM OK" : "FAIL"));
- });
- console.log("System update callback: " + "EXEC OK");
- }
- }
- });
- var midProTestSystem = new MidProTestSystem();
- console.log("MidProTestSystem: " + "CREATE OK")
-
-
- Class("TestComponent").inherits(Serpentity.Component)({
- prototype : {
- testMessage : "test"
- }
- });
- console.log("TestComponent: " + "CREATE OK")
-
- Class("TestNode").inherits(Serpentity.Node)({
- types : {
- test : TestComponent
- }
- });
- console.log("TestNode: " + "CREATE OK")
-
-
- console.log("\n## Adding system to the engine")
-
- var engine = new Serpentity();
- console.log("engine: " + "CREATE OK")
-
- engine.addSystem(testSystem, 0);
-
- console.log("\n## Running update without any entities")
- engine.update(10);
-
- console.log("\n## Adding system to the engine and updating")
- var entity = new Serpentity.Entity();
- entity.addComponent(new TestComponent());
- engine.addEntity(entity);
- engine.update(10);
-
- console.log("\n## Adding Low Priority System")
- engine.addSystem(lowProTestSystem, 10);
- engine.update(10);
-
- console.log("\n## Adding Mid Priority System")
- engine.addSystem(midProTestSystem, 5);
- engine.update(10);
-
- console.log("\n## Removing the system and readding")
- engine.removeSystem(testSystem);
- engine.update(10);
- engine.addSystem(testSystem, 0);
- engine.update(10);
-
- console.log("\n## Adding a second entity")
- var entity = new Serpentity.Entity();
- entity.addComponent(new TestComponent());
- engine.addEntity(entity);
- engine.update(10);
-
- console.log("\n## Removing entity")
- engine.removeEntity(entity)
- engine.update(10);
-
- console.log("\n## Removing system")
- engine.removeSystem(testSystem)
- engine.update(10);
- </script>
- </head>
- <body>
- <h1>404 Droids Not Found</h1>
- Look in your console...
- </body>
-</html>
-if (typeof require !== "undefined") {
- require("neon");
-}
+'use strict';
/*
Serpentity is a simple entity framework inspired by Ash.
Usage:
- require('serpentity');
+ let Serpentity = require('serpentity');
## Instantiating an engine
- var engine = Serpentity();
+ let engine = Serpentity();
Add entities or systems, systems are added with a priority (the smaller
the number, the earlier it will be called):
Entities are the basic object of Serpentity, and they do nothing.
- var entity = new Serpentity.Entity();
+ let entity = new Serpentity.Entity();
All the behavior is added through components
Components define data that we can add to an entity. This data will
eventually be consumed by "Systems"
- Class("PositionComponent").inherits(Serpentity.Component)({
- prototype : {
- x : 0,
- y : 0
- }
- });
+ let PositionComponent = class PositionComponent extends Serpentity.Component {
+ constructor (config) {
+ this.x = 0;
+ this.y = 0;
+
+ super(config);
+ }
+ };
You can add components to entities by using the add method:
Nodes are sets of components that you define, so your system can require
entities that always follow the API defined in the node.
- Class("MovementNode").inherits(Serpentity.Node)({
- types : {
- position : PositionComponent,
- motion : MotionComponent
- }
- });
+ let MovementNode = class MovementNode extends Serpentity.Node;
+ MovementNode.position = PositionComponent;
+ MovementNode.motion = MotionComponent;
You can then request an array of all the nodes representing entities
that comply with that API
Systems are called on every update, and they use components through nodes.
- Class("TestSystem").inherits(Serpentity.System)({
- prototype : {
- added : function added(engine){
- this.nodeList = engine.getNodes(MovementNode);
- },
- removed : function removed(engine){
- this.nodeList = undefined;
- }
- update : function update(dt){
- this.nodeList.forEach(function (node) {
- console.log("Current position is: " + node.position.x + "," + node.position.y);
- });
- }
+ let TestSystem = class TestSystem extends Serpentity.System {
+ added (engine){
+ this.nodeList = engine.getNodes(MovementNode);
+ },
+ removed (engine){
+ this.nodeList = undefined;
+ }
+ update (dt){
+ let node;
+ for (node of this.nodeList) {
+ console.log(`Current position is: ${node.position.x},${node.position.y}`);
}
- });
+ }
+ };
## That's it
Just run `engine.update(dt)` in your game loop :D
*/
-Class("Serpentity")({
- prototype : {
- systems : null,
- entities : null,
- _nodeCollections : null,
- _nodeCollectionKeys : null,
-
- init : function init(config) {
- var property;
-
- config = config || {};
-
- this.systems = [];
- this.entities = [];
- this._nodeCollections = [];
- this._nodeCollectionKeys = [];
-
- for (property in config) {
- if (config.hasOwnProperty(property)) {
- this[property] = config[property];
- }
- }
- },
-
- /*
- * Adds a system to the engine, so its update method will be called
- * with the others. Triggers added hook.
- *
- * returns true if added succesfully, false if already added
- */
- addSystem : function addSystem(system, priority) {
- var lastIndex, found;
-
- if (this.systems.indexOf(system) >= 0) {
- return false;
- }
-
- system.priority = priority;
-
- found = false;
- lastIndex = 0;
-
- this.systems.some(function findPriority(existingSystem, i) {
- lastIndex = i;
- if (existingSystem.priority >= system.priority) {
- found = true;
- return true;
- }
- });
-
- if (!found) {
- lastIndex += 1
- }
-
- this.systems.splice(lastIndex, 0, system);
- system.added(this);
- return true;
- },
-
- /*
- * Removes a system from the engine, so its update method will no
- * longer will be called. Triggers the removed hook.
- *
- * returns true if removed succesfully, false if already added
- */
- removeSystem : function removeSystem(system) {
- var position;
-
- position = this.systems.indexOf(system);
- if (position >= 0) {
- this.systems[position].removed(this);
- this.systems.splice(position, 1);
- return true;
- }
- return false;
- },
-
- /*
- * Adds an entity to the engine, adds to existing node collections
- *
- * returns true if added, false if already there
- */
- addEntity : function addEntity(entity) {
- if (this.entities.indexOf(entity) >= 0) {
- return false;
- }
- this.entities.push(entity);
-
- this._nodeCollections.forEach(function (collection) {
- collection.add(entity);
- });
-
- return true;
- },
-
- /*
- * Removes entity from system, removing from all node collections
- *
- * returns true if removed, false if not present
- */
- removeEntity : function removeEntity(entity) {
- var position;
-
- position = this.entities.indexOf(entity);
- if (position >= 0) {
- this._nodeCollections.forEach(function (collection) {
- collection.remove(entity);
- });
-
- this.entities.splice(position, 1);
- return true;
- }
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
- return false;
- },
-
- /*
- * Given a Node Class, retrieves a list of all the nodes for each
- * applicable entity.
- */
- getNodes : function getNodes(nodeType) {
- var position, nodeCollection;
-
- position = this._nodeCollectionKeys.indexOf(nodeType);
-
- if (position >= 0) {
- return this._nodeCollections[position].nodes;
- }
-
- nodeCollection = new Serpentity.NodeCollection({
- type : nodeType,
- });
-
- this._nodeCollectionKeys.push(nodeType);
- this._nodeCollections.push(nodeCollection);
-
- this.entities.forEach(function (entity) {
- nodeCollection.add(entity);
- });
-
- return nodeCollection.nodes;
- },
-
- /*
- * Calls update for every loaded system.
- */
- update : function update(dt) {
- this.systems.forEach(function (system) {
- system.update(dt);
- });
- }
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Serpentity = function () {
+ function Serpentity(config) {
+ _classCallCheck(this, Serpentity);
+
+ this.systems = [];
+ this.entities = [];
+ this._nodeCollections = [];
+ this._nodeCollectionKeys = [];
+
+ Object.assign(this, config || {});
+ }
+
+ /*
+ * Adds a system to the engine, so its update method will be called
+ * with the others. Triggers added hook.
+ *
+ * returns true if added succesfully, false if already added
+ */
+
+
+ _createClass(Serpentity, [{
+ key: 'addSystem',
+ value: function addSystem(system, priority) {
+ var lastIndex = void 0,
+ found = void 0;
+
+ if (this.systems.indexOf(system) >= 0) {
+ return false;
+ }
+
+ system.priority = priority;
+
+ found = false;
+ lastIndex = 0;
+
+ this.systems.some(function findPriority(existingSystem, i) {
+ lastIndex = i;
+ if (existingSystem.priority >= system.priority) {
+ found = true;
+ return true;
+ }
+ });
+
+ if (!found) {
+ lastIndex += 1;
+ }
+
+ this.systems.splice(lastIndex, 0, system);
+ system.added(this);
+ return true;
+ }
+
+ /*
+ * Removes a system from the engine, so its update method will no
+ * longer will be called. Triggers the removed hook.
+ *
+ * returns true if removed succesfully, false if already added
+ */
+
+ }, {
+ key: 'removeSystem',
+ value: function removeSystem(system) {
+ var position = void 0;
+
+ position = this.systems.indexOf(system);
+ if (position >= 0) {
+ this.systems[position].removed(this);
+ this.systems.splice(position, 1);
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Adds an entity to the engine, adds to existing node collections
+ *
+ * returns true if added, false if already there
+ */
+
+ }, {
+ key: 'addEntity',
+ value: function addEntity(entity) {
+ if (this.entities.indexOf(entity) >= 0) {
+ return false;
+ }
+ this.entities.push(entity);
+
+ this._nodeCollections.forEach(function (collection) {
+ collection.add(entity);
+ });
+
+ return true;
+ }
+
+ /*
+ * Removes entity from system, removing from all node collections
+ *
+ * returns true if removed, false if not present
+ */
+
+ }, {
+ key: 'removeEntity',
+ value: function removeEntity(entity) {
+ var position = void 0;
+
+ position = this.entities.indexOf(entity);
+ if (position >= 0) {
+ this._nodeCollections.forEach(function (collection) {
+ collection.remove(entity);
+ });
+
+ this.entities.splice(position, 1);
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Given a Node Class, retrieves a list of all the nodes for each
+ * applicable entity.
+ */
+
+ }, {
+ key: 'getNodes',
+ value: function getNodes(nodeType) {
+ var position = void 0,
+ nodeCollection = void 0;
+
+ position = this._nodeCollectionKeys.indexOf(nodeType);
+
+ if (position >= 0) {
+ return this._nodeCollections[position].nodes;
+ }
+
+ nodeCollection = new Serpentity.NodeCollection({
+ type: nodeType
+ });
+
+ this._nodeCollectionKeys.push(nodeType);
+ this._nodeCollections.push(nodeCollection);
+
+ this.entities.forEach(function (entity) {
+ nodeCollection.add(entity);
+ });
+
+ return nodeCollection.nodes;
+ }
+
+ /*
+ * Calls update for every loaded system.
+ */
+
+ }, {
+ key: 'update',
+ value: function update(dt) {
+ this.systems.forEach(function (system) {
+ system.update(dt);
+ });
}
-});
-
-if (typeof require !== "undefined") {
- require("./component.js");
- require("./entity.js");
- require("./node.js");
- require("./node_collection.js");
- require("./system.js");
+ }]);
+
+ return Serpentity;
+}();
+
+// Add namespaced objects.
+if (typeof module !== 'undefined' && undefined.module !== module) {
+ Serpentity.Component = require('./serpentity/component.js');
+ Serpentity.Entity = require('./serpentity/entity.js');
+ Serpentity.Node = require('./serpentity/node.js');
+ Serpentity.NodeCollection = require('./serpentity/node_collection.js');
+ Serpentity.System = require('./serpentity/system.js');
+
+ module.exports = Serpentity;
}
+'use strict';
+
+/* global Serpentity */
/*
* The entity gives the entity framework its name. It exists only
* to hold components.
*/
-Class(Serpentity, "Entity")({
- prototype : {
- _components : null,
- _componentKeys : null,
-
- init : function init(config) {
- var property;
-
- this._componentKeys = [];
- this._components = [];
-
- for (property in config) {
- if (config.hasOwnProperty(property)) {
- this[property] = config[property];
- }
- }
- },
-
- /*
- * Adds a component to the entity.
- *
- * returns true if added, false if already present
- */
- addComponent : function addComponent(component) {
- if (this._componentKeys.indexOf(component.constructor) >= 0) {
- return false;
- }
- this._componentKeys.push(component.constructor);
- this._components.push(component);
- return true;
- },
-
- /*
- * returns true if component is included, false otherwise
- */
- hasComponent : function hasComponent(componentClass) {
- if (this._componentKeys.indexOf(componentClass) >= 0) {
- return true;
- }
- return false;
- },
-
- /*
- * returns the component associated with that key
- */
- getComponent : function getComponent(componentClass) {
- var position;
- position = this._componentKeys.indexOf(componentClass);
- if (position >= 0) {
- return this._components[position];
- }
- }
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Entity = function () {
+ function Entity(config) {
+ _classCallCheck(this, Entity);
+
+ this._componentKeys = [];
+ this._components = [];
+
+ Object.assign(this, config || {});
+ }
+
+ /*
+ * Adds a component to the entity.
+ *
+ * returns true if added, false if already present
+ */
+
+
+ _createClass(Entity, [{
+ key: 'addComponent',
+ value: function addComponent(component) {
+ if (this._componentKeys.indexOf(component.constructor) >= 0) {
+ return false;
+ }
+ this._componentKeys.push(component.constructor);
+ this._components.push(component);
+ return true;
}
-});
+
+ /*
+ * returns true if component is included, false otherwise
+ */
+
+ }, {
+ key: 'hasComponent',
+ value: function hasComponent(componentClass) {
+ if (this._componentKeys.indexOf(componentClass) >= 0) {
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * returns the component associated with that key
+ */
+
+ }, {
+ key: 'getComponent',
+ value: function getComponent(componentClass) {
+ var position = this._componentKeys.indexOf(componentClass);
+ if (position >= 0) {
+ return this._components[position];
+ }
+ }
+ }]);
+
+ return Entity;
+}();
+
+if (typeof module !== 'undefined' && undefined.module !== module) {
+ module.exports = Entity;
+} else {
+ Serpentity.Entity = Entity;
+}
+'use strict';
+
+/* global Serpentity */
/*
* A node describes a set of components in order to describe entities
* that include them.
*/
-Class(Serpentity, "Node")({
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Node = function () {
+ _createClass(Node, null, [{
+ key: 'matches',
+
/*
* Returns true if the given entity matches the defined protocol,
* false otherwise
*/
- matches : function matches(entity) {
- var property, matched, types;
+ value: function matches(entity) {
+ var types = this.types;
- types = this.types;
+ for (var typeName in types) {
+ if (types.hasOwnProperty(typeName)) {
- for (property in this.types) {
+ var matched = false;
+ var type = types[typeName];
- if (this.types.hasOwnProperty(property)) {
- matched = false;
+ if (entity.hasComponent(type)) {
+ matched = true;
+ }
- if (entity.hasComponent(types[property])) {
- matched = true;
- }
+ if (!matched) {
+ return false;
+ }
+ }
+ }
- if (!matched) {
- return false;
- }
- }
- }
+ return true;
+ }
+ }]);
- return true;
- },
+ function Node(config) {
+ _classCallCheck(this, Node);
- prototype : {
+ this.types = {};
- types : null,
+ Object.assign(this, config || {});
+ }
- init : function (config) {
- var property;
+ return Node;
+}();
- this.types = {};
+if (typeof module !== 'undefined' && undefined.module !== module) {
+ module.exports = Node;
+} else {
+ Serpentity.Node = Node;
+}
+'use strict';
- for (property in this.constructor) {
- if (this.constructor.hasOwnProperty(property)) {
- this.types[property] = this.constructor[property];
- }
- }
- }
- }
-});
+/* global Serpentity */
/*
* Node Collections contain nodes, in order to keep the lists of nodes
* It has a type which is the class name of the node, and an array of
* instances of that class.
*/
-Class(Serpentity, "NodeCollection")({
- prototype : {
- type : null,
- nodes : null,
- init : function init(config) {
- var property;
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
- config = config || {};
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
- this.nodes = [];
+var NodeCollection = function () {
+ function NodeCollection(config) {
+ _classCallCheck(this, NodeCollection);
- for (property in config) {
- if (config.hasOwnProperty(property)) {
- this[property] = config[property];
- }
- }
- },
+ this.nodes = [];
+ this.type = null;
- /*
- * Creates a node for an entity if it matches, and adds it to the
- * node list.
- *
- * Returns true if added, false otherwise.
- */
- add : function add(entity) {
- var node, types, property;
+ Object.assign(this, config || {});
+ }
- if (this.type.matches(entity) && !this._entityExists(entity)) {
- node = new this.type({});
+ /*
+ * Creates a node for an entity if it matches, and adds it to the
+ * node list.
+ *
+ * Returns true if added, false otherwise.
+ */
- node.entity = entity;
- types = this.type.types;
+ _createClass(NodeCollection, [{
+ key: 'add',
+ value: function add(entity) {
- for (property in types) {
- if (types.hasOwnProperty(property)) {
- node[property] = entity.getComponent(types[property]);
- }
- }
+ if (this.type.matches(entity) && !this._entityExists(entity)) {
- this.nodes.push(node);
+ var node = new this.type({});
+ var types = this.type.types;
- return true;
- }
+ node.entity = entity;
- return false;
- },
-
- /*
- * Removes an entity by removing its related node from the list of nodes
- *
- * returns true if it was removed, false otherwise.
- */
- remove : function (entity) {
- var found;
- found = -1;
- this.nodes.forEach(function (node, i) {
- if (node.entity === entity) {
- found = i;
- }
- });
-
- if (found >= 0) {
- this.nodes.splice(found, 1);
- return true;
- }
+ for (var typeName in types) {
+ if (types.hasOwnProperty(typeName)) {
+ node[typeName] = entity.getComponent(types[typeName]);
+ }
+ }
- return false;
- },
-
- /*
- * Checks whether we already have nodes for this entity.
- */
- _entityExists : function entityExists(entity) {
- var found;
- found = false;
- this.nodes.forEach(function (node) {
- if (node.entity === entity) {
- found = true;
- }
- });
-
- return found;
+ this.nodes.push(node);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Removes an entity by removing its related node from the list of nodes
+ *
+ * returns true if it was removed, false otherwise.
+ */
+
+ }, {
+ key: 'remove',
+ value: function remove(entity) {
+ var found = -1;
+
+ this.nodes.forEach(function (node, i) {
+ if (node.entity === entity) {
+ found = i;
}
+ });
+
+ if (found >= 0) {
+ this.nodes.splice(found, 1);
+ return true;
+ }
+
+ return false;
}
-});
+
+ /*
+ * Checks whether we already have nodes for this entity.
+ */
+
+ }, {
+ key: '_entityExists',
+ value: function _entityExists(entity) {
+ var found = false;
+
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = this.nodes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var node = _step.value;
+
+ if (node.entity === entity) {
+ found = true;
+ }
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator.return) {
+ _iterator.return();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+
+ return found;
+ }
+ }]);
+
+ return NodeCollection;
+}();
+
+if (typeof module !== 'undefined' && undefined.module !== module) {
+ module.exports = NodeCollection;
+} else {
+ Serpentity.NodeCollection = NodeCollection;
+}
+'use strict';
+
+/* global Serpentity */
/*
* Components store data. Nothing to say here really, just
* It's just an empty class, so what I'm trying to say is your
* components can be any class whatsoever.
*/
-Class(Serpentity, "Component")({
- prototype : {
- init : function init(config) {
- var property;
-
- config = config || {};
-
- for (property in config) {
- if (config.hasOwnProperty(property)) {
- this[property] = config[property];
- }
- }
- }
- }
-});
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Component = function Component(config) {
+ _classCallCheck(this, Component);
+
+ Object.assign(this, config || {});
+};
+
+if (typeof module !== 'undefined' && undefined.module !== module) {
+ module.exports = Component;
+} else {
+ Serpentity.Component = Component;
+}
+'use strict';
+
+/* global Serpentity */
/*
* Systems contain most of the logic, and work with nodes in order to
* act and change their values.
*
* You usually want to inherit from this class and override the
- * three methods.
+ * three methods. They are shown here to document the interface.
*/
-Class(Serpentity, "System")({
- prototype : {
-
- /*
- * This will be run when the system is added to the engine
- */
- added : function added(engine) {
- // Override
- },
-
- /*
- * This will be run when the system is removed from the engine
- */
- removed : function removed(engine) {
- // Override
- },
-
- /*
- * This will run every time the engine's update method is called
- */
- update : function update(dt) {
- // Override
- }
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var System = function () {
+ function System() {
+ _classCallCheck(this, System);
+ }
+
+ _createClass(System, [{
+ key: 'added',
+
+
+ /*
+ * This will be run when the system is added to the engine
+ */
+ value: function added() {}
+ // Override with added(engine)
+ // Receives an instance of the serpentity engine
+
+
+ /*
+ * This will be run when the system is removed from the engine
+ */
+
+ }, {
+ key: 'removed',
+ value: function removed() {}
+ // Override with removed(engine)
+ // Receives an instance of the serpentity engine
+
+
+ /*
+ * This will run every time the engine's update method is called
+ */
+
+ }, {
+ key: 'update',
+ value: function update() {
+ // Override with update(dt)
+ // Receives a delta of the time
}
-});
+ }]);
+
+ return System;
+}();
+
+if (typeof module !== 'undefined' && undefined.module !== module) {
+ module.exports = System;
+} else {
+ Serpentity.System = System;
+}
\ No newline at end of file
-"undefined"!=typeof require&&require("neon"),Class("Serpentity")({prototype:{systems:null,entities:null,_nodeCollections:null,_nodeCollectionKeys:null,init:function(e){var t;e=e||{},this.systems=[],this.entities=[],this._nodeCollections=[],this._nodeCollectionKeys=[];for(t in e)e.hasOwnProperty(t)&&(this[t]=e[t])},addSystem:function(e,t){var i,s;return this.systems.indexOf(e)>=0?!1:(e.priority=t,s=!1,i=0,this.systems.some(function(t,n){return i=n,t.priority>=e.priority?(s=!0,!0):void 0}),s||(i+=1),this.systems.splice(i,0,e),e.added(this),!0)},removeSystem:function(e){var t;return t=this.systems.indexOf(e),t>=0?(this.systems[t].removed(this),this.systems.splice(t,1),!0):!1},addEntity:function(e){return this.entities.indexOf(e)>=0?!1:(this.entities.push(e),this._nodeCollections.forEach(function(t){t.add(e)}),!0)},removeEntity:function(e){var t;return t=this.entities.indexOf(e),t>=0?(this._nodeCollections.forEach(function(t){t.remove(e)}),this.entities.splice(t,1),!0):!1},getNodes:function(e){var t,i;return t=this._nodeCollectionKeys.indexOf(e),t>=0?this._nodeCollections[t].nodes:(i=new Serpentity.NodeCollection({type:e}),this._nodeCollectionKeys.push(e),this._nodeCollections.push(i),this.entities.forEach(function(e){i.add(e)}),i.nodes)},update:function(e){this.systems.forEach(function(t){t.update(e)})}}}),"undefined"!=typeof require&&(require("./component.js"),require("./entity.js"),require("./node.js"),require("./node_collection.js"),require("./system.js"));
-Class(Serpentity,"Entity")({prototype:{_components:null,_componentKeys:null,init:function(n){var t;this._componentKeys=[],this._components=[];for(t in n)n.hasOwnProperty(t)&&(this[t]=n[t])},addComponent:function(n){return this._componentKeys.indexOf(n.constructor)>=0?!1:(this._componentKeys.push(n.constructor),this._components.push(n),!0)},hasComponent:function(n){return this._componentKeys.indexOf(n)>=0?!0:!1},getComponent:function(n){var t;return t=this._componentKeys.indexOf(n),t>=0?this._components[t]:void 0}}});
-Class(Serpentity,"Node")({matches:function(t){var s,r,n;n=this.types;for(s in this.types)if(this.types.hasOwnProperty(s)&&(r=!1,t.hasComponent(n[s])&&(r=!0),!r))return!1;return!0},prototype:{types:null,init:function(){var t;this.types={};for(t in this.constructor)this.constructor.hasOwnProperty(t)&&(this.types[t]=this.constructor[t])}}});
-Class(Serpentity,"NodeCollection")({prototype:{type:null,nodes:null,init:function(t){var n;t=t||{},this.nodes=[];for(n in t)t.hasOwnProperty(n)&&(this[n]=t[n])},add:function(t){var n,e,i;if(this.type.matches(t)&&!this._entityExists(t)){n=new this.type({}),n.entity=t,e=this.type.types;for(i in e)e.hasOwnProperty(i)&&(n[i]=t.getComponent(e[i]));return this.nodes.push(n),!0}return!1},remove:function(t){var n;return n=-1,this.nodes.forEach(function(e,i){e.entity===t&&(n=i)}),n>=0?(this.nodes.splice(n,1),!0):!1},_entityExists:function(t){var n;return n=!1,this.nodes.forEach(function(e){e.entity===t&&(n=!0)}),n}}});
-Class(Serpentity,"Component")({prototype:{init:function(t){var n;t=t||{};for(n in t)t.hasOwnProperty(n)&&(this[n]=t[n])}}});
-Class(Serpentity,"System")({prototype:{added:function(){},removed:function(){},update:function(){}}});
\ No newline at end of file
+"use strict";function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var _createClass=function(){function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n&&e(t.prototype,n),o&&e(t,o),t}}(),Serpentity=function(){function e(t){_classCallCheck(this,e),this.systems=[],this.entities=[],this._nodeCollections=[],this._nodeCollectionKeys=[],Object.assign(this,t||{})}return _createClass(e,[{key:"addSystem",value:function(e,t){var n=void 0,o=void 0;return this.systems.indexOf(e)>=0?!1:(e.priority=t,o=!1,n=0,this.systems.some(function(t,i){return n=i,t.priority>=e.priority?(o=!0,!0):void 0}),o||(n+=1),this.systems.splice(n,0,e),e.added(this),!0)}},{key:"removeSystem",value:function(e){var t=void 0;return t=this.systems.indexOf(e),t>=0?(this.systems[t].removed(this),this.systems.splice(t,1),!0):!1}},{key:"addEntity",value:function(e){return this.entities.indexOf(e)>=0?!1:(this.entities.push(e),this._nodeCollections.forEach(function(t){t.add(e)}),!0)}},{key:"removeEntity",value:function(e){var t=void 0;return t=this.entities.indexOf(e),t>=0?(this._nodeCollections.forEach(function(t){t.remove(e)}),this.entities.splice(t,1),!0):!1}},{key:"getNodes",value:function(t){var n=void 0,o=void 0;return n=this._nodeCollectionKeys.indexOf(t),n>=0?this._nodeCollections[n].nodes:(o=new e.NodeCollection({type:t}),this._nodeCollectionKeys.push(t),this._nodeCollections.push(o),this.entities.forEach(function(e){o.add(e)}),o.nodes)}},{key:"update",value:function(e){this.systems.forEach(function(t){t.update(e)})}}]),e}();"undefined"!=typeof module&&(void 0).module!==module&&(Serpentity.Component=require("./serpentity/component.js"),Serpentity.Entity=require("./serpentity/entity.js"),Serpentity.Node=require("./serpentity/node.js"),Serpentity.NodeCollection=require("./serpentity/node_collection.js"),Serpentity.System=require("./serpentity/system.js"),module.exports=Serpentity);var _createClass=function(){function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n&&e(t.prototype,n),o&&e(t,o),t}}(),Entity=function(){function e(t){_classCallCheck(this,e),this._componentKeys=[],this._components=[],Object.assign(this,t||{})}return _createClass(e,[{key:"addComponent",value:function(e){return this._componentKeys.indexOf(e.constructor)>=0?!1:(this._componentKeys.push(e.constructor),this._components.push(e),!0)}},{key:"hasComponent",value:function(e){return!!(this._componentKeys.indexOf(e)>=0)}},{key:"getComponent",value:function(e){var t=this._componentKeys.indexOf(e);return t>=0?this._components[t]:void 0}}]),e}();"undefined"!=typeof module&&(void 0).module!==module?module.exports=Entity:Serpentity.Entity=Entity;var _createClass=function(){function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n&&e(t.prototype,n),o&&e(t,o),t}}(),Node=function(){function e(t){_classCallCheck(this,e),this.types={},Object.assign(this,t||{})}return _createClass(e,null,[{key:"matches",value:function(e){var t=this.types;for(var n in t)if(t.hasOwnProperty(n)){var o=!1,i=t[n];if(e.hasComponent(i)&&(o=!0),!o)return!1}return!0}}]),e}();"undefined"!=typeof module&&(void 0).module!==module?module.exports=Node:Serpentity.Node=Node;var _createClass=function(){function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n&&e(t.prototype,n),o&&e(t,o),t}}(),NodeCollection=function(){function e(t){_classCallCheck(this,e),this.nodes=[],this.type=null,Object.assign(this,t||{})}return _createClass(e,[{key:"add",value:function(e){if(this.type.matches(e)&&!this._entityExists(e)){var t=new this.type({}),n=this.type.types;t.entity=e;for(var o in n)n.hasOwnProperty(o)&&(t[o]=e.getComponent(n[o]));return this.nodes.push(t),!0}return!1}},{key:"remove",value:function(e){var t=-1;return this.nodes.forEach(function(n,o){n.entity===e&&(t=o)}),t>=0?(this.nodes.splice(t,1),!0):!1}},{key:"_entityExists",value:function(e){var t=!1,n=!0,o=!1,i=void 0;try{for(var s,r=this.nodes[Symbol.iterator]();!(n=(s=r.next()).done);n=!0){var a=s.value;a.entity===e&&(t=!0)}}catch(l){o=!0,i=l}finally{try{!n&&r["return"]&&r["return"]()}finally{if(o)throw i}}return t}}]),e}();"undefined"!=typeof module&&(void 0).module!==module?module.exports=NodeCollection:Serpentity.NodeCollection=NodeCollection;var Component=function e(t){_classCallCheck(this,e),Object.assign(this,t||{})};"undefined"!=typeof module&&(void 0).module!==module?module.exports=Component:Serpentity.Component=Component;var _createClass=function(){function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n&&e(t.prototype,n),o&&e(t,o),t}}(),System=function(){function e(){_classCallCheck(this,e)}return _createClass(e,[{key:"added",value:function(){}},{key:"removed",value:function(){}},{key:"update",value:function(){}}]),e}();"undefined"!=typeof module&&(void 0).module!==module?module.exports=System:Serpentity.System=System;
\ No newline at end of file
-var gulp = require('gulp');
-var uglify = require('gulp-uglify');
-var concat = require('gulp-concat');
+'use strict';
-gulp.task('build', function() {
- gulp.src([
- 'lib/serpentity/serpentity.js',
- 'lib/serpentity/entity.js',
- 'lib/serpentity/node.js',
- 'lib/serpentity/node_collection.js',
- 'lib/serpentity/component.js',
- 'lib/serpentity/system.js',
- ])
- .pipe(uglify())
- .pipe(concat('serpentity.min.js'))
- .pipe(gulp.dest('dist'))
+const Gulp = require('gulp');
+const Babel = require('gulp-babel');
+const Concat = require('gulp-concat');
+const Rename = require('gulp-rename');
+const Uglify = require('gulp-uglify');
- gulp.src([
- 'lib/serpentity/serpentity.js',
- 'lib/serpentity/entity.js',
- 'lib/serpentity/node.js',
- 'lib/serpentity/node_collection.js',
- 'lib/serpentity/component.js',
- 'lib/serpentity/system.js',
- ])
- .pipe(concat('serpentity.js'))
- .pipe(gulp.dest('dist'))
+Gulp.task('build', function() {
+ Gulp.src([
+ 'lib/serpentity.js',
+ 'lib/serpentity/entity.js',
+ 'lib/serpentity/node.js',
+ 'lib/serpentity/node_collection.js',
+ 'lib/serpentity/component.js',
+ 'lib/serpentity/system.js'
+ ])
+ .pipe(Babel({
+ presets: ['es2015']
+ }))
+ .pipe(Concat('serpentity.js'))
+ .pipe(Gulp.dest('dist'))
+ .pipe(Uglify())
+ .pipe(Rename({
+ suffix: '.min'
+ }))
+ .pipe(Gulp.dest('dist'));
});
--- /dev/null
+'use strict';
+
+/*
+Serpentity is a simple entity framework inspired by Ash.
+
+Usage:
+
+ let Serpentity = require('serpentity');
+
+## Instantiating an engine
+
+ let engine = Serpentity();
+
+Add entities or systems, systems are added with a priority (the smaller
+the number, the earlier it will be called):
+
+ engine.addEntity(entityFactory());
+ engine.addSystem(new GameSystem(), priority);
+
+Update all systems:
+
+ engine.update(dt);
+
+Remove entities or systems:
+
+ engine.removeEntity(entityReference);
+ engine.removeSystem(systemReference);
+
+## Creating Entities
+
+Entities are the basic object of Serpentity, and they do nothing.
+
+ let entity = new Serpentity.Entity();
+
+All the behavior is added through components
+
+## Creating Components
+
+Components define data that we can add to an entity. This data will
+eventually be consumed by "Systems"
+
+ let PositionComponent = class PositionComponent extends Serpentity.Component {
+ constructor (config) {
+ this.x = 0;
+ this.y = 0;
+
+ super(config);
+ }
+ };
+
+You can add components to entities by using the add method:
+
+ entity.addComponent(new PositionComponent());
+
+
+Systems can refer to entities by requesting nodes.
+
+## Working with Nodes
+
+Nodes are sets of components that you define, so your system can require
+entities that always follow the API defined in the node.
+
+ let MovementNode = class MovementNode extends Serpentity.Node;
+ MovementNode.position = PositionComponent;
+ MovementNode.motion = MotionComponent;
+
+You can then request an array of all the nodes representing entities
+that comply with that API
+
+ engine.getNodes(MovementNode);
+
+## Creating Systems
+
+Systems are called on every update, and they use components through nodes.
+
+ let TestSystem = class TestSystem extends Serpentity.System {
+ added (engine){
+ this.nodeList = engine.getNodes(MovementNode);
+ },
+ removed (engine){
+ this.nodeList = undefined;
+ }
+ update (dt){
+ let node;
+ for (node of this.nodeList) {
+ console.log(`Current position is: ${node.position.x},${node.position.y}`);
+ }
+ }
+ };
+
+## That's it
+
+Just run `engine.update(dt)` in your game loop :D
+
+*/
+let Serpentity = class Serpentity {
+
+ constructor (config) {
+ this.systems = [];
+ this.entities = [];
+ this._nodeCollections = [];
+ this._nodeCollectionKeys = [];
+
+ Object.assign(this, config || {});
+ }
+
+ /*
+ * Adds a system to the engine, so its update method will be called
+ * with the others. Triggers added hook.
+ *
+ * returns true if added succesfully, false if already added
+ */
+ addSystem (system, priority) {
+ let lastIndex, found;
+
+ if (this.systems.indexOf(system) >= 0) {
+ return false;
+ }
+
+ system.priority = priority;
+
+ found = false;
+ lastIndex = 0;
+
+ this.systems.some(function findPriority(existingSystem, i) {
+ lastIndex = i;
+ if (existingSystem.priority >= system.priority) {
+ found = true;
+ return true;
+ }
+ });
+
+ if (!found) {
+ lastIndex += 1;
+ }
+
+ this.systems.splice(lastIndex, 0, system);
+ system.added(this);
+ return true;
+ }
+
+ /*
+ * Removes a system from the engine, so its update method will no
+ * longer will be called. Triggers the removed hook.
+ *
+ * returns true if removed succesfully, false if already added
+ */
+ removeSystem (system) {
+ let position;
+
+ position = this.systems.indexOf(system);
+ if (position >= 0) {
+ this.systems[position].removed(this);
+ this.systems.splice(position, 1);
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Adds an entity to the engine, adds to existing node collections
+ *
+ * returns true if added, false if already there
+ */
+ addEntity (entity) {
+ if (this.entities.indexOf(entity) >= 0) {
+ return false;
+ }
+ this.entities.push(entity);
+
+ this._nodeCollections.forEach(function (collection) {
+ collection.add(entity);
+ });
+
+ return true;
+ }
+
+ /*
+ * Removes entity from system, removing from all node collections
+ *
+ * returns true if removed, false if not present
+ */
+ removeEntity (entity) {
+ let position;
+
+ position = this.entities.indexOf(entity);
+ if (position >= 0) {
+ this._nodeCollections.forEach(function (collection) {
+ collection.remove(entity);
+ });
+
+ this.entities.splice(position, 1);
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Given a Node Class, retrieves a list of all the nodes for each
+ * applicable entity.
+ */
+ getNodes (nodeType) {
+ let position, nodeCollection;
+
+ position = this._nodeCollectionKeys.indexOf(nodeType);
+
+ if (position >= 0) {
+ return this._nodeCollections[position].nodes;
+ }
+
+ nodeCollection = new Serpentity.NodeCollection({
+ type : nodeType
+ });
+
+ this._nodeCollectionKeys.push(nodeType);
+ this._nodeCollections.push(nodeCollection);
+
+ this.entities.forEach(function (entity) {
+ nodeCollection.add(entity);
+ });
+
+ return nodeCollection.nodes;
+ }
+
+ /*
+ * Calls update for every loaded system.
+ */
+ update (dt) {
+ this.systems.forEach(function (system) {
+ system.update(dt);
+ });
+ }
+};
+
+// Add namespaced objects.
+if (typeof module !== 'undefined' && this.module !== module) {
+ Serpentity.Component = require('./serpentity/component.js');
+ Serpentity.Entity = require('./serpentity/entity.js');
+ Serpentity.Node = require('./serpentity/node.js');
+ Serpentity.NodeCollection = require('./serpentity/node_collection.js');
+ Serpentity.System = require('./serpentity/system.js');
+
+ module.exports = Serpentity;
+}
+'use strict';
+
+/* global Serpentity */
+
/*
* Components store data. Nothing to say here really, just
* inherit and add a prototype, or don't even inherit, see?
* It's just an empty class, so what I'm trying to say is your
* components can be any class whatsoever.
*/
-Class(Serpentity, "Component")({
- prototype : {
- init : function init(config) {
- var property;
- config = config || {};
+let Component = class Component {
+ constructor (config) {
+ Object.assign(this, config || {});
+ }
+};
- for (property in config) {
- if (config.hasOwnProperty(property)) {
- this[property] = config[property];
- }
- }
- }
- }
-});
+if (typeof module !== 'undefined' && this.module !== module) {
+ module.exports = Component;
+} else {
+ Serpentity.Component = Component;
+}
+'use strict';
+
+/* global Serpentity */
+
/*
* The entity gives the entity framework its name. It exists only
* to hold components.
*/
-Class(Serpentity, "Entity")({
- prototype : {
- _components : null,
- _componentKeys : null,
-
- init : function init(config) {
- var property;
-
- this._componentKeys = [];
- this._components = [];
-
- for (property in config) {
- if (config.hasOwnProperty(property)) {
- this[property] = config[property];
- }
- }
- },
-
- /*
- * Adds a component to the entity.
- *
- * returns true if added, false if already present
- */
- addComponent : function addComponent(component) {
- if (this._componentKeys.indexOf(component.constructor) >= 0) {
- return false;
- }
- this._componentKeys.push(component.constructor);
- this._components.push(component);
- return true;
- },
-
- /*
- * returns true if component is included, false otherwise
- */
- hasComponent : function hasComponent(componentClass) {
- if (this._componentKeys.indexOf(componentClass) >= 0) {
- return true;
- }
- return false;
- },
-
- /*
- * returns the component associated with that key
- */
- getComponent : function getComponent(componentClass) {
- var position;
- position = this._componentKeys.indexOf(componentClass);
- if (position >= 0) {
- return this._components[position];
- }
- }
+
+let Entity = class Entity {
+ constructor (config) {
+ this._componentKeys = [];
+ this._components = [];
+
+ Object.assign(this, config || {});
+ }
+
+ /*
+ * Adds a component to the entity.
+ *
+ * returns true if added, false if already present
+ */
+ addComponent (component) {
+ if (this._componentKeys.indexOf(component.constructor) >= 0) {
+ return false;
}
-});
+ this._componentKeys.push(component.constructor);
+ this._components.push(component);
+ return true;
+ }
+
+ /*
+ * returns true if component is included, false otherwise
+ */
+ hasComponent (componentClass) {
+ if (this._componentKeys.indexOf(componentClass) >= 0) {
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * returns the component associated with that key
+ */
+ getComponent (componentClass) {
+ let position = this._componentKeys.indexOf(componentClass);
+ if (position >= 0) {
+ return this._components[position];
+ }
+ }
+};
+
+if (typeof module !== 'undefined' && this.module !== module) {
+ module.exports = Entity;
+} else {
+ Serpentity.Entity = Entity;
+}
+'use strict';
+
+/* global Serpentity */
+
/*
* A node describes a set of components in order to describe entities
* that include them.
*/
-Class(Serpentity, "Node")({
-
- /*
- * Returns true if the given entity matches the defined protocol,
- * false otherwise
- */
- matches : function matches(entity) {
- var property, matched, types;
-
- types = this.types;
-
- for (property in this.types) {
+let Node = class Node {
- if (this.types.hasOwnProperty(property)) {
- matched = false;
+ /*
+ * Returns true if the given entity matches the defined protocol,
+ * false otherwise
+ */
+ static matches (entity) {
+ let types = this.types;
- if (entity.hasComponent(types[property])) {
- matched = true;
- }
+ for (let typeName in types) {
+ if (types.hasOwnProperty(typeName)) {
- if (!matched) {
- return false;
- }
- }
- }
+ let matched = false;
+ let type = types[typeName];
- return true;
- },
+ if (entity.hasComponent(type)) {
+ matched = true;
+ }
- prototype : {
+ if (!matched) {
+ return false;
+ }
+ }
+ }
- types : null,
+ return true;
+ }
- init : function (config) {
- var property;
+ constructor (config) {
+ this.types = {};
- this.types = {};
+ Object.assign(this, config || {});
+ }
+};
- for (property in this.constructor) {
- if (this.constructor.hasOwnProperty(property)) {
- this.types[property] = this.constructor[property];
- }
- }
- }
- }
-});
+if (typeof module !== 'undefined' && this.module !== module) {
+ module.exports = Node;
+} else {
+ Serpentity.Node = Node;
+}
+'use strict';
+
+/* global Serpentity */
+
/*
* Node Collections contain nodes, in order to keep the lists of nodes
* that belong to each type.
* It has a type which is the class name of the node, and an array of
* instances of that class.
*/
-Class(Serpentity, "NodeCollection")({
- prototype : {
- type : null,
- nodes : null,
-
- init : function init(config) {
- var property;
-
- config = config || {};
-
- this.nodes = [];
-
- for (property in config) {
- if (config.hasOwnProperty(property)) {
- this[property] = config[property];
- }
- }
- },
-
- /*
- * Creates a node for an entity if it matches, and adds it to the
- * node list.
- *
- * Returns true if added, false otherwise.
- */
- add : function add(entity) {
- var node, types, property;
-
- if (this.type.matches(entity) && !this._entityExists(entity)) {
- node = new this.type({});
-
- node.entity = entity;
-
- types = this.type.types;
-
- for (property in types) {
- if (types.hasOwnProperty(property)) {
- node[property] = entity.getComponent(types[property]);
- }
- }
-
- this.nodes.push(node);
-
- return true;
- }
-
- return false;
- },
-
- /*
- * Removes an entity by removing its related node from the list of nodes
- *
- * returns true if it was removed, false otherwise.
- */
- remove : function (entity) {
- var found;
- found = -1;
- this.nodes.forEach(function (node, i) {
- if (node.entity === entity) {
- found = i;
- }
- });
-
- if (found >= 0) {
- this.nodes.splice(found, 1);
- return true;
- }
-
- return false;
- },
-
- /*
- * Checks whether we already have nodes for this entity.
- */
- _entityExists : function entityExists(entity) {
- var found;
- found = false;
- this.nodes.forEach(function (node) {
- if (node.entity === entity) {
- found = true;
- }
- });
-
- return found;
+
+let NodeCollection = class NodeCollection {
+
+ constructor (config) {
+ this.nodes = [];
+ this.type = null;
+
+ Object.assign(this, config || {});
+ }
+
+ /*
+ * Creates a node for an entity if it matches, and adds it to the
+ * node list.
+ *
+ * Returns true if added, false otherwise.
+ */
+ add (entity) {
+
+ if (this.type.matches(entity) && !this._entityExists(entity)) {
+
+ let node = new this.type({});
+ let types = this.type.types;
+
+ node.entity = entity;
+
+ for (let typeName in types) {
+ if (types.hasOwnProperty(typeName)) {
+ node[typeName] = entity.getComponent(types[typeName]);
}
+ }
+
+ this.nodes.push(node);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Removes an entity by removing its related node from the list of nodes
+ *
+ * returns true if it was removed, false otherwise.
+ */
+ remove (entity) {
+ let found = -1;
+
+ this.nodes.forEach(function (node, i) {
+ if (node.entity === entity) {
+ found = i;
+ }
+ });
+
+ if (found >= 0) {
+ this.nodes.splice(found, 1);
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Checks whether we already have nodes for this entity.
+ */
+ _entityExists (entity) {
+ let found = false;
+
+ for (let node of this.nodes) {
+ if (node.entity === entity) {
+ found = true;
+ }
}
-});
+
+ return found;
+ }
+};
+
+if (typeof module !== 'undefined' && this.module !== module) {
+ module.exports = NodeCollection;
+} else {
+ Serpentity.NodeCollection = NodeCollection;
+}
+++ /dev/null
-if (typeof require !== "undefined") {
- require("neon");
-}
-
-/*
-Serpentity is a simple entity framework inspired by Ash.
-
-Usage:
-
- require('serpentity');
-
-## Instantiating an engine
-
- var engine = Serpentity();
-
-Add entities or systems, systems are added with a priority (the smaller
-the number, the earlier it will be called):
-
- engine.addEntity(entityFactory());
- engine.addSystem(new GameSystem(), priority);
-
-Update all systems:
-
- engine.update(dt);
-
-Remove entities or systems:
-
- engine.removeEntity(entityReference);
- engine.removeSystem(systemReference);
-
-## Creating Entities
-
-Entities are the basic object of Serpentity, and they do nothing.
-
- var entity = new Serpentity.Entity();
-
-All the behavior is added through components
-
-## Creating Components
-
-Components define data that we can add to an entity. This data will
-eventually be consumed by "Systems"
-
- Class("PositionComponent").inherits(Serpentity.Component)({
- prototype : {
- x : 0,
- y : 0
- }
- });
-
-You can add components to entities by using the add method:
-
- entity.addComponent(new PositionComponent());
-
-
-Systems can refer to entities by requesting nodes.
-
-## Working with Nodes
-
-Nodes are sets of components that you define, so your system can require
-entities that always follow the API defined in the node.
-
- Class("MovementNode").inherits(Serpentity.Node)({
- types : {
- position : PositionComponent,
- motion : MotionComponent
- }
- });
-
-You can then request an array of all the nodes representing entities
-that comply with that API
-
- engine.getNodes(MovementNode);
-
-## Creating Systems
-
-Systems are called on every update, and they use components through nodes.
-
- Class("TestSystem").inherits(Serpentity.System)({
- prototype : {
- added : function added(engine){
- this.nodeList = engine.getNodes(MovementNode);
- },
- removed : function removed(engine){
- this.nodeList = undefined;
- }
- update : function update(dt){
- this.nodeList.forEach(function (node) {
- console.log("Current position is: " + node.position.x + "," + node.position.y);
- });
- }
- }
- });
-
-## That's it
-
-Just run `engine.update(dt)` in your game loop :D
-
-*/
-Class("Serpentity")({
- prototype : {
- systems : null,
- entities : null,
- _nodeCollections : null,
- _nodeCollectionKeys : null,
-
- init : function init(config) {
- var property;
-
- config = config || {};
-
- this.systems = [];
- this.entities = [];
- this._nodeCollections = [];
- this._nodeCollectionKeys = [];
-
- for (property in config) {
- if (config.hasOwnProperty(property)) {
- this[property] = config[property];
- }
- }
- },
-
- /*
- * Adds a system to the engine, so its update method will be called
- * with the others. Triggers added hook.
- *
- * returns true if added succesfully, false if already added
- */
- addSystem : function addSystem(system, priority) {
- var lastIndex, found;
-
- if (this.systems.indexOf(system) >= 0) {
- return false;
- }
-
- system.priority = priority;
-
- found = false;
- lastIndex = 0;
-
- this.systems.some(function findPriority(existingSystem, i) {
- lastIndex = i;
- if (existingSystem.priority >= system.priority) {
- found = true;
- return true;
- }
- });
-
- if (!found) {
- lastIndex += 1
- }
-
- this.systems.splice(lastIndex, 0, system);
- system.added(this);
- return true;
- },
-
- /*
- * Removes a system from the engine, so its update method will no
- * longer will be called. Triggers the removed hook.
- *
- * returns true if removed succesfully, false if already added
- */
- removeSystem : function removeSystem(system) {
- var position;
-
- position = this.systems.indexOf(system);
- if (position >= 0) {
- this.systems[position].removed(this);
- this.systems.splice(position, 1);
- return true;
- }
-
- return false;
- },
-
- /*
- * Adds an entity to the engine, adds to existing node collections
- *
- * returns true if added, false if already there
- */
- addEntity : function addEntity(entity) {
- if (this.entities.indexOf(entity) >= 0) {
- return false;
- }
- this.entities.push(entity);
-
- this._nodeCollections.forEach(function (collection) {
- collection.add(entity);
- });
-
- return true;
- },
-
- /*
- * Removes entity from system, removing from all node collections
- *
- * returns true if removed, false if not present
- */
- removeEntity : function removeEntity(entity) {
- var position;
-
- position = this.entities.indexOf(entity);
- if (position >= 0) {
- this._nodeCollections.forEach(function (collection) {
- collection.remove(entity);
- });
-
- this.entities.splice(position, 1);
- return true;
- }
-
- return false;
- },
-
- /*
- * Given a Node Class, retrieves a list of all the nodes for each
- * applicable entity.
- */
- getNodes : function getNodes(nodeType) {
- var position, nodeCollection;
-
- position = this._nodeCollectionKeys.indexOf(nodeType);
-
- if (position >= 0) {
- return this._nodeCollections[position].nodes;
- }
-
- nodeCollection = new Serpentity.NodeCollection({
- type : nodeType,
- });
-
- this._nodeCollectionKeys.push(nodeType);
- this._nodeCollections.push(nodeCollection);
-
- this.entities.forEach(function (entity) {
- nodeCollection.add(entity);
- });
-
- return nodeCollection.nodes;
- },
-
- /*
- * Calls update for every loaded system.
- */
- update : function update(dt) {
- this.systems.forEach(function (system) {
- system.update(dt);
- });
- }
- }
-});
-
-if (typeof require !== "undefined") {
- require("./component.js");
- require("./entity.js");
- require("./node.js");
- require("./node_collection.js");
- require("./system.js");
-}
+'use strict';
+
+/* global Serpentity */
+
/*
* Systems contain most of the logic, and work with nodes in order to
* act and change their values.
*
* You usually want to inherit from this class and override the
- * three methods.
+ * three methods. They are shown here to document the interface.
*/
-Class(Serpentity, "System")({
- prototype : {
- /*
- * This will be run when the system is added to the engine
- */
- added : function added(engine) {
- // Override
- },
+let System = class System {
+
+ /*
+ * This will be run when the system is added to the engine
+ */
+ added () {
+ // Override with added(engine)
+ // Receives an instance of the serpentity engine
+ }
+
+ /*
+ * This will be run when the system is removed from the engine
+ */
+ removed () {
+ // Override with removed(engine)
+ // Receives an instance of the serpentity engine
+ }
- /*
- * This will be run when the system is removed from the engine
- */
- removed : function removed(engine) {
- // Override
- },
+ /*
+ * This will run every time the engine's update method is called
+ */
+ update () {
+ // Override with update(dt)
+ // Receives a delta of the time
+ }
+};
- /*
- * This will run every time the engine's update method is called
- */
- update : function update(dt) {
- // Override
- }
- }
-});
+if (typeof module !== 'undefined' && this.module !== module) {
+ module.exports = System;
+} else {
+ Serpentity.System = System;
+}
{
"name": "serpentity",
"description": "A simple entity framework inspired by ash",
- "version": "0.1.7",
+ "version": "1.0.0",
"contributors": [
{
- "name": "Ben Beltran",
+ "name": "Rubén Beltrán del Río",
"email": "ben@nsovocal.com",
"url": "http://nsovocal.com"
}
"url": "https://github.com/rbdr/serpentity.git"
},
"dependencies": {
- "neon": "2.0.x"
},
"devDependencies": {
- "colors": "0.6.2",
- "tellurium": "2.0.x",
- "gulp-uglify": "~0.3.1",
- "gulp": "~3.8.7",
- "gulp-concat": "~2.3.4"
+ "babel-preset-es2015": "6.6.x",
+ "gulp": "3.9.x",
+ "gulp-babel": "6.1.x",
+ "gulp-concat": "2.6.x",
+ "gulp-rename": "1.2.x",
+ "gulp-uglify": "1.5.x"
},
"engines": {
- "node": ">= 0.10.0"
+ "node": ">= 4.0.0"
},
- "main": "./lib/serpentity/serpentity.js"
+ "main": "./lib/serpentity.js"
}
--- /dev/null
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Serpentity Browser Test</title>
+ <script src="/node_modules/serpentity/dist/serpentity.js"></script>
+ <script src="/test/integration.js"></script>
+ </head>
+ <body>
+ <h1>404 Droids Not Found</h1>
+ Look in your console...
+ </body>
+</html>
--- /dev/null
+'use strict';
+
+let test = function test (Serpentity) {
+
+ /* eslint no-console: 0 */
+
+ /////////////////
+ // Load the stuff
+ /////////////////
+ console.log('\n## Loading');
+ console.log('Serpentity: ' + (typeof Serpentity !== 'undefined' ? 'LOAD OK' : 'FAIL'));
+ console.log('Serpentity.Entity: ' + (typeof Serpentity !== 'undefined' && Serpentity.Entity ? 'LOAD OK' : 'FAIL'));
+ console.log('Serpentity.Component: ' + (typeof Serpentity !== 'undefined' && Serpentity.Component ? 'LOAD OK' : 'FAIL'));
+ console.log('Serpentity.System: ' + (typeof Serpentity !== 'undefined' && Serpentity.System ? 'LOAD OK' : 'FAIL'));
+ console.log('Serpentity.Node: ' + (typeof Serpentity !== 'undefined' && Serpentity.Node ? 'LOAD OK' : 'FAIL'));
+ console.log('Serpentity.NodeCollection: ' + (typeof Serpentity !== 'undefined' && Serpentity.NodeCollection ? 'LOAD OK' : 'FAIL'));
+
+ //////////////////////
+ // Create test classes
+ //////////////////////
+ console.log('\n## Creating Test Classes');
+ let TestSystem = class TestSystem extends Serpentity.System {
+ added (engine) {
+ this.testNodes = engine.getNodes(TestNode);
+ console.log('Engine is serpentity: ' + (engine instanceof Serpentity ? 'OK' : 'FAIL'));
+ console.log('System added callback: EXEC OK');
+ }
+
+ removed (engine) {
+ this.testNodes = null;
+ console.log('Engine is serpentity: ' + (engine instanceof Serpentity ? 'OK' : 'FAIL'));
+ console.log('System removed callback: EXEC OK');
+ }
+
+ update (dt) {
+ this.testNodes.forEach(function (node) {
+ console.log('Running Node: ' + (node.test.testMessage === 'test' ? 'SYSTEM OK' : 'FAIL'));
+ });
+ console.log('dt is number: ' + (typeof dt === 'number' ? 'OK' : 'FAIL'));
+ console.log('System update callback: EXEC OK');
+ }
+ };
+ let testSystem = new TestSystem();
+
+ let LowProTestSystem = class LowProTestSystem extends Serpentity.System {
+ added (engine) {
+ this.testNodes = engine.getNodes(TestNode);
+ console.log('Engine is serpentity: ' + (engine instanceof Serpentity ? 'OK' : 'FAIL'));
+ console.log('System added callback: EXEC OK');
+ }
+
+ removed (engine) {
+ this.testNodes = null;
+ console.log('Engine is serpentity: ' + (engine instanceof Serpentity ? 'OK' : 'FAIL'));
+ console.log('System removed callback: EXEC OK');
+ }
+
+ update (dt) {
+ this.testNodes.forEach(function (node) {
+ console.log('Running Low Priority Node: ' + (node.test.testMessage === 'test' ? 'SYSTEM OK' : 'FAIL'));
+ });
+ console.log('dt is number: ' + (typeof dt === 'number' ? 'OK' : 'FAIL'));
+ console.log('System update callback: EXEC OK');
+ }
+ };
+ let lowProTestSystem = new LowProTestSystem();
+ console.log('LowProTestSystem: CREATE OK');
+
+ let MidProTestSystem = class MidProTestSystem extends Serpentity.System {
+ added (engine) {
+ this.testNodes = engine.getNodes(TestNode);
+ console.log('Engine is serpentity: ' + (engine instanceof Serpentity ? 'OK' : 'FAIL'));
+ console.log('System added callback: EXEC OK');
+ }
+
+ removed (engine) {
+ this.testNodes = null;
+ console.log('Engine is serpentity: ' + (engine instanceof Serpentity ? 'OK' : 'FAIL'));
+ console.log('System removed callback: EXEC OK');
+ }
+
+ update (dt) {
+ this.testNodes.forEach(function (node) {
+ console.log('Running Mid Priority Node: ' + (node.test.testMessage === 'test' ? 'SYSTEM OK' : 'FAIL'));
+ });
+ console.log('dt is number: ' + (typeof dt === 'number' ? 'OK' : 'FAIL'));
+ console.log('System update callback: EXEC OK');
+ }
+ };
+ var midProTestSystem = new MidProTestSystem();
+ console.log('MidProTestSystem: CREATE OK');
+
+
+ let TestComponent = class TestComponent extends Serpentity.Component {
+ constructor (config) {
+ super(config);
+
+ this.testMessage = this.testMessage || 'test';
+ }
+ };
+ console.log('TestComponent: CREATE OK');
+
+ let TestNode = class TestNode extends Serpentity.Node {};
+ TestNode.types = {
+ test : TestComponent
+ };
+ console.log('TestNode: CREATE OK');
+
+ console.log('\n## Adding system to the engine');
+
+ let engine = new Serpentity();
+ console.log('engine: CREATE OK');
+
+ engine.addSystem(testSystem, 0);
+
+ console.log('\n## Running update without any entities');
+ engine.update(10);
+
+ console.log('\n## Adding system to the engine and updating');
+ let entity = new Serpentity.Entity();
+ entity.addComponent(new TestComponent());
+ engine.addEntity(entity);
+ engine.update(10);
+
+ console.log('\n## Adding Low Priority System');
+ engine.addSystem(lowProTestSystem, 10);
+ engine.update(10);
+
+ console.log('\n## Adding Mid Priority System');
+ engine.addSystem(midProTestSystem, 5);
+ engine.update(10);
+
+ console.log('\n## Removing the system and readding');
+ engine.removeSystem(testSystem);
+ engine.update(10);
+ engine.addSystem(testSystem, 0);
+ engine.update(10);
+
+ console.log('\n## Adding a second entity');
+ entity = new Serpentity.Entity();
+ entity.addComponent(new TestComponent());
+ engine.addEntity(entity);
+ engine.update(10);
+
+ console.log('\n## Removing entity');
+ engine.removeEntity(entity);
+ engine.update(10);
+
+ console.log('\n## Removing system');
+ engine.removeSystem(testSystem);
+ engine.update(10);
+
+};
+
+if (typeof require === 'function') {
+ let Serpentity = require('serpentity');
+ test(Serpentity);
+} else {
+ window.addEventListener('load', function () {
+ test(window.Serpentity);
+ });
+}