laya-coreui-es
Version:
laya核心库、ui库es版本,剔除了媒体、TTF等功能。基于 LayaAir-release_2.12.0 修改
587 lines (586 loc) • 22.9 kB
JavaScript
import { ILaya } from "../../ILaya";
import { Text } from "../display/Text";
import { Event } from "../events/Event";
import { EventDispatcher } from "../events/EventDispatcher";
import { Texture } from "../resource/Texture";
import { Texture2D } from "../resource/Texture2D";
import { Browser } from "../utils/Browser";
import { Byte } from "../utils/Byte";
import { Handler } from "../utils/Handler";
import { Utils } from "../utils/Utils";
import { BitmapFont } from "./../display/BitmapFont";
import { HttpRequest } from "./HttpRequest";
import { URL } from "./URL";
import { TextureFormat } from "../resource/TextureFormat";
import { WarpMode } from "../resource/WrapMode";
export class Loader extends EventDispatcher {
constructor() {
super(...arguments);
this._customParse = false;
}
static getTypeFromUrl(url) {
var type = Utils.getFileExtension(url);
if (type)
return Loader.typeMap[type];
console.warn("Not recognize the resources suffix", url);
return "text";
}
load(url, type = null, cache = true, group = null, ignoreCache = false, useWorkerLoader = ILaya.WorkerLoader.enable) {
if (!url) {
this.onLoaded(null);
return;
}
Loader.setGroup(url, "666");
this._url = url;
if (url.indexOf("data:image") === 0 && !type)
type = Loader.IMAGE;
else
url = URL.formatURL(url);
this._type = type || (type = Loader.getTypeFromUrl(this._url));
this._cache = cache;
this._useWorkerLoader = useWorkerLoader;
this._data = null;
if (useWorkerLoader)
ILaya.WorkerLoader.enableWorkerLoader();
var cacheRes;
if (type == Loader.IMAGE) {
cacheRes = Loader.textureMap[url];
if (cacheRes && cacheRes.bitmap && cacheRes.bitmap.destroyed) {
cacheRes = null;
}
}
else
cacheRes = Loader.loadedMap[url];
if (!ignoreCache && cacheRes) {
this._data = cacheRes;
this.event(Event.PROGRESS, 1);
this.event(Event.COMPLETE, this._data);
return;
}
if (group)
Loader.setGroup(url, group);
if (Loader.parserMap[type] != null) {
this._customParse = true;
if (Loader.parserMap[type] instanceof Handler)
Loader.parserMap[type].runWith(this);
else
Loader.parserMap[type].call(null, this);
return;
}
this._loadResourceFilter(type, url);
}
_loadResourceFilter(type, url) {
this._loadResource(type, url);
}
_loadResource(type, url) {
switch (type) {
case Loader.IMAGE:
case "htmlimage":
case "nativeimage":
this._loadImage(url);
break;
case Loader.ATLAS:
case Loader.PREFAB:
case Loader.PLF:
this._loadHttpRequestWhat(url, Loader.JSON);
break;
case Loader.FONT:
this._loadHttpRequestWhat(url, Loader.XML);
break;
case Loader.PLFB:
this._loadHttpRequestWhat(url, Loader.BUFFER);
break;
default:
this._loadHttpRequestWhat(url, type);
}
}
_loadHttpRequest(url, contentType, onLoadCaller, onLoad, onProcessCaller, onProcess, onErrorCaller, onError) {
if (Browser.onVVMiniGame || Browser.onHWMiniGame) {
this._http = new HttpRequest();
}
else {
if (!this._http)
this._http = new HttpRequest();
}
onProcess && this._http.on(Event.PROGRESS, onProcessCaller, onProcess);
onLoad && this._http.on(Event.COMPLETE, onLoadCaller, onLoad);
this._http.on(Event.ERROR, onErrorCaller, onError);
this._http.send(url, null, "get", contentType);
}
_loadHtmlImage(url, onLoadCaller, onLoad, onErrorCaller, onError) {
var image;
function clear() {
var img = image;
img.onload = null;
img.onerror = null;
delete Loader._imgCache[url];
}
var onerror = function () {
clear();
onError.call(onErrorCaller);
};
var onload = function () {
clear();
onLoad.call(onLoadCaller, image);
};
image = new Browser.window.Image();
image.crossOrigin = "";
image.onload = onload;
image.onerror = onerror;
image.src = url;
Loader._imgCache[url] = image;
}
_loadHttpRequestWhat(url, contentType) {
if (Loader.preLoadedMap[url])
this.onLoaded(Loader.preLoadedMap[url]);
else
this._loadHttpRequest(url, contentType, this, this.onLoaded, this, this.onProgress, this, this.onError);
}
_loadImage(url, isformatURL = true) {
var _this = this;
if (isformatURL)
url = URL.formatURL(url);
var onError = function () {
_this.event(Event.ERROR, "Load image failed");
};
if (this._type === "nativeimage") {
this._loadHtmlImage(url, this, this.onLoaded, this, onError);
}
else {
var ext = Utils.getFileExtension(url);
if (ext == 'bin' && this._url) {
ext = Utils.getFileExtension(this._url);
}
if (ext === "ktx" || ext === "pvr")
this._loadHttpRequest(url, Loader.BUFFER, this, this.onLoaded, this, this.onProgress, this, this.onError);
else
this._loadHtmlImage(url, this, this.onLoaded, this, onError);
}
}
onProgress(value) {
if (this._type === Loader.ATLAS)
this.event(Event.PROGRESS, value * 0.3);
else if (this._originType == Loader.HIERARCHY)
this.event(Event.PROGRESS, value / 3);
else
this.event(Event.PROGRESS, value);
}
onError(message) {
this.event(Event.ERROR, message);
}
onLoaded(data = null) {
var type = this._type;
if (type == Loader.PLFB) {
this.parsePLFBData(data);
this.complete(data);
}
else if (type == Loader.PLF) {
this.parsePLFData(data);
this.complete(data);
}
else if (type === Loader.IMAGE) {
let tex;
if (data instanceof ArrayBuffer) {
var ext = Utils.getFileExtension(this._url);
let format;
switch (ext) {
case "ktx":
format = TextureFormat.ETC1RGB;
break;
case "pvr":
format = TextureFormat.PVRTCRGBA_4BPPV;
break;
default: {
console.error('unknown format', ext);
return;
}
}
tex = new Texture2D(0, 0, format, false, false);
tex.wrapModeU = WarpMode.Clamp;
tex.wrapModeV = WarpMode.Clamp;
tex.setCompressData(data);
tex._setCreateURL(this.url);
}
else if (!(data instanceof Texture2D)) {
tex = new Texture2D(data.width, data.height, 1, false, false);
tex.wrapModeU = WarpMode.Clamp;
tex.wrapModeV = WarpMode.Clamp;
tex.loadImageSource(data, true);
tex._setCreateURL(data.src);
}
else {
tex = data;
}
var texture = new Texture(tex);
texture.url = this._url;
this.complete(texture);
}
else if (type === Loader.SOUND || type === "nativeimage") {
this.complete(data);
}
else if (type === "htmlimage") {
let tex = new Texture2D(data.width, data.height, 1, false, false);
tex.wrapModeU = WarpMode.Clamp;
tex.wrapModeV = WarpMode.Clamp;
tex.loadImageSource(data, true);
tex._setCreateURL(data.src);
this.complete(tex);
}
else if (type === Loader.ATLAS) {
if (data.frames) {
var toloadPics = [];
if (!this._data) {
this._data = data;
if (data.meta && data.meta.image) {
toloadPics = data.meta.image.split(",");
var split = this._url.indexOf("/") >= 0 ? "/" : "\\";
var idx = this._url.lastIndexOf(split);
var folderPath = idx >= 0 ? this._url.substr(0, idx + 1) : "";
var changeType = null;
if (Browser.onAndroid && data.meta.compressTextureAndroid) {
changeType = ".ktx";
}
if (Browser.onIOS && data.meta.compressTextureIOS) {
if (data.meta.astc) {
changeType = ".ktx";
}
else {
changeType = ".pvr";
}
}
for (var i = 0, len = toloadPics.length; i < len; i++) {
if (changeType) {
toloadPics[i] = folderPath + toloadPics[i].replace(".png", changeType);
}
else {
toloadPics[i] = folderPath + toloadPics[i];
}
}
}
else {
toloadPics = [this._url.replace(".json", ".png")];
}
toloadPics.reverse();
data.toLoads = toloadPics;
data.pics = [];
}
this.event(Event.PROGRESS, 0.3 + 1 / toloadPics.length * 0.6);
var url = URL.formatURL(toloadPics.pop());
var ext = Utils.getFileExtension(url);
var type = Loader.IMAGE;
if (ext == "pvr" || ext == "ktx") {
type = Loader.BUFFER;
}
return this._loadResourceFilter(type, url);
}
else {
if (!(data instanceof Texture2D)) {
if (data instanceof ArrayBuffer) {
let url = this._http ? this._http.url : this._url;
var ext = Utils.getFileExtension(url);
let format;
switch (ext) {
case "ktx":
format = TextureFormat.ETC1RGB;
break;
case "pvr":
format = TextureFormat.PVRTCRGBA_4BPPV;
break;
default: {
console.error('unknown format', ext);
return;
}
}
let tex = new Texture2D(0, 0, format, false, false);
tex.wrapModeU = WarpMode.Clamp;
tex.wrapModeV = WarpMode.Clamp;
tex.setCompressData(data);
tex._setCreateURL(url);
data = tex;
}
else {
let tex = new Texture2D(data.width, data.height, 1, false, false);
tex.wrapModeU = WarpMode.Clamp;
tex.wrapModeV = WarpMode.Clamp;
tex.loadImageSource(data, true);
tex._setCreateURL(data.src);
data = tex;
}
}
this._data.pics.push(data);
if (this._data.toLoads.length > 0) {
this.event(Event.PROGRESS, 0.3 + 1 / this._data.toLoads.length * 0.6);
var url = URL.formatURL(this._data.toLoads.pop());
var ext = Utils.getFileExtension(url);
var type = Loader.IMAGE;
if (ext == "pvr" || ext == "ktx") {
type = Loader.BUFFER;
}
return this._loadResourceFilter(type, url);
}
var frames = this._data.frames;
var cleanUrl = this._url.split("?")[0];
var directory = (this._data.meta && this._data.meta.prefix) ? this._data.meta.prefix : cleanUrl.substring(0, cleanUrl.lastIndexOf(".")) + "/";
var pics = this._data.pics;
var atlasURL = URL.formatURL(this._url);
var map = Loader.atlasMap[atlasURL] || (Loader.atlasMap[atlasURL] = []);
map.dir = directory;
var scaleRate = 1;
if (this._data.meta && this._data.meta.scale && this._data.meta.scale != 1) {
scaleRate = parseFloat(this._data.meta.scale);
for (var name in frames) {
var obj = frames[name];
var tPic = pics[obj.frame.idx ? obj.frame.idx : 0];
var url = URL.formatURL(directory + name);
tPic.scaleRate = scaleRate;
var tTexture;
tTexture = Texture._create(tPic, obj.frame.x, obj.frame.y, obj.frame.w, obj.frame.h, obj.spriteSourceSize.x, obj.spriteSourceSize.y, obj.sourceSize.w, obj.sourceSize.h, Loader.getRes(url));
Loader.cacheTexture(url, tTexture);
tTexture.url = url;
map.push(url);
}
}
else {
for (name in frames) {
obj = frames[name];
tPic = pics[obj.frame.idx ? obj.frame.idx : 0];
url = URL.formatURL(directory + name);
tTexture = Texture._create(tPic, obj.frame.x, obj.frame.y, obj.frame.w, obj.frame.h, obj.spriteSourceSize.x, obj.spriteSourceSize.y, obj.sourceSize.w, obj.sourceSize.h, Loader.getRes(url));
Loader.cacheTexture(url, tTexture);
tTexture.url = url;
map.push(url);
}
}
delete this._data.pics;
this.complete(this._data);
}
}
else if (type === Loader.FONT) {
if (!data._source) {
this._data = data;
this.event(Event.PROGRESS, 0.5);
return this._loadResourceFilter(Loader.IMAGE, this._url.replace(".fnt", ".png"));
}
else {
var bFont = new BitmapFont();
bFont.parseFont(this._data, new Texture(data));
var tArr = this._url.split(".fnt")[0].split("/");
var fontName = tArr[tArr.length - 1];
Text.registerBitmapFont(fontName, bFont);
this._data = bFont;
this.complete(this._data);
}
}
else {
this.complete(data);
}
}
parsePLFData(plfData) {
var type;
var filePath;
var fileDic;
for (type in plfData) {
fileDic = plfData[type];
switch (type) {
case "json":
case "text":
for (filePath in fileDic) {
Loader.preLoadedMap[URL.formatURL(filePath)] = fileDic[filePath];
}
break;
default:
for (filePath in fileDic) {
Loader.preLoadedMap[URL.formatURL(filePath)] = fileDic[filePath];
}
}
}
}
parsePLFBData(plfData) {
var byte;
byte = new Byte(plfData);
var i, len;
len = byte.getInt32();
for (i = 0; i < len; i++) {
this.parseOnePLFBFile(byte);
}
}
parseOnePLFBFile(byte) {
var fileLen;
var fileName;
var fileData;
fileName = byte.getUTFString();
fileLen = byte.getInt32();
fileData = byte.readArrayBuffer(fileLen);
Loader.preLoadedMap[URL.formatURL(fileName)] = fileData;
}
complete(data) {
this._data = data;
if (this._customParse) {
this.event(Event.LOADED, data instanceof Array ? [data] : data);
}
else {
Loader._loaders.push(this);
if (!Loader._isWorking)
Loader.checkNext();
}
}
static checkNext() {
Loader._isWorking = true;
var startTimer = Browser.now();
while (Loader._startIndex < Loader._loaders.length) {
Loader._loaders[Loader._startIndex].endLoad();
Loader._startIndex++;
if (Browser.now() - startTimer > Loader.maxTimeOut) {
console.warn("loader callback cost a long time:" + (Browser.now() - startTimer) + " url=" + Loader._loaders[Loader._startIndex - 1].url);
ILaya.systemTimer.frameOnce(1, null, Loader.checkNext);
return;
}
}
Loader._loaders.length = 0;
Loader._startIndex = 0;
Loader._isWorking = false;
}
endLoad(content = null) {
content && (this._data = content);
if (this._cache)
Loader.cacheRes(this._url, this._data);
this.event(Event.PROGRESS, 1);
this.event(Event.COMPLETE, this.data instanceof Array ? [this.data] : this.data);
}
get url() {
return this._url;
}
get type() {
return this._type;
}
get cache() {
return this._cache;
}
get data() {
return this._data;
}
static clearRes(url) {
url = URL.formatURL(url);
var arr = Loader.getAtlas(url);
if (arr) {
for (var i = 0, n = arr.length; i < n; i++) {
var resUrl = arr[i];
var tex = Loader.getRes(resUrl);
delete Loader.textureMap[resUrl];
if (tex)
tex.destroy();
}
arr.length = 0;
delete Loader.atlasMap[url];
}
var texture = Loader.textureMap[url];
if (texture) {
texture.destroy();
delete Loader.textureMap[url];
}
var res = Loader.loadedMap[url];
(res) && (delete Loader.loadedMap[url]);
}
static clearTextureRes(url) {
url = URL.formatURL(url);
var arr = Loader.getAtlas(url);
if (arr && arr.length > 0) {
arr.forEach(function (t) {
var tex = Loader.getRes(t);
if (tex instanceof Texture) {
tex.disposeBitmap();
}
});
}
else {
var t = Loader.getRes(url);
if (t instanceof Texture) {
t.disposeBitmap();
}
}
}
static getRes(url) {
var res = Loader.textureMap[URL.formatURL(url)];
if (res)
return res;
else
return Loader.loadedMap[URL.formatURL(url)];
}
static getAtlas(url) {
return Loader.atlasMap[URL.formatURL(url)];
}
static cacheRes(url, data) {
url = URL.formatURL(url);
if (Loader.loadedMap[url] != null) {
console.warn("Resources already exist,is repeated loading:", url);
}
else {
if (data instanceof Texture) {
Loader.loadedMap[url] = data.bitmap;
Loader.textureMap[url] = data;
}
else {
Loader.loadedMap[url] = data;
}
}
}
static cacheResForce(url, data) {
Loader.loadedMap[url] = data;
}
static cacheTexture(url, data) {
url = URL.formatURL(url);
if (Loader.textureMap[url] != null) {
console.warn("Resources already exist,is repeated loading:", url);
}
else {
Loader.textureMap[url] = data;
}
}
static setGroup(url, group) {
if (!Loader.groupMap[group])
Loader.groupMap[group] = [];
Loader.groupMap[group].push(url);
}
static clearResByGroup(group) {
if (!Loader.groupMap[group])
return;
var arr = Loader.groupMap[group], i, len = arr.length;
for (i = 0; i < len; i++) {
Loader.clearRes(arr[i]);
}
arr.length = 0;
}
}
Loader.TEXT = "text";
Loader.JSON = "json";
Loader.PREFAB = "prefab";
Loader.XML = "xml";
Loader.BUFFER = "arraybuffer";
Loader.IMAGE = "image";
Loader.SOUND = "sound";
Loader.ATLAS = "atlas";
Loader.FONT = "font";
Loader.TTF = "ttf";
Loader.PLF = "plf";
Loader.PLFB = "plfb";
Loader.HIERARCHY = "HIERARCHY";
Loader.MESH = "MESH";
Loader.MATERIAL = "MATERIAL";
Loader.TEXTURE2D = "TEXTURE2D";
Loader.TEXTURECUBE = "TEXTURECUBE";
Loader.ANIMATIONCLIP = "ANIMATIONCLIP";
Loader.AVATAR = "AVATAR";
Loader.TERRAINHEIGHTDATA = "TERRAINHEIGHTDATA";
Loader.TERRAINRES = "TERRAIN";
Loader.typeMap = { "ttf": "ttf", "png": "image", "jpg": "image", "jpeg": "image", "ktx": "image", "pvr": "image", "txt": "text", "json": "json", "prefab": "prefab", "xml": "xml", "als": "atlas", "atlas": "atlas", "mp3": "sound", "ogg": "sound", "wav": "sound", "part": "json", "fnt": "font", "plf": "plf", "plfb": "plfb", "scene": "json", "ani": "json", "sk": "arraybuffer", "wasm": "arraybuffer" };
Loader.parserMap = {};
Loader.maxTimeOut = 100;
Loader.groupMap = {};
Loader.loadedMap = {};
Loader.atlasMap = {};
Loader.textureMap = {};
Loader.preLoadedMap = {};
Loader._imgCache = {};
Loader._loaders = [];
Loader._isWorking = false;
Loader._startIndex = 0;