/** * The image factory takes care that we only make requests for Image URLs which we have not already started downloading * @param graphics * @param apiImageFactory * @param progressCallback * @returns {GameLib.D3.ImageFactory} * @constructor */ GameLib.D3.ImageFactory = function ( graphics, apiImageFactory, progressCallback ) { graphics.isNotThreeThrow(); this.graphics = graphics; if (GameLib.Utils.UndefinedOrNull(apiImageFactory)) { apiImageFactory = {}; } if (apiImageFactory instanceof GameLib.D3.ImageFactory) { return apiImageFactory; } GameLib.D3.API.ImageFactory.call( this, apiImageFactory.id, apiImageFactory.name, apiImageFactory.baseUrl, apiImageFactory.parentEntity ); if (GameLib.Utils.UndefinedOrNull(progressCallback)) { progressCallback = null; } this.progressCallback = progressCallback; GameLib.Component.call( this, GameLib.Component.COMPONENT_IMAGE_FACTORY ); this.promiseList = {}; }; GameLib.D3.ImageFactory.prototype = Object.create(GameLib.D3.API.ImageFactory.prototype); GameLib.D3.ImageFactory.prototype.constructor = GameLib.D3.ImageFactory; GameLib.D3.ImageFactory.prototype.createInstance = function(update) { if (!this.loaded) { console.log('Attempted to create an instance but the runtime object is not fully loaded : ' + this.name); return null; } var instance = null; if (update) { instance = this.instance; } else { instance = new THREE.ImageLoader(); } instance.crossOrigin = ''; return instance; }; /** * Update instance */ GameLib.D3.ImageFactory.prototype.updateInstance = function() { this.instance = this.createInstance(true); }; /** * Loads an image, either returns the image immediately if already loaded, or a promise to load the image * @param imagePath * @returns {*} * @constructor */ GameLib.D3.ImageFactory.prototype.loadImage = function( imagePath, force ) { imagePath = imagePath.replace(new RegExp('\/*'), '/'); if (!imagePath) { console.log('Attempted to download bad URL : ' + imagePath); throw new Error('Bad URL : ' + imagePath); } if (!force && this.promiseList[imagePath]) { return this.promiseList[imagePath]; } var defer = Q.defer(); this.promiseList[imagePath] = defer.promise; this.instance.load( this.baseUrl + imagePath + '?ts=' + Date.now(), function (image) { GameLib.Event.Emit( GameLib.Event.IMAGE_LOADED, { imagePath : imagePath, imageInstance : image } ); defer.resolve(image); }.bind(this), function onProgress(xhr) { if (this.progressCallback) { this.progressCallback((xhr.loaded / xhr.total * 100)); } }.bind(this), function onError() { defer.reject('Failed to download image : ' + this.baseUrl + imagePath); }.bind(this) ); return this.promiseList[imagePath]; }; /** * Converts a GameLib.D3.ImageFactory to a GameLib.D3.API.ImageFactory * @returns {GameLib.D3.API.ImageFactory} */ GameLib.D3.ImageFactory.prototype.toApiObject = function() { return new GameLib.D3.API.ImageFactory( this.id, this.name, this.baseUrl, GameLib.Utils.IdOrNull(this.parentEntity) ); }; /** * Returns a new GameLib.D3.ImageFactory from a GameLib.D3.API.ImageFactory * @param graphics GameLib.D3.Graphics * @param objectImageFactory GameLib.D3.API.ImageFactory * @returns {GameLib.D3.ImageFactory} */ GameLib.D3.ImageFactory.FromObject = function(graphics, objectImageFactory) { return new GameLib.D3.ImageFactory( graphics, GameLib.D3.API.ImageFactory.FromObject(objectImageFactory) ); };