-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathloadResources.js
More file actions
84 lines (77 loc) · 2.63 KB
/
loadResources.js
File metadata and controls
84 lines (77 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
const ajaxByUrlAndType = (url, type) => new Promise((s, f) => {
const ajax = new XMLHttpRequest();
ajax.onreadystatechange = function() {
if (this.readyState !== 4) return;
if (this.status === 200) s(this.response);
else f(new Error(this.statusText));
};
ajax.responseType = type;
ajax.open("GET", url);
ajax.send();
});
const getJSON = url => ajaxByUrlAndType(url, "json");
const getText = url => ajaxByUrlAndType(url, "text");
const getImg = url => new Promise((s, f) => {
const img = new Image();
img.onload = function() { this.uri = url; s(this); };
img.onerror = f;
img.src = url;
});
const getFilename = url => {
let [filename, filenameNoExt, fileExtension] = url.match(/([^\\\/<>|:"*?]+)\.(\w+$)/);
return [filename || "", filenameNoExt || "", fileExtension || ""];
};
const RESOURCES = {};
import { edm } from "./EventDispatcher.js";
const RESLoadEventDispatcher = edm.getOrNewEventDispatcher("mc.load");
const awaitResCallbacks = {};
const newAwaitRes = url => {
let promise = new Promise((resolve, reject) => {
if (url in RESOURCES) resolve(RESOURCES[url]);
else if (url in awaitResCallbacks)
awaitResCallbacks[url].push({resolve, reject});
else awaitResCallbacks[url] = [{resolve, reject}];
});
RESLoadEventDispatcher.dispatchEvent("newAwaitRes", url, promise);
return promise;
};
const notifyAllAwaitRes = (url, val, {
status = "resolve",
type = ""
} = {}) => {
if (status === "resolve") RESOURCES[url] = val;
if (url in awaitResCallbacks) {
awaitResCallbacks[url].forEach(o => o[status](val, status, url, type));
if (status === "resolve") delete awaitResCallbacks[url];
}
};
const setResource = (key, val) => notifyAllAwaitRes(key, val);
const waitResource = key => newAwaitRes(key);
const asyncLoadResByUrl = (url, {
type = {
png: "img",
json: "json",
}[getFilename(url)[2].toLowerCase()] || "text",
} = {}) => {
// console.log(url);
if (url in RESOURCES) return Promise.resolve(RESOURCES[url]);
let handles = [
res => notifyAllAwaitRes(url, res, { type }),
err => notifyAllAwaitRes(url, err, { type, status: "reject" })
];
if (url in awaitResCallbacks)
return newAwaitRes(url);
else if (type === "img" || type === "png")
getImg(url).then(...handles);
else if (type === "json")
getJSON(url).then(...handles);
else if (type === "text")
getText(url).then(...handles);
return newAwaitRes(url);
};
export {
asyncLoadResByUrl as default,
asyncLoadResByUrl,
RESOURCES,
setResource, waitResource,
};