]> git.r.bdr.sh - rbdr/serpentity/blobdiff - dist/serpentity.js
Replace code and lab with ndoe test runner
[rbdr/serpentity] / dist / serpentity.js
index 3522b063a3a715436c6fe5131e2dd8bfb6c53556..c3b6f62861c05bb98dad1674cf8bf98fc06a9845 100644 (file)
@@ -1,521 +1 @@
-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.add(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");
-}
-
-/*
- * 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
-         */
-        add : function add(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];
-            }
-         }
-    }
-});
-
-/*
- * 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) {
-
-                if (this.types.hasOwnProperty(property)) {
-                    matched = false;
-
-                    if (entity.hasComponent(types[property])) {
-                        matched = true;
-                    }
-
-                    if (!matched) {
-                        return false;
-                    }
-                }
-            }
-
-            return true;
-    },
-
-    prototype : {
-
-        types : null,
-
-        init : function (config) {
-            var property;
-
-            this.types = {};
-
-            for (property in this.constructor) {
-                if (this.constructor.hasOwnProperty(property)) {
-                    this.types[property] = this.constructor[property];
-                }
-            }
-        }
-    }
-});
-
-/*
- * 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;
-        }
-    }
-});
-
-/*
- * 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 || {};
-
-            for (property in config) {
-                if (config.hasOwnProperty(property)) {
-                    this[property] = config[property];
-                }
-            }
-        }
-    }
-});
-
-/*
- * 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.
- */
-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
-        }
-    }
-});
+!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Serpentity=t():e.Serpentity=t()}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([function(e,t,n){"use strict";var r,i="object"==typeof Reflect?Reflect:null,s=i&&"function"==typeof i.apply?i.apply:function(e,t,n){return Function.prototype.apply.call(e,t,n)};r=i&&"function"==typeof i.ownKeys?i.ownKeys:Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:function(e){return Object.getOwnPropertyNames(e)};var o=Number.isNaN||function(e){return e!=e};function u(){u.init.call(this)}e.exports=u,u.EventEmitter=u,u.prototype._events=void 0,u.prototype._eventsCount=0,u.prototype._maxListeners=void 0;var c=10;function f(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function p(e){return void 0===e._maxListeners?u.defaultMaxListeners:e._maxListeners}function l(e,t,n,r){var i,s,o,u;if(f(n),void 0===(s=e._events)?(s=e._events=Object.create(null),e._eventsCount=0):(void 0!==s.newListener&&(e.emit("newListener",t,n.listener?n.listener:n),s=e._events),o=s[t]),void 0===o)o=s[t]=n,++e._eventsCount;else if("function"==typeof o?o=s[t]=r?[n,o]:[o,n]:r?o.unshift(n):o.push(n),(i=p(e))>0&&o.length>i&&!o.warned){o.warned=!0;var c=new Error("Possible EventEmitter memory leak detected. "+o.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");c.name="MaxListenersExceededWarning",c.emitter=e,c.type=t,c.count=o.length,u=c,console&&console.warn&&console.warn(u)}return e}function h(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function a(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},i=h.bind(r);return i.listener=n,r.wrapFn=i,i}function d(e,t,n){var r=e._events;if(void 0===r)return[];var i=r[t];return void 0===i?[]:"function"==typeof i?n?[i.listener||i]:[i]:n?function(e){for(var t=new Array(e.length),n=0;n<t.length;++n)t[n]=e[n].listener||e[n];return t}(i):v(i,i.length)}function y(e){var t=this._events;if(void 0!==t){var n=t[e];if("function"==typeof n)return 1;if(void 0!==n)return n.length}return 0}function v(e,t){for(var n=new Array(t),r=0;r<t;++r)n[r]=e[r];return n}Object.defineProperty(u,"defaultMaxListeners",{enumerable:!0,get:function(){return c},set:function(e){if("number"!=typeof e||e<0||o(e))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+e+".");c=e}}),u.init=function(){void 0!==this._events&&this._events!==Object.getPrototypeOf(this)._events||(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0},u.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||o(e))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+e+".");return this._maxListeners=e,this},u.prototype.getMaxListeners=function(){return p(this)},u.prototype.emit=function(e){for(var t=[],n=1;n<arguments.length;n++)t.push(arguments[n]);var r="error"===e,i=this._events;if(void 0!==i)r=r&&void 0===i.error;else if(!r)return!1;if(r){var o;if(t.length>0&&(o=t[0]),o instanceof Error)throw o;var u=new Error("Unhandled error."+(o?" ("+o.message+")":""));throw u.context=o,u}var c=i[e];if(void 0===c)return!1;if("function"==typeof c)s(c,this,t);else{var f=c.length,p=v(c,f);for(n=0;n<f;++n)s(p[n],this,t)}return!0},u.prototype.addListener=function(e,t){return l(this,e,t,!1)},u.prototype.on=u.prototype.addListener,u.prototype.prependListener=function(e,t){return l(this,e,t,!0)},u.prototype.once=function(e,t){return f(t),this.on(e,a(this,e,t)),this},u.prototype.prependOnceListener=function(e,t){return f(t),this.prependListener(e,a(this,e,t)),this},u.prototype.removeListener=function(e,t){var n,r,i,s,o;if(f(t),void 0===(r=this._events))return this;if(void 0===(n=r[e]))return this;if(n===t||n.listener===t)0==--this._eventsCount?this._events=Object.create(null):(delete r[e],r.removeListener&&this.emit("removeListener",e,n.listener||t));else if("function"!=typeof n){for(i=-1,s=n.length-1;s>=0;s--)if(n[s]===t||n[s].listener===t){o=n[s].listener,i=s;break}if(i<0)return this;0===i?n.shift():function(e,t){for(;t+1<e.length;t++)e[t]=e[t+1];e.pop()}(n,i),1===n.length&&(r[e]=n[0]),void 0!==r.removeListener&&this.emit("removeListener",e,o||t)}return this},u.prototype.off=u.prototype.removeListener,u.prototype.removeAllListeners=function(e){var t,n,r;if(void 0===(n=this._events))return this;if(void 0===n.removeListener)return 0===arguments.length?(this._events=Object.create(null),this._eventsCount=0):void 0!==n[e]&&(0==--this._eventsCount?this._events=Object.create(null):delete n[e]),this;if(0===arguments.length){var i,s=Object.keys(n);for(r=0;r<s.length;++r)"removeListener"!==(i=s[r])&&this.removeAllListeners(i);return this.removeAllListeners("removeListener"),this._events=Object.create(null),this._eventsCount=0,this}if("function"==typeof(t=n[e]))this.removeListener(e,t);else if(void 0!==t)for(r=t.length-1;r>=0;r--)this.removeListener(e,t[r]);return this},u.prototype.listeners=function(e){return d(this,e,!0)},u.prototype.rawListeners=function(e){return d(this,e,!1)},u.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):y.call(e,t)},u.prototype.listenerCount=y,u.prototype.eventNames=function(){return this._eventsCount>0?r(this._events):[]}},function(e,t,n){"use strict";n.r(t),n.d(t,"Component",(function(){return r})),n.d(t,"Entity",(function(){return i})),n.d(t,"Node",(function(){return s})),n.d(t,"System",(function(){return o})),n.d(t,"default",(function(){return p}));class r{constructor(e){Object.assign(this,e)}}class i{constructor(e){this._componentKeys=[],this._components=[],Object.assign(this,e)}addComponent(e){return!(this._componentKeys.indexOf(e.constructor)>=0)&&(this._componentKeys.push(e.constructor),this._components.push(e),!0)}hasComponent(e){return this._componentKeys.indexOf(e)>=0}getComponent(e){const t=this._componentKeys.indexOf(e);if(t>=0)return this._components[t]}}class s{static matches(e){const t=Object.keys(this.types);for(const n of t){const t=this.types[n];let r=!1;if(e.hasComponent(t)&&(r=!0),!r)return!1}return!0}constructor(e){this.types={},Object.assign(this,e)}}class o{added(){}removed(){}update(){}}var u=n(0),c=n.n(u);class f extends c.a{constructor(e){super(),this.nodes=[],this.type=null,Object.assign(this,e)}add(e){if(this.type.matches(e)&&!this._entityExists(e)){const t=new this.type({}),n=this.type.types,r=Object.keys(n);t.entity=e;for(const i of r)t[i]=e.getComponent(n[i]);return this.nodes.push(t),this.emit("nodeAdded",{node:t}),!0}return!1}remove(e){let t=-1,n=null;const r=this.nodes.some((r,i)=>{if(r.entity===e)return t=i,n=r,!0});return r&&(this.nodes.splice(t,1),this.emit("nodeRemoved",{node:n})),r}_entityExists(e){let t=!1;for(const n of this.nodes)n.entity===e&&(t=!0);return t}}f.prototype[Symbol.iterator]=function*(){yield*this.nodes};class p{constructor(e){this.systems=[],this.entities=[],this._nodeCollections=[],this._nodeCollectionKeys=[],Object.assign(this,e)}addSystem(e,t){if(this.systems.indexOf(e)>=0)return!1;e.priority=t;let n=0;return this.systems.some((t,r)=>{if(n=r,t.priority>=e.priority)return!0})||(n+=1),this.systems.splice(n,0,e),e.added(this),!0}removeSystem(e){const t=this.systems.indexOf(e);return t>=0&&(this.systems[t].removed(this),this.systems.splice(t,1),!0)}addEntity(e){if(this.entities.indexOf(e)>=0)return!1;this.entities.push(e);for(const t of this._nodeCollections)t.add(e);return!0}removeEntity(e){const t=this.entities.indexOf(e);if(t>=0){for(const t of this._nodeCollections)t.remove(e);return this.entities.splice(t,1),!0}return!1}getNodes(e){const t=this._nodeCollectionKeys.indexOf(e);if(t>=0)return this._nodeCollections[t].nodes;const n=new f({type:e});this._nodeCollectionKeys.push(e),this._nodeCollections.push(n);for(const e of this.entities)n.add(e);return n}update(e){for(const t of this.systems)t.update(e)}}}])}));
\ No newline at end of file