dragonbones-runtime
Version:
the tools to build dragonbones file for diffrent framework
266 lines (245 loc) • 9.73 kB
text/typescript
//////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2014-present, Egret Technology.
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Egret nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////////////
/// <reference path="EXMLParser.ts" />
namespace EXML {
let parser = new eui.sys.EXMLParser();
let requestPool: egret.HttpRequest[] = [];
let callBackMap: any = {};
let parsedClasses: any = {};
let $prefixURL: string = "";
/**
* Set a prefix url.
* The prefix url will add to the front of the Exml file path when it’s loading.
* @param text the text of a EXML file.
*
* @version Egret 2.5.3
* @version eui 1.0
* @platform Web,Native
* @language en_US
*/
/**
* 设置 EXML 文件加载的根路径。
* 设置后,再加载 EXML 文件时会自动把根路径加到文件路径前面
* @version Egret 2.5.3
* @version eui 1.0
* @platform Web,Native
* @language zh_CN
*/
export let prefixURL: string;
Object.defineProperty(EXML, "prefixURL", {
get: function (): string { return $prefixURL },
set: function (value: string) { $prefixURL = value },
enumerable: true,
configurable: true
});
/**
* Parsing a text of EXML file for a definition of class. You can declare the <code>class</code> property in the root
* node of the EXML to register to the global as a class name.
*
* It will be fail to register and output a warning if the specified name already exists. You can get a definition
* of a class through <code>egret.getDefinitionByName(className)</code>.
*
* @param text the text of a EXML file.
*
* @version Egret 2.4
* @version eui 1.0
* @platform Web,Native
* @language en_US
*/
/**
* 解析一个 EXML 文件的文本内容为一个类定义。您可以在 EXML 文件的根节点上声明 class 属性作为要注册到全局的类名。
* 若指定的类名已经存在,将会注册失败,并输出一个警告。注册成功后,您也可以通过 egret.getDefinitionByName(className) 方法获取这个 EXML 文件对应的类定义。
*
* @param text 要解析的 EXML 文件内容。
*
* @version Egret 2.4
* @version eui 1.0
* @platform Web,Native
* @language zh_CN
*/
export function parse(text: string): { new (): any } {
return parser.parse(text);
}
/**
* Load and parse an external EXML file for a class definition. You can declare the <code>class</code> property in the root
* node of the EXML to register to the global as a class name.
*
* It will be fail to register and output a warning if the specified name already exists. You can get a definition
* of a class through <code>egret.getDefinitionByName(className)</code>.
*
* @param url the path of an EXML file
* @param callBack method to invoke with an argument of the result when load and parse completed or failed. The argument will be
* <code>undefined</code> if load or parse failed.
* @param thisObject <code>this</code> object of callBack
* @param useCache use cached EXML
*
* @version Egret 2.4
* @version eui 1.0
* @platform Web,Native
* @language en_US
*/
/**
* 加载并解析一个外部的 EXML 文件为一个类定义。您可以在 EXML 文件的根节点上声明 class 属性作为要注册到全局的类名。
* 若指定的类名已经存在,将会注册失败,并输出一个警告。注册成功后,您也可以通过 egret.getDefinitionByName(className) 方法获取这个 EXML 文件对应的类定义。
*
* @param url 要加载的 EXML 文件路径
* @param callBack 加载并解析完成后的回调函数,无论加载成功还是失败,此函数均会被回调。失败时将传入 undefined 作为回调函数参数。
* @param thisObject 回调函数的 this 引用。
* @param useCache 使用缓存的EXML
*
* @version Egret 2.4
* @version eui 1.0
* @platform Web,Native
* @language zh_CN
*/
export function load(url: string, callBack?: (clazz: any, url: string) => void, thisObject?: any, useCache = false): void {
if (DEBUG) {
if (!url) {
egret.$error(1003, "url");
}
}
if (useCache && (url in parsedClasses)) {
callBack && callBack.call(thisObject, parsedClasses[url], url);
return;
}
let list = callBackMap[url];
if (list) {
list.push([callBack, thisObject]);
return;
}
callBackMap[url] = [[callBack, thisObject]];
request(url, $parseURLContent);
}
/**
* @private
*/
export function $loadAll(urls: string[], callBack?: (clazz: any[], url: string[]) => void, thisObject?: any, useCache = false): void {
if (!urls || urls.length == 0) {
callBack && callBack.call(thisObject, [], urls);
return;
}
let exmlContents: string[] = [];
urls.forEach(url => {
let loaded = (url: string, text: string) => {
exmlContents[url] = text;
exmlContents.push(url);
if (exmlContents.length == urls.length)
onLoadAllFinished(urls, exmlContents, callBack, thisObject);
};
if (useCache && (url in parsedClasses)) {
loaded(url, "");
return;
}
request(url, loaded);
});
}
/**
* @private
*/
function onLoadAllFinished(urls: string[], exmlContents: any, callBack?: (clazz: any[], url: string[]) => void, thisObject?: any) {
let clazzes = [];
urls.forEach((url, i) => {
if ((url in parsedClasses) && !exmlContents[url]) {
clazzes[i] = parsedClasses[url];
return;
}
let text = exmlContents[url];
let clazz = $parseURLContent(url, text);
clazzes[i] = clazz;
});
callBack && callBack.call(thisObject, clazzes, urls);
}
/**
* @private
* @param url
* @param text
*/
export function $parseURLContentAsJs(url: string, text: string, className: string): any {
let clazz: any = null;
if (text) {
clazz = parser.$parseCode(text, className);
}
if (url) {
parsedClasses[url] = clazz;
let list: any[] = callBackMap[url];
delete callBackMap[url];
let length = list ? list.length : 0;
for (let i = 0; i < length; i++) {
let arr = list[i];
if (arr[0] && arr[1])
arr[0].call(arr[1], clazz, url);
}
}
return clazz;
}
/**
* @private
*/
export function $parseURLContent(url: string, text: string): any {
let clazz: any = null;
if (text) {
try {
clazz = parse(text);
}
catch (e) {
console.error(url + "\n" + e.message)
}
}
if (url) {
if(clazz) {
parsedClasses[url] = clazz;
}
let list: any[] = callBackMap[url];
delete callBackMap[url];
let length = list ? list.length : 0;
for (let i = 0; i < length; i++) {
let arr = list[i];
if (arr[0] && arr[1])
arr[0].call(arr[1], clazz, url);
}
}
return clazz;
}
/**
* @private
*/
function request(url: string, callback: (url: string, text: string) => void) {
let openUrl = url;
if (url.indexOf("://") == -1) {
openUrl = $prefixURL + url;
}
let onConfigLoaded = function (str: string) {
if (!str) {
str = "";
}
callback(url, str);
};
eui.getTheme(openUrl, onConfigLoaded);
}
}