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 Pisces000221
Corrected a few mistakes in the README file of project-creator. Corrected a few mistakes in the README file of project-creator.
Corrected a mistake in README.
hbbalfred hbbalfred
Fixed a bug that crash if file doesn't exist when using FileUtils::getStringFromFile. Fixed a bug that crash if file doesn't exist when using FileUtils::getStringFromFile.

View File

@ -1,5 +1,6 @@
cocos2d-x-3.0beta2 ?.? ? cocos2d-x-3.0beta2 ?.? ?
[All] [All]
[NEW] Adds performance test for Containers(Vector<>, Array, Map<K,V>, Dictionary).
[NEW] DrawNode supports to draw triangle, quad bezier, cubic bezier. [NEW] DrawNode supports to draw triangle, quad bezier, cubic bezier.
[NEW] Console: added the 'textures', 'fileutils dump' and 'config' commands [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 [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] 1. Download the code from [cocos2d download site][4]
2. Enter `tools/project-creator` 2. Enter `tools/project-creator`
3. Run the `create-projects.py` script 3. Run the `create_project.py` script
Example: Example:
$ cd cocos2d-x/tools/project-creator $ 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 $ cd /home/mygame
### Build new project for android ### ### Build new project for android ###

View File

@ -12,6 +12,16 @@ LUA_SAMPLES = ['hellolua', 'testlua']
JSB_SAMPLES = ['cocosdragon', 'crystalcraze', 'moonwarriors', 'testjavascript', 'watermelonwithme'] JSB_SAMPLES = ['cocosdragon', 'crystalcraze', 'moonwarriors', 'testjavascript', 'watermelonwithme']
ALL_SAMPLES = CPP_SAMPLES + LUA_SAMPLES + JSB_SAMPLES 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(): def check_environment_variables():
''' Checking the environment NDK_ROOT, which will be used for building ''' 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: else:
ndk_module_path = 'NDK_MODULE_PATH=%s:%s/external:%s/cocos' % (cocos_root, cocos_root, cocos_root) 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: 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: 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: if os.system(command) != 0:
raise Exception("Build dynamic library for project [ " + app_android_root + " ] fails!") raise Exception("Build dynamic library for project [ " + app_android_root + " ] fails!")
elif android_platform is not None: elif android_platform is not None:

View File

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

View File

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

View File

@ -207,16 +207,16 @@ protected:
enum class DirtyFlag enum class DirtyFlag
{ {
NONE = 0, NONE = 0,
FIXED_PRITORY = 1 << 0, FIXED_PRIORITY = 1 << 0,
SCENE_GRAPH_PRIORITY = 1 << 1, 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 */ /** Sets the dirty flag for a specified listener ID */
void setDirty(const EventListener::ListenerID& listenerID, DirtyFlag flag); 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 */ /** 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 */ /** Listeners map */
std::unordered_map<EventListener::ListenerID, EventListenerVector*> _listeners; std::unordered_map<EventListener::ListenerID, EventListenerVector*> _listeners;
@ -230,6 +230,9 @@ protected:
/** The map of node and its event priority */ /** The map of node and its event priority */
std::unordered_map<Node*, int> _nodePriorityMap; 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 */ /** The listeners to be added after dispatching event */
std::vector<EventListener*> _toAddedListeners; std::vector<EventListener*> _toAddedListeners;

View File

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

View File

@ -26,7 +26,6 @@
#ifndef _CCFontCharMap_h_ #ifndef _CCFontCharMap_h_
#define _CCFontCharMap_h_ #define _CCFontCharMap_h_
#include "cocos2d.h"
#include "CCFont.h" #include "CCFont.h"
NS_CC_BEGIN 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 *n1 = static_cast<Node*>(p1);
Node *n2 = static_cast<Node*>(p2); Node *n2 = static_cast<Node*>(p2);
return( n1->getZOrder() < n2->getZOrder() || return( n1->getLocalZOrder() < n2->getLocalZOrder() ||
( n1->getZOrder() == n2->getZOrder() && n1->getOrderOfArrival() < n2->getOrderOfArrival() ) ( n1->getLocalZOrder() == n2->getLocalZOrder() && n1->getOrderOfArrival() < n2->getOrderOfArrival() )
); );
} }
#else #else
@ -82,8 +82,8 @@ bool nodeComparisonLess(Object* p1, Object* p2)
Node *n1 = static_cast<Node*>(p1); Node *n1 = static_cast<Node*>(p1);
Node *n2 = static_cast<Node*>(p2); Node *n2 = static_cast<Node*>(p2);
return( n1->getZOrder() < n2->getZOrder() || return( n1->getLocalZOrder() < n2->getLocalZOrder() ||
( n1->getZOrder() == n2->getZOrder() && n1->getOrderOfArrival() < n2->getOrderOfArrival() ) ( n1->getLocalZOrder() == n2->getLocalZOrder() && n1->getOrderOfArrival() < n2->getOrderOfArrival() )
); );
} }
#endif #endif
@ -232,6 +232,15 @@ void Node::setLocalZOrder(int z)
_eventDispatcher->setDirtyForNode(this); _eventDispatcher->setDirtyForNode(this);
} }
void Node::setGlobalZOrder(float zOrder)
{
if (_globalZOrder != zOrder)
{
_globalZOrder = zOrder;
_eventDispatcher->setDirtyForNode(this);
}
}
/// vertexZ getter /// vertexZ getter
float Node::getVertexZ() const float Node::getVertexZ() const
{ {

View File

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

View File

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

View File

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

View File

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

View File

@ -174,7 +174,7 @@ void TMXTiledMap::buildWithMapInfo(TMXMapInfo* mapInfo)
if (layerInfo->_visible) if (layerInfo->_visible)
{ {
TMXLayer *child = parseLayer(layerInfo, mapInfo); TMXLayer *child = parseLayer(layerInfo, mapInfo);
addChild((Node*)child, idx, idx); addChild(child, idx, idx);
// update content size with the max size // update content size with the max size
const Size& childSize = child->getContentSize(); 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); long len = cc_utf8_strlen(str_old, length);
if (rUtf16Size != nullptr) { if (rUtf16Size != nullptr) {
*rUtf16Size = len; *rUtf16Size = static_cast<int>(len);
} }
unsigned short* str_new = new unsigned short[len + 1]; unsigned short* str_new = new unsigned short[len + 1];

View File

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

View File

@ -142,7 +142,7 @@ static int readTuple (const char* end, Str tuple[]) {
} }
static char* mallocString (Str* str) { static char* mallocString (Str* str) {
int length = str->end - str->begin; long length = str->end - str->begin;
char* string = MALLOC(char, length + 1); char* string = MALLOC(char, length + 1);
memcpy(string, str->begin, length); memcpy(string, str->begin, length);
string[length] = '\0'; string[length] = '\0';
@ -150,7 +150,7 @@ static char* mallocString (Str* str) {
} }
static int indexOf (const char** array, int count, 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; int i;
for (i = count - 1; i >= 0; i--) for (i = count - 1; i >= 0; i--)
if (strncmp(array[i], str->begin, length) == 0) return 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) { 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) { 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) { spAtlas* spAtlas_readAtlas (const char* begin, int length, const char* dir) {
int count; int count;
const char* end = begin + length; const char* end = begin + length;
int dirLength = strlen(dir); size_t dirLength = strlen(dir);
int needsSlash = dirLength > 0 && dir[dirLength - 1] != '/' && dir[dirLength - 1] != '\\'; int needsSlash = dirLength > 0 && dir[dirLength - 1] != '/' && dir[dirLength - 1] != '\\';
spAtlas* self = NEW(spAtlas); 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) { spAtlas* spAtlas_readAtlasFile (const char* path) {
int dirLength; long dirLength;
char *dir; char *dir;
int length; int length;
const char* data; const char* data;

View File

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

View File

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

View File

@ -28,9 +28,12 @@
****************************************************************************/ ****************************************************************************/
#include "SocketIO.h" #include "SocketIO.h"
#include "CCDirector.h"
#include "CCScheduler.h"
#include "WebSocket.h" #include "WebSocket.h"
#include "HttpClient.h" #include "HttpClient.h"
#include <algorithm> #include <algorithm>
#include <sstream>
NS_CC_BEGIN 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__ #ifndef __CC_SOCKETIO_H__
#define __CC_SOCKETIO_H__ #define __CC_SOCKETIO_H__
#include "cocos2d.h" #include "CCPlatformMacros.h"
#include "CCMap.h"
#include <string>
NS_CC_BEGIN NS_CC_BEGIN

View File

@ -28,6 +28,8 @@
****************************************************************************/ ****************************************************************************/
#include "WebSocket.h" #include "WebSocket.h"
#include "CCDirector.h"
#include "CCScheduler.h"
#include <thread> #include <thread>
#include <mutex> #include <mutex>
@ -521,7 +523,7 @@ int WebSocket::onSocketCallback(struct libwebsocket_context *ctx,
size_t remaining = data->len - data->issued; size_t remaining = data->len - data->issued;
size_t n = std::min(remaining, c_bufferSize ); 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]; 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__ #ifndef __CC_WEBSOCKET_H__
#define __CC_WEBSOCKET_H__ #define __CC_WEBSOCKET_H__
#include "cocos2d.h" #include "CCPlatformMacros.h"
#include "CCStdC.h"
#include <list> #include <list>
#include <string>
#include <vector>
struct libwebsocket; struct libwebsocket;
struct libwebsocket_context; struct libwebsocket_context;
@ -153,8 +156,8 @@ private:
unsigned int _port; unsigned int _port;
std::string _path; std::string _path;
size_t _pendingFrameDataLen; ssize_t _pendingFrameDataLen;
unsigned int _currentDataLen; ssize_t _currentDataLen;
char *_currentData; char *_currentData;
friend class WsThreadHelper; 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" ); JSB_PRECONDITION2( argc == 1, cx, JS_FALSE, "Invalid number of arguments" );
jsval *argvp = JS_ARGV(cx,vp); jsval *argvp = JS_ARGV(cx,vp);
JSBool ok = JS_TRUE; 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"); 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 ); JS_SET_RVAL(cx, vp, ret_jsval );
return JS_TRUE; 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" ); JSB_PRECONDITION2( argc == 1, cx, JS_FALSE, "Invalid number of arguments" );
jsval *argvp = JS_ARGV(cx,vp); jsval *argvp = JS_ARGV(cx,vp);
JSBool ok = JS_TRUE; 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"); JSB_PRECONDITION2(ok, cx, JS_FALSE, "Error processing arguments");
localStorageRemoveItem((char*)arg0 ); localStorageRemoveItem(arg0);
JS_SET_RVAL(cx, vp, JSVAL_VOID); JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; 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" ); JSB_PRECONDITION2( argc == 2, cx, JS_FALSE, "Invalid number of arguments" );
jsval *argvp = JS_ARGV(cx,vp); jsval *argvp = JS_ARGV(cx,vp);
JSBool ok = JS_TRUE; 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_std_string( cx, *argvp++, &arg0 );
ok &= jsval_to_charptr( cx, *argvp++, &arg1 ); ok &= jsval_to_std_string( cx, *argvp++, &arg1 );
JSB_PRECONDITION2(ok, cx, JS_FALSE, "Error processing arguments"); JSB_PRECONDITION2(ok, cx, JS_FALSE, "Error processing arguments");
localStorageSetItem((char*)arg0 , (char*)arg1 ); localStorageSetItem(arg0 , arg1);
JS_SET_RVAL(cx, vp, JSVAL_VOID); JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -22,6 +22,7 @@ std::function<Layer*()> createFunctions[] =
CL(RemoveAndRetainNodeTest), CL(RemoveAndRetainNodeTest),
CL(RemoveListenerAfterAddingTest), CL(RemoveListenerAfterAddingTest),
CL(DirectorEventTest), CL(DirectorEventTest),
CL(GlobalZTouchTest),
}; };
unsigned int TEST_CASE_COUNT = sizeof(createFunctions) / sizeof(createFunctions[0]); 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"; 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; 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__) */ #endif /* defined(__samples__NewEventDispatcherTest__) */

View File

@ -1790,7 +1790,7 @@ void ReorderParticleSystems::onEnter()
void ReorderParticleSystems::reorderSystem(float time) void ReorderParticleSystems::reorderSystem(float time)
{ {
auto system = static_cast<ParticleSystem*>(_batchNode->getChildren().at(1)); 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[] = static std::function<PerformanceContainerScene*()> createFunctions[] =
{ {
CL(TemplateVectorPerfTest), CL(TemplateVectorPerfTest),
CL(ArrayPerfTest) CL(ArrayPerfTest),
CL(TemplateMapStringKeyPerfTest),
CL(DictionaryStringKeyPerfTest),
CL(TemplateMapIntKeyPerfTest),
CL(DictionaryIntKeyPerfTest)
}; };
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0])) #define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
@ -264,27 +268,6 @@ void PerformanceContainerScene::updateProfilerName()
snprintf(_profilerName, sizeof(_profilerName)-1, "%s(%d)", testName(), quantityOfNodes); 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) void PerformanceContainerScene::dumpProfilerInfo(float dt)
{ {
CC_PROFILER_DISPLAY_TIMERS(); CC_PROFILER_DISPLAY_TIMERS();
@ -507,8 +490,6 @@ void TemplateVectorPerfTest::generateTestFunctions()
} }
} }
std::string TemplateVectorPerfTest::title() const std::string TemplateVectorPerfTest::title() const
{ {
return "Vector<T> Perf test"; return "Vector<T> Perf test";
@ -519,8 +500,6 @@ std::string TemplateVectorPerfTest::subtitle() const
return "Test 'pushBack', See console"; return "Test 'pushBack', See console";
} }
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
// //
// ArrayPerfTest // 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() void runContainerPerformanceTest()
{ {

View File

@ -44,8 +44,6 @@ public:
void dumpProfilerInfo(float dt); void dumpProfilerInfo(float dt);
// overrides // overrides
virtual void onExitTransitionDidStart() override;
virtual void onEnterTransitionDidFinish() override;
virtual void update(float dt) override; virtual void update(float dt) override;
protected: protected:
@ -85,6 +83,49 @@ public:
virtual std::string subtitle() const override; 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(); 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 // get the userdata, it's the index of the menu item clicked
auto menuItem = static_cast<MenuItem *>(sender); auto menuItem = static_cast<MenuItem *>(sender);
int idx = menuItem->getZOrder() - 10000; int idx = menuItem->getLocalZOrder() - 10000;
// create the test scene and run it // create the test scene and run it
auto scene = g_aTestNames[idx].callback(); auto scene = g_aTestNames[idx].callback();