Merge https://github.com/cocos2d/cocos2d-x into iss3713-replace_CCObject

This commit is contained in:
minggo 2014-01-21 13:46:40 +08:00
commit 5fd35c3bab
37 changed files with 1054 additions and 147 deletions

View File

@ -718,6 +718,7 @@ Developers:
Pisces000221
Corrected a few mistakes in the README file of project-creator.
Corrected a mistake in README.
hbbalfred
Fixed a bug that crash if file doesn't exist when using FileUtils::getStringFromFile.

View File

@ -1,5 +1,6 @@
cocos2d-x-3.0beta2 ?.? ?
[All]
[NEW] Adds performance test for Containers(Vector<>, Array, Map<K,V>, Dictionary).
[NEW] DrawNode supports to draw triangle, quad bezier, cubic bezier.
[NEW] Console: added the 'textures', 'fileutils dump' and 'config' commands
[NEW] GLCache: glActiveTexture() is cached with GL::activeTexture(). All code MUST call the cached version in order to work correctly

View File

@ -24,12 +24,12 @@ How to start a new game
1. Download the code from [cocos2d download site][4]
2. Enter `tools/project-creator`
3. Run the `create-projects.py` script
3. Run the `create_project.py` script
Example:
$ cd cocos2d-x/tools/project-creator
$ ./project-creator.py -n mygame -k com.your_company.mygame -l cpp -p /home/mygame
$ ./create_project.py -n mygame -k com.your_company.mygame -l cpp -p /home/mygame
$ cd /home/mygame
### Build new project for android ###

View File

