untitled-rhythm-game/js/libassetloader.js
2025-04-23 00:02:59 +08:00

112 lines
3.3 KiB
JavaScript

//libassetloader.js
(async function() {
if(typeof XMLHttpRequest!="function") {
if(typeof loadfail=="function") {
loadfail("libassetloader.js: XMLHttpRequest(type of "+(typeof XMLHttpRequest)+") is not a function");
} else {
window.alert("libassetloader.js: XMLHttpRequest(type of "+(typeof XMLHttpRequest)+") is not a function");
}
return;
}
if(typeof Blob!="function") {
if(typeof loadfail=="function") {
loadfail("libassetloader.js: Blob(type of "+(typeof Blob)+") is not a function");
} else {
window.alert("libassetloader.js: Blob(type of "+(typeof Blob)+") is not a function");
}
return;
}
if(typeof URL!="function") {
if(typeof loadfail=="function") {
loadfail("libassetloader.js: URL(type of "+(typeof URL)+") is not a function");
} else {
window.alert("libassetloader.js: URL(type of "+(typeof URL)+") is not a function");
}
return;
}
var AssetManager= {};
// map http_url -> blob_url
AssetManager.loadedAssets= {};
AssetManager.loading_count=0;
AssetManager.loadWithCache=async function(pth) {
if(pth in AssetManager.loadedAssets) {
return Promise.resolve(AssetManager.loadedAssets[pth]);
}
return AssetManager.do_fetch_res(pth);
};
AssetManager.do_fetch_res=async function(pth) {
var resolve;
var reject;
var ret=new Promise(function(s, r) {
resolve=s;
reject=r;
});
var xhr=new XMLHttpRequest();
xhr.responseType = "blob";
var onreadystatechange=async function() {
if(xhr.readyState!=XMLHttpRequest.DONE) {
return;
}
removelisteners();
AssetManager.loading_count--;
if(xhr.status!=200) {
onfail();
return;
}
AssetManager.loadedAssets[pth]=URL.createObjectURL(xhr.response);
console.debug("asset "+pth+" loaded from source.");
resolve(AssetManager.loadedAssets[pth]);
return;
};
var onfail=function() {
removelisteners();
xhr.abort();
window.loadfail("asset "+pth+" load failed");
reject("asset "+pth+" load failed");
};
var removelisteners=function() {
xhr.removeEventListener("readystatechange", onreadystatechange);
xhr.removeEventListener("error", onfail);
xhr.removeEventListener("abort", onfail);
};
xhr.addEventListener("readystatechange", onreadystatechange);
xhr.addEventListener("error", onfail);
xhr.addEventListener("abort", onfail);
xhr.open("GET", pth, true);
xhr.send();
AssetManager.loading_count++;
return ret;
};
AssetManager.isDone=function() {
return AssetManager.loading_count==0;
};
AssetManager.waitAll=async function() {
return new Promise(function(resolve, reject) {
var i;
i=setInterval(function() {
if(AssetManager.loading_count==0) {
clearInterval(i);
resolve();
}
}, 100);
});
};
window.AssetManager=AssetManager;
})();