mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2025-09-24 08:50:16 +00:00
初始化
This commit is contained in:
184
engine/cocos2d/core/utils/CCPath.js
Normal file
184
engine/cocos2d/core/utils/CCPath.js
Normal file
@@ -0,0 +1,184 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
require('../platform/CCSys');
|
||||
|
||||
var EXTNAME_RE = /(\.[^\.\/\?\\]*)(\?.*)?$/;
|
||||
var DIRNAME_RE = /((.*)(\/|\\|\\\\))?(.*?\..*$)?/;
|
||||
var NORMALIZE_RE = /[^\.\/]+\/\.\.\//;
|
||||
|
||||
/**
|
||||
* !#en The module provides utilities for working with file and directory paths
|
||||
* !#zh 用于处理文件与目录的路径的模块
|
||||
* @class path
|
||||
* @static
|
||||
*/
|
||||
cc.path = /** @lends cc.path# */{
|
||||
/**
|
||||
* !#en Join strings to be a path.
|
||||
* !#zh 拼接字符串为 Path
|
||||
* @method join
|
||||
* @example {@link cocos2d/core/utils/CCPath/join.js}
|
||||
* @returns {String}
|
||||
*/
|
||||
join: function () {
|
||||
var l = arguments.length;
|
||||
var result = "";
|
||||
for (var i = 0; i < l; i++) {
|
||||
result = (result + (result === "" ? "" : "/") + arguments[i]).replace(/(\/|\\\\)$/, "");
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en Get the ext name of a path including '.', like '.png'.
|
||||
* !#zh 返回 Path 的扩展名,包括 '.',例如 '.png'。
|
||||
* @method extname
|
||||
* @example {@link cocos2d/core/utils/CCPath/extname.js}
|
||||
* @param {String} pathStr
|
||||
* @returns {*}
|
||||
*/
|
||||
extname: function (pathStr) {
|
||||
var temp = EXTNAME_RE.exec(pathStr);
|
||||
return temp ? temp[1] : '';
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en Get the main name of a file name
|
||||
* !#zh 获取文件名的主名称
|
||||
* @method mainFileName
|
||||
* @param {String} fileName
|
||||
* @returns {String}
|
||||
* @deprecated
|
||||
*/
|
||||
mainFileName: function (fileName) {
|
||||
if (fileName) {
|
||||
var idx = fileName.lastIndexOf(".");
|
||||
if (idx !== -1)
|
||||
return fileName.substring(0, idx);
|
||||
}
|
||||
return fileName;
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en Get the file name of a file path.
|
||||
* !#zh 获取文件路径的文件名。
|
||||
* @method basename
|
||||
* @example {@link cocos2d/core/utils/CCPath/basename.js}
|
||||
* @param {String} pathStr
|
||||
* @param {String} [extname]
|
||||
* @returns {*}
|
||||
*/
|
||||
basename: function (pathStr, extname) {
|
||||
var index = pathStr.indexOf("?");
|
||||
if (index > 0) pathStr = pathStr.substring(0, index);
|
||||
var reg = /(\/|\\)([^\/\\]+)$/g;
|
||||
var result = reg.exec(pathStr.replace(/(\/|\\)$/, ""));
|
||||
if (!result) return pathStr;
|
||||
var baseName = result[2];
|
||||
if (extname && pathStr.substring(pathStr.length - extname.length).toLowerCase() === extname.toLowerCase())
|
||||
return baseName.substring(0, baseName.length - extname.length);
|
||||
return baseName;
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en Get dirname of a file path.
|
||||
* !#zh 获取文件路径的目录名。
|
||||
* @method dirname
|
||||
* @example {@link cocos2d/core/utils/CCPath/dirname.js}
|
||||
* @param {String} pathStr
|
||||
* @returns {*}
|
||||
*/
|
||||
dirname: function (pathStr) {
|
||||
var temp = DIRNAME_RE.exec(pathStr);
|
||||
return temp ? temp[2] : '';
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en Change extname of a file path.
|
||||
* !#zh 更改文件路径的扩展名。
|
||||
* @method changeExtname
|
||||
* @example {@link cocos2d/core/utils/CCPath/changeExtname.js}
|
||||
* @param {String} pathStr
|
||||
* @param {String} [extname]
|
||||
* @returns {String}
|
||||
*/
|
||||
changeExtname: function (pathStr, extname) {
|
||||
extname = extname || "";
|
||||
var index = pathStr.indexOf("?");
|
||||
var tempStr = "";
|
||||
if (index > 0) {
|
||||
tempStr = pathStr.substring(index);
|
||||
pathStr = pathStr.substring(0, index);
|
||||
}
|
||||
index = pathStr.lastIndexOf(".");
|
||||
if (index < 0) return pathStr + extname + tempStr;
|
||||
return pathStr.substring(0, index) + extname + tempStr;
|
||||
},
|
||||
/**
|
||||
* !#en Change file name of a file path.
|
||||
* !#zh 更改文件路径的文件名。
|
||||
* @example {@link cocos2d/core/utils/CCPath/changeBasename.js}
|
||||
* @param {String} pathStr
|
||||
* @param {String} basename
|
||||
* @param {Boolean} [isSameExt]
|
||||
* @returns {String}
|
||||
*/
|
||||
changeBasename: function (pathStr, basename, isSameExt) {
|
||||
if (basename.indexOf(".") === 0) return this.changeExtname(pathStr, basename);
|
||||
var index = pathStr.indexOf("?");
|
||||
var tempStr = "";
|
||||
var ext = isSameExt ? this.extname(pathStr) : "";
|
||||
if (index > 0) {
|
||||
tempStr = pathStr.substring(index);
|
||||
pathStr = pathStr.substring(0, index);
|
||||
}
|
||||
index = pathStr.lastIndexOf("/");
|
||||
index = index <= 0 ? 0 : index + 1;
|
||||
return pathStr.substring(0, index) + basename + ext + tempStr;
|
||||
},
|
||||
//todo make public after verification
|
||||
_normalize: function (url) {
|
||||
var oldUrl = url = String(url);
|
||||
|
||||
//removing all ../
|
||||
do {
|
||||
oldUrl = url;
|
||||
url = url.replace(NORMALIZE_RE, "");
|
||||
} while (oldUrl.length !== url.length);
|
||||
return url;
|
||||
},
|
||||
|
||||
// The platform-specific file separator. '\\' or '/'.
|
||||
sep: (cc.sys.os === cc.sys.OS_WINDOWS ? '\\' : '/'),
|
||||
|
||||
// @param {string} path
|
||||
stripSep (path) {
|
||||
return path.replace(/[\/\\]$/, '');
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = cc.path;
|
287
engine/cocos2d/core/utils/affine-transform.js
Normal file
287
engine/cocos2d/core/utils/affine-transform.js
Normal file
@@ -0,0 +1,287 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2008-2010 Ricardo Quesada
|
||||
Copyright (c) 2011-2012 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* AffineTransform class represent an affine transform matrix. It's composed basically by translation, rotation, scale transformations.<br/>
|
||||
* !#zh
|
||||
* AffineTransform 类代表一个仿射变换矩阵。它基本上是由平移旋转,缩放转变所组成。<br/>
|
||||
* @class AffineTransform
|
||||
* @constructor
|
||||
* @param {Number} a
|
||||
* @param {Number} b
|
||||
* @param {Number} c
|
||||
* @param {Number} d
|
||||
* @param {Number} tx
|
||||
* @param {Number} ty
|
||||
* @see AffineTransform.create
|
||||
*/
|
||||
var AffineTransform = function (a, b, c, d, tx, ty) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.c = c;
|
||||
this.d = d;
|
||||
this.tx = tx;
|
||||
this.ty = ty;
|
||||
};
|
||||
|
||||
/**
|
||||
* !#en Create a AffineTransform object with all contents in the matrix.
|
||||
* !#zh 用在矩阵中的所有内容创建一个 AffineTransform 对象。
|
||||
* @method create
|
||||
* @static
|
||||
* @param {Number} a
|
||||
* @param {Number} b
|
||||
* @param {Number} c
|
||||
* @param {Number} d
|
||||
* @param {Number} tx
|
||||
* @param {Number} ty
|
||||
* @return {AffineTransform}
|
||||
*/
|
||||
AffineTransform.create = function (a, b, c, d, tx, ty) {
|
||||
return {a: a, b: b, c: c, d: d, tx: tx, ty: ty};
|
||||
};
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Create a identity transformation matrix: <br/>
|
||||
* [ 1, 0, 0, <br/>
|
||||
* 0, 1, 0 ]
|
||||
* !#zh
|
||||
* 单位矩阵:<br/>
|
||||
* [ 1, 0, 0, <br/>
|
||||
* 0, 1, 0 ]
|
||||
*
|
||||
* @method identity
|
||||
* @static
|
||||
* @return {AffineTransform}
|
||||
*/
|
||||
AffineTransform.identity = function () {
|
||||
return {a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 0.0, ty: 0.0};
|
||||
};
|
||||
|
||||
/**
|
||||
* !#en Clone a AffineTransform object from the specified transform.
|
||||
* !#zh 克隆指定的 AffineTransform 对象。
|
||||
* @method clone
|
||||
* @static
|
||||
* @param {AffineTransform} t
|
||||
* @return {AffineTransform}
|
||||
*/
|
||||
AffineTransform.clone = function (t) {
|
||||
return {a: t.a, b: t.b, c: t.c, d: t.d, tx: t.tx, ty: t.ty};
|
||||
};
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Concatenate a transform matrix to another
|
||||
* The results are reflected in the out affine transform
|
||||
* out = t1 * t2
|
||||
* This function is memory free, you should create the output affine transform by yourself and manage its memory.
|
||||
* !#zh
|
||||
* 拼接两个矩阵,将结果保存到 out 矩阵。这个函数不创建任何内存,你需要先创建 AffineTransform 对象用来存储结果,并作为第一个参数传入函数。
|
||||
* out = t1 * t2
|
||||
* @method concat
|
||||
* @static
|
||||
* @param {AffineTransform} out Out object to store the concat result
|
||||
* @param {AffineTransform} t1 The first transform object.
|
||||
* @param {AffineTransform} t2 The transform object to concatenate.
|
||||
* @return {AffineTransform} Out object with the result of concatenation.
|
||||
*/
|
||||
AffineTransform.concat = function (out, t1, t2) {
|
||||
var a = t1.a, b = t1.b, c = t1.c, d = t1.d, tx = t1.tx, ty = t1.ty;
|
||||
out.a = a * t2.a + b * t2.c;
|
||||
out.b = a * t2.b + b * t2.d;
|
||||
out.c = c * t2.a + d * t2.c;
|
||||
out.d = c * t2.b + d * t2.d;
|
||||
out.tx = tx * t2.a + ty * t2.c + t2.tx;
|
||||
out.ty = tx * t2.b + ty * t2.d + t2.ty;
|
||||
return out;
|
||||
};
|
||||
|
||||
/**
|
||||
* !#en Get the invert transform of an AffineTransform object.
|
||||
* This function is memory free, you should create the output affine transform by yourself and manage its memory.
|
||||
* !#zh 求逆矩阵。这个函数不创建任何内存,你需要先创建 AffineTransform 对象用来存储结果,并作为第一个参数传入函数。
|
||||
* @method invert
|
||||
* @static
|
||||
* @param {AffineTransform} out
|
||||
* @param {AffineTransform} t
|
||||
* @return {AffineTransform} Out object with inverted result.
|
||||
*/
|
||||
AffineTransform.invert = function (out, t) {
|
||||
var a = t.a, b = t.b, c = t.c, d = t.d;
|
||||
var determinant = 1 / (a * d - b * c);
|
||||
var tx = t.tx, ty = t.ty;
|
||||
out.a = determinant * d;
|
||||
out.b = -determinant * b;
|
||||
out.c = -determinant * c;
|
||||
out.d = determinant * a;
|
||||
out.tx = determinant * (c * ty - d * tx);
|
||||
out.ty = determinant * (b * tx - a * ty);
|
||||
return out;
|
||||
};
|
||||
|
||||
/**
|
||||
* !#en Get an AffineTransform object from a given matrix 4x4.
|
||||
* This function is memory free, you should create the output affine transform by yourself and manage its memory.
|
||||
* !#zh 从一个 4x4 Matrix 获取 AffineTransform 对象。这个函数不创建任何内存,你需要先创建 AffineTransform 对象用来存储结果,并作为第一个参数传入函数。
|
||||
* @method invert
|
||||
* @static
|
||||
* @param {AffineTransform} out
|
||||
* @param {Mat4} mat
|
||||
* @return {AffineTransform} Out object with inverted result.
|
||||
*/
|
||||
AffineTransform.fromMat4 = function (out, mat) {
|
||||
let matm = mat.m;
|
||||
out.a = matm[0];
|
||||
out.b = matm[1];
|
||||
out.c = matm[4];
|
||||
out.d = matm[5];
|
||||
out.tx = matm[12];
|
||||
out.ty = matm[13];
|
||||
return out;
|
||||
};
|
||||
|
||||
/**
|
||||
* !#en Apply the affine transformation on a point.
|
||||
* This function is memory free, you should create the output Vec2 by yourself and manage its memory.
|
||||
* !#zh 对一个点应用矩阵变换。这个函数不创建任何内存,你需要先创建一个 Vec2 对象用来存储结果,并作为第一个参数传入函数。
|
||||
* @method transformVec2
|
||||
* @static
|
||||
* @param {Vec2} out The output point to store the result
|
||||
* @param {Vec2|Number} point Point to apply transform or x.
|
||||
* @param {AffineTransform|Number} transOrY transform matrix or y.
|
||||
* @param {AffineTransform} [t] transform matrix.
|
||||
* @return {Vec2}
|
||||
*/
|
||||
AffineTransform.transformVec2 = function (out, point, transOrY, t) {
|
||||
var x, y;
|
||||
if (t === undefined) {
|
||||
t = transOrY;
|
||||
x = point.x;
|
||||
y = point.y;
|
||||
} else {
|
||||
x = point;
|
||||
y = transOrY;
|
||||
}
|
||||
out.x = t.a * x + t.c * y + t.tx;
|
||||
out.y = t.b * x + t.d * y + t.ty;
|
||||
return out;
|
||||
};
|
||||
|
||||
/**
|
||||
* !#en Apply the affine transformation on a size.
|
||||
* This function is memory free, you should create the output Size by yourself and manage its memory.
|
||||
* !#zh 应用仿射变换矩阵到 Size 上。这个函数不创建任何内存,你需要先创建一个 Size 对象用来存储结果,并作为第一个参数传入函数。
|
||||
* @method transformSize
|
||||
* @static
|
||||
* @param {Size} out The output point to store the result
|
||||
* @param {Size} size
|
||||
* @param {AffineTransform} t
|
||||
* @return {Size}
|
||||
*/
|
||||
AffineTransform.transformSize = function (out, size, t) {
|
||||
out.width = t.a * size.width + t.c * size.height;
|
||||
out.height = t.b * size.width + t.d * size.height;
|
||||
return out;
|
||||
};
|
||||
|
||||
/**
|
||||
* !#en Apply the affine transformation on a rect.
|
||||
* This function is memory free, you should create the output Rect by yourself and manage its memory.
|
||||
* !#zh 应用仿射变换矩阵到 Rect 上。这个函数不创建任何内存,你需要先创建一个 Rect 对象用来存储结果,并作为第一个参数传入函数。
|
||||
* @method transformRect
|
||||
* @static
|
||||
* @param {Rect} out
|
||||
* @param {Rect} rect
|
||||
* @param {AffineTransform} anAffineTransform
|
||||
* @return {Rect}
|
||||
*/
|
||||
AffineTransform.transformRect = function(out, rect, t){
|
||||
var ol = rect.x;
|
||||
var ob = rect.y;
|
||||
var or = ol + rect.width;
|
||||
var ot = ob + rect.height;
|
||||
var lbx = t.a * ol + t.c * ob + t.tx;
|
||||
var lby = t.b * ol + t.d * ob + t.ty;
|
||||
var rbx = t.a * or + t.c * ob + t.tx;
|
||||
var rby = t.b * or + t.d * ob + t.ty;
|
||||
var ltx = t.a * ol + t.c * ot + t.tx;
|
||||
var lty = t.b * ol + t.d * ot + t.ty;
|
||||
var rtx = t.a * or + t.c * ot + t.tx;
|
||||
var rty = t.b * or + t.d * ot + t.ty;
|
||||
|
||||
var minX = Math.min(lbx, rbx, ltx, rtx);
|
||||
var maxX = Math.max(lbx, rbx, ltx, rtx);
|
||||
var minY = Math.min(lby, rby, lty, rty);
|
||||
var maxY = Math.max(lby, rby, lty, rty);
|
||||
|
||||
out.x = minX;
|
||||
out.y = minY;
|
||||
out.width = maxX - minX;
|
||||
out.height = maxY - minY;
|
||||
return out;
|
||||
};
|
||||
|
||||
/**
|
||||
* !#en Apply the affine transformation on a rect, and truns to an Oriented Bounding Box.
|
||||
* This function is memory free, you should create the output vectors by yourself and manage their memory.
|
||||
* !#zh 应用仿射变换矩阵到 Rect 上, 并转换为有向包围盒。这个函数不创建任何内存,你需要先创建包围盒的四个 Vector 对象用来存储结果,并作为前四个参数传入函数。
|
||||
* @method transformObb
|
||||
* @static
|
||||
* @param {Vec2} out_bl
|
||||
* @param {Vec2} out_tl
|
||||
* @param {Vec2} out_tr
|
||||
* @param {Vec2} out_br
|
||||
* @param {Rect} rect
|
||||
* @param {AffineTransform} anAffineTransform
|
||||
*/
|
||||
AffineTransform.transformObb = function (out_bl, out_tl, out_tr, out_br, rect, anAffineTransform) {
|
||||
var x = rect.x;
|
||||
var y = rect.y;
|
||||
var width = rect.width;
|
||||
var height = rect.height;
|
||||
|
||||
var tx = anAffineTransform.a * x + anAffineTransform.c * y + anAffineTransform.tx;
|
||||
var ty = anAffineTransform.b * x + anAffineTransform.d * y + anAffineTransform.ty;
|
||||
var xa = anAffineTransform.a * width;
|
||||
var xb = anAffineTransform.b * width;
|
||||
var yc = anAffineTransform.c * height;
|
||||
var yd = anAffineTransform.d * height;
|
||||
|
||||
out_tl.x = tx;
|
||||
out_tl.y = ty;
|
||||
out_tr.x = xa + tx;
|
||||
out_tr.y = xb + ty;
|
||||
out_bl.x = yc + tx;
|
||||
out_bl.y = yd + ty;
|
||||
out_br.x = xa + yc + tx;
|
||||
out_br.y = xb + yd + ty;
|
||||
};
|
||||
|
||||
cc.AffineTransform = module.exports = AffineTransform;
|
1349
engine/cocos2d/core/utils/base-node.js
Normal file
1349
engine/cocos2d/core/utils/base-node.js
Normal file
File diff suppressed because it is too large
Load Diff
108
engine/cocos2d/core/utils/binary-search.js
Normal file
108
engine/cocos2d/core/utils/binary-search.js
Normal file
@@ -0,0 +1,108 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
var EPSILON = 1e-6;
|
||||
|
||||
/**
|
||||
* Searches the entire sorted Array for an element and returns the index of the element.
|
||||
*
|
||||
* @method binarySearch
|
||||
* @param {number[]} array
|
||||
* @param {number} value
|
||||
* @return {number} The index of item in the sorted Array, if item is found; otherwise, a negative number that is the bitwise complement of the index of the next element that is larger than item or, if there is no larger element, the bitwise complement of array's length.
|
||||
*/
|
||||
// function binarySearch (array, value) {
|
||||
// for (var l = 0, h = array.length - 1, m = h >>> 1;
|
||||
// l <= h;
|
||||
// m = (l + h) >>> 1
|
||||
// ) {
|
||||
// var test = array[m];
|
||||
// if (test > value) {
|
||||
// h = m - 1;
|
||||
// }
|
||||
// else if (test < value) {
|
||||
// l = m + 1;
|
||||
// }
|
||||
// else {
|
||||
// return m;
|
||||
// }
|
||||
// }
|
||||
// return ~l;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Searches the entire sorted Array for an element and returns the index of the element.
|
||||
* It accepts iteratee which is invoked for value and each element of array to compute their sort ranking.
|
||||
* The iteratee is invoked with one argument: (value).
|
||||
*
|
||||
* @method binarySearchBy
|
||||
* @param {number[]} array
|
||||
* @param {number} value
|
||||
* @param {function} iteratee - the iteratee invoked per element
|
||||
* @return {number} The index of item in the sorted Array, if item is found; otherwise, a negative number that is the bitwise complement of the index of the next element that is larger than item or, if there is no larger element, the bitwise complement of array's length.
|
||||
*/
|
||||
// function binarySearchBy (array, value, iteratee) {
|
||||
// for (var l = 0, h = array.length - 1, m = h >>> 1;
|
||||
// l <= h;
|
||||
// m = (l + h) >>> 1
|
||||
// ) {
|
||||
// var test = iteratee(array[m]);
|
||||
// if (test > value) {
|
||||
// h = m - 1;
|
||||
// }
|
||||
// else if (test < value) {
|
||||
// l = m + 1;
|
||||
// }
|
||||
// else {
|
||||
// return m;
|
||||
// }
|
||||
// }
|
||||
// return ~l;
|
||||
// }
|
||||
|
||||
function binarySearchEpsilon (array, value) {
|
||||
for (var l = 0, h = array.length - 1, m = h >>> 1;
|
||||
l <= h;
|
||||
m = (l + h) >>> 1
|
||||
) {
|
||||
var test = array[m];
|
||||
if (test > value + EPSILON) {
|
||||
h = m - 1;
|
||||
}
|
||||
else if (test < value - EPSILON) {
|
||||
l = m + 1;
|
||||
}
|
||||
else {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
return ~l;
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
binarySearchEpsilon
|
||||
};
|
109
engine/cocos2d/core/utils/blend-func.js
Normal file
109
engine/cocos2d/core/utils/blend-func.js
Normal file
@@ -0,0 +1,109 @@
|
||||
|
||||
const RenderComponent = require('../components/CCRenderComponent');
|
||||
const BlendFactor = require('../platform/CCMacro').BlendFactor;
|
||||
const gfx = require('../../renderer/gfx');
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Helper class for setting material blend function.
|
||||
* !#zh
|
||||
* 设置材质混合模式的辅助类。
|
||||
* @class BlendFunc
|
||||
*/
|
||||
let BlendFunc = cc.Class({
|
||||
properties: {
|
||||
_srcBlendFactor: BlendFactor.SRC_ALPHA,
|
||||
_dstBlendFactor: BlendFactor.ONE_MINUS_SRC_ALPHA,
|
||||
|
||||
/**
|
||||
* !#en specify the source Blend Factor, this will generate a custom material object, please pay attention to the memory cost.
|
||||
* !#zh 指定原图的混合模式,这会克隆一个新的材质对象,注意这带来的开销
|
||||
* @property srcBlendFactor
|
||||
* @type {macro.BlendFactor}
|
||||
* @example
|
||||
* sprite.srcBlendFactor = cc.macro.BlendFactor.ONE;
|
||||
*/
|
||||
srcBlendFactor: {
|
||||
get () {
|
||||
return this._srcBlendFactor;
|
||||
},
|
||||
set (value) {
|
||||
if (this._srcBlendFactor === value) return;
|
||||
this._srcBlendFactor = value;
|
||||
this._updateBlendFunc(true);
|
||||
this._onBlendChanged && this._onBlendChanged();
|
||||
},
|
||||
animatable: false,
|
||||
type: BlendFactor,
|
||||
tooltip: CC_DEV && 'i18n:COMPONENT.sprite.src_blend_factor',
|
||||
visible: true
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en specify the destination Blend Factor.
|
||||
* !#zh 指定目标的混合模式
|
||||
* @property dstBlendFactor
|
||||
* @type {macro.BlendFactor}
|
||||
* @example
|
||||
* sprite.dstBlendFactor = cc.macro.BlendFactor.ONE;
|
||||
*/
|
||||
dstBlendFactor: {
|
||||
get () {
|
||||
return this._dstBlendFactor;
|
||||
},
|
||||
set (value) {
|
||||
if (this._dstBlendFactor === value) return;
|
||||
this._dstBlendFactor = value;
|
||||
this._updateBlendFunc(true);
|
||||
},
|
||||
animatable: false,
|
||||
type: BlendFactor,
|
||||
tooltip: CC_DEV && 'i18n:COMPONENT.sprite.dst_blend_factor',
|
||||
visible: true
|
||||
},
|
||||
},
|
||||
|
||||
setMaterial (index, material) {
|
||||
let materialVar = RenderComponent.prototype.setMaterial.call(this, index, material);
|
||||
|
||||
if (this._srcBlendFactor !== BlendFactor.SRC_ALPHA || this._dstBlendFactor !== BlendFactor.ONE_MINUS_SRC_ALPHA) {
|
||||
this._updateMaterialBlendFunc(materialVar);
|
||||
}
|
||||
|
||||
return materialVar;
|
||||
},
|
||||
|
||||
_updateMaterial () {
|
||||
this._updateBlendFunc();
|
||||
},
|
||||
|
||||
_updateBlendFunc (force) {
|
||||
if (!force) {
|
||||
if (this._srcBlendFactor === BlendFactor.SRC_ALPHA && this._dstBlendFactor === BlendFactor.ONE_MINUS_SRC_ALPHA) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let materials = this.getMaterials();
|
||||
for (let i = 0; i < materials.length; i++) {
|
||||
let material = materials[i];
|
||||
this._updateMaterialBlendFunc(material);
|
||||
}
|
||||
},
|
||||
|
||||
_updateMaterialBlendFunc (material) {
|
||||
material.setBlend(
|
||||
true,
|
||||
gfx.BLEND_FUNC_ADD,
|
||||
this._srcBlendFactor, this._dstBlendFactor,
|
||||
gfx.BLEND_FUNC_ADD,
|
||||
this._srcBlendFactor, this._dstBlendFactor
|
||||
);
|
||||
|
||||
if (CC_JSB) {
|
||||
RenderComponent.prototype.markForRender.call(this, true);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = cc.BlendFunc = BlendFunc;
|
54
engine/cocos2d/core/utils/decode-uuid.js
Normal file
54
engine/cocos2d/core/utils/decode-uuid.js
Normal file
@@ -0,0 +1,54 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
var Base64Values = require('./misc').BASE64_VALUES;
|
||||
|
||||
var HexChars = '0123456789abcdef'.split('');
|
||||
|
||||
var _t = ['', '', '', ''];
|
||||
var UuidTemplate = _t.concat(_t, '-', _t, '-', _t, '-', _t, '-', _t, _t, _t);
|
||||
var Indices = UuidTemplate.map(function (x, i) { return x === '-' ? NaN : i; }).filter(isFinite);
|
||||
|
||||
// fcmR3XADNLgJ1ByKhqcC5Z -> fc991dd7-0033-4b80-9d41-c8a86a702e59
|
||||
module.exports = function (base64) {
|
||||
if (base64.length !== 22) {
|
||||
return base64;
|
||||
}
|
||||
UuidTemplate[0] = base64[0];
|
||||
UuidTemplate[1] = base64[1];
|
||||
for (var i = 2, j = 2; i < 22; i += 2) {
|
||||
var lhs = Base64Values[base64.charCodeAt(i)];
|
||||
var rhs = Base64Values[base64.charCodeAt(i + 1)];
|
||||
UuidTemplate[Indices[j++]] = HexChars[lhs >> 2];
|
||||
UuidTemplate[Indices[j++]] = HexChars[((lhs & 3) << 2) | rhs >> 4];
|
||||
UuidTemplate[Indices[j++]] = HexChars[rhs & 0xF];
|
||||
}
|
||||
return UuidTemplate.join('');
|
||||
};
|
||||
|
||||
if (CC_TEST) {
|
||||
cc._Test.decodeUuid = module.exports;
|
||||
}
|
85
engine/cocos2d/core/utils/find.js
Normal file
85
engine/cocos2d/core/utils/find.js
Normal file
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* Finds a node by hierarchy path, the path is case-sensitive.
|
||||
* It will traverse the hierarchy by splitting the path using '/' character.
|
||||
* This function will still returns the node even if it is inactive.
|
||||
* It is recommended to not use this function every frame instead cache the result at startup.
|
||||
*
|
||||
* @method find
|
||||
* @static
|
||||
* @param {String} path
|
||||
* @param {Node} [referenceNode]
|
||||
* @return {Node|null} the node or null if not found
|
||||
*/
|
||||
cc.find = module.exports = function (path, referenceNode) {
|
||||
if (path == null) {
|
||||
cc.errorID(3814);
|
||||
return null;
|
||||
}
|
||||
if (!referenceNode) {
|
||||
var scene = cc.director.getScene();
|
||||
if (!scene) {
|
||||
if (CC_DEV) {
|
||||
cc.warnID(5601);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
else if (CC_DEV && !scene.isValid) {
|
||||
cc.warnID(5602);
|
||||
return null;
|
||||
}
|
||||
referenceNode = scene;
|
||||
}
|
||||
else if (CC_DEV && !referenceNode.isValid) {
|
||||
cc.warnID(5603);
|
||||
return null;
|
||||
}
|
||||
|
||||
var match = referenceNode;
|
||||
var startIndex = (path[0] !== '/') ? 0 : 1; // skip first '/'
|
||||
var nameList = path.split('/');
|
||||
|
||||
// parse path
|
||||
for (var n = startIndex; n < nameList.length; n++) {
|
||||
var name = nameList[n];
|
||||
var children = match._children;
|
||||
match = null;
|
||||
for (var t = 0, len = children.length; t < len; ++t) {
|
||||
var subChild = children[t];
|
||||
if (subChild.name === name) {
|
||||
match = subChild;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return match;
|
||||
};
|
77
engine/cocos2d/core/utils/gray-sprite-state.js
Normal file
77
engine/cocos2d/core/utils/gray-sprite-state.js
Normal file
@@ -0,0 +1,77 @@
|
||||
|
||||
import MaterialVariant from '../assets/material/material-variant';
|
||||
const Material = require('../assets/material/CCMaterial');
|
||||
|
||||
/**
|
||||
* An internal helper class for switching render component's material between normal sprite material and gray sprite material.
|
||||
* @class GraySpriteState
|
||||
*/
|
||||
let GraySpriteState = cc.Class({
|
||||
properties: {
|
||||
_normalMaterial: null,
|
||||
|
||||
/**
|
||||
* !#en The normal material.
|
||||
* !#zh 正常状态的材质。
|
||||
* @property normalMaterial
|
||||
* @type {Material}
|
||||
* @default null
|
||||
*/
|
||||
normalMaterial: {
|
||||
get () {
|
||||
return this._normalMaterial;
|
||||
},
|
||||
set (val) {
|
||||
this._normalMaterial = val;
|
||||
this._updateDisabledState && this._updateDisabledState();
|
||||
},
|
||||
type: Material,
|
||||
tooltip: CC_DEV && 'i18n:COMPONENT.button.normal_material',
|
||||
animatable: false
|
||||
},
|
||||
|
||||
_grayMaterial: null,
|
||||
|
||||
/**
|
||||
* !#en The gray material.
|
||||
* !#zh 置灰状态的材质。
|
||||
* @property grayMaterial
|
||||
* @type {Material}
|
||||
* @default null
|
||||
*/
|
||||
grayMaterial: {
|
||||
get () {
|
||||
return this._grayMaterial;
|
||||
},
|
||||
set (val) {
|
||||
this._grayMaterial = val;
|
||||
this._updateDisabledState && this._updateDisabledState();
|
||||
},
|
||||
type: Material,
|
||||
tooltip: CC_DEV && 'i18n:COMPONENT.button.gray_material',
|
||||
animatable: false
|
||||
}
|
||||
},
|
||||
|
||||
_switchGrayMaterial (useGrayMaterial, renderComp) {
|
||||
let material;
|
||||
if (useGrayMaterial) {
|
||||
material = this._grayMaterial;
|
||||
if (!material) {
|
||||
material = Material.getBuiltinMaterial('2d-gray-sprite');
|
||||
}
|
||||
material = this._grayMaterial = MaterialVariant.create(material, renderComp);
|
||||
}
|
||||
else {
|
||||
material = this._normalMaterial;
|
||||
if (!material) {
|
||||
material = Material.getBuiltinMaterial('2d-sprite', renderComp);
|
||||
}
|
||||
material = this._normalMaterial = MaterialVariant.create(material, renderComp);
|
||||
}
|
||||
|
||||
renderComp.setMaterial(0, material);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = GraySpriteState;
|
367
engine/cocos2d/core/utils/html-text-parser.js
Normal file
367
engine/cocos2d/core/utils/html-text-parser.js
Normal file
@@ -0,0 +1,367 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
var eventRegx = /^(click)(\s)*=|(param)(\s)*=/;
|
||||
var imageAttrReg = /(\s)*src(\s)*=|(\s)*height(\s)*=|(\s)*width(\s)*=|(\s)*align(\s)*=|(\s)*offset(\s)*=|(\s)*click(\s)*=|(\s)*param(\s)*=/;
|
||||
/**
|
||||
* A utils class for parsing HTML texts. The parsed results will be an object array.
|
||||
*/
|
||||
var HtmlTextParser = function() {
|
||||
this._parsedObject = {};
|
||||
this._specialSymbolArray = [];
|
||||
this._specialSymbolArray.push([/</g, '<']);
|
||||
this._specialSymbolArray.push([/>/g, '>']);
|
||||
this._specialSymbolArray.push([/&/g, '&']);
|
||||
this._specialSymbolArray.push([/"/g, '"']);
|
||||
this._specialSymbolArray.push([/'/g, '\'']);
|
||||
this._specialSymbolArray.push([/ /g, ' ']);
|
||||
};
|
||||
|
||||
HtmlTextParser.prototype = {
|
||||
constructor: HtmlTextParser,
|
||||
parse: function(htmlString) {
|
||||
this._resultObjectArray = [];
|
||||
if (!htmlString) {
|
||||
return this._resultObjectArray;
|
||||
}
|
||||
this._stack = [];
|
||||
|
||||
var startIndex = 0;
|
||||
var length = htmlString.length;
|
||||
while (startIndex < length) {
|
||||
var tagEndIndex = htmlString.indexOf('>', startIndex);
|
||||
var tagBeginIndex = -1;
|
||||
if (tagEndIndex >= 0) {
|
||||
tagBeginIndex = htmlString.lastIndexOf('<', tagEndIndex);
|
||||
var noTagBegin = tagBeginIndex < (startIndex - 1);
|
||||
|
||||
if (noTagBegin) {
|
||||
tagBeginIndex = htmlString.indexOf('<', tagEndIndex + 1);
|
||||
tagEndIndex = htmlString.indexOf('>', tagBeginIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (tagBeginIndex < 0) {
|
||||
this._stack.pop();
|
||||
this._processResult(htmlString.substring(startIndex));
|
||||
startIndex = length;
|
||||
} else {
|
||||
var newStr = htmlString.substring(startIndex, tagBeginIndex);
|
||||
var tagStr = htmlString.substring(tagBeginIndex + 1, tagEndIndex);
|
||||
if (tagStr === "") newStr = htmlString.substring(startIndex, tagEndIndex + 1);
|
||||
this._processResult(newStr);
|
||||
if (tagEndIndex === -1) {
|
||||
// cc.error('The HTML tag is invalid!');
|
||||
tagEndIndex = tagBeginIndex;
|
||||
} else if (htmlString.charAt(tagBeginIndex + 1) === '\/'){
|
||||
this._stack.pop();
|
||||
} else {
|
||||
this._addToStack(tagStr);
|
||||
}
|
||||
startIndex = tagEndIndex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return this._resultObjectArray;
|
||||
},
|
||||
|
||||
_attributeToObject: function (attribute) {
|
||||
attribute = attribute.trim();
|
||||
|
||||
var obj = {};
|
||||
var header = attribute.match(/^(color|size)(\s)*=/);
|
||||
var tagName;
|
||||
var nextSpace;
|
||||
var eventObj;
|
||||
var eventHanlderString;
|
||||
if (header) {
|
||||
tagName = header[0];
|
||||
attribute = attribute.substring(tagName.length).trim();
|
||||
if(attribute === "") return obj;
|
||||
|
||||
//parse color
|
||||
nextSpace = attribute.indexOf(' ');
|
||||
switch(tagName[0]){
|
||||
case 'c':
|
||||
if (nextSpace > -1) {
|
||||
obj.color = attribute.substring(0, nextSpace).trim();
|
||||
} else {
|
||||
obj.color = attribute;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
obj.size = parseInt(attribute);
|
||||
break;
|
||||
}
|
||||
|
||||
//tag has event arguments
|
||||
if(nextSpace > -1) {
|
||||
eventHanlderString = attribute.substring(nextSpace+1).trim();
|
||||
eventObj = this._processEventHandler(eventHanlderString);
|
||||
obj.event = eventObj;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
header = attribute.match(/^(br(\s)*\/)/);
|
||||
if(header && header[0].length > 0) {
|
||||
tagName = header[0].trim();
|
||||
if(tagName.startsWith("br") && tagName[tagName.length-1] === "/") {
|
||||
obj.isNewLine = true;
|
||||
this._resultObjectArray.push({text: "", style: {newline: true}});
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
header = attribute.match(/^(img(\s)*src(\s)*=[^>]+\/)/);
|
||||
if(header && header[0].length > 0) {
|
||||
tagName = header[0].trim();
|
||||
if(tagName.startsWith("img") && tagName[tagName.length-1] === "/") {
|
||||
header = attribute.match(imageAttrReg);
|
||||
var tagValue;
|
||||
var remainingArgument;
|
||||
var isValidImageTag = false;
|
||||
while (header) {
|
||||
//skip the invalid tags at first
|
||||
attribute = attribute.substring(attribute.indexOf(header[0]));
|
||||
tagName = attribute.substr(0, header[0].length);
|
||||
//remove space and = character
|
||||
remainingArgument = attribute.substring(tagName.length).trim();
|
||||
nextSpace = remainingArgument.indexOf(' ');
|
||||
|
||||
tagValue = (nextSpace > -1) ? remainingArgument.substr(0, nextSpace) : remainingArgument;
|
||||
tagName = tagName.replace(/[^a-zA-Z]/g, "").trim();
|
||||
tagName = tagName.toLocaleLowerCase();
|
||||
|
||||
attribute = remainingArgument.substring(nextSpace).trim();
|
||||
if ( tagValue.endsWith( '\/' ) ) tagValue = tagValue.slice( 0, -1 );
|
||||
if (tagName === "src") {
|
||||
switch (tagValue.charCodeAt(0)) {
|
||||
case 34: // "
|
||||
case 39: // '
|
||||
isValidImageTag = true;
|
||||
tagValue = tagValue.slice(1, -1);
|
||||
break;
|
||||
}
|
||||
obj.isImage = true;
|
||||
obj.src = tagValue;
|
||||
} else if (tagName === "height") {
|
||||
obj.imageHeight = parseInt(tagValue);
|
||||
} else if (tagName === "width") {
|
||||
obj.imageWidth = parseInt(tagValue);
|
||||
} else if (tagName === "align") {
|
||||
switch (tagValue.charCodeAt(0)) {
|
||||
case 34: // "
|
||||
case 39: // '
|
||||
tagValue = tagValue.slice(1, -1);
|
||||
break;
|
||||
}
|
||||
obj.imageAlign = tagValue.toLocaleLowerCase();
|
||||
} else if (tagName === "offset") {
|
||||
obj.imageOffset = tagValue;
|
||||
} else if (tagName === "click") {
|
||||
obj.event = this._processEventHandler(tagName + "=" + tagValue);
|
||||
}
|
||||
|
||||
if (obj.event && tagName === 'param') {
|
||||
obj.event.param = tagValue.replace(/^\"|\"$/g, '');
|
||||
}
|
||||
|
||||
header = attribute.match(imageAttrReg);
|
||||
}
|
||||
|
||||
if( isValidImageTag && obj.isImage ) {
|
||||
this._resultObjectArray.push({text: "", style: obj});
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
header = attribute.match(/^(outline(\s)*[^>]*)/);
|
||||
if (header) {
|
||||
attribute = header[0].substring("outline".length).trim();
|
||||
var defaultOutlineObject = {color: "#ffffff", width: 1};
|
||||
if (attribute) {
|
||||
var outlineAttrReg = /(\s)*color(\s)*=|(\s)*width(\s)*=|(\s)*click(\s)*=|(\s)*param(\s)*=/;
|
||||
header = attribute.match(outlineAttrReg);
|
||||
var tagValue;
|
||||
while (header) {
|
||||
//skip the invalid tags at first
|
||||
attribute = attribute.substring(attribute.indexOf(header[0]));
|
||||
tagName = attribute.substr(0, header[0].length);
|
||||
//remove space and = character
|
||||
remainingArgument = attribute.substring(tagName.length).trim();
|
||||
nextSpace = remainingArgument.indexOf(' ');
|
||||
if (nextSpace > -1) {
|
||||
tagValue = remainingArgument.substr(0, nextSpace);
|
||||
} else {
|
||||
tagValue = remainingArgument;
|
||||
}
|
||||
tagName = tagName.replace(/[^a-zA-Z]/g, "").trim();
|
||||
tagName = tagName.toLocaleLowerCase();
|
||||
|
||||
attribute = remainingArgument.substring(nextSpace).trim();
|
||||
if (tagName === "click") {
|
||||
obj.event = this._processEventHandler(tagName + "=" + tagValue);
|
||||
} else if (tagName === "color") {
|
||||
defaultOutlineObject.color = tagValue;
|
||||
} else if (tagName === "width") {
|
||||
defaultOutlineObject.width = parseInt(tagValue);
|
||||
}
|
||||
|
||||
if (obj.event && tagName === 'param') {
|
||||
obj.event.param = tagValue.replace(/^\"|\"$/g, '');
|
||||
}
|
||||
|
||||
header = attribute.match(outlineAttrReg);
|
||||
}
|
||||
}
|
||||
obj.outline = defaultOutlineObject;
|
||||
}
|
||||
|
||||
header = attribute.match(/^(on|u|b|i)(\s)*/);
|
||||
if(header && header[0].length > 0) {
|
||||
tagName = header[0];
|
||||
attribute = attribute.substring(tagName.length).trim();
|
||||
switch(tagName[0]){
|
||||
case 'u':
|
||||
obj.underline = true;
|
||||
break;
|
||||
case 'i':
|
||||
obj.italic = true;
|
||||
break;
|
||||
case 'b':
|
||||
obj.bold = true;
|
||||
break;
|
||||
}
|
||||
if(attribute === "") {
|
||||
return obj;
|
||||
}
|
||||
eventObj = this._processEventHandler(attribute);
|
||||
obj.event = eventObj;
|
||||
}
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
_processEventHandler: function (eventString) {
|
||||
var index = 0;
|
||||
var obj = {};
|
||||
var eventNames = eventString.match(eventRegx);
|
||||
var isValidTag = false;
|
||||
while(eventNames) {
|
||||
var eventName = eventNames[0];
|
||||
var eventValue = "";
|
||||
isValidTag = false;
|
||||
eventString = eventString.substring(eventName.length).trim();
|
||||
if(eventString.charAt(0) === "\"") {
|
||||
index = eventString.indexOf("\"", 1);
|
||||
if (index > -1) {
|
||||
eventValue = eventString.substring(1, index).trim();
|
||||
isValidTag = true;
|
||||
}
|
||||
index++;
|
||||
} else if(eventString.charAt(0) === "\'") {
|
||||
index = eventString.indexOf('\'', 1);
|
||||
if(index > -1) {
|
||||
eventValue = eventString.substring(1, index).trim();
|
||||
isValidTag = true;
|
||||
}
|
||||
index++;
|
||||
} else {
|
||||
//skip the invalid attribute value
|
||||
var match = eventString.match(/(\S)+/);
|
||||
if(match) {
|
||||
eventValue = match[0];
|
||||
} else {
|
||||
eventValue = "";
|
||||
}
|
||||
index = eventValue.length;
|
||||
}
|
||||
|
||||
if(isValidTag) {
|
||||
eventName = eventName.substring(0, eventName.length-1).trim();
|
||||
obj[eventName] = eventValue;
|
||||
}
|
||||
|
||||
eventString = eventString.substring(index).trim();
|
||||
eventNames = eventString.match(eventRegx);
|
||||
}
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
_addToStack: function(attribute) {
|
||||
var obj = this._attributeToObject(attribute);
|
||||
|
||||
if (this._stack.length === 0){
|
||||
this._stack.push(obj);
|
||||
} else {
|
||||
if(obj.isNewLine || obj.isImage) {
|
||||
return;
|
||||
}
|
||||
//for nested tags
|
||||
var previousTagObj = this._stack[this._stack.length - 1];
|
||||
for (var key in previousTagObj) {
|
||||
if (!(obj[key])) {
|
||||
obj[key] = previousTagObj[key];
|
||||
}
|
||||
}
|
||||
this._stack.push(obj);
|
||||
}
|
||||
},
|
||||
|
||||
_processResult: function(value) {
|
||||
if (value === "") {
|
||||
return;
|
||||
}
|
||||
|
||||
value = this._escapeSpecialSymbol(value);
|
||||
if (this._stack.length > 0) {
|
||||
this._resultObjectArray.push({text: value, style: this._stack[this._stack.length - 1]});
|
||||
} else {
|
||||
this._resultObjectArray.push({text: value});
|
||||
}
|
||||
},
|
||||
|
||||
_escapeSpecialSymbol: function(str) {
|
||||
for(var i = 0; i < this._specialSymbolArray.length; ++i) {
|
||||
var key = this._specialSymbolArray[i][0];
|
||||
var value = this._specialSymbolArray[i][1];
|
||||
|
||||
str = str.replace(key, value);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
if (CC_TEST) {
|
||||
cc._Test.HtmlTextParser = HtmlTextParser;
|
||||
}
|
||||
|
||||
module.exports = HtmlTextParser;
|
32
engine/cocos2d/core/utils/index.js
Normal file
32
engine/cocos2d/core/utils/index.js
Normal file
@@ -0,0 +1,32 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
require('./CCPath');
|
||||
if (!CC_EDITOR) {
|
||||
require('./profiler/CCProfiler');
|
||||
}
|
||||
require('./find');
|
||||
require('./mutable-forward-iterator');
|
86
engine/cocos2d/core/utils/math-pools.js
Normal file
86
engine/cocos2d/core/utils/math-pools.js
Normal file
@@ -0,0 +1,86 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
const js = require('../platform/js');
|
||||
// const Vec2 = require('../value-types/vec2');
|
||||
// const Vec3 = require('../value-types/vec3');
|
||||
const Quat = require('../value-types/quat');
|
||||
const Mat4 = require('../value-types/mat4');
|
||||
|
||||
var mat4Pool = new js.Pool(128);
|
||||
mat4Pool.get = function () {
|
||||
var matrix = this._get();
|
||||
if (matrix) {
|
||||
Mat4.identity(matrix);
|
||||
}
|
||||
else {
|
||||
matrix = new Mat4();
|
||||
}
|
||||
return matrix;
|
||||
};
|
||||
|
||||
// var vec2Pool = new js.Pool(128);
|
||||
// vec2Pool.get = function () {
|
||||
// var vec2 = this._get();
|
||||
// if (vec2) {
|
||||
// vec2.x = vec2.y = 0;
|
||||
// }
|
||||
// else {
|
||||
// vec2 = new Vec2();
|
||||
// }
|
||||
// return vec2;
|
||||
// };
|
||||
|
||||
// var vec3Pool = new js.Pool(128);
|
||||
// vec3Pool.get = function () {
|
||||
// var vec3 = this._get();
|
||||
// if (vec3) {
|
||||
// vec3.x = vec3.y = vec3.z = 0;
|
||||
// }
|
||||
// else {
|
||||
// vec3 = new Vec3();
|
||||
// }
|
||||
// return vec3;
|
||||
// };
|
||||
|
||||
var quatPool = new js.Pool(64);
|
||||
quatPool.get = function () {
|
||||
var q = this._get();
|
||||
if (q) {
|
||||
q.x = q.y = q.z = 0;
|
||||
q.w = 1;
|
||||
}
|
||||
else {
|
||||
q = new Quat();
|
||||
}
|
||||
return q;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
mat4: mat4Pool,
|
||||
// vec2: vec2Pool,
|
||||
// vec3: vec3Pool,
|
||||
quat: quatPool
|
||||
};
|
219
engine/cocos2d/core/utils/misc.js
Normal file
219
engine/cocos2d/core/utils/misc.js
Normal file
@@ -0,0 +1,219 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
var js = require('../platform/js');
|
||||
|
||||
/**
|
||||
* misc utilities
|
||||
* @class misc
|
||||
* @static
|
||||
*/
|
||||
var misc = {};
|
||||
|
||||
misc.propertyDefine = function (ctor, sameNameGetSets, diffNameGetSets) {
|
||||
function define (np, propName, getter, setter) {
|
||||
var pd = Object.getOwnPropertyDescriptor(np, propName);
|
||||
if (pd) {
|
||||
if (pd.get) np[getter] = pd.get;
|
||||
if (pd.set && setter) np[setter] = pd.set;
|
||||
}
|
||||
else {
|
||||
var getterFunc = np[getter];
|
||||
if (CC_DEV && !getterFunc) {
|
||||
var clsName = (cc.Class._isCCClass(ctor) && js.getClassName(ctor)) ||
|
||||
ctor.name ||
|
||||
'(anonymous class)';
|
||||
cc.warnID(5700, propName, getter, clsName);
|
||||
}
|
||||
else {
|
||||
js.getset(np, propName, getterFunc, np[setter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
var propName, np = ctor.prototype;
|
||||
for (var i = 0; i < sameNameGetSets.length; i++) {
|
||||
propName = sameNameGetSets[i];
|
||||
var suffix = propName[0].toUpperCase() + propName.slice(1);
|
||||
define(np, propName, 'get' + suffix, 'set' + suffix);
|
||||
}
|
||||
for (propName in diffNameGetSets) {
|
||||
var getset = diffNameGetSets[propName];
|
||||
define(np, propName, getset[0], getset[1]);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Number} x
|
||||
* @return {Number}
|
||||
* Constructor
|
||||
*/
|
||||
misc.NextPOT = function (x) {
|
||||
x = x - 1;
|
||||
x = x | (x >> 1);
|
||||
x = x | (x >> 2);
|
||||
x = x | (x >> 4);
|
||||
x = x | (x >> 8);
|
||||
x = x | (x >> 16);
|
||||
return x + 1;
|
||||
};
|
||||
|
||||
//var DirtyFlags = m.DirtyFlags = {
|
||||
// TRANSFORM: 1 << 0,
|
||||
// SIZE: 1 << 1,
|
||||
// //Visible:
|
||||
// //Color:
|
||||
// //Opacity
|
||||
// //Cache
|
||||
// //Order
|
||||
// //Text
|
||||
// //Gradient
|
||||
// ALL: (1 << 2) - 1
|
||||
//};
|
||||
//
|
||||
//DirtyFlags.WIDGET = DirtyFlags.TRANSFORM | DirtyFlags.SIZE;
|
||||
|
||||
if (CC_EDITOR) {
|
||||
// use anonymous function here to ensure it will not being hoisted without CC_EDITOR
|
||||
|
||||
misc.tryCatchFunctor_EDITOR = function (funcName) {
|
||||
return Function('target',
|
||||
'try {\n' +
|
||||
' target.' + funcName + '();\n' +
|
||||
'}\n' +
|
||||
'catch (e) {\n' +
|
||||
' cc._throw(e);\n' +
|
||||
'}');
|
||||
};
|
||||
}
|
||||
|
||||
misc.BUILTIN_CLASSID_RE = /^(?:cc|dragonBones|sp|ccsg)\..+/;
|
||||
|
||||
|
||||
var BASE64_KEYS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
||||
var BASE64_VALUES = new Array(123); // max char code in base64Keys
|
||||
for (let i = 0; i < 123; ++i) BASE64_VALUES[i] = 64; // fill with placeholder('=') index
|
||||
for (let i = 0; i < 64; ++i) BASE64_VALUES[BASE64_KEYS.charCodeAt(i)] = i;
|
||||
|
||||
// decoded value indexed by base64 char code
|
||||
misc.BASE64_VALUES = BASE64_VALUES;
|
||||
|
||||
// set value to map, if key exists, push to array
|
||||
misc.pushToMap = function (map, key, value, pushFront) {
|
||||
var exists = map[key];
|
||||
if (exists) {
|
||||
if (Array.isArray(exists)) {
|
||||
if (pushFront) {
|
||||
exists.push(exists[0]);
|
||||
exists[0] = value;
|
||||
}
|
||||
else {
|
||||
exists.push(value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
map[key] = (pushFront ? [value, exists] : [exists, value]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
map[key] = value;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* !#en Clamp a value between from and to.
|
||||
* !#zh
|
||||
* 限定浮点数的最大最小值。<br/>
|
||||
* 数值大于 max_inclusive 则返回 max_inclusive。<br/>
|
||||
* 数值小于 min_inclusive 则返回 min_inclusive。<br/>
|
||||
* 否则返回自身。
|
||||
* @method clampf
|
||||
* @param {Number} value
|
||||
* @param {Number} min_inclusive
|
||||
* @param {Number} max_inclusive
|
||||
* @return {Number}
|
||||
* @example
|
||||
* var v1 = cc.misc.clampf(20, 0, 20); // 20;
|
||||
* var v2 = cc.misc.clampf(-1, 0, 20); // 0;
|
||||
* var v3 = cc.misc.clampf(10, 0, 20); // 10;
|
||||
*/
|
||||
misc.clampf = function (value, min_inclusive, max_inclusive) {
|
||||
if (min_inclusive > max_inclusive) {
|
||||
var temp = min_inclusive;
|
||||
min_inclusive = max_inclusive;
|
||||
max_inclusive = temp;
|
||||
}
|
||||
return value < min_inclusive ? min_inclusive : value < max_inclusive ? value : max_inclusive;
|
||||
};
|
||||
|
||||
/**
|
||||
* !#en Clamp a value between 0 and 1.
|
||||
* !#zh 限定浮点数的取值范围为 0 ~ 1 之间。
|
||||
* @method clamp01
|
||||
* @param {Number} value
|
||||
* @return {Number}
|
||||
* @example
|
||||
* var v1 = cc.misc.clamp01(20); // 1;
|
||||
* var v2 = cc.misc.clamp01(-1); // 0;
|
||||
* var v3 = cc.misc.clamp01(0.5); // 0.5;
|
||||
*/
|
||||
misc.clamp01 = function (value) {
|
||||
return value < 0 ? 0 : value < 1 ? value : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Linear interpolation between 2 numbers, the ratio sets how much it is biased to each end
|
||||
* @method lerp
|
||||
* @param {Number} a number A
|
||||
* @param {Number} b number B
|
||||
* @param {Number} r ratio between 0 and 1
|
||||
* @return {Number}
|
||||
* @example {@link cocos2d/core/platform/CCMacro/lerp.js}
|
||||
*/
|
||||
misc.lerp = function (a, b, r) {
|
||||
return a + (b - a) * r;
|
||||
};
|
||||
|
||||
/**
|
||||
* converts degrees to radians
|
||||
* @param {Number} angle
|
||||
* @return {Number}
|
||||
* @method degreesToRadians
|
||||
*/
|
||||
misc.degreesToRadians = function (angle) {
|
||||
return angle * cc.macro.RAD;
|
||||
};
|
||||
|
||||
/**
|
||||
* converts radians to degrees
|
||||
* @param {Number} angle
|
||||
* @return {Number}
|
||||
* @method radiansToDegrees
|
||||
*/
|
||||
misc.radiansToDegrees = function (angle) {
|
||||
return angle * cc.macro.DEG;
|
||||
};
|
||||
|
||||
cc.misc = module.exports = misc;
|
88
engine/cocos2d/core/utils/mutable-forward-iterator.js
Normal file
88
engine/cocos2d/core/utils/mutable-forward-iterator.js
Normal file
@@ -0,0 +1,88 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @example
|
||||
* var array = [0, 1, 2, 3, 4];
|
||||
* var iterator = new cc.js.array.MutableForwardIterator(array);
|
||||
* for (iterator.i = 0; iterator.i < array.length; ++iterator.i) {
|
||||
* var item = array[iterator.i];
|
||||
* ...
|
||||
* }
|
||||
*/
|
||||
function MutableForwardIterator (array) {
|
||||
this.i = 0;
|
||||
this.array = array;
|
||||
}
|
||||
|
||||
var proto = MutableForwardIterator.prototype;
|
||||
|
||||
proto.remove = function (value) {
|
||||
var index = this.array.indexOf(value);
|
||||
if (index >= 0) {
|
||||
this.removeAt(index);
|
||||
}
|
||||
};
|
||||
proto.removeAt = function (i) {
|
||||
this.array.splice(i, 1);
|
||||
|
||||
if (i <= this.i) {
|
||||
--this.i;
|
||||
}
|
||||
};
|
||||
proto.fastRemove = function (value) {
|
||||
var index = this.array.indexOf(value);
|
||||
if (index >= 0) {
|
||||
this.fastRemoveAt(index);
|
||||
}
|
||||
};
|
||||
proto.fastRemoveAt = function (i) {
|
||||
var array = this.array;
|
||||
array[i] = array[array.length - 1];
|
||||
--array.length;
|
||||
|
||||
if (i <= this.i) {
|
||||
--this.i;
|
||||
}
|
||||
};
|
||||
|
||||
proto.push = function (item) {
|
||||
this.array.push(item);
|
||||
};
|
||||
|
||||
//js.getset(proto, 'length',
|
||||
// function () {
|
||||
// return this.array.length;
|
||||
// },
|
||||
// function (len) {
|
||||
// this.array.length = len;
|
||||
// if (this.i >= len) {
|
||||
// this.i = len - 1;
|
||||
// }
|
||||
// }
|
||||
//);
|
||||
|
||||
module.exports = MutableForwardIterator;
|
22
engine/cocos2d/core/utils/pool.js
Normal file
22
engine/cocos2d/core/utils/pool.js
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
export default class Pool {
|
||||
enabled = false;
|
||||
count = 0;
|
||||
maxSize = 1024;
|
||||
|
||||
get () {
|
||||
|
||||
}
|
||||
put () {
|
||||
|
||||
}
|
||||
clear () {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
cc.pool = {};
|
||||
|
||||
Pool.register = function (name, pool) {
|
||||
cc.pool[name] = pool;
|
||||
}
|
116
engine/cocos2d/core/utils/prefab-helper.js
Normal file
116
engine/cocos2d/core/utils/prefab-helper.js
Normal file
@@ -0,0 +1,116 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
cc._PrefabInfo = cc.Class({
|
||||
name: 'cc.PrefabInfo',
|
||||
// extends: require('../platform/CCObject'),
|
||||
properties: {
|
||||
// the most top node of this prefab
|
||||
root: null,
|
||||
|
||||
// 所属的 prefab 资源对象 (cc.Prefab)
|
||||
// In Editor, only asset._uuid is usable because asset will be changed.
|
||||
asset: null,
|
||||
|
||||
// To identify the node in the prefab asset, so only needs to be unique.
|
||||
// Not available in the root node.
|
||||
fileId: '',
|
||||
|
||||
// Indicates whether this node should always synchronize with the prefab asset, only available in the root node
|
||||
sync: false,
|
||||
},
|
||||
});
|
||||
|
||||
// prefab helper function
|
||||
module.exports = {
|
||||
// update node to make it sync with prefab
|
||||
syncWithPrefab: function (node) {
|
||||
var _prefab = node._prefab;
|
||||
|
||||
if (!_prefab.asset) {
|
||||
if (CC_EDITOR) {
|
||||
var NodeUtils = Editor.require('scene://utils/node');
|
||||
var PrefabUtils = Editor.require('scene://utils/prefab');
|
||||
|
||||
cc.warn(Editor.T('MESSAGE.prefab.missing_prefab', { node: NodeUtils.getNodePath(node) }));
|
||||
node.name += PrefabUtils.MISSING_PREFAB_SUFFIX;
|
||||
}
|
||||
else {
|
||||
cc.errorID(3701, node.name);
|
||||
}
|
||||
node._prefab = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// save root's preserved props to avoid overwritten by prefab
|
||||
var _objFlags = node._objFlags;
|
||||
var _parent = node._parent;
|
||||
var _id = node._id;
|
||||
var _name = node._name;
|
||||
var _active = node._active;
|
||||
var eulerAnglesX = node._eulerAngles.x;
|
||||
var eulerAnglesY = node._eulerAngles.y;
|
||||
var eulerAnglesZ = node._eulerAngles.z;
|
||||
var _localZOrder = node._localZOrder;
|
||||
var trs = node._trs;
|
||||
var x = trs[0];
|
||||
var y = trs[1];
|
||||
var z = trs[2];
|
||||
|
||||
// instantiate prefab
|
||||
cc.game._isCloning = true;
|
||||
if (CC_SUPPORT_JIT) {
|
||||
_prefab.asset._doInstantiate(node);
|
||||
}
|
||||
else {
|
||||
// root in prefab asset is always synced
|
||||
var prefabRoot = _prefab.asset.data;
|
||||
|
||||
// use node as the instantiated prefabRoot to make references to prefabRoot in prefab redirect to node
|
||||
prefabRoot._iN$t = node;
|
||||
|
||||
// instantiate prefab and apply to node
|
||||
cc.instantiate._clone(prefabRoot, prefabRoot);
|
||||
}
|
||||
cc.game._isCloning = false;
|
||||
|
||||
// restore preserved props
|
||||
node._objFlags = _objFlags;
|
||||
node._parent = _parent;
|
||||
node._id = _id;
|
||||
node._prefab = _prefab;
|
||||
node._name = _name;
|
||||
node._active = _active;
|
||||
node._localZOrder = _localZOrder;
|
||||
trs = node._trs;
|
||||
trs[0] = x;
|
||||
trs[1] = y;
|
||||
trs[2] = z;
|
||||
node._eulerAngles.x = eulerAnglesX;
|
||||
node._eulerAngles.y = eulerAnglesY;
|
||||
node._eulerAngles.z = eulerAnglesZ;
|
||||
}
|
||||
};
|
178
engine/cocos2d/core/utils/profiler/CCProfiler.js
Normal file
178
engine/cocos2d/core/utils/profiler/CCProfiler.js
Normal file
@@ -0,0 +1,178 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
var macro = require('../../platform/CCMacro');
|
||||
|
||||
const PerfCounter = require('./perf-counter');
|
||||
|
||||
let _showFPS = false;
|
||||
let _fontSize = 15;
|
||||
|
||||
let _stats = null;
|
||||
let _rootNode = null;
|
||||
let _label = null;
|
||||
|
||||
function generateStats () {
|
||||
if (_stats) return;
|
||||
|
||||
_stats = {
|
||||
fps: { desc: 'Framerate (FPS)', below: 30, average: 500 },
|
||||
draws: { desc: 'Draw Call' },
|
||||
frame: { desc: 'Frame time (ms)', min: 0, max: 50, average: 500 },
|
||||
logic: { desc: 'Game Logic (ms)', min: 0, max: 50, average: 500, color: '#080' },
|
||||
render: { desc: 'Renderer (ms)', min: 0, max: 50, average: 500, color: '#f90' },
|
||||
mode: { desc: cc.game.renderType === cc.game.RENDER_TYPE_WEBGL ? 'WebGL' : 'Canvas', min: 1 }
|
||||
};
|
||||
|
||||
let now = performance.now();
|
||||
for (let id in _stats) {
|
||||
_stats[id]._counter = new PerfCounter(id, _stats[id], now);
|
||||
}
|
||||
}
|
||||
|
||||
function generateNode () {
|
||||
if (_rootNode && _rootNode.isValid) return;
|
||||
|
||||
|
||||
_rootNode = new cc.Node('PROFILER-NODE');
|
||||
_rootNode.x = _rootNode.y = 10;
|
||||
|
||||
_rootNode.groupIndex = cc.Node.BuiltinGroupIndex.DEBUG;
|
||||
cc.Camera._setupDebugCamera();
|
||||
|
||||
_rootNode.zIndex = macro.MAX_ZINDEX;
|
||||
cc.game.addPersistRootNode(_rootNode);
|
||||
|
||||
let left = new cc.Node('LEFT-PANEL');
|
||||
left.anchorX = left.anchorY = 0;
|
||||
let leftLabel = left.addComponent(cc.Label);
|
||||
leftLabel.fontSize = _fontSize;
|
||||
leftLabel.lineHeight = _fontSize;
|
||||
left.parent = _rootNode;
|
||||
|
||||
let right = new cc.Node('RIGHT-PANEL');
|
||||
right.anchorX = 1;
|
||||
right.anchorY = 0;
|
||||
right.x = 200;
|
||||
let rightLabel = right.addComponent(cc.Label);
|
||||
rightLabel.horizontalAlign = cc.Label.HorizontalAlign.RIGHT;
|
||||
rightLabel.fontSize = _fontSize;
|
||||
rightLabel.lineHeight = _fontSize;
|
||||
right.parent = _rootNode;
|
||||
if (cc.sys.platform !== cc.sys.BAIDU_GAME_SUB &&
|
||||
cc.sys.platform !== cc.sys.WECHAT_GAME_SUB) {
|
||||
leftLabel.cacheMode = cc.Label.CacheMode.CHAR;
|
||||
rightLabel.cacheMode = cc.Label.CacheMode.CHAR;
|
||||
}
|
||||
|
||||
_label = {
|
||||
left: leftLabel,
|
||||
right: rightLabel
|
||||
};
|
||||
}
|
||||
|
||||
function beforeUpdate () {
|
||||
generateNode();
|
||||
|
||||
let now = cc.director._lastUpdate;
|
||||
_stats['frame']._counter.start(now);
|
||||
_stats['logic']._counter.start(now);
|
||||
}
|
||||
|
||||
function afterUpdate () {
|
||||
let now = performance.now();
|
||||
if (cc.director.isPaused()) {
|
||||
_stats['frame']._counter.start(now);
|
||||
}
|
||||
else {
|
||||
_stats['logic']._counter.end(now);
|
||||
}
|
||||
_stats['render']._counter.start(now);
|
||||
}
|
||||
|
||||
function updateLabel (stat) {
|
||||
let length = 20;
|
||||
let desc = stat.desc;
|
||||
let value = stat._counter.human() + '';
|
||||
stat.label.string = stat.desc + ' ' + stat._counter.human();
|
||||
}
|
||||
|
||||
function afterDraw () {
|
||||
let now = performance.now();
|
||||
_stats['render']._counter.end(now);
|
||||
_stats['draws']._counter.value = cc.renderer.drawCalls;
|
||||
_stats['frame']._counter.end(now);
|
||||
_stats['fps']._counter.frame(now);
|
||||
|
||||
let left = '';
|
||||
let right = '';
|
||||
for (let id in _stats) {
|
||||
let stat = _stats[id];
|
||||
stat._counter.sample(now);
|
||||
|
||||
left += stat.desc + '\n';
|
||||
right += stat._counter.human() + '\n';
|
||||
}
|
||||
|
||||
if (_label) {
|
||||
_label.left.string = left;
|
||||
_label.right.string = right;
|
||||
}
|
||||
}
|
||||
|
||||
cc.profiler = module.exports = {
|
||||
isShowingStats () {
|
||||
return _showFPS;
|
||||
},
|
||||
|
||||
hideStats () {
|
||||
if (_showFPS) {
|
||||
if (_rootNode) {
|
||||
_rootNode.active = false;
|
||||
}
|
||||
|
||||
cc.director.off(cc.Director.EVENT_BEFORE_UPDATE, beforeUpdate);
|
||||
cc.director.off(cc.Director.EVENT_AFTER_UPDATE, afterUpdate);
|
||||
cc.director.off(cc.Director.EVENT_AFTER_DRAW, afterDraw);
|
||||
_showFPS = false;
|
||||
}
|
||||
},
|
||||
|
||||
showStats () {
|
||||
if (!_showFPS) {
|
||||
generateStats();
|
||||
|
||||
if (_rootNode) {
|
||||
_rootNode.active = true;
|
||||
}
|
||||
|
||||
cc.director.on(cc.Director.EVENT_BEFORE_UPDATE, beforeUpdate);
|
||||
cc.director.on(cc.Director.EVENT_AFTER_UPDATE, afterUpdate);
|
||||
cc.director.on(cc.Director.EVENT_AFTER_DRAW, afterDraw);
|
||||
_showFPS = true;
|
||||
}
|
||||
}
|
||||
}
|
58
engine/cocos2d/core/utils/profiler/counter.js
Normal file
58
engine/cocos2d/core/utils/profiler/counter.js
Normal file
@@ -0,0 +1,58 @@
|
||||
let Counter = cc.Class({
|
||||
name: 'cc.Counter',
|
||||
ctor (id, opts, now) {
|
||||
this._id = id;
|
||||
this._opts = opts || {};
|
||||
|
||||
this._value = 0;
|
||||
this._total = 0;
|
||||
this._averageValue = 0;
|
||||
this._accumValue = 0;
|
||||
this._accumSamples = 0;
|
||||
this._accumStart = now;
|
||||
},
|
||||
|
||||
properties: {
|
||||
value: {
|
||||
get () {
|
||||
return this._value;
|
||||
},
|
||||
set (v) {
|
||||
this._value = v;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_average (v, now) {
|
||||
if (this._opts.average) {
|
||||
this._accumValue += v;
|
||||
++this._accumSamples;
|
||||
|
||||
let t = now;
|
||||
if (t - this._accumStart >= this._opts.average) {
|
||||
this._averageValue = this._accumValue / this._accumSamples;
|
||||
this._accumValue = 0;
|
||||
this._accumStart = t;
|
||||
this._accumSamples = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
sample (now) {
|
||||
this._average(this._value, now);
|
||||
},
|
||||
|
||||
human () {
|
||||
let v = this._opts.average ? this._averageValue : this._value;
|
||||
return Math.round(v * 100) / 100;
|
||||
},
|
||||
|
||||
alarm () {
|
||||
return (
|
||||
(this._opts.below && this._value < this._opts.below) ||
|
||||
(this._opts.over && this._value > this._opts.over)
|
||||
);
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = Counter;
|
52
engine/cocos2d/core/utils/profiler/perf-counter.js
Normal file
52
engine/cocos2d/core/utils/profiler/perf-counter.js
Normal file
@@ -0,0 +1,52 @@
|
||||
const Counter = require('./counter');
|
||||
|
||||
let PerfCounter = cc.Class({
|
||||
name: 'cc.PerfCounter',
|
||||
extends: Counter,
|
||||
|
||||
ctor (id, opts, now) {
|
||||
// DISABLE
|
||||
// this._idstart = `${id}_start`;
|
||||
// this._idend = `${id}_end`;
|
||||
|
||||
this._time = now;
|
||||
},
|
||||
|
||||
start(now) {
|
||||
this._time = now;
|
||||
|
||||
// DISABLE: long time running will cause performance drop down
|
||||
// window.performance.mark(this._idstart);
|
||||
},
|
||||
|
||||
end(now) {
|
||||
this._value = now - this._time;
|
||||
|
||||
// DISABLE: long time running will cause performance drop down
|
||||
// window.performance.mark(this._idend);
|
||||
// window.performance.measure(this._id, this._idstart, this._idend);
|
||||
|
||||
this._average(this._value);
|
||||
},
|
||||
|
||||
tick() {
|
||||
this.end();
|
||||
this.start();
|
||||
},
|
||||
|
||||
frame(now) {
|
||||
let t = now;
|
||||
let e = t - this._time;
|
||||
this._total++;
|
||||
let avg = this._opts.average || 1000;
|
||||
|
||||
if (e > avg) {
|
||||
this._value = this._total * 1000 / e;
|
||||
this._total = 0;
|
||||
this._time = t;
|
||||
this._average(this._value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = PerfCounter;
|
313
engine/cocos2d/core/utils/text-utils.js
Normal file
313
engine/cocos2d/core/utils/text-utils.js
Normal file
@@ -0,0 +1,313 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
import js from '../platform/js'
|
||||
|
||||
// Draw text the textBaseline ratio (Can adjust the appropriate baseline ratio based on the platform)
|
||||
let _BASELINE_RATIO = 0.26;
|
||||
let _BASELINE_OFFSET = 0;
|
||||
if (CC_RUNTIME) {
|
||||
_BASELINE_OFFSET = _BASELINE_RATIO * 2 / 3;
|
||||
}
|
||||
|
||||
const MAX_CACHE_SIZE = 100;
|
||||
|
||||
let pool = new js.Pool(2);
|
||||
pool.get = function () {
|
||||
var node = this._get() || {
|
||||
key: null,
|
||||
value: null,
|
||||
prev: null,
|
||||
next: null
|
||||
};
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
function LRUCache(size) {
|
||||
this.count = 0;
|
||||
this.limit = size;
|
||||
this.datas = {};
|
||||
this.head = null;
|
||||
this.tail = null;
|
||||
}
|
||||
|
||||
LRUCache.prototype.moveToHead = function (node) {
|
||||
node.next = this.head;
|
||||
node.prev = null;
|
||||
if (this.head !== null)
|
||||
this.head.prev = node;
|
||||
this.head = node;
|
||||
if (this.tail === null)
|
||||
this.tail = node;
|
||||
this.count++;
|
||||
this.datas[node.key] = node;
|
||||
}
|
||||
|
||||
LRUCache.prototype.put = function (key, value) {
|
||||
const node = pool.get();
|
||||
node.key = key;
|
||||
node.value = value;
|
||||
|
||||
if (this.count >= this.limit) {
|
||||
let discard = this.tail;
|
||||
delete this.datas[discard.key];
|
||||
this.count--;
|
||||
this.tail = discard.prev;
|
||||
this.tail.next = null;
|
||||
discard.prev = null;
|
||||
discard.next = null;
|
||||
pool.put(discard);
|
||||
}
|
||||
this.moveToHead(node);
|
||||
}
|
||||
|
||||
LRUCache.prototype.remove = function (node) {
|
||||
if (node.prev !== null) {
|
||||
node.prev.next = node.next;
|
||||
} else {
|
||||
this.head = node.next;
|
||||
}
|
||||
if (node.next !== null) {
|
||||
node.next.prev = node.prev;
|
||||
} else {
|
||||
this.tail = node.prev;
|
||||
}
|
||||
delete this.datas[node.key];
|
||||
this.count--;
|
||||
}
|
||||
|
||||
LRUCache.prototype.get = function (key) {
|
||||
const node = this.datas[key];
|
||||
if (node) {
|
||||
this.remove(node);
|
||||
this.moveToHead(node);
|
||||
return node.value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
LRUCache.prototype.clear = function () {
|
||||
this.count = 0;
|
||||
this.datas = {};
|
||||
this.head = null;
|
||||
this.tail = null;
|
||||
}
|
||||
|
||||
LRUCache.prototype.has = function (key) {
|
||||
return !!this.datas[key];
|
||||
}
|
||||
|
||||
LRUCache.prototype.delete = function (key) {
|
||||
const node = this.datas[key];
|
||||
this.remove(node);
|
||||
}
|
||||
|
||||
let measureCache = new LRUCache(MAX_CACHE_SIZE);
|
||||
|
||||
var textUtils = {
|
||||
|
||||
BASELINE_RATIO: _BASELINE_RATIO,
|
||||
MIDDLE_RATIO: (_BASELINE_RATIO + 1) / 2 - _BASELINE_RATIO,
|
||||
BASELINE_OFFSET: _BASELINE_OFFSET,
|
||||
|
||||
label_wordRex : /([a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôûа-яА-ЯЁё]+|\S)/,
|
||||
label_symbolRex : /^[!,.:;'}\]%\?>、‘“》?。,!]/,
|
||||
label_lastWordRex : /([a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôûаíìÍÌïÁÀáàÉÈÒÓòóŐőÙÚŰúűñÑæÆœŒÃÂãÔõěščřžýáíéóúůťďňĚŠČŘŽÁÍÉÓÚŤżźśóńłęćąŻŹŚÓŃŁĘĆĄ-яА-ЯЁё]+|\S)$/,
|
||||
label_lastEnglish : /[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôûаíìÍÌïÁÀáàÉÈÒÓòóŐőÙÚŰúűñÑæÆœŒÃÂãÔõěščřžýáíéóúůťďňĚŠČŘŽÁÍÉÓÚŤżźśóńłęćąŻŹŚÓŃŁĘĆĄ-яА-ЯЁё]+$/,
|
||||
label_firstEnglish : /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôûаíìÍÌïÁÀáàÉÈÒÓòóŐőÙÚŰúűñÑæÆœŒÃÂãÔõěščřžýáíéóúůťďňĚŠČŘŽÁÍÉÓÚŤżźśóńłęćąŻŹŚÓŃŁĘĆĄ-яА-ЯЁё]/,
|
||||
// The unicode standard will never assign a character from code point 0xD800 to 0xDFFF
|
||||
// high surrogate (0xD800-0xDBFF) and low surrogate(0xDC00-0xDFFF) combines to a character on the Supplementary Multilingual Plane
|
||||
// reference: https://en.wikipedia.org/wiki/UTF-16
|
||||
highSurrogateRex: /[\uD800-\uDBFF]/,
|
||||
lowSurrogateRex: /[\uDC00-\uDFFF]/,
|
||||
label_wrapinspection : true,
|
||||
|
||||
__CHINESE_REG: /^[\u4E00-\u9FFF\u3400-\u4DFF]+$/,
|
||||
__JAPANESE_REG: /[\u3000-\u303F]|[\u3040-\u309F]|[\u30A0-\u30FF]|[\uFF00-\uFFEF]|[\u4E00-\u9FAF]|[\u2605-\u2606]|[\u2190-\u2195]|\u203B/g,
|
||||
__KOREAN_REG: /^[\u1100-\u11FF]|[\u3130-\u318F]|[\uA960-\uA97F]|[\uAC00-\uD7AF]|[\uD7B0-\uD7FF]+$/,
|
||||
|
||||
isUnicodeCJK: function(ch) {
|
||||
return this.__CHINESE_REG.test(ch) || this.__JAPANESE_REG.test(ch) || this.__KOREAN_REG.test(ch);
|
||||
},
|
||||
|
||||
//Checking whether the character is a whitespace
|
||||
isUnicodeSpace: function(ch) {
|
||||
ch = ch.charCodeAt(0);
|
||||
return ((ch >= 9 && ch <= 13) || ch === 32 || ch === 133 || ch === 160 || ch === 5760 || (ch >= 8192 && ch <= 8202) || ch === 8232 || ch === 8233 || ch === 8239 || ch === 8287 || ch === 12288);
|
||||
},
|
||||
|
||||
safeMeasureText: function (ctx, string, desc) {
|
||||
let font = desc || ctx.font;
|
||||
let key = font + "\uD83C\uDFAE" + string;
|
||||
let cache = measureCache.get(key);
|
||||
if (cache !== null) {
|
||||
return cache;
|
||||
}
|
||||
|
||||
let metric = ctx.measureText(string);
|
||||
let width = metric && metric.width || 0;
|
||||
measureCache.put(key, width);
|
||||
|
||||
return width;
|
||||
},
|
||||
|
||||
// in case truncate a character on the Supplementary Multilingual Plane
|
||||
// test case: a = '😉🚗'
|
||||
// _safeSubstring(a, 1) === '😉🚗'
|
||||
// _safeSubstring(a, 0, 1) === '😉'
|
||||
// _safeSubstring(a, 0, 2) === '😉'
|
||||
// _safeSubstring(a, 0, 3) === '😉'
|
||||
// _safeSubstring(a, 0, 4) === '😉🚗'
|
||||
// _safeSubstring(a, 1, 2) === _safeSubstring(a, 1, 3) === '😉'
|
||||
// _safeSubstring(a, 2, 3) === _safeSubstring(a, 2, 4) === '🚗'
|
||||
_safeSubstring (targetString, startIndex, endIndex) {
|
||||
let newStartIndex = startIndex, newEndIndex = endIndex;
|
||||
let startChar = targetString[startIndex];
|
||||
if (this.lowSurrogateRex.test(startChar)) {
|
||||
newStartIndex--;
|
||||
}
|
||||
if (endIndex !== undefined) {
|
||||
if (endIndex - 1 !== startIndex) {
|
||||
let endChar = targetString[endIndex - 1];
|
||||
if (this.highSurrogateRex.test(endChar)) {
|
||||
newEndIndex--;
|
||||
}
|
||||
}
|
||||
else if (this.highSurrogateRex.test(startChar)) {
|
||||
newEndIndex++;
|
||||
}
|
||||
}
|
||||
return targetString.substring(newStartIndex, newEndIndex);
|
||||
},
|
||||
|
||||
fragmentText: function (stringToken, allWidth, maxWidth, measureText) {
|
||||
//check the first character
|
||||
var wrappedWords = [];
|
||||
//fast return if strArr is empty
|
||||
if(stringToken.length === 0 || maxWidth < 0) {
|
||||
wrappedWords.push('');
|
||||
return wrappedWords;
|
||||
}
|
||||
|
||||
var text = stringToken;
|
||||
while (allWidth > maxWidth && text.length > 1) {
|
||||
|
||||
var fuzzyLen = text.length * ( maxWidth / allWidth ) | 0;
|
||||
var tmpText = this._safeSubstring(text, fuzzyLen);
|
||||
var width = allWidth - measureText(tmpText);
|
||||
var sLine = tmpText;
|
||||
var pushNum = 0;
|
||||
|
||||
var checkWhile = 0;
|
||||
var checkCount = 10;
|
||||
|
||||
//Exceeded the size
|
||||
while (width > maxWidth && checkWhile++ < checkCount) {
|
||||
fuzzyLen *= maxWidth / width;
|
||||
fuzzyLen = fuzzyLen | 0;
|
||||
tmpText = this._safeSubstring(text, fuzzyLen);
|
||||
width = allWidth - measureText(tmpText);
|
||||
}
|
||||
|
||||
checkWhile = 0;
|
||||
|
||||
//Find the truncation point
|
||||
while (width <= maxWidth && checkWhile++ < checkCount) {
|
||||
if (tmpText) {
|
||||
var exec = this.label_wordRex.exec(tmpText);
|
||||
pushNum = exec ? exec[0].length : 1;
|
||||
sLine = tmpText;
|
||||
}
|
||||
|
||||
fuzzyLen = fuzzyLen + pushNum;
|
||||
tmpText = this._safeSubstring(text, fuzzyLen);
|
||||
width = allWidth - measureText(tmpText);
|
||||
}
|
||||
|
||||
fuzzyLen -= pushNum;
|
||||
// in case maxWidth cannot contain any characters, need at least one character per line
|
||||
if (fuzzyLen === 0) {
|
||||
fuzzyLen = 1;
|
||||
sLine = this._safeSubstring(text, 1);
|
||||
}
|
||||
else if (fuzzyLen === 1 && this.highSurrogateRex.test(text[0])) {
|
||||
fuzzyLen = 2;
|
||||
sLine = this._safeSubstring(text, 2);
|
||||
}
|
||||
|
||||
var sText = this._safeSubstring(text, 0, fuzzyLen), result;
|
||||
|
||||
//symbol in the first
|
||||
if (this.label_wrapinspection) {
|
||||
if (this.label_symbolRex.test(sLine || tmpText)) {
|
||||
result = this.label_lastWordRex.exec(sText);
|
||||
fuzzyLen -= result ? result[0].length : 0;
|
||||
if (fuzzyLen === 0) fuzzyLen = 1;
|
||||
|
||||
sLine = this._safeSubstring(text, fuzzyLen);
|
||||
sText = this._safeSubstring(text, 0, fuzzyLen);
|
||||
}
|
||||
}
|
||||
|
||||
//To judge whether a English words are truncated
|
||||
if (this.label_firstEnglish.test(sLine)) {
|
||||
result = this.label_lastEnglish.exec(sText);
|
||||
if (result && sText !== result[0]) {
|
||||
fuzzyLen -= result[0].length;
|
||||
sLine = this._safeSubstring(text, fuzzyLen);
|
||||
sText = this._safeSubstring(text, 0, fuzzyLen);
|
||||
}
|
||||
}
|
||||
|
||||
// The first line And do not wrap should not remove the space
|
||||
if (wrappedWords.length === 0) {
|
||||
wrappedWords.push(sText);
|
||||
}
|
||||
else {
|
||||
sText = sText.trimLeft();
|
||||
if (sText.length > 0) {
|
||||
wrappedWords.push(sText);
|
||||
}
|
||||
}
|
||||
text = sLine || tmpText;
|
||||
allWidth = measureText(text);
|
||||
}
|
||||
|
||||
if (wrappedWords.length === 0) {
|
||||
wrappedWords.push(text);
|
||||
}
|
||||
else {
|
||||
text = text.trimLeft();
|
||||
if (text.length > 0) {
|
||||
wrappedWords.push(text);
|
||||
}
|
||||
}
|
||||
return wrappedWords;
|
||||
},
|
||||
};
|
||||
|
||||
cc.textUtils = module.exports = textUtils;
|
77
engine/cocos2d/core/utils/texture-util.js
Normal file
77
engine/cocos2d/core/utils/texture-util.js
Normal file
@@ -0,0 +1,77 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
const Texture2D = require('../assets/CCTexture2D');
|
||||
|
||||
let textureUtil = {
|
||||
loadImage (url, cb, target) {
|
||||
cc.assertID(url, 3103);
|
||||
|
||||
var tex = cc.assetManager.assets.get(url);
|
||||
if (tex) {
|
||||
if (tex.loaded) {
|
||||
cb && cb.call(target, null, tex);
|
||||
return tex;
|
||||
}
|
||||
else
|
||||
{
|
||||
tex.once("load", function(){
|
||||
cb && cb.call(target, null, tex);
|
||||
}, target);
|
||||
return tex;
|
||||
}
|
||||
}
|
||||
else {
|
||||
cc.assetManager.loadRemote(url, function (err, texture) {
|
||||
cb && cb.call(target, err, texture);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
cacheImage (url, image) {
|
||||
if (url && image) {
|
||||
var tex = new Texture2D();
|
||||
tex.initWithElement(image);
|
||||
cc.assetManager.assets.add(url, tex);
|
||||
return tex;
|
||||
}
|
||||
},
|
||||
|
||||
postLoadTexture (texture, callback) {
|
||||
if (texture.loaded) {
|
||||
callback && callback();
|
||||
return;
|
||||
}
|
||||
if (!texture.nativeUrl) {
|
||||
callback && callback();
|
||||
return;
|
||||
}
|
||||
// load image
|
||||
cc.assetManager.postLoadNative(texture, callback);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = textureUtil;
|
31
engine/cocos2d/core/utils/trans-pool/index.js
Normal file
31
engine/cocos2d/core/utils/trans-pool/index.js
Normal file
@@ -0,0 +1,31 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
let NodeUnit = require('./node-unit');
|
||||
let NodeMemPool = require('./node-mem-pool');
|
||||
|
||||
module.exports = {
|
||||
NodeMemPool: new NodeMemPool(NodeUnit)
|
||||
};
|
109
engine/cocos2d/core/utils/trans-pool/mem-pool.js
Normal file
109
engine/cocos2d/core/utils/trans-pool/mem-pool.js
Normal file
@@ -0,0 +1,109 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
let MemPool = function (unitClass) {
|
||||
this._unitClass = unitClass;
|
||||
this._pool = [];
|
||||
this._findOrder = [];
|
||||
|
||||
if (CC_JSB && CC_NATIVERENDERER) {
|
||||
this._initNative();
|
||||
}
|
||||
};
|
||||
|
||||
let proto = MemPool.prototype;
|
||||
proto._initNative = function () {
|
||||
this._nativeMemPool = new renderer.MemPool();
|
||||
};
|
||||
|
||||
proto._buildUnit = function (unitID) {
|
||||
let unit = new this._unitClass(unitID, this);
|
||||
if (CC_JSB && CC_NATIVERENDERER) {
|
||||
this._nativeMemPool.updateCommonData(unitID, unit._data, unit._signData);
|
||||
}
|
||||
return unit;
|
||||
};
|
||||
|
||||
proto._destroyUnit = function (unitID) {
|
||||
this._pool[unitID] = null;
|
||||
for (let idx = 0, n = this._findOrder.length; idx < n; idx++) {
|
||||
let unit = this._findOrder[idx];
|
||||
if (unit && unit.unitID == unitID) {
|
||||
this._findOrder.splice(idx, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (CC_JSB && CC_NATIVERENDERER) {
|
||||
this._nativeMemPool.removeCommonData(unitID);
|
||||
}
|
||||
};
|
||||
|
||||
proto._findUnitID = function () {
|
||||
let unitID = 0;
|
||||
let pool = this._pool;
|
||||
while (pool[unitID]) unitID++;
|
||||
return unitID;
|
||||
};
|
||||
|
||||
proto.pop = function () {
|
||||
let findUnit = null;
|
||||
let idx = 0;
|
||||
let findOrder = this._findOrder;
|
||||
let pool = this._pool;
|
||||
for (let n = findOrder.length; idx < n; idx++) {
|
||||
let unit = findOrder[idx];
|
||||
if (unit && unit.hasSpace()) {
|
||||
findUnit = unit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!findUnit) {
|
||||
let unitID = this._findUnitID();
|
||||
findUnit = this._buildUnit(unitID);
|
||||
pool[unitID] = findUnit;
|
||||
findOrder.push(findUnit);
|
||||
idx = findOrder.length - 1;
|
||||
}
|
||||
|
||||
// swap has space unit to first position, so next find will fast
|
||||
let firstUnit = findOrder[0];
|
||||
if (firstUnit !== findUnit) {
|
||||
findOrder[0] = findUnit;
|
||||
findOrder[idx] = firstUnit;
|
||||
}
|
||||
|
||||
return findUnit.pop();
|
||||
};
|
||||
|
||||
proto.push = function (info) {
|
||||
let unit = this._pool[info.unitID];
|
||||
unit.push(info.index);
|
||||
if (this._findOrder.length > 1 && unit.isAllFree()) {
|
||||
this._destroyUnit(info.unitID);
|
||||
}
|
||||
return unit;
|
||||
};
|
||||
module.exports = MemPool;
|
49
engine/cocos2d/core/utils/trans-pool/node-mem-pool.js
Normal file
49
engine/cocos2d/core/utils/trans-pool/node-mem-pool.js
Normal file
@@ -0,0 +1,49 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
let MemPool = require('./mem-pool');
|
||||
let NodeMemPool = function (unitClass) {
|
||||
MemPool.call(this, unitClass);
|
||||
};
|
||||
|
||||
(function(){
|
||||
let Super = function(){};
|
||||
Super.prototype = MemPool.prototype;
|
||||
NodeMemPool.prototype = new Super();
|
||||
})();
|
||||
|
||||
let proto = NodeMemPool.prototype;
|
||||
proto._initNative = function () {
|
||||
this._nativeMemPool = new renderer.NodeMemPool();
|
||||
};
|
||||
|
||||
proto._destroyUnit = function (unitID) {
|
||||
MemPool.prototype._destroyUnit.call(this, unitID);
|
||||
if (CC_JSB && CC_NATIVERENDERER) {
|
||||
this._nativeMemPool.removeNodeData(unitID);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = NodeMemPool;
|
142
engine/cocos2d/core/utils/trans-pool/node-unit.js
Normal file
142
engine/cocos2d/core/utils/trans-pool/node-unit.js
Normal file
@@ -0,0 +1,142 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
import { FLOAT_ARRAY_TYPE, FLOAT_BYTES } from '../../value-types/utils'
|
||||
|
||||
const Uint32_Bytes = 4;
|
||||
const Uint8_Bytes = 1;
|
||||
|
||||
// Space : [Dirty] [Size:4 Uint32]
|
||||
const Dirty_Type = Uint32Array;
|
||||
const Dirty_Members = 1;
|
||||
const Dirty_Stride = Dirty_Members * Uint32_Bytes;
|
||||
|
||||
// Space : [TRS] [Size:4 * 10 Float32|Float64]
|
||||
const TRS_Members = 10;
|
||||
const TRS_Stride = TRS_Members * FLOAT_BYTES;
|
||||
|
||||
// Space : [LocalMatrix] [Size:4 * 16 Float32|Float64]
|
||||
const LocalMatrix_Members = 16;
|
||||
const LocalMatrix_Stride = LocalMatrix_Members * FLOAT_BYTES;
|
||||
|
||||
// Space : [WorldMatrix] [Size:4 * 16 Float32|Float64]
|
||||
const WorldMatrix_Members = 16;
|
||||
const WorldMatrix_Stride = WorldMatrix_Members * FLOAT_BYTES;
|
||||
|
||||
// Space : [Parent Unit] [Size:4 Uint32]
|
||||
// Space : [Parent Index] [Size:4 Uint32]
|
||||
const Parent_Type = Uint32Array;
|
||||
const Parent_Members = 2;
|
||||
const Parent_Stride = Parent_Members * Uint32_Bytes;
|
||||
|
||||
// Space : [ZOrder] [Size:4 Uint32]
|
||||
const ZOrder_Type = Uint32Array;
|
||||
const ZOrder_Members = 1;
|
||||
const ZOrder_Stride = ZOrder_Members * Uint32_Bytes;
|
||||
|
||||
// Space : [CullingMask] [Size:4 Int32]
|
||||
const CullingMask_Type = Int32Array;
|
||||
const CullingMask_Members = 1;
|
||||
const CullingMask_Stride = CullingMask_Members * Uint32_Bytes;
|
||||
|
||||
// Space : [Opacity] [Size:1 Uint8]
|
||||
const Opacity_Type = Uint8Array;
|
||||
const Opacity_Members = 1;
|
||||
const Opacity_Stride = Opacity_Members * Uint8_Bytes;
|
||||
|
||||
// Space : [Is3D] [Size:1 Uint8]
|
||||
const Is3D_Type = Uint8Array;
|
||||
const Is3D_Members = 1;
|
||||
const Is3D_Stride = Is3D_Members * Uint8_Bytes;
|
||||
|
||||
// Space : [NodePtr] [Size:4 * 2 Uint32]
|
||||
const Node_Type = Uint32Array;
|
||||
const Node_Members = 2;
|
||||
|
||||
// Space : [Skew] [Size:4 * 2 Float32]
|
||||
const Skew_Members = 2;
|
||||
const Skew_Stride = Skew_Members * FLOAT_BYTES;
|
||||
|
||||
let UnitBase = require('./unit-base');
|
||||
let NodeUnit = function (unitID, memPool) {
|
||||
UnitBase.call(this, unitID, memPool);
|
||||
|
||||
let contentNum = this._contentNum;
|
||||
this.trsList = new FLOAT_ARRAY_TYPE(contentNum * TRS_Members);
|
||||
this.localMatList = new FLOAT_ARRAY_TYPE(contentNum * LocalMatrix_Members);
|
||||
this.worldMatList = new FLOAT_ARRAY_TYPE(contentNum * WorldMatrix_Members);
|
||||
|
||||
if (CC_JSB && CC_NATIVERENDERER) {
|
||||
this.dirtyList = new Dirty_Type(contentNum * Dirty_Members);
|
||||
this.parentList = new Parent_Type(contentNum * Parent_Members);
|
||||
this.zOrderList = new ZOrder_Type(contentNum * ZOrder_Members);
|
||||
this.cullingMaskList = new CullingMask_Type(contentNum * CullingMask_Members);
|
||||
this.opacityList = new Opacity_Type(contentNum * Opacity_Members);
|
||||
this.is3DList = new Is3D_Type(contentNum * Is3D_Members);
|
||||
this.nodeList = new Node_Type(contentNum * Node_Members);
|
||||
this.skewList = new FLOAT_ARRAY_TYPE(contentNum * Skew_Members);
|
||||
|
||||
this._memPool._nativeMemPool.updateNodeData(
|
||||
unitID,
|
||||
this.dirtyList,
|
||||
this.trsList,
|
||||
this.localMatList,
|
||||
this.worldMatList,
|
||||
this.parentList,
|
||||
this.zOrderList,
|
||||
this.cullingMaskList,
|
||||
this.opacityList,
|
||||
this.is3DList,
|
||||
this.nodeList,
|
||||
this.skewList
|
||||
);
|
||||
}
|
||||
|
||||
for (let i = 0; i < contentNum; i ++) {
|
||||
let space = this._spacesData[i];
|
||||
|
||||
space.trs = new FLOAT_ARRAY_TYPE(this.trsList.buffer, i * TRS_Stride, TRS_Members);
|
||||
space.localMat = new FLOAT_ARRAY_TYPE(this.localMatList.buffer, i * LocalMatrix_Stride, LocalMatrix_Members);
|
||||
space.worldMat = new FLOAT_ARRAY_TYPE(this.worldMatList.buffer, i * WorldMatrix_Stride, WorldMatrix_Members);
|
||||
|
||||
if (CC_JSB && CC_NATIVERENDERER) {
|
||||
space.dirty = new Dirty_Type(this.dirtyList.buffer, i * Dirty_Stride, Dirty_Members);
|
||||
space.parent = new Parent_Type(this.parentList.buffer, i * Parent_Stride, Parent_Members);
|
||||
space.zOrder = new ZOrder_Type(this.zOrderList.buffer, i * ZOrder_Stride, ZOrder_Members);
|
||||
space.cullingMask = new CullingMask_Type(this.cullingMaskList.buffer, i * CullingMask_Stride, CullingMask_Members);
|
||||
space.opacity = new Opacity_Type(this.opacityList.buffer, i * Opacity_Stride, Opacity_Members);
|
||||
space.is3D = new Is3D_Type(this.is3DList.buffer, i * Is3D_Stride, Is3D_Members);
|
||||
space.skew = new FLOAT_ARRAY_TYPE(this.skewList.buffer, i * Skew_Stride, Skew_Members);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
(function(){
|
||||
let Super = function(){};
|
||||
Super.prototype = UnitBase.prototype;
|
||||
NodeUnit.prototype = new Super();
|
||||
})();
|
||||
|
||||
module.exports = NodeUnit;
|
167
engine/cocos2d/core/utils/trans-pool/unit-base.js
Normal file
167
engine/cocos2d/core/utils/trans-pool/unit-base.js
Normal file
@@ -0,0 +1,167 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
// Unit has many segment, layout such as :
|
||||
// Head Free Pointer + Using Segment Num + Segment 1 + Segment 2 + Segment 3 ...
|
||||
|
||||
// sign data format
|
||||
// Space : [If Free Flag] [Size:1 Uint16]
|
||||
// Space : [Next Free Index] [Size:1 Uint16]
|
||||
|
||||
// invalid pointer value
|
||||
let POINTER_INVALID_FLAG = 0xffff;
|
||||
let SPACE_FREE_FLAG = 0x0;
|
||||
let SPACE_USE_FLAG = 0x1;
|
||||
let POS_NEXT_FREE = 0;
|
||||
let POS_FREE_FLAG = 1;
|
||||
|
||||
let UnitBase = function (unitID, memPool, contentNum) {
|
||||
contentNum = contentNum || 128;
|
||||
|
||||
// set unit id
|
||||
this.unitID = unitID;
|
||||
this._memPool = memPool;
|
||||
|
||||
this._data = new Uint16Array(2);
|
||||
// head of the free content index
|
||||
this._data[0] = 0;
|
||||
// using segment num
|
||||
this._data[1] = 0;
|
||||
|
||||
this._contentNum = contentNum;
|
||||
this._signData = new Uint16Array(this._contentNum * 2);
|
||||
this._spacesData = [];
|
||||
|
||||
for (let i = 0; i < contentNum; i++) {
|
||||
let signIndex = i * 2;
|
||||
// store content block index but not sign array index
|
||||
this._signData[signIndex + POS_NEXT_FREE] = i + 1;
|
||||
this._signData[signIndex + POS_FREE_FLAG] = SPACE_FREE_FLAG;
|
||||
|
||||
this._spacesData[i] = {
|
||||
index: i,
|
||||
unitID: unitID,
|
||||
};
|
||||
}
|
||||
// last one has no next space;
|
||||
this._signData[(contentNum - 1) * 2] = POINTER_INVALID_FLAG;
|
||||
};
|
||||
|
||||
let UnitBaseProto = UnitBase.prototype;
|
||||
UnitBaseProto.hasSpace = function () {
|
||||
return this._data[0] !== POINTER_INVALID_FLAG;
|
||||
};
|
||||
|
||||
UnitBaseProto.isAllFree = function () {
|
||||
return this._data[1] == 0;
|
||||
};
|
||||
|
||||
// pop space from unit
|
||||
UnitBaseProto.pop = function () {
|
||||
let headFreeIndex = this._data[0];
|
||||
if (headFreeIndex === POINTER_INVALID_FLAG) return null;
|
||||
|
||||
let index = headFreeIndex;
|
||||
let signIndex = index * 2;
|
||||
let space = this._spacesData[index];
|
||||
|
||||
// set use flag
|
||||
this._signData[signIndex + POS_FREE_FLAG] = SPACE_USE_FLAG;
|
||||
|
||||
// store new next free space index
|
||||
this._data[0] = this._signData[signIndex + POS_NEXT_FREE];
|
||||
// add using segment num
|
||||
this._data[1]++;
|
||||
return space;
|
||||
};
|
||||
|
||||
// push back to unit
|
||||
UnitBaseProto.push = function (index) {
|
||||
let signIndex = index * 2;
|
||||
|
||||
// set free flag
|
||||
this._signData[signIndex + POS_FREE_FLAG] = SPACE_FREE_FLAG;
|
||||
|
||||
// store head free index to the space
|
||||
this._signData[signIndex + POS_NEXT_FREE] = this._data[0];
|
||||
// update head free index
|
||||
this._data[0] = index;
|
||||
// sub using segment num
|
||||
this._data[1]--;
|
||||
};
|
||||
|
||||
// dump all space info
|
||||
UnitBaseProto.dump = function () {
|
||||
let spaceNum = 0;
|
||||
let index = this._data[0];
|
||||
let freeStr = "";
|
||||
|
||||
while (index != POINTER_INVALID_FLAG) {
|
||||
spaceNum ++;
|
||||
freeStr += index + "->";
|
||||
index = this._signData[index * 2 + POS_NEXT_FREE];
|
||||
}
|
||||
|
||||
let usingNum = 0;
|
||||
let usingStr = "";
|
||||
let contentNum = this._contentNum;
|
||||
for (let i = 0; i < contentNum; i++) {
|
||||
let freeFlag = this._signData[i * 2 + POS_FREE_FLAG];
|
||||
if (freeFlag == SPACE_USE_FLAG) {
|
||||
usingNum ++;
|
||||
usingStr += i + "->";
|
||||
}
|
||||
}
|
||||
|
||||
let totalNum = spaceNum + usingNum;
|
||||
console.log(
|
||||
"unitID:", this.unitID,
|
||||
"spaceNum:", spaceNum,
|
||||
"calc using num:", usingNum,
|
||||
'store using num:', this._data[1],
|
||||
'calc total num:', totalNum,
|
||||
'actually total num:', this._contentNum
|
||||
);
|
||||
console.log("free info:", freeStr);
|
||||
console.log("using info:", usingStr);
|
||||
|
||||
if (usingNum != this._data[1]) {
|
||||
cc.error(
|
||||
'using num error',
|
||||
"calc using num:", usingNum,
|
||||
'store using num:', this._data[1]
|
||||
);
|
||||
}
|
||||
|
||||
if (spaceNum + usingNum != this._contentNum) {
|
||||
cc.error(
|
||||
'total num error',
|
||||
'calc total num:', totalNum,
|
||||
'actually total num:', this._contentNum
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = UnitBase;
|
Reference in New Issue
Block a user