/** * System takes care of updating all the entities (based on their component data) * @param graphics * @param apiSystem GameLib.API.System * @constructor */ GameLib.System = function( graphics, apiSystem ) { this.graphics = graphics; this.graphics.isNotThreeThrow(); if (GameLib.Utils.UndefinedOrNull(apiSystem)) { apiSystem = {}; } if (apiSystem instanceof GameLib.System) { return apiSystem; } GameLib.API.System.call( this, apiSystem.id, apiSystem.name, apiSystem.systemType, apiSystem.entityManager, apiSystem.domElement, apiSystem.domStats, apiSystem.parentEntity ); if (this.entityManager instanceof GameLib.API.EntityManager) { this.entityManager = new GameLib.EntityManager( this.graphics, this.entityManager ); } if (this.domElement instanceof GameLib.API.DomElement) { this.domElement = new GameLib.DomElement( this.domElement ); } }; GameLib.System.prototype = Object.create(GameLib.API.System.prototype); GameLib.System.prototype.constructor = GameLib.System; GameLib.System.SYSTEM_TYPE_RENDER = 0x1; GameLib.System.SYSTEM_TYPE_ANIMATION = 0x2; GameLib.System.SYSTEM_TYPE_INPUT = 0x4; GameLib.System.SYSTEM_TYPE_ALL = 0x7; /** * @callback * @override */ GameLib.System.prototype.start = function() { if (this.systemType === GameLib.System.SYSTEM_TYPE_INPUT) { // this.driveInputObjects = this.entityManager.query([GameLib.D3.Input.Drive]); } if (this.systemType === GameLib.System.SYSTEM_TYPE_RENDER) { if (GameLib.Utils.UndefinedOrNull(this.domElement)) { console.warn('Cannot start a rendering system without a valid DOM element'); throw new Error('Cannot start a rendering system without a valid DOM element'); } if (GameLib.Utils.UndefinedOrNull(this.domStats)) { console.warn('No stats DOM - will run the render process without statistics information'); } else { //this.domElement.instance.appendChild(this.domStats.instance); } this.renderers = this.entityManager.queryComponents(GameLib.D3.Renderer); this.renderers.forEach( function (renderer) { renderer.domElement.instance.appendChild(renderer.instance.domElement); }.bind(this) ); this.renderEntities = this.entityManager.query( [ GameLib.D3.Viewport, GameLib.D3.Scene, GameLib.D3.Renderer, GameLib.D3.Camera ] ); } if (this.systemType === GameLib.System.SYSTEM_TYPE_ANIMATION) { // this.pathFollowingObjects = this.entityManager.query([GameLib.D3.PathFollowing]); // this.followObjects = this.entityManager.query([GameLib.D3.Follow]); // this.meshObjects = this.entityManager.query([GameLib.D3.Mesh]); // this.lookAtObjects = this.entityManager.query([GameLib.D3.LookAt]); // this.cameraObjects = this.entityManager.query([GameLib.D3.Camera]); // this.lightObjects = this.entityManager.query([GameLib.D3.Light]); } this.update(); }; /** * @callback * @override */ GameLib.System.prototype.update = function(deltaTime) { if (this.systemType === GameLib.System.SYSTEM_TYPE_INPUT) { this.driveInputObjects.forEach( function(object) { object.update(deltaTime); } ); } if (this.systemType === GameLib.System.SYSTEM_TYPE_ANIMATION) { this.pathFollowingObjects.forEach( function(object) { object.update(deltaTime); } ); this.followObjects.forEach( function(object) { object.update(deltaTime); } ); this.lookAtObjects.forEach( function(object) { object.update(deltaTime); } ); this.meshObjects.forEach( function(object) { object.updateInstance(); } ); this.cameraObjects.forEach( function(object) { object.updateInstance(); } ); this.lightObjects.forEach( function(object) { object.updateInstance(); } ); } if (this.systemType === GameLib.System.SYSTEM_TYPE_RENDER) { this.renderEntities.map( function(renderEntity) { var renderer = renderEntity.getFirstComponent(GameLib.D3.Renderer); var camera = renderEntity.getFirstComponent(GameLib.D3.Camera); var viewport = renderEntity.getFirstComponent(GameLib.D3.Viewport); renderer.instance.setViewport( viewport.x, viewport.y, viewport.width, viewport.height ); var scenes = renderEntity.getComponent(GameLib.D3.Scene); scenes.map(function(scene){ renderer.instance.render( scene.instance, camera.instance ); }); } ); } }; /** * @callback * @override */ GameLib.System.prototype.stop = function() { if (this.systemType === GameLib.System.SYSTEM_TYPE_INPUT) { // this.driveInputObjects = []; } if (this.systemType === GameLib.System.SYSTEM_TYPE_RENDER) { this.domElement.innerHTML = 'Rendering System Stopped'; this.renderers = []; this.viewports = []; this.meshes = []; } if (this.systemType === GameLib.System.SYSTEM_TYPE_ANIMATION) { // this.pathFollowingObjects = []; // this.followObjects = []; // this.meshObjects = []; // this.lookAtObjects = []; // this.cameraObjects = []; // this.lightObjects = []; } }; /** * Converts runtime vector to API Vector * @returns {GameLib.API.System} */ GameLib.System.prototype.toApiSystem = function() { var apiDomElement = null; if (this.domElement instanceof GameLib.DomElement) { apiDomElement = this.domElement.toApiDomElement(); } var apiDomStats = null; if (this.domStats instanceof GameLib.DomElement) { apiDomStats = this.domStats.toApiDomElement(); } return new GameLib.API.System( this.id, this.name, this.systemType, GameLib.Utils.IdOrNull(this.entityManager), apiDomElement, apiDomStats, GameLib.Utils.IdOrNull(this.parentEntity) ); }; GameLib.System.prototype.notify = function(property, constructor) { this[property] = this.entityManager.queryComponents(constructor); /** * For meshes, we need to notify all scene objects */ if (constructor === GameLib.D3.Mesh) { } };