Skip to content

Commit

Permalink
Merge pull request cocos#1927 from jareguo/master
Browse files Browse the repository at this point in the history
optimize deserialize
  • Loading branch information
nantas authored Aug 28, 2017
2 parents 3055157 + 78b7a0d commit 71ecadb
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 71 deletions.
20 changes: 10 additions & 10 deletions cocos2d/core/CCDirector.js
Original file line number Diff line number Diff line change
Expand Up @@ -537,9 +537,9 @@ cc.Director = Class.extend(/** @lends cc.Director# */{
*/
runSceneImmediate: function (scene, onBeforeLoadScene, onLaunched) {
if (scene instanceof cc.Scene) {
CC_DEBUG && console.time('InitScene');
CC_BUILD && CC_DEBUG && console.time('InitScene');
scene._load(); // ensure scene initialized
CC_DEBUG && console.timeEnd('InitScene');
CC_BUILD && CC_DEBUG && console.timeEnd('InitScene');
}

// detach persist nodes
Expand All @@ -558,14 +558,14 @@ cc.Director = Class.extend(/** @lends cc.Director# */{

if (!CC_EDITOR) {
// auto release assets
CC_DEBUG && console.time('AutoRelease');
CC_BUILD && CC_DEBUG && console.time('AutoRelease');
var autoReleaseAssets = oldScene && oldScene.autoReleaseAssets && oldScene.dependAssets;
AutoReleaseUtils.autoRelease(autoReleaseAssets, scene.dependAssets, persistNodeList);
CC_DEBUG && console.timeEnd('AutoRelease');
CC_BUILD && CC_DEBUG && console.timeEnd('AutoRelease');
}

// unload scene
CC_DEBUG && console.time('Destroy');
CC_BUILD && CC_DEBUG && console.time('Destroy');
if (cc.isValid(oldScene)) {
oldScene.destroy();
}
Expand All @@ -574,7 +574,7 @@ cc.Director = Class.extend(/** @lends cc.Director# */{

// purge destroyed nodes belongs to old scene
cc.Object._deferredDestroy();
CC_DEBUG && console.timeEnd('Destroy');
CC_BUILD && CC_DEBUG && console.timeEnd('Destroy');

if (onBeforeLoadScene) {
onBeforeLoadScene();
Expand All @@ -591,7 +591,7 @@ cc.Director = Class.extend(/** @lends cc.Director# */{
// Re-attach or replace persist nodes
for (let i = 0; i < persistNodeList.length; i++) {
let node = persistNodeList[i];
CC_DEBUG && console.time('AttachPersist');
CC_BUILD && CC_DEBUG && console.time('AttachPersist');
var existNode = scene.getChildByUuid(node.uuid);
if (existNode) {
// scene also contains the persist node, select the old one
Expand All @@ -603,10 +603,10 @@ cc.Director = Class.extend(/** @lends cc.Director# */{
node.parent = scene;
}
}
CC_DEBUG && console.timeEnd('AttachPersist');
CC_DEBUG && console.time('Activate');
CC_BUILD && CC_DEBUG && console.timeEnd('AttachPersist');
CC_BUILD && CC_DEBUG && console.time('Activate');
scene._activate();
CC_DEBUG && console.timeEnd('Activate');
CC_BUILD && CC_DEBUG && console.timeEnd('Activate');
}

// Run or replace rendering scene
Expand Down
4 changes: 2 additions & 2 deletions cocos2d/core/components/missing-script.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
****************************************************************************/

var JS = cc.js;
var isBuiltinClassId = require('../utils/misc').isBuiltinClassId;
var BUILTIN_CLASSID_RE = require('../utils/misc').BUILTIN_CLASSID_RE;

/*
* A temp fallback to contain the original serialized data which can not be loaded.
Expand Down Expand Up @@ -110,7 +110,7 @@ var MissingScript = cc.Class({
return null;
},
getMissingWrapper: function (id, data) {
if (data.node && (/^[0-9a-zA-Z+/]{23}$/.test(id) || isBuiltinClassId(id))) {
if (data.node && (/^[0-9a-zA-Z+/]{23}$/.test(id) || BUILTIN_CLASSID_RE.test(id))) {
// is component
return MissingScript;
}
Expand Down
50 changes: 50 additions & 0 deletions cocos2d/core/platform/compiler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/****************************************************************************
Copyright (c) 2013-2017 Chukong Technologies Inc.
http://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.
Chukong Aipu 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.
****************************************************************************/

function deepFlatten (strList, array) {
for (var i = 0; i < array.length; i++) {
var item = array[i];
if (Array.isArray(item)) {
deepFlatten(strList, item);
}
// else if (item instanceof Declaration) {
// strList.push(item.toString());
// }
else {
strList.push(item);
}
}
}

function flattenCodeArray (array) {
var separator = CC_DEV ? '\n' : '';
var strList = [];
deepFlatten(strList, array);
return strList.join(separator);
}

module.exports = {
flattenCodeArray
};
106 changes: 76 additions & 30 deletions cocos2d/core/platform/deserialize.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var JS = require('./js');
var CCObject = require('./CCObject');
var Attr = require('./attribute');
var CCClass = require('./CCClass');
var Misc = require('../utils/misc');

// HELPERS

Expand Down Expand Up @@ -223,11 +224,11 @@ var _Deserializer = (function () {
var prop;
var obj = null; // the obj to return
var klass = null;
if (serialized.__type__) {
var type = serialized.__type__;
if (type) {

// Type Object (including CCClass)

var type = serialized.__type__;
klass = this._classFinder(type, serialized, owner, propName);
if (!klass) {
var notReported = this._classFinder === JS._getClassById;
Expand All @@ -247,10 +248,6 @@ var _Deserializer = (function () {
else {
// instantiate a new object
obj = new klass();
// Temporary solution
if (CC_JSB && klass === cc.SpriteFrame) {
obj.retain();
}
}

if (obj._deserialize) {
Expand Down Expand Up @@ -370,6 +367,32 @@ var _Deserializer = (function () {
}
};

// function _compileTypedObject (accessor, klass, ctorCode) {
// if (klass === cc.Vec2) {
// return `{` +
// `o${accessor}.x=prop.x||0;` +
// `o${accessor}.y=prop.y||0;` +
// `}`;
// }
// else if (klass === cc.Color) {
// return `{` +
// `o${accessor}.r=prop.r||0;` +
// `o${accessor}.g=prop.g||0;` +
// `o${accessor}.b=prop.b||0;` +
// `o${accessor}.a=(prop.a===undefined?255:prop.a);` +
// `}`;
// }
// else if (klass === cc.Size) {
// return `{` +
// `o${accessor}.width=prop.width||0;` +
// `o${accessor}.height=prop.height||0;` +
// `}`;
// }
// else {
// return `s._deserializeTypedObject(o${accessor},prop,${ctorCode});`;
// }
// }

prototype._deserializeTypedObject = function (instance, serialized, klass) {
if (klass === cc.Vec2) {
instance.x = serialized.x || 0;
Expand All @@ -384,6 +407,11 @@ var _Deserializer = (function () {
instance.a = (a === undefined ? 255 : a);
return;
}
else if (klass === cc.Size) {
instance.width = serialized.width || 0;
instance.height = serialized.height || 0;
return;
}

var fastDefinedProps = klass.__props__;
if (!fastDefinedProps) {
Expand Down Expand Up @@ -467,18 +495,45 @@ var _Deserializer = (function () {
// self._deserializePrimitiveObject(obj._$erialized, serialized);
// }
// }

function compileObjectType (sources, defaultValue, accessor, propNameLiteral, assumeHavePropIfIsValue) {
if (defaultValue instanceof cc.ValueType) {
// fast case
if (!assumeHavePropIfIsValue) {
sources.push('if(prop){');
}
var ctorCode = JS.getClassName(defaultValue);
sources.push(`s._deserializeTypedObject(o${accessor},prop,${ctorCode});`);
if (!assumeHavePropIfIsValue) {
sources.push('}else o' + accessor + '=null;');
}
}
else {
sources.push('if(prop){');
if (CC_EDITOR || CC_TEST) {
sources.push('s._deserializeObjField(o,prop,' + propNameLiteral + ',t&&o);');
}
else {
sources.push('s._deserializeObjField(o,prop,' + propNameLiteral + ');');
}
sources.push('}else o' + accessor + '=null;');
}
}

function compileDeserialize (self, klass) {
var RAW_TYPE = Attr.DELIMETER + 'rawType';
var EDITOR_ONLY = Attr.DELIMETER + 'editorOnly';
var SERIALIZABLE = Attr.DELIMETER + 'serializable';
var DEFAULT = Attr.DELIMETER + 'default';
var SAVE_URL_AS_ASSET = Attr.DELIMETER + 'saveUrlAsAsset';
var attrs = Attr.getClassAttrs(klass);

var props = klass.__props__;
// self, obj, serializedData, klass, target
var sources = [
'var prop;'
];
var fastMode = Misc.BUILTIN_CLASSID_RE.test(JS._getClassId(klass));
// sources.push('var vb,vn,vs,vo,vu,vf;'); // boolean, number, string, object, undefined, function
for (var p = 0; p < props.length; p++) {
var propName = props[p];
Expand Down Expand Up @@ -507,38 +562,29 @@ var _Deserializer = (function () {

sources.push('prop=d' + accessor + ';');
sources.push(`if(typeof ${CC_JSB ? '(prop)' : 'prop'}!=="undefined"){`);
sources.push( `if(typeof ${CC_JSB ? '(prop)' : 'prop'}!=="object"){` +
'o' + accessor + '=prop;');
sources.push( '}else{' +
'if(prop){');

// function undefined object(null) string boolean number
var defaultValue = CCClass.getDefault(attrs[propName + DEFAULT]);
if (defaultValue instanceof cc.ValueType) {
// fast case
var ctorCode = JS.getClassName(defaultValue);
if (CC_EDITOR || CC_TEST) {
sources.push( 'if(!t)' + // if has default value
`s._deserializeTypedObject(o${accessor},prop,${ctorCode});`);
sources.push( 'else ' + // slow case
's._deserializeObjField(o,prop,' + propNameLiteral + ',o);');
if (fastMode) {
var defaultType = typeof defaultValue;
var isPrimitiveType = (defaultType === 'string' && !attrs[propName + SAVE_URL_AS_ASSET]) ||
defaultType === 'number' ||
defaultType === 'boolean';
if (isPrimitiveType) {
sources.push(`o${accessor}=prop;`);
}
else {
sources.push( `s._deserializeTypedObject(o${accessor},prop,${ctorCode});`);
compileObjectType(sources, defaultValue, accessor, propNameLiteral, true);
}
}
else {
// slow case
if (CC_EDITOR || CC_TEST) {
sources.push( 's._deserializeObjField(o,prop,' + propNameLiteral + ',t&&o);');
}
else {
sources.push( 's._deserializeObjField(o,prop,' + propNameLiteral + ');');
}
sources.push(`if(typeof ${CC_JSB ? '(prop)' : 'prop'}!=="object"){` +
'o' + accessor + '=prop;' +
'}else{');
compileObjectType(sources, defaultValue, accessor, propNameLiteral, false);
sources.push('}');
}

sources.push( '}else o' + accessor + '=null;' +
'}' +
'}');
sources.push('}');
}
else {
if (CCClass.IDENTIFIER_RE.test(propName)) {
Expand Down
34 changes: 8 additions & 26 deletions cocos2d/core/platform/instantiate-jit.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
/****************************************************************************
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2013-2017 Chukong Technologies Inc.
http://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
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.
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.
Chukong Aipu reserves all rights not expressly granted to you.
Expand All @@ -31,6 +31,7 @@ var PersistentMask = CCObject.Flags.PersistentMask;
var Attr = require('./attribute');
var JS = require('./js');
var CCClass = require('./CCClass');
var Compiler = require('./compiler');

var SERIALIZABLE = Attr.DELIMETER + 'serializable';
var DEFAULT = Attr.DELIMETER + 'default';
Expand Down Expand Up @@ -169,25 +170,6 @@ function equalsToDefault (def, value) {
return false;
}

function flattenCodeArray (array, separator) {
var strList = [];
(function deepFlatten (array) {
for (var i = 0; i < array.length; i++) {
var item = array[i];
if (Array.isArray(item)) {
deepFlatten(item);
}
// else if (item instanceof Declaration) {
// strList.push(item.toString());
// }
else {
strList.push(item);
}
}
})(array);
return strList.join(separator);
}

function getPropAccessor (key) {
return IDENTIFIER_RE.test(key) ? ('.' + key) : ('[' + escapeForJS(key) + ']');
}
Expand Down Expand Up @@ -248,11 +230,11 @@ function Parser (obj, parent) {
if (this.globalVariables.length > 0) {
globalVariablesDeclaration = VAR + this.globalVariables.join(',') + ';';
}
var code = flattenCodeArray(['return (function(R){',
var code = Compiler.flattenCodeArray(['return (function(R){',
globalVariablesDeclaration || [],
this.codeArray,
'return o;',
'})'], CC_DEV ? '\n' : '');
'})']);

// generate method and bind with objs
this.result = Function('O', 'F', code)(this.objs, this.funcs);
Expand Down
4 changes: 1 addition & 3 deletions cocos2d/core/utils/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,7 @@ if ((sys.os === sys.OS_WINDOWS || sys.os === sys.OS_LINUX) && sys.browser !== sy
misc.imagePool.resize(0);
}

misc.isBuiltinClassId = function (id) {
return id.startsWith('cc.') || id.startsWith('dragonBones.') || id.startsWith('sp.') || id.startsWith('ccsg.');
};
misc.BUILTIN_CLASSID_RE = /^(?:cc|dragonBones|sp|ccsg)\..+/;


var BASE64_KEYS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
Expand Down

0 comments on commit 71ecadb

Please sign in to comment.