import FileToLoad from './FileToLoad.js';
const STATUS_OK = 200;
const RESET = -2;
const START = -1;
/**
FileLoader can load files and send their responce using calbacks.
It can load text, json, html or blob. See : {@link FileToLoad FileToLoad}
@example
<code type="javascript">
function init() {
FileLoader.getInstance().readAsText('./leveldesign.json', (pD) => {
LevelManager.init(pD);
});
FileLoader.getInstance().oncomplete = () => { FlowManager.showMainMenu() };
FileLoader.getInstance().start();
}
</code>
* @memberof Public.Common
*/
class FileLoader {
//static _instance;
//_currentLoadingItemIndex;
//loadList;
//onerror
//onparseerror
//oncomplete
//onprogress
/**
* @returns {FileLoader}
*/
static getInstance() {
return FileLoader._instance || (FileLoader._instance = new FileLoader());
}
/*
Constructor
*/
constructor() {
this._reset();
/**
* True if not started or not ended
*/
this.isComplete = true;
/**
* @callback Next
* @returns {void}
* @memberof Public.Common.FileLoader
*/
/**
* @callback Reset
* @returns {void}
* @memberof Public.Common.FileLoader
*/
/**
* @callback onerror
* @param {Error} pErr
* @param {Next} pNext
* @param {Reset} pReset
* @param {number} pCurrentLoadingItemIndex
* @returns {void}
* @memberof Public.Common.FileLoader
*/
/**
* @type {onerror}
*/
this.onerror = null;
/**
* @callback onparseerror
* @param {Error} pErr
* @param {Next} pNext
* @param {Reset} pReset
* @param {number} pCurrentLoadingItemIndex
* @returns {void}
* @memberof Public.Common.FileLoader
*/
/**
* @type {onparseerror}
*/
this.onparseerror = null;
/**
* @callback oncomplete
* @returns {void}
* @memberof Public.Common.FileLoader
*/
/**
* @type {oncomplete}
*/
this.oncomplete = null;
/**
* @callback onprogress
* @param {number} pProgress
* @returns {void}
* @memberof Public.Common.FileLoader
*/
/**
* @type {onprogress}
*/
this.onprogress = null;
/**
* @type {FileToLoad[]}
*/
this.loadList = [];
}
/**
* @protected
*/
_destroy()
{
if (FileLoader._instance == this)
{
FileLoader._instance = null;
}
this._reset();
}
/**
* @callback TextDataCallback
* @param {string} pData
* @return {void}
* @memberof Public.Common.FileLoader
*/
/**
* Renvoie une chaine de charactère contenant le contenu du fichier
* @param {string} pURL
* @param {TextDataCallback} pCallback
*/
readAsText(pURL, pCallback) {
this.loadList.push(new FileToLoad(
pURL,
FileToLoad.getTYPE_TEXT(),
pCallback
));
return this;
}
/**
* @callback JsonDataCallback
* @param {*} pData
* @return {void}
* @memberof Public.Common.FileLoader
*/
/**
* Renvoie l'object json contenu dans le fichier
* @param {string} pURL
* @param {JsonDataCallback} pCallback
*/
readAsJson(pURL, pCallback) {
this.loadList.push(new FileToLoad(
pURL,
FileToLoad.getTYPE_JSON(),
pCallback
));
return this;
}
/**
* @callback HTMLDataCallback
* @param {Document} pData
* @return {void}
* @memberof Public.Common.FileLoader
*/
/**
* Renvoie le document html contenu dans le fichier
* @param {string} pURL
* @param {HTMLDataCallback} pCallback
*/
readAsHTML(pURL, pCallback) {
this.loadList.push(new FileToLoad(
pURL,
FileToLoad.getTYPE_HTML(),
pCallback
));
return this;
}
/**
* @callback BlobDataCallback
* @param {string} pData
* @return {void}
* @memberof Public.Common.FileLoader
*/
/**
* Renvoie un url blob pointant vers le fichier stocké en cache
* @param {string} pURL
* @param {BlobDataCallback} pCallback
*/
readAsBlob(pURL, pCallback) {
this.loadList.push(new FileToLoad(
pURL,
FileToLoad.getTYPE_BLOB(),
pCallback
));
return this;
}
start() {
this.isComplete = false;
this._currentLoadingItemIndex = START;
this._callNext();
}
_reset() {
this._currentLoadingItemIndex = RESET;
this.loadList = [];
return this;
}
_callNext() {
if (this._currentLoadingItemIndex < START) return;
this._currentLoadingItemIndex++;
//Si on est arrivé à la fin de la loadlist, on execute oncomplete
if (this._currentLoadingItemIndex >= this.loadList.length) {
if (this.oncomplete instanceof Function) this.oncomplete();
this.isComplete = true;
//this._destroy();
return;
}
//On execute onprogress lorsque l'on charge un nouveau fichier
let lProgress = this._currentLoadingItemIndex / this.loadList.length;
if (this.onprogress instanceof Function) this.onprogress(lProgress);
let currentLoadingItem = this.loadList[this._currentLoadingItemIndex];
/**
*
* @param {Error} pErr
*/
let lCatchFunction = (pCalback, pErr) => {
console.error(pErr, currentLoadingItem);
if (pCalback instanceof Function) pCalback(pErr, this._callNext.bind(this), this._reset.bind(this), this._currentLoadingItemIndex);
}
//On récupère le contenu du fichier
fetch(currentLoadingItem.url)
.then((pResult) => {
if (pResult.status !== STATUS_OK) {
lCatchFunction(this.onerror, new Error(pResult.status+" "+pResult.statusText+" : " + pResult.url));
return;
}
/*
On parse le résultat en text ou en blob en fonction de la réponse
*/
/**
* @type {Promise<*>}
*/
let lFunction = null;
switch (currentLoadingItem.type) {
case FileToLoad.getTYPE_HTML():
case FileToLoad.getTYPE_TEXT():
lFunction = pResult.text();
break;
case FileToLoad.getTYPE_BLOB():
lFunction = pResult.blob();
break;
case FileToLoad.getTYPE_JSON():
lFunction = pResult.text().then(txt => {
console.group("JSON");
console.log(txt);
return JSON.parse(txt);
})
.catch( e => {
console.log(e);
})
.finally( () => console.groupEnd() );
break;
}
lFunction.then(
(pData) => {
switch (currentLoadingItem.type) {
case FileToLoad.getTYPE_BLOB():
this._createUrlAndSendResult(pData, currentLoadingItem)
break;
case FileToLoad.getTYPE_HTML():
this._parseAsHtmlAndSendResult(pData, currentLoadingItem);
break;
default:
this._directSendResult(pData, currentLoadingItem)
break;
}
this._callNext();
}
)
.catch( lCatchFunction.bind(this, this.onparseerror) );
})
.catch( lCatchFunction.bind(this, this.onerror) );
}
_directSendResult(pData, pCurrentLoadingItem) {
pCurrentLoadingItem.callback(pData);
}
_createUrlAndSendResult(pData, pCurrentLoadingItem) {
pCurrentLoadingItem.callback(URL.createObjectURL(pData));
}
_parseAsHtmlAndSendResult(pData, pCurrentLoadingItem)
{
// Convert the HTML string into a document object
var parser = new DOMParser();
var doc = parser.parseFromString(pData, 'text/html');
pCurrentLoadingItem(doc);
}
}
export default FileLoader;