初始化

This commit is contained in:
SmallMain
2022-06-25 00:23:03 +08:00
commit ef0589e8e5
2264 changed files with 617829 additions and 0 deletions

View 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;

View 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;

File diff suppressed because it is too large Load Diff

View 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
};

View 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;

View 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;
}

View 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;
};

View 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;

View 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([/&lt;/g, '<']);
this._specialSymbolArray.push([/&gt;/g, '>']);
this._specialSymbolArray.push([/&amp;/g, '&']);
this._specialSymbolArray.push([/&quot;/g, '"']);
this._specialSymbolArray.push([/&apos;/g, '\'']);
this._specialSymbolArray.push([/&nbsp;/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;

View 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');

View 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
};

View 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;

View 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;

View 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;
}

View 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;
}
};

View 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;
}
}
}

View 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;

View 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;

View 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;

View 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;

View 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)
};

View 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;

View 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;

View 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;

View 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;