2016-11-30 17:16:45 +00:00
|
|
|
|
2016-12-06 15:15:42 +00:00
|
|
|
var CONST = require('./const');
|
2016-11-30 17:16:45 +00:00
|
|
|
var Set = require('../structs/Set');
|
|
|
|
var XHRSettings = require('./XHRSettings');
|
2016-12-06 15:15:42 +00:00
|
|
|
var Event = require('./events/');
|
|
|
|
var EventDispatcher = require('../events/EventDispatcher');
|
2016-11-30 17:16:45 +00:00
|
|
|
|
|
|
|
var BaseLoader = function ()
|
|
|
|
{
|
2016-12-05 15:29:53 +00:00
|
|
|
// To finish the loader ...
|
|
|
|
//
|
|
|
|
// 3) Progress update
|
|
|
|
// 4) JSON loader
|
|
|
|
// 5) XML Loader
|
|
|
|
// 6) Multi File support (atlas + data)
|
|
|
|
// 7) Atlas Loader
|
|
|
|
|
2016-12-06 15:15:42 +00:00
|
|
|
this.events = new EventDispatcher();
|
2016-12-05 15:29:53 +00:00
|
|
|
|
2016-12-07 00:04:32 +00:00
|
|
|
this.forceImageTags = false;
|
|
|
|
|
2016-11-30 17:16:45 +00:00
|
|
|
// Move to a 'setURL' method?
|
|
|
|
this.baseURL = '';
|
|
|
|
this.path = '';
|
|
|
|
|
|
|
|
// Read from Game / State Config
|
|
|
|
this.enableParallel = true;
|
|
|
|
this.maxParallelDownloads = 8;
|
|
|
|
|
|
|
|
// xhr specific global settings (can be overridden on a per-file basis)
|
|
|
|
this.xhr = XHRSettings();
|
|
|
|
|
|
|
|
this.crossOrigin = undefined;
|
|
|
|
|
|
|
|
this.list = new Set();
|
|
|
|
this.inflight = new Set();
|
|
|
|
this.failed = new Set();
|
|
|
|
this.queue = new Set();
|
2016-12-05 15:29:53 +00:00
|
|
|
|
2016-11-30 17:16:45 +00:00
|
|
|
this.storage = new Set();
|
|
|
|
|
2016-12-06 15:15:42 +00:00
|
|
|
this._state = CONST.LOADER_IDLE;
|
2016-11-30 17:16:45 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
BaseLoader.prototype.contructor = BaseLoader;
|
|
|
|
|
|
|
|
BaseLoader.prototype = {
|
|
|
|
|
|
|
|
addFile: function (file)
|
|
|
|
{
|
|
|
|
if (!this.isReady())
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Multipart file?
|
|
|
|
if (file.multipart)
|
|
|
|
{
|
|
|
|
file.fileA.path = this.path;
|
|
|
|
file.fileB.path = this.path;
|
|
|
|
|
|
|
|
this.list.add(file.fileA);
|
|
|
|
this.list.add(file.fileB);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
file.path = this.path;
|
|
|
|
|
|
|
|
this.list.add(file);
|
|
|
|
}
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
// Is the Loader actively loading (or processing loaded files)
|
|
|
|
isLoading: function ()
|
|
|
|
{
|
2016-12-06 15:15:42 +00:00
|
|
|
return (this._state === CONST.LOADER_LOADING || this._state === CONST.LOADER_PROCESSING);
|
2016-11-30 17:16:45 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
// Is the Loader ready to start a new load?
|
|
|
|
isReady: function ()
|
|
|
|
{
|
2016-12-06 15:15:42 +00:00
|
|
|
return (this._state === CONST.LOADER_IDLE || this._state === CONST.LOADER_COMPLETE || this._state === CONST.LOADER_FAILED);
|
2016-11-30 17:16:45 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
start: function ()
|
|
|
|
{
|
2016-12-06 15:25:24 +00:00
|
|
|
// console.log('BaseLoader start. Files to load:', this.list.size);
|
2016-11-30 17:16:45 +00:00
|
|
|
|
|
|
|
if (!this.isReady())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-12-06 15:15:42 +00:00
|
|
|
this.events.dispatch(new Event.LOADER_START_EVENT(this));
|
2016-12-05 17:19:12 +00:00
|
|
|
|
2016-11-30 17:16:45 +00:00
|
|
|
if (this.list.size === 0)
|
|
|
|
{
|
|
|
|
this.finishedLoading();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-12-06 15:15:42 +00:00
|
|
|
this._state = CONST.LOADER_LOADING;
|
2016-11-30 17:16:45 +00:00
|
|
|
|
|
|
|
this.failed.clear();
|
|
|
|
this.inflight.clear();
|
|
|
|
this.queue.clear();
|
|
|
|
|
|
|
|
this.updateProgress();
|
|
|
|
|
|
|
|
this.processLoadQueue();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
updateProgress: function ()
|
|
|
|
{
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
processLoadQueue: function ()
|
|
|
|
{
|
2016-12-06 15:25:24 +00:00
|
|
|
// console.log('BaseLoader processLoadQueue', this.list.size);
|
2016-11-30 17:16:45 +00:00
|
|
|
|
|
|
|
var _this = this;
|
|
|
|
|
|
|
|
this.list.each(function (file)
|
|
|
|
{
|
2016-12-06 15:15:42 +00:00
|
|
|
if (file.state === CONST.FILE_PENDING && _this.inflight.size < _this.maxParallelDownloads)
|
2016-11-30 17:16:45 +00:00
|
|
|
{
|
2016-12-06 15:25:24 +00:00
|
|
|
// console.log('ADDED TO QUEUE:', file.key);
|
2016-11-30 17:16:45 +00:00
|
|
|
|
|
|
|
_this.inflight.add(file);
|
|
|
|
|
|
|
|
_this.list.delete(file);
|
|
|
|
|
|
|
|
_this.loadFile(file);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_this.inflight.size === _this.maxParallelDownloads)
|
|
|
|
{
|
|
|
|
// Tells the Set iterator to abort
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
// private
|
|
|
|
loadFile: function (file)
|
|
|
|
{
|
2016-12-06 15:25:24 +00:00
|
|
|
// console.log('LOADING', file.key);
|
2016-11-30 17:16:45 +00:00
|
|
|
|
|
|
|
// If the file doesn't have its own crossOrigin set,
|
|
|
|
// we'll use the Loaders (which is undefined by default)
|
|
|
|
if (!file.crossOrigin)
|
|
|
|
{
|
|
|
|
file.crossOrigin = this.crossOrigin;
|
|
|
|
}
|
|
|
|
|
2016-12-01 12:50:58 +00:00
|
|
|
file.load(this.nextFile.bind(this), this.baseURL);
|
2016-11-30 17:16:45 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
nextFile: function (previousFile, success)
|
|
|
|
{
|
2016-12-06 15:25:24 +00:00
|
|
|
// console.log('LOADED:', previousFile.src, success);
|
2016-11-30 17:16:45 +00:00
|
|
|
|
|
|
|
// Move the file that just loaded from the inflight list to the queue or failed Set
|
|
|
|
|
|
|
|
if (success)
|
|
|
|
{
|
|
|
|
this.queue.add(previousFile);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.failed.add(previousFile);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.inflight.delete(previousFile);
|
|
|
|
|
|
|
|
if (this.list.size > 0)
|
|
|
|
{
|
2016-12-06 15:25:24 +00:00
|
|
|
// console.log('nextFile - still something in the list');
|
2016-11-30 17:16:45 +00:00
|
|
|
this.processLoadQueue();
|
|
|
|
}
|
|
|
|
else if (this.inflight.size === 0)
|
|
|
|
{
|
2016-12-06 15:25:24 +00:00
|
|
|
// console.log('nextFile calling finishedLoading');
|
2016-11-30 17:16:45 +00:00
|
|
|
this.finishedLoading();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
finishedLoading: function ()
|
|
|
|
{
|
2016-12-06 15:25:24 +00:00
|
|
|
// console.log('BaseLoader.finishedLoading PROCESSING');
|
2016-11-30 17:16:45 +00:00
|
|
|
|
2016-12-06 15:15:42 +00:00
|
|
|
this._state = CONST.LOADER_PROCESSING;
|
2016-11-30 17:16:45 +00:00
|
|
|
|
2016-12-01 12:50:58 +00:00
|
|
|
var storage = this.storage;
|
|
|
|
|
|
|
|
storage.clear();
|
2016-11-30 17:16:45 +00:00
|
|
|
|
|
|
|
// This could be Promise based as well, allowing for async processing
|
|
|
|
|
|
|
|
this.queue.each(function (file)
|
|
|
|
{
|
|
|
|
file.onProcess();
|
|
|
|
|
|
|
|
// The File specific process handler has run
|
|
|
|
// Now run any custom callbacks
|
|
|
|
if (file.processCallback)
|
|
|
|
{
|
|
|
|
file.processCallback(file);
|
|
|
|
}
|
|
|
|
|
|
|
|
file.onComplete();
|
|
|
|
|
2016-12-01 12:50:58 +00:00
|
|
|
storage.add(file);
|
2016-11-30 17:16:45 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
this.list.clear();
|
|
|
|
this.inflight.clear();
|
|
|
|
this.queue.clear();
|
|
|
|
|
2016-12-06 15:25:24 +00:00
|
|
|
// console.log('Loader Complete. Loaded:', storage.size, 'Failed:', this.failed.size);
|
2016-11-30 17:16:45 +00:00
|
|
|
|
2016-12-06 15:15:42 +00:00
|
|
|
this._state = CONST.LOADER_COMPLETE;
|
2016-11-30 17:16:45 +00:00
|
|
|
|
2016-12-06 15:15:42 +00:00
|
|
|
this.events.dispatch(new Event.LOADER_COMPLETE_EVENT(this));
|
2016-11-30 17:16:45 +00:00
|
|
|
},
|
|
|
|
|
2016-12-07 00:04:32 +00:00
|
|
|
getLoadedFiles: function ()
|
|
|
|
{
|
|
|
|
return this.storage.slice();
|
2016-11-30 17:16:45 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
reset: function ()
|
|
|
|
{
|
|
|
|
this.list.clear();
|
|
|
|
this.inflight.clear();
|
|
|
|
this.failed.clear();
|
|
|
|
this.queue.clear();
|
|
|
|
this.storage.clear();
|
|
|
|
|
|
|
|
this.tag = '';
|
|
|
|
this.path = '';
|
|
|
|
this.baseURL = '';
|
|
|
|
|
2016-12-06 15:15:42 +00:00
|
|
|
this._state = CONST.LOADER_IDLE;
|
2016-11-30 17:16:45 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
destroy: function ()
|
|
|
|
{
|
|
|
|
this.reset();
|
2016-12-06 15:15:42 +00:00
|
|
|
this._state = CONST.LOADER_DESTROYED;
|
2016-11-30 17:16:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = BaseLoader;
|