@ -12,6 +12,16 @@ LUA_SAMPLES = ['hellolua', 'testlua']
JSB_SAMPLES = ['cocosdragon', 'crystalcraze', 'moonwarriors', 'testjavascript', 'watermelonwithme']
ALL_SAMPLES = CPP_SAMPLES + LUA_SAMPLES + JSB_SAMPLES
def get_num_of_cpu():
''' The build process can be accelerated by running multiple concurrent job processes using the -j-option.
'''
try:
from numpy.distutils import cpuinfo
return cpuinfo.cpu._getNCPUs()
except Exception:
print "Can't know cpuinfo, use default 1 cpu"
return 1
def check_environment_variables():
''' Checking the environment NDK_ROOT, which will be used for building
'''
@ -94,10 +104,12 @@ def do_build(cocos_root, ndk_root, app_android_root, ndk_build_param,sdk_root,an
else:
ndk_module_path = 'NDK_MODULE_PATH=%s:%s/external:%s/cocos' % (cocos_root, cocos_root, cocos_root)
num_of_cpu = get_num_of_cpu()
if ndk_build_param == None:
command = '%s -C %s %s' % (ndk_path, app_android_root, ndk_module_path)
command = '%s -j%d -C %s %s' % (ndk_path, num_of_cpu, app_android_root, ndk_module_path)
else:
command = '%s -C %s %s %s' % (ndk_path, app_android_root, ndk_build_param, ndk_module_path)
command = '%s -j%d -C %s %s %s' % (ndk_path, num_of_cpu, app_android_root, ndk_build_param, ndk_module_path)
print command
if os.system(command) != 0:
raise Exception("Build dynamic library for project [ " + app_android_root + " ] fails!")
elif android_platform is not None:

View File

@ -252,7 +252,7 @@ void ClippingNode::visit()
{
auto node = _children.at(i);
if ( node && node->getZOrder() < 0 )
if ( node && node->getLocalZOrder() < 0 )
node->visit();
else
break;

View File

@ -191,7 +191,7 @@ EventDispatcher::~EventDispatcher()
removeAllEventListeners();
}
void EventDispatcher::visitTarget(Node* node)
void EventDispatcher::visitTarget(Node* node, bool isRootNode)
{
int i = 0;
auto& children = node->getChildren();
@ -206,24 +206,55 @@ void EventDispatcher::visitTarget(Node* node)
{
child = children.at(i);
if ( child && child->getZOrder() < 0 )
visitTarget(child);
if ( child && child->getLocalZOrder() < 0 )
visitTarget(child, false);
else
break;
}
_nodePriorityMap.insert(std::make_pair(node, ++_nodePriorityIndex));
if (_nodeListenersMap.find(node) != _nodeListenersMap.end())
{
_globalZOrderNodeMap[node->getGlobalZOrder()].push_back(node);
}
for( ; i < childrenCount; i++ )
{
child = children.at(i);
if (child)
visitTarget(child);
visitTarget(child, false);
}
}
else
{
_nodePriorityMap.insert(std::make_pair(node, ++_nodePriorityIndex));
if (_nodeListenersMap.find(node) != _nodeListenersMap.end())
{
_globalZOrderNodeMap[node->getGlobalZOrder()].push_back(node);
}
}
if (isRootNode)
{
std::vector<int> globalZOrders;
globalZOrders.reserve(_globalZOrderNodeMap.size());
for (const auto& e : _globalZOrderNodeMap)
{
globalZOrders.push_back(e.first);
}
std::sort(globalZOrders.begin(), globalZOrders.end(), [](const int a, const int b){
return a < b;
});
for (const auto& globalZ : globalZOrders)
{
for (const auto& n : _globalZOrderNodeMap[globalZ])
{
_nodePriorityMap[n] = ++_nodePriorityIndex;
}
}
_globalZOrderNodeMap.clear();
}
}
@ -354,7 +385,7 @@ void EventDispatcher::forceAddEventListener(EventListener* listener)
}
else
{
setDirty(listenerID, DirtyFlag::FIXED_PRITORY);
setDirty(listenerID, DirtyFlag::FIXED_PRIORITY);
}
}
@ -496,7 +527,7 @@ void EventDispatcher::setPriority(EventListener* listener, int fixedPriority)
if (listener->getFixedPriority() != fixedPriority)
{
listener->setFixedPriority(fixedPriority);
setDirty(listener->getListenerID(), DirtyFlag::FIXED_PRITORY);
setDirty(listener->getListenerID(), DirtyFlag::FIXED_PRIORITY);
}
return;
}
@ -921,7 +952,7 @@ void EventDispatcher::sortEventListeners(const EventListener::ListenerID& listen
if (dirtyFlag != DirtyFlag::NONE)
{
if ((int)dirtyFlag & (int)DirtyFlag::FIXED_PRITORY)
if ((int)dirtyFlag & (int)DirtyFlag::FIXED_PRIORITY)
{
sortEventListenersOfFixedPriority(listenerID);
}
@ -947,7 +978,7 @@ void EventDispatcher::sortEventListenersOfSceneGraphPriority(const EventListener
_nodePriorityIndex = 0;
_nodePriorityMap.clear();
visitTarget(rootNode);
visitTarget(rootNode, true);
// After sort: priority < 0, > 0
auto sceneGraphlisteners = listeners->getSceneGraphPriorityListeners();

View File

@ -207,16 +207,16 @@ protected:
enum class DirtyFlag
{
NONE = 0,
FIXED_PRITORY = 1 << 0,
FIXED_PRIORITY = 1 << 0,
SCENE_GRAPH_PRIORITY = 1 << 1,
ALL = FIXED_PRITORY | SCENE_GRAPH_PRIORITY
ALL = FIXED_PRIORITY | SCENE_GRAPH_PRIORITY
};
/** Sets the dirty flag for a specified listener ID */
void setDirty(const EventListener::ListenerID& listenerID, DirtyFlag flag);
/** Walks though scene graph to get the draw order for each node, it's called before sorting event listener with scene graph priority */
void visitTarget(Node* node);
void visitTarget(Node* node, bool isRootNode);
/** Listeners map */
std::unordered_map<EventListener::ListenerID, EventListenerVector*> _listeners;
@ -230,6 +230,9 @@ protected:
/** The map of node and its event priority */
std::unordered_map<Node*, int> _nodePriorityMap;
/** key: Global Z Order, value: Sorted Nodes */
std::unordered_map<int, std::vector<Node*>> _globalZOrderNodeMap;
/** The listeners to be added after dispatching event */
std::vector<EventListener*> _toAddedListeners;

View File

@ -25,6 +25,10 @@
#include "CCFontCharMap.h"
#include "CCFontAtlas.h"
#include "platform/CCFileUtils.h"
#include "CCDirector.h"
#include "CCTextureCache.h"
#include "ccUTF8.h"
NS_CC_BEGIN

View File

@ -26,7 +26,6 @@
#ifndef _CCFontCharMap_h_
#define _CCFontCharMap_h_
#include "cocos2d.h"
#include "CCFont.h"
NS_CC_BEGIN

View File

@ -72,8 +72,8 @@ bool nodeComparisonLess(const RCPtr<Object>& pp1, const RCPtr<Object>& pp2)
Node *n1 = static_cast<Node*>(p1);
Node *n2 = static_cast<Node*>(p2);
return( n1->getZOrder() < n2->getZOrder() ||
( n1->getZOrder() == n2->getZOrder() && n1->getOrderOfArrival() < n2->getOrderOfArrival() )
return( n1->getLocalZOrder() < n2->getLocalZOrder() ||
( n1->getLocalZOrder() == n2->getLocalZOrder() && n1->getOrderOfArrival() < n2->getOrderOfArrival() )
);
}
#else
@ -82,8 +82,8 @@ bool nodeComparisonLess(Object* p1, Object* p2)
Node *n1 = static_cast<Node*>(p1);
Node *n2 = static_cast<Node*>(p2);
return( n1->getZOrder() < n2->getZOrder() ||
( n1->getZOrder() == n2->getZOrder() && n1->getOrderOfArrival() < n2->getOrderOfArrival() )
return( n1->getLocalZOrder() < n2->getLocalZOrder() ||
( n1->getLocalZOrder() == n2->getLocalZOrder() && n1->getOrderOfArrival() < n2->getOrderOfArrival() )
);
}
#endif
@ -232,6 +232,15 @@ void Node::setLocalZOrder(int z)
_eventDispatcher->setDirtyForNode(this);
}
void Node::setGlobalZOrder(float zOrder)
{
if (_globalZOrder != zOrder)
{
_globalZOrder = zOrder;
_eventDispatcher->setDirtyForNode(this);
}
}
/// vertexZ getter
float Node::getVertexZ() const
{

View File

@ -208,7 +208,7 @@ public:
@since v3.0
*/
virtual void setGlobalZOrder(float zOrder) { _globalZOrder = zOrder; }
virtual void setGlobalZOrder(float zOrder);
/**
* Returns the Node's Global Z Order.
*

View File

@ -125,7 +125,7 @@ void NodeGrid::visit()
{
auto node = _children.at(i);
if ( node && node->getZOrder() < 0 )
if ( node && node->getLocalZOrder() < 0 )
node->visit();
else
break;

View File

@ -218,7 +218,7 @@ void ParticleBatchNode::reorderChild(Node * aChild, int zOrder)
ParticleSystem* child = static_cast<ParticleSystem*>(aChild);
if( zOrder == child->getZOrder() )
if( zOrder == child->getLocalZOrder() )
{
return;
}
@ -280,7 +280,7 @@ void ParticleBatchNode::getCurrentIndex(int* oldIndex, int* newIndex, Node* chil
Node* pNode = _children.at(i);
// new index
if( pNode->getZOrder() > z && ! foundNewIdx )
if( pNode->getLocalZOrder() > z && ! foundNewIdx )
{
*newIndex = i;
foundNewIdx = true;
@ -325,7 +325,7 @@ int ParticleBatchNode::searchNewPositionInChildrenForZ(int z)
for( int i=0; i < count; i++ )
{
Node *child = _children.at(i);
if (child->getZOrder() > z)
if (child->getLocalZOrder() > z)
{
return i;
}

View File

@ -822,8 +822,8 @@ void Sprite::sortAllChildren()
auto tempJ = static_cast<Node*>( _children->getObjectAtIndex(j) );
//continue moving element downwards while zOrder is smaller or when zOrder is the same but mutatedIndex is smaller
while(j>=0 && ( tempI->getZOrder() < tempJ->getZOrder() ||
( tempI->getZOrder() == tempJ->getZOrder() &&
while(j>=0 && ( tempI->getLocalZOrder() < tempJ->getLocalZOrder() ||
( tempI->getLocalZOrder() == tempJ->getLocalZOrder() &&
tempI->getOrderOfArrival() < tempJ->getOrderOfArrival() ) ) )
{
_children->fastSetObject( tempJ, j+1 );

View File

@ -179,7 +179,7 @@ void SpriteBatchNode::reorderChild(Node *child, int zOrder)
CCASSERT(child != nullptr, "the child should not be null");
CCASSERT(_children.contains(child), "Child doesn't belong to Sprite");
if (zOrder == child->getZOrder())
if (zOrder == child->getLocalZOrder())
{
return;
}
@ -277,7 +277,7 @@ void SpriteBatchNode::updateAtlasIndex(Sprite* sprite, ssize_t* curIndex)
{
bool needNewIndex=true;
if (array.at(0)->getZOrder() >= 0)
if (array.at(0)->getLocalZOrder() >= 0)
{
//all children are in front of the parent
oldIndex = sprite->getAtlasIndex();
@ -294,7 +294,7 @@ void SpriteBatchNode::updateAtlasIndex(Sprite* sprite, ssize_t* curIndex)
for(const auto &child: array) {
Sprite* sp = static_cast<Sprite*>(child);
if (needNewIndex && sp->getZOrder() >= 0)
if (needNewIndex && sp->getLocalZOrder() >= 0)
{
oldIndex = sprite->getAtlasIndex();
sprite->setAtlasIndex(*curIndex);
@ -392,7 +392,7 @@ ssize_t SpriteBatchNode::rebuildIndexInOrder(Sprite *parent, ssize_t index)
auto& children = parent->getChildren();
for(const auto &child: children) {
Sprite* sp = static_cast<Sprite*>(child);
if (sp && (sp->getZOrder() < 0))
if (sp && (sp->getLocalZOrder() < 0))
{
index = rebuildIndexInOrder(sp, index);
}
@ -407,7 +407,7 @@ ssize_t SpriteBatchNode::rebuildIndexInOrder(Sprite *parent, ssize_t index)
for(const auto &child: children) {
Sprite* sp = static_cast<Sprite*>(child);
if (sp && (sp->getZOrder() >= 0))
if (sp && (sp->getLocalZOrder() >= 0))
{
index = rebuildIndexInOrder(sp, index);
}
@ -488,7 +488,7 @@ ssize_t SpriteBatchNode::atlasIndexForChild(Sprite *sprite, int nZ)
else
{
// previous & sprite belong to the same branch
if ((prev->getZOrder() < 0 && nZ < 0) || (prev->getZOrder() >= 0 && nZ >= 0))
if ((prev->getLocalZOrder() < 0 && nZ < 0) || (prev->getLocalZOrder() >= 0 && nZ >= 0))
{
return highestAtlasIndexInChild(prev) + 1;
}

View File

@ -174,7 +174,7 @@ void TMXTiledMap::buildWithMapInfo(TMXMapInfo* mapInfo)
if (layerInfo->_visible)
{
TMXLayer *child = parseLayer(layerInfo, mapInfo);
addChild((Node*)child, idx, idx);
addChild(child, idx, idx);
// update content size with the max size
const Size& childSize = child->getContentSize();

View File

@ -281,7 +281,7 @@ unsigned short* cc_utf8_to_utf16(const char* str_old, int length/* = -1 */, int*
{
long len = cc_utf8_strlen(str_old, length);
if (rUtf16Size != nullptr) {
*rUtf16Size = len;
*rUtf16Size = static_cast<int>(len);
}
unsigned short* str_new = new unsigned short[len + 1];

View File

@ -25,10 +25,17 @@
#ifndef __CCMAP_H__
#define __CCMAP_H__
#define USE_STD_UNORDERED_MAP 1
#include "ccMacros.h"
#include "CCObject.h"
#include <vector>
#if USE_STD_UNORDERED_MAP
#include <unordered_map>
#else
#include <map>
#endif
NS_CC_BEGIN
@ -44,7 +51,11 @@ public:
// ------------------------------------------
// Iterators
// ------------------------------------------
#if USE_STD_UNORDERED_MAP
typedef std::unordered_map<K, V> RefMap;
#else
typedef std::map<K, V> RefMap;
#endif
typedef typename RefMap::iterator iterator;
typedef typename RefMap::const_iterator const_iterator;
@ -104,25 +115,39 @@ public:
/** Sets capacity of the map */
void reserve(ssize_t capacity)
{
#if USE_STD_UNORDERED_MAP
_data.reserve(capacity);
#endif
}
/** Returns the number of buckets in the Map container. */
ssize_t bucketCount() const
{
#if USE_STD_UNORDERED_MAP
return _data.bucket_count();
#else
return 0;
#endif
}
/** Returns the number of elements in bucket n. */
ssize_t bucketSize(ssize_t n) const
{
#if USE_STD_UNORDERED_MAP
return _data.bucket_size(n);
#else
return 0;
#endif
}
/** Returns the bucket number where the element with key k is located. */
ssize_t bucket(const K& k) const
{
#if USE_STD_UNORDERED_MAP
return _data.bucket(k);
#else
return 0;
#endif
}
/** The number of elements in the map. */
@ -144,9 +169,11 @@ public:
std::vector<K> keys() const
{
std::vector<K> keys;
if (!_data.empty())
{
keys.reserve(_data.size());
for (auto iter = _data.cbegin(); iter != _data.cend(); ++iter)
{
keys.push_back(iter->first);
@ -160,14 +187,21 @@ public:
{
std::vector<K> keys;
for (auto iter = _data.cbegin(); iter != _data.cend(); ++iter)
if (!_data.empty())
{
if (iter->second == object)
keys.reserve(_data.size() / 10);
for (auto iter = _data.cbegin(); iter != _data.cend(); ++iter)
{
keys.push_back(iter->first);
if (iter->second == object)
{
keys.push_back(iter->first);
}
}
}
keys.shrink_to_fit();
return keys;
}

View File

@ -142,7 +142,7 @@ static int readTuple (const char* end, Str tuple[]) {
}
static char* mallocString (Str* str) {
int length = str->end - str->begin;
long length = str->end - str->begin;
char* string = MALLOC(char, length + 1);
memcpy(string, str->begin, length);
string[length] = '\0';
@ -150,7 +150,7 @@ static char* mallocString (Str* str) {
}
static int indexOf (const char** array, int count, Str* str) {
int length = str->end - str->begin;
long length = str->end - str->begin;
int i;
for (i = count - 1; i >= 0; i--)
if (strncmp(array[i], str->begin, length) == 0) return i;
@ -162,7 +162,7 @@ static int equals (Str* str, const char* other) {
}
static int toInt (Str* str) {
return strtol(str->begin, (char**)&str->end, 10);
return static_cast<int>(strtol(str->begin, (char**)&str->end, 10));
}
static spAtlas* abortAtlas (spAtlas* self) {
@ -177,7 +177,7 @@ static const char* textureFilterNames[] = {"Nearest", "Linear", "MipMap", "MipMa
spAtlas* spAtlas_readAtlas (const char* begin, int length, const char* dir) {
int count;
const char* end = begin + length;
int dirLength = strlen(dir);
size_t dirLength = strlen(dir);
int needsSlash = dirLength > 0 && dir[dirLength - 1] != '/' && dir[dirLength - 1] != '\\';
spAtlas* self = NEW(spAtlas);
@ -289,7 +289,7 @@ spAtlas* spAtlas_readAtlas (const char* begin, int length, const char* dir) {
}
spAtlas* spAtlas_readAtlasFile (const char* path) {
int dirLength;
long dirLength;
char *dir;
int length;
const char* data;

View File

@ -235,7 +235,7 @@ void Layout::stencilClippingVisit()
{
auto node = _children.at(i);
if ( node && node->getZOrder() < 0 )
if ( node && node->getLocalZOrder() < 0 )
node->visit();
else
break;

View File

@ -255,7 +255,7 @@ Widget* Widget::getChildByName(const char *name)
void Widget::addNode(Node* node)
{
addNode(node, node->getZOrder(), node->getTag());
addNode(node, node->getLocalZOrder(), node->getTag());
}
void Widget::addNode(Node * node, int zOrder)

View File

@ -28,9 +28,12 @@
****************************************************************************/
#include "SocketIO.h"
#include "CCDirector.h"
#include "CCScheduler.h"
#include "WebSocket.h"
#include "HttpClient.h"
#include <algorithm>
#include <sstream>
NS_CC_BEGIN

View File

@ -59,7 +59,10 @@ in the onClose method the pointer should be set to NULL or used to connect to a
#ifndef __CC_SOCKETIO_H__
#define __CC_SOCKETIO_H__
#include "cocos2d.h"
#include "CCPlatformMacros.h"
#include "CCMap.h"
#include <string>
NS_CC_BEGIN

View File

@ -28,6 +28,8 @@
****************************************************************************/
#include "WebSocket.h"
#include "CCDirector.h"
#include "CCScheduler.h"
#include <thread>
#include <mutex>
@ -521,7 +523,7 @@ int WebSocket::onSocketCallback(struct libwebsocket_context *ctx,
size_t remaining = data->len - data->issued;
size_t n = std::min(remaining, c_bufferSize );
CCLOG("[websocket:send] total: %d, sent: %d, remaining: %d, buffer size: %d", data->len, data->issued, remaining, n);
CCLOG("[websocket:send] total: %d, sent: %d, remaining: %d, buffer size: %d", static_cast<int>(data->len), static_cast<int>(data->issued), static_cast<int>(remaining), static_cast<int>(n));
unsigned char* buf = new unsigned char[LWS_SEND_BUFFER_PRE_PADDING + n + LWS_SEND_BUFFER_POST_PADDING];

View File

@ -30,8 +30,11 @@
#ifndef __CC_WEBSOCKET_H__
#define __CC_WEBSOCKET_H__
#include "cocos2d.h"
#include "CCPlatformMacros.h"
#include "CCStdC.h"
#include <list>
#include <string>
#include <vector>
struct libwebsocket;
struct libwebsocket_context;
@ -153,8 +156,8 @@ private:
unsigned int _port;
std::string _path;
size_t _pendingFrameDataLen;
unsigned int _currentDataLen;
ssize_t _pendingFrameDataLen;
ssize_t _currentDataLen;
char *_currentData;
friend class WsThreadHelper;

View File

@ -24,15 +24,15 @@ JSBool JSB_localStorageGetItem(JSContext *cx, uint32_t argc, jsval *vp) {
JSB_PRECONDITION2( argc == 1, cx, JS_FALSE, "Invalid number of arguments" );
jsval *argvp = JS_ARGV(cx,vp);
JSBool ok = JS_TRUE;
const char* arg0;
std::string arg0;
ok &= jsval_to_charptr( cx, *argvp++, &arg0 );
ok &= jsval_to_std_string( cx, *argvp++, &arg0 );
JSB_PRECONDITION2(ok, cx, JS_FALSE, "Error processing arguments");
const char* ret_val;
std::string ret_val;
ret_val = localStorageGetItem((char*)arg0 );
ret_val = localStorageGetItem(arg0);
jsval ret_jsval = c_string_to_jsval(cx, ret_val ? ret_val : "");
jsval ret_jsval = std_string_to_jsval(cx, ret_val);
JS_SET_RVAL(cx, vp, ret_jsval );
return JS_TRUE;
@ -44,12 +44,12 @@ JSBool JSB_localStorageRemoveItem(JSContext *cx, uint32_t argc, jsval *vp) {
JSB_PRECONDITION2( argc == 1, cx, JS_FALSE, "Invalid number of arguments" );
jsval *argvp = JS_ARGV(cx,vp);
JSBool ok = JS_TRUE;
const char* arg0;
std::string arg0;
ok &= jsval_to_charptr( cx, *argvp++, &arg0 );
ok &= jsval_to_std_string( cx, *argvp++, &arg0 );
JSB_PRECONDITION2(ok, cx, JS_FALSE, "Error processing arguments");
localStorageRemoveItem((char*)arg0 );
localStorageRemoveItem(arg0);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE;
}
@ -60,13 +60,13 @@ JSBool JSB_localStorageSetItem(JSContext *cx, uint32_t argc, jsval *vp) {
JSB_PRECONDITION2( argc == 2, cx, JS_FALSE, "Invalid number of arguments" );
jsval *argvp = JS_ARGV(cx,vp);
JSBool ok = JS_TRUE;
const char* arg0; const char* arg1;
std::string arg0; std::string arg1;
ok &= jsval_to_charptr( cx, *argvp++, &arg0 );
ok &= jsval_to_charptr( cx, *argvp++, &arg1 );
ok &= jsval_to_std_string( cx, *argvp++, &arg0 );
ok &= jsval_to_std_string( cx, *argvp++, &arg1 );
JSB_PRECONDITION2(ok, cx, JS_FALSE, "Error processing arguments");
localStorageSetItem((char*)arg0 , (char*)arg1 );
localStorageSetItem(arg0 , arg1);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE;
}

View File

@ -27,7 +27,8 @@
Works on cocos2d-iphone and cocos2d-x.
*/
#include "cocos2d.h"
#include "LocalStorage.h"
#include "CCPlatformMacros.h"
#if (CC_TARGET_PLATFORM != CC_PLATFORM_ANDROID)
@ -55,16 +56,16 @@ static void localStorageCreateTable()
printf("Error in CREATE TABLE\n");
}
void localStorageInit( const char *fullpath)
void localStorageInit( const std::string& fullpath/* = "" */)
{
if( ! _initialized ) {
int ret = 0;
if (!fullpath)
if (fullpath.empty())
ret = sqlite3_open(":memory:",&_db);
else
ret = sqlite3_open(fullpath, &_db);
ret = sqlite3_open(fullpath.c_str(), &_db);
localStorageCreateTable();
@ -103,12 +104,12 @@ void localStorageFree()
}
/** sets an item in the LS */
void localStorageSetItem( const char *key, const char *value)
void localStorageSetItem( const std::string& key, const std::string& value)
{
assert( _initialized );
int ok = sqlite3_bind_text(_stmt_update, 1, key, -1, SQLITE_TRANSIENT);
ok |= sqlite3_bind_text(_stmt_update, 2, value, -1, SQLITE_TRANSIENT);
int ok = sqlite3_bind_text(_stmt_update, 1, key.c_str(), -1, SQLITE_TRANSIENT);
ok |= sqlite3_bind_text(_stmt_update, 2, value.c_str(), -1, SQLITE_TRANSIENT);
ok |= sqlite3_step(_stmt_update);
@ -119,13 +120,13 @@ void localStorageSetItem( const char *key, const char *value)
}
/** gets an item from the LS */
const char* localStorageGetItem( const char *key )
std::string localStorageGetItem( const std::string& key )
{
assert( _initialized );
int ok = sqlite3_reset(_stmt_select);
ok |= sqlite3_bind_text(_stmt_select, 1, key, -1, SQLITE_TRANSIENT);
ok |= sqlite3_bind_text(_stmt_select, 1, key.c_str(), -1, SQLITE_TRANSIENT);
ok |= sqlite3_step(_stmt_select);
const unsigned char *ret = sqlite3_column_text(_stmt_select, 0);
@ -137,11 +138,11 @@ const char* localStorageGetItem( const char *key )
}
/** removes an item from the LS */
void localStorageRemoveItem( const char *key )
void localStorageRemoveItem( const std::string& key )
{
assert( _initialized );
int ok = sqlite3_bind_text(_stmt_remove, 1, key, -1, SQLITE_TRANSIENT);
int ok = sqlite3_bind_text(_stmt_remove, 1, key.c_str(), -1, SQLITE_TRANSIENT);
ok |= sqlite3_step(_stmt_remove);

View File

@ -30,22 +30,21 @@ THE SOFTWARE.
#ifndef __JSB_LOCALSTORAGE_H
#define __JSB_LOCALSTORAGE_H
#include <stdio.h>
#include <stdlib.h>
#include <string>
/** Initializes the database. If path is null, it will create an in-memory DB */
void localStorageInit( const char *fullpath);
void localStorageInit( const std::string& fullpath = "");
/** Frees the allocated resources */
void localStorageFree();
/** sets an item in the LS */
void localStorageSetItem( const char *key, const char *value);
void localStorageSetItem( const std::string& key, const std::string& value);
/** gets an item from the LS */
const char* localStorageGetItem( const char *key );
std::string localStorageGetItem( const std::string& key );
/** removes an item from the LS */
void localStorageRemoveItem( const char *key );
void localStorageRemoveItem( const std::string& key );
#endif // __JSB_LOCALSTORAGE_H

View File

@ -28,14 +28,14 @@
Works on cocos2d-iphone and cocos2d-x.
*/
#include "cocos2d.h"
#include "LocalStorage.h"
#include "CCPlatformMacros.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string>
#include "jni.h"
#include "jni/JniHelper.h"
@ -52,27 +52,28 @@ static void splitFilename (std::string& str)
}
}
void localStorageInit( const char *fullpath)
void localStorageInit( const std::string& fullpath)
{
if (fullpath == NULL || strlen(fullpath) == 0) return;
if (fullpath.empty())
return;
if( ! _initialized ) {
JniMethodInfo t;
if( ! _initialized )
{
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxLocalStorage", "init", "(Ljava/lang/String;Ljava/lang/String;)Z")) {
std::string strDBFilename = fullpath;
splitFilename(strDBFilename);
jstring jdbName = t.env->NewStringUTF(strDBFilename.c_str());
jstring jtableName = t.env->NewStringUTF("data");
jboolean ret = t.env->CallStaticBooleanMethod(t.classID, t.methodID, jdbName, jtableName);
t.env->DeleteLocalRef(jdbName);
t.env->DeleteLocalRef(jtableName);
t.env->DeleteLocalRef(t.classID);
if (ret) {
_initialized = 1;
}
}
if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxLocalStorage", "init", "(Ljava/lang/String;Ljava/lang/String;)Z")) {
std::string strDBFilename = fullpath;
splitFilename(strDBFilename);
jstring jdbName = t.env->NewStringUTF(strDBFilename.c_str());
jstring jtableName = t.env->NewStringUTF("data");
jboolean ret = t.env->CallStaticBooleanMethod(t.classID, t.methodID, jdbName, jtableName);
t.env->DeleteLocalRef(jdbName);
t.env->DeleteLocalRef(jtableName);
t.env->DeleteLocalRef(t.classID);
if (ret) {
_initialized = 1;
}
}
}
}
@ -93,15 +94,15 @@ void localStorageFree()
}
/** sets an item in the LS */
void localStorageSetItem( const char *key, const char *value)
void localStorageSetItem( const std::string& key, const std::string& value)
{
assert( _initialized );
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxLocalStorage", "setItem", "(Ljava/lang/String;Ljava/lang/String;)V")) {
jstring jkey = t.env->NewStringUTF(key);
jstring jvalue = t.env->NewStringUTF(value);
jstring jkey = t.env->NewStringUTF(key.c_str());
jstring jvalue = t.env->NewStringUTF(value.c_str());
t.env->CallStaticVoidMethod(t.classID, t.methodID, jkey, jvalue);
t.env->DeleteLocalRef(jkey);
t.env->DeleteLocalRef(jvalue);
@ -110,30 +111,31 @@ void localStorageSetItem( const char *key, const char *value)
}
/** gets an item from the LS */
const char* localStorageGetItem( const char *key )
std::string localStorageGetItem( const std::string& key )
{
assert( _initialized );
JniMethodInfo t;
String* pStr = NULL;
std::string ret;
if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxLocalStorage", "getItem", "(Ljava/lang/String;)Ljava/lang/String;")) {
jstring jkey = t.env->NewStringUTF(key);
jstring ret = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID, jkey);
pStr = String::create(JniHelper::jstring2string(ret));
t.env->DeleteLocalRef(ret);
jstring jkey = t.env->NewStringUTF(key.c_str());
jstring jret = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID, jkey);
ret = JniHelper::jstring2string(jret);
t.env->DeleteLocalRef(jret);
t.env->DeleteLocalRef(jkey);
t.env->DeleteLocalRef(t.classID);
}
return pStr ? pStr->getCString() : NULL;
return ret;
}
/** removes an item from the LS */
void localStorageRemoveItem( const char *key )
void localStorageRemoveItem( const std::string& key )
{
assert( _initialized );
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxLocalStorage", "removeItem", "(Ljava/lang/String;)V")) {
jstring jkey = t.env->NewStringUTF(key);
jstring jkey = t.env->NewStringUTF(key.c_str());
t.env->CallStaticVoidMethod(t.classID, t.methodID, jkey);
t.env->DeleteLocalRef(jkey);
t.env->DeleteLocalRef(t.classID);

View File

@ -572,7 +572,7 @@ void ScrollView::visit()
for( ; i < _children.size(); i++ )
{
Node *child = _children.at(i);
if ( child->getZOrder() < 0 )
if ( child->getLocalZOrder() < 0 )
{
child->visit();
}

View File

@ -22,6 +22,7 @@ std::function<Layer*()> createFunctions[] =
CL(RemoveAndRetainNodeTest),
CL(RemoveListenerAfterAddingTest),
CL(DirectorEventTest),
CL(GlobalZTouchTest),
};
unsigned int TEST_CASE_COUNT = sizeof(createFunctions) / sizeof(createFunctions[0]);
@ -859,4 +860,88 @@ std::string DirectorEventTest::subtitle() const
return "after visit, after draw, after update, projection changed";
}
// GlobalZTouchTest
GlobalZTouchTest::GlobalZTouchTest()
: _sprite(nullptr)
, _accum(0)
{
auto listener1 = EventListenerTouchOneByOne::create();
listener1->setSwallowTouches(true);
listener1->onTouchBegan = [](Touch* touch, Event* event){
auto target = static_cast<Sprite*>(event->getCurrentTarget());
Point locationInNode = target->convertToNodeSpace(touch->getLocation());
Size s = target->getContentSize();
Rect rect = Rect(0, 0, s.width, s.height);
if (rect.containsPoint(locationInNode))
{
log("sprite began... x = %f, y = %f", locationInNode.x, locationInNode.y);
target->setOpacity(180);
return true;
}
return false;
};
listener1->onTouchMoved = [](Touch* touch, Event* event){
auto target = static_cast<Sprite*>(event->getCurrentTarget());
target->setPosition(target->getPosition() + touch->getDelta());
};
listener1->onTouchEnded = [=](Touch* touch, Event* event){
auto target = static_cast<Sprite*>(event->getCurrentTarget());
log("sprite onTouchesEnded.. ");
target->setOpacity(255);
};
const int SPRITE_COUNT = 8;
for (int i = 0; i < SPRITE_COUNT; i++)
{
Sprite *sprite;
auto parent = Node::create();
if(i==4)
{
sprite = Sprite::create("Images/CyanSquare.png");
_sprite = sprite;
_sprite->setGlobalZOrder(-1);
}
else
{
sprite = Sprite::create("Images/YellowSquare.png");
}
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite);
parent->addChild(sprite);
this->addChild(parent);
Size visibleSize = Director::getInstance()->getVisibleSize();
sprite->setPosition(VisibleRect::left().x + visibleSize.width / (SPRITE_COUNT - 1) * i, VisibleRect::center().y);
}
this->scheduleUpdate();
}
void GlobalZTouchTest::update(float dt)
{
_accum += dt;
if( _accum > 2.0f) {
float z = _sprite->getGlobalZOrder();
_sprite->setGlobalZOrder(-z);
_accum = 0;
}
}
std::string GlobalZTouchTest::title() const
{
return "Global Z Value, Try touch blue sprite";
}
std::string GlobalZTouchTest::subtitle() const
{
return "Blue Sprite should change go from foreground to background";
}

View File

@ -135,4 +135,20 @@ protected:
EventListenerCustom *_event1, *_event2, *_event3, *_event4;
};
class GlobalZTouchTest : public EventDispatcherTestDemo
{
public:
CREATE_FUNC(GlobalZTouchTest);
GlobalZTouchTest();
virtual void update(float dt) override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
protected:
Sprite* _sprite;
float _accum;
};
#endif /* defined(__samples__NewEventDispatcherTest__) */

View File

@ -1790,7 +1790,7 @@ void ReorderParticleSystems::onEnter()
void ReorderParticleSystems::reorderSystem(float time)
{
auto system = static_cast<ParticleSystem*>(_batchNode->getChildren().at(1));
_batchNode->reorderChild(system, system->getZOrder() - 1);
_batchNode->reorderChild(system, system->getLocalZOrder() - 1);
}

View File

@ -35,7 +35,11 @@
static std::function<PerformanceContainerScene*()> createFunctions[] =
{
CL(TemplateVectorPerfTest),
CL(ArrayPerfTest)
CL(ArrayPerfTest),
CL(TemplateMapStringKeyPerfTest),
CL(DictionaryStringKeyPerfTest),
CL(TemplateMapIntKeyPerfTest),
CL(DictionaryIntKeyPerfTest)
};
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
@ -264,27 +268,6 @@ void PerformanceContainerScene::updateProfilerName()
snprintf(_profilerName, sizeof(_profilerName)-1, "%s(%d)", testName(), quantityOfNodes);
}
void PerformanceContainerScene::onExitTransitionDidStart()
{
Scene::onExitTransitionDidStart();
auto director = Director::getInstance();
auto sched = director->getScheduler();
sched->unscheduleSelector(schedule_selector(PerformanceContainerScene::dumpProfilerInfo), this);
}
void PerformanceContainerScene::onEnterTransitionDidFinish()
{
Scene::onEnterTransitionDidFinish();
auto director = Director::getInstance();
auto sched = director->getScheduler();
CC_PROFILER_PURGE_ALL();
sched->scheduleSelector(schedule_selector(PerformanceContainerScene::dumpProfilerInfo), this, 2, false);
}
void PerformanceContainerScene::dumpProfilerInfo(float dt)
{
CC_PROFILER_DISPLAY_TIMERS();
@ -507,8 +490,6 @@ void TemplateVectorPerfTest::generateTestFunctions()
}
}
std::string TemplateVectorPerfTest::title() const
{
return "Vector<T> Perf test";
@ -519,8 +500,6 @@ std::string TemplateVectorPerfTest::subtitle() const
return "Test 'pushBack', See console";
}
////////////////////////////////////////////////////////
//
// ArrayPerfTest
@ -701,6 +680,685 @@ void ArrayPerfTest::generateTestFunctions()
}
}
////////////////////////////////////////////////////////
//
// TemplateMapStringKeyPerfTest
//
////////////////////////////////////////////////////////
void TemplateMapStringKeyPerfTest::generateTestFunctions()
{
auto createMap = [this](){
Map<std::string, Node*> ret;
for( int i=0; i<quantityOfNodes; ++i)
{
auto node = Node::create();
node->setTag(i);
ret.insert(StringUtils::format("key_%d", i), node);
}
return ret;
};
TestFunction testFunctions[] = {
{ "insert", [=](){
Map<std::string, Node*> map;
std::string* keys = new std::string[quantityOfNodes];
for (int i = 0; i < quantityOfNodes; ++i)
{
keys[i] = StringUtils::format("key_%d", i);
}
CC_PROFILER_START(this->profilerName());
for( int i=0; i<quantityOfNodes; ++i)
map.insert(keys[i], Node::create());
CC_PROFILER_STOP(this->profilerName());
CC_SAFE_DELETE_ARRAY(keys);
} } ,
{ "at", [=](){
Map<std::string, Node*> map = createMap();
std::string* keys = new std::string[quantityOfNodes];
Node** nodes = (Node**)malloc(sizeof(Node*) * quantityOfNodes);
for (int i = 0; i < quantityOfNodes; ++i)
{
keys[i] = StringUtils::format("key_%d", i);
}
CC_PROFILER_START(this->profilerName());
for( int i=0; i<quantityOfNodes; ++i)
nodes[i] = map.at(keys[i]);
CC_PROFILER_STOP(this->profilerName());
CC_SAFE_DELETE_ARRAY(keys);
for (int i = 0; i < quantityOfNodes; ++i)
{
nodes[i]->setTag(100);
}
CC_SAFE_FREE(nodes);
} } ,
{ "erase", [=](){
auto map = createMap();
std::string* keys = new std::string[quantityOfNodes];
Node** nodes = (Node**)malloc(sizeof(Node*) * quantityOfNodes);
for (int i = 0; i < quantityOfNodes; ++i)
{
keys[i] = StringUtils::format("key_%d", i);
}
CC_PROFILER_START(this->profilerName());
for( int i=0; i<quantityOfNodes; ++i)
map.erase(keys[i]);
CC_PROFILER_STOP(this->profilerName());
CC_SAFE_DELETE_ARRAY(keys);
CC_SAFE_FREE(nodes);
} } ,
{ "clear", [=](){
auto map = createMap();
CC_PROFILER_START(this->profilerName());
map.clear();
CC_PROFILER_STOP(this->profilerName());
} } ,
{ "size", [=](){
auto map = createMap();
ssize_t size = 0;
CC_PROFILER_START(this->profilerName());
size = map.size();
CC_PROFILER_STOP(this->profilerName());
} } ,
{ "keys(all)", [=](){
auto map = createMap();
CC_PROFILER_START(this->profilerName());
auto keys = map.keys();
CC_PROFILER_STOP(this->profilerName());
std::string allKeysString;
for (const auto& key : keys)
{
allKeysString += "_" + key;
}
} } ,
{ "keys(object)", [=](){
Map<std::string, Node*> map;
Node** nodes = (Node**) malloc(sizeof(Node*) * quantityOfNodes);
Node* sameNode = Node::create();
for( int i=0; i<quantityOfNodes; ++i)
{
if (quantityOfNodes % 100 == 0)
{
map.insert(StringUtils::format("key_%d", i), sameNode);
}
else
{
auto node = Node::create();
node->setTag(i);
map.insert(StringUtils::format("key_%d", i), node);
}
}
CC_PROFILER_START(this->profilerName());
auto keys = map.keys(sameNode);
CC_PROFILER_STOP(this->profilerName());
std::string allKeysString;
for (const auto& key : keys)
{
allKeysString += "_" + key;
}
CC_SAFE_FREE(nodes);
} } ,
{ "c++11 range loop", [=](){
auto map = createMap();
CC_PROFILER_START(this->profilerName());
for (const auto& e : map)
{
e.second->setTag(100);
}
CC_PROFILER_STOP(this->profilerName());
} } ,
};
for (const auto& func : testFunctions)
{
_testFunctions.push_back(func);
}
}
std::string TemplateMapStringKeyPerfTest::title() const
{
return "Map<T> String Key Perf test";
}
std::string TemplateMapStringKeyPerfTest::subtitle() const
{
return "Test 'insert', See console";
}
////////////////////////////////////////////////////////
//
// DictionaryStringKeyPerfTest
//
////////////////////////////////////////////////////////
void DictionaryStringKeyPerfTest::generateTestFunctions()
{
auto createDict = [this](){
Dictionary* ret = Dictionary::create();
for( int i=0; i<quantityOfNodes; ++i)
{
auto node = Node::create();
node->setTag(i);
ret->setObject(node, StringUtils::format("key_%d", i));
}
return ret;
};
TestFunction testFunctions[] = {
{ "setObject", [=](){
Dictionary* dict = Dictionary::create();
std::string* keys = new std::string[quantityOfNodes];
for (int i = 0; i < quantityOfNodes; ++i)
{
keys[i] = StringUtils::format("key_%d", i);
}
CC_PROFILER_START(this->profilerName());
for( int i=0; i<quantityOfNodes; ++i)
dict->setObject(Node::create(), keys[i]);
CC_PROFILER_STOP(this->profilerName());
CC_SAFE_DELETE_ARRAY(keys);
} } ,
{ "objectForKey", [=](){
auto dict = createDict();
std::string* keys = new std::string[quantityOfNodes];
Node** nodes = (Node**)malloc(sizeof(Node*) * quantityOfNodes);
for (int i = 0; i < quantityOfNodes; ++i)
{
keys[i] = StringUtils::format("key_%d", i);
}
CC_PROFILER_START(this->profilerName());
for( int i=0; i<quantityOfNodes; ++i)
nodes[i] = static_cast<Node*>(dict->objectForKey(keys[i]));
CC_PROFILER_STOP(this->profilerName());
CC_SAFE_DELETE_ARRAY(keys);
for (int i = 0; i < quantityOfNodes; ++i)
{
nodes[i]->setTag(100);
}
CC_SAFE_FREE(nodes);
} } ,
{ "removeObjectForKey", [=](){
auto dict = createDict();
std::string* keys = new std::string[quantityOfNodes];
Node** nodes = (Node**)malloc(sizeof(Node*) * quantityOfNodes);
for (int i = 0; i < quantityOfNodes; ++i)
{
keys[i] = StringUtils::format("key_%d", i);
}
CC_PROFILER_START(this->profilerName());
for( int i=0; i<quantityOfNodes; ++i)
dict->removeObjectForKey(keys[i]);
CC_PROFILER_STOP(this->profilerName());
CC_SAFE_DELETE_ARRAY(keys);
CC_SAFE_FREE(nodes);
} } ,
{ "removeAllObjects", [=](){
auto dict = createDict();
CC_PROFILER_START(this->profilerName());
dict->removeAllObjects();
CC_PROFILER_STOP(this->profilerName());
} } ,
{ "count", [=](){
auto dict = createDict();
ssize_t size = 0;
CC_PROFILER_START(this->profilerName());
size = dict->count();
CC_PROFILER_STOP(this->profilerName());
} } ,
{ "allKeys", [=](){
auto dict = createDict();
CC_PROFILER_START(this->profilerName());
auto keys = dict->allKeys();
CC_PROFILER_STOP(this->profilerName());
std::string allKeysString;
Object* obj;
CCARRAY_FOREACH(keys, obj)
{
auto key = static_cast<String*>(obj);
allKeysString += (std::string("_") + key->getCString());
}
} } ,
{ "allKeysForObject", [=](){
Dictionary* dict = Dictionary::create();
Node** nodes = (Node**) malloc(sizeof(Node*) * quantityOfNodes);
Node* sameNode = Node::create();
for( int i=0; i<quantityOfNodes; ++i)
{
if (quantityOfNodes % 100 == 0)
{
dict->setObject(sameNode, StringUtils::format("key_%d", i));
}
else
{
auto node = Node::create();
node->setTag(i);
dict->setObject(node, StringUtils::format("key_%d", i));
}
}
CC_PROFILER_START(this->profilerName());
auto keys = dict->allKeysForObject(sameNode);
CC_PROFILER_STOP(this->profilerName());
std::string allKeysString;
Object* obj;
CCARRAY_FOREACH(keys, obj)
{
auto key = static_cast<String*>(obj);
allKeysString += (std::string("_") + key->getCString());
}
CC_SAFE_FREE(nodes);
} } ,
{ "CCDICT_FOREACH", [=](){
auto dict = createDict();
CC_PROFILER_START(this->profilerName());
DictElement* e = nullptr;
CCDICT_FOREACH(dict, e)
{
static_cast<Node*>(e->getObject())->setTag(100);
}
CC_PROFILER_STOP(this->profilerName());
} } ,
};
for (const auto& func : testFunctions)
{
_testFunctions.push_back(func);
}
}
std::string DictionaryStringKeyPerfTest::title() const
{
return "Dictionary String Key Perf test";
}
std::string DictionaryStringKeyPerfTest::subtitle() const
{
return "Test `setObject`, See console";
}
////////////////////////////////////////////////////////
//
// TemplateMapIntKeyPerfTest
//
////////////////////////////////////////////////////////
void TemplateMapIntKeyPerfTest::generateTestFunctions()
{
auto createMap = [this](){
Map<int, Node*> ret;
for( int i=0; i<quantityOfNodes; ++i)
{
auto node = Node::create();
node->setTag(i);
ret.insert(100+i, node);
}
return ret;
};
TestFunction testFunctions[] = {
{ "insert", [=](){
Map<int, Node*> map;
CC_PROFILER_START(this->profilerName());
for( int i=0; i<quantityOfNodes; ++i)
map.insert(100 + i, Node::create());
CC_PROFILER_STOP(this->profilerName());
} } ,
{ "at", [=](){
auto map = createMap();
Node** nodes = (Node**)malloc(sizeof(Node*) * quantityOfNodes);
CC_PROFILER_START(this->profilerName());
for( int i=0; i<quantityOfNodes; ++i)
nodes[i] = map.at(100 + i);
CC_PROFILER_STOP(this->profilerName());
for (int i = 0; i < quantityOfNodes; ++i)
{
nodes[i]->setTag(100);
}
CC_SAFE_FREE(nodes);
} } ,
{ "erase", [=](){
auto map = createMap();
Node** nodes = (Node**)malloc(sizeof(Node*) * quantityOfNodes);
CC_PROFILER_START(this->profilerName());
for( int i=0; i<quantityOfNodes; ++i)
map.erase(100 + i);
CC_PROFILER_STOP(this->profilerName());
CC_SAFE_FREE(nodes);
} } ,
{ "clear", [=](){
auto map = createMap();
CC_PROFILER_START(this->profilerName());
map.clear();
CC_PROFILER_STOP(this->profilerName());
} } ,
{ "size", [=](){
auto map = createMap();
ssize_t size = 0;
CC_PROFILER_START(this->profilerName());
size = map.size();
CC_PROFILER_STOP(this->profilerName());
} } ,
{ "keys(all)", [=](){
auto map = createMap();
CC_PROFILER_START(this->profilerName());
auto keys = map.keys();
CC_PROFILER_STOP(this->profilerName());
int allKeysInt = 0;
for (const auto& key : keys)
{
allKeysInt += key;
}
} } ,
{ "keys(object)", [=](){
Map<int, Node*> map;
Node** nodes = (Node**) malloc(sizeof(Node*) * quantityOfNodes);
Node* sameNode = Node::create();
for( int i=0; i<quantityOfNodes; ++i)
{
if (quantityOfNodes % 100 == 0)
{
map.insert(100 + i, sameNode);
}
else
{
auto node = Node::create();
node->setTag(i);
map.insert(100 + i, node);
}
}
CC_PROFILER_START(this->profilerName());
auto keys = map.keys(sameNode);
CC_PROFILER_STOP(this->profilerName());
int allKeysInt = 0;
for (const auto& key : keys)
{
allKeysInt += key;
}
CC_SAFE_FREE(nodes);
} } ,
{ "c++11 range loop", [=](){
auto map = createMap();
CC_PROFILER_START(this->profilerName());
for (const auto& e : map)
{
e.second->setTag(100);
}
CC_PROFILER_STOP(this->profilerName());
} } ,
};
for (const auto& func : testFunctions)
{
_testFunctions.push_back(func);
}
}
std::string TemplateMapIntKeyPerfTest::title() const
{
return "Map<T> Integer Key Perf test";
}
std::string TemplateMapIntKeyPerfTest::subtitle() const
{
return "Test 'insert', See console";
}
////////////////////////////////////////////////////////
//
// DictionaryIntKeyPerfTest
//
////////////////////////////////////////////////////////
void DictionaryIntKeyPerfTest::generateTestFunctions()
{
auto createDict = [this](){
Dictionary* ret = Dictionary::create();
for( int i=0; i<quantityOfNodes; ++i)
{
auto node = Node::create();
node->setTag(i);
ret->setObject(node, 100 + i);
}
return ret;
};
TestFunction testFunctions[] = {
{ "setObject", [=](){
Dictionary* dict = Dictionary::create();
CC_PROFILER_START(this->profilerName());
for( int i=0; i<quantityOfNodes; ++i)
dict->setObject(Node::create(), 100 + i);
CC_PROFILER_STOP(this->profilerName());
} } ,
{ "objectForKey", [=](){
auto dict = createDict();
Node** nodes = (Node**)malloc(sizeof(Node*) * quantityOfNodes);
CC_PROFILER_START(this->profilerName());
for( int i=0; i<quantityOfNodes; ++i)
nodes[i] = static_cast<Node*>(dict->objectForKey(100 + i));
CC_PROFILER_STOP(this->profilerName());
for (int i = 0; i < quantityOfNodes; ++i)
{
nodes[i]->setTag(100);
}
CC_SAFE_FREE(nodes);
} } ,
{ "removeObjectForKey", [=](){
auto dict = createDict();
Node** nodes = (Node**)malloc(sizeof(Node*) * quantityOfNodes);
CC_PROFILER_START(this->profilerName());
for( int i=0; i<quantityOfNodes; ++i)
dict->removeObjectForKey(100 + i);
CC_PROFILER_STOP(this->profilerName());
CC_SAFE_FREE(nodes);
} } ,
{ "removeAllObjects", [=](){
auto dict = createDict();
CC_PROFILER_START(this->profilerName());
dict->removeAllObjects();
CC_PROFILER_STOP(this->profilerName());
} } ,
{ "count", [=](){
auto dict = createDict();
unsigned int size = 0;
CC_PROFILER_START(this->profilerName());
size = dict->count();
CC_PROFILER_STOP(this->profilerName());
} } ,
{ "allKeys", [=](){
auto dict = createDict();
CC_PROFILER_START(this->profilerName());
auto keys = dict->allKeys();
CC_PROFILER_STOP(this->profilerName());
int allKeysInt = 0;
Object* obj;
CCARRAY_FOREACH(keys, obj)
{
auto key = static_cast<Integer*>(obj);
allKeysInt += key->getValue();
}
} } ,
{ "allKeysForObject", [=](){
Dictionary* dict = Dictionary::create();
Node** nodes = (Node**) malloc(sizeof(Node*) * quantityOfNodes);
Node* sameNode = Node::create();
for( int i=0; i<quantityOfNodes; ++i)
{
if (quantityOfNodes % 100 == 0)
{
dict->setObject(sameNode, 100 + i);
}
else
{
auto node = Node::create();
node->setTag(i);
dict->setObject(node, 100 + i);
}
}
CC_PROFILER_START(this->profilerName());
auto keys = dict->allKeysForObject(sameNode);
CC_PROFILER_STOP(this->profilerName());
int allKeysInt = 0;
Object* obj;
CCARRAY_FOREACH(keys, obj)
{
auto key = static_cast<Integer*>(obj);
allKeysInt += key->getValue();
}
CC_SAFE_FREE(nodes);
} } ,
{ "CCDICT_FOREACH", [=](){
auto dict = createDict();
CC_PROFILER_START(this->profilerName());
DictElement* e = nullptr;
CCDICT_FOREACH(dict, e)
{
static_cast<Node*>(e->getObject())->setTag(100);
}
CC_PROFILER_STOP(this->profilerName());
} } ,
};
for (const auto& func : testFunctions)
{
_testFunctions.push_back(func);
}
}
std::string DictionaryIntKeyPerfTest::title() const
{
return "Dictionary Integer Key Perf test";
}
std::string DictionaryIntKeyPerfTest::subtitle() const
{
return "Test `setObject`, See console";
}
///----------------------------------------
void runContainerPerformanceTest()
{

View File

@ -44,8 +44,6 @@ public:
void dumpProfilerInfo(float dt);
// overrides
virtual void onExitTransitionDidStart() override;
virtual void onEnterTransitionDidFinish() override;
virtual void update(float dt) override;
protected:
@ -85,6 +83,49 @@ public:
virtual std::string subtitle() const override;
};
class TemplateMapStringKeyPerfTest : public PerformanceContainerScene
{
public:
CREATE_FUNC(TemplateMapStringKeyPerfTest);
virtual void generateTestFunctions() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
class DictionaryStringKeyPerfTest : public PerformanceContainerScene
{
public:
CREATE_FUNC(DictionaryStringKeyPerfTest);
virtual void generateTestFunctions() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
class TemplateMapIntKeyPerfTest : public PerformanceContainerScene
{
public:
CREATE_FUNC(TemplateMapIntKeyPerfTest);
virtual void generateTestFunctions() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
class DictionaryIntKeyPerfTest : public PerformanceContainerScene
{
public:
CREATE_FUNC(DictionaryIntKeyPerfTest);
virtual void generateTestFunctions() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
void runContainerPerformanceTest();

View File

@ -1 +1 @@
689b357d7acda141d13a3dfc4cb52aabb274f6cd
c098eac3962854bc7d1981ec16aad7d2907c0e33

View File

@ -155,7 +155,7 @@ void TestController::menuCallback(Object * sender)
// get the userdata, it's the index of the menu item clicked
auto menuItem = static_cast<MenuItem *>(sender);
int idx = menuItem->getZOrder() - 10000;
int idx = menuItem->getLocalZOrder() - 10000;
// create the test scene and run it
auto scene = g_aTestNames[idx].callback();