Merge branch 'develop' of https://github.com/cocos2d/cocos2d-x into developBugFix

This commit is contained in:
samuele3hu 2014-01-21 23:10:36 +08:00
commit dbeac80cae
21 changed files with 208 additions and 302 deletions

View File

@ -10,6 +10,7 @@ cocos2d-x-3.0beta2 ?.? ?
[NEW] Renderer: Added BatchCommand. This command is not "batchable" with other commands, but improves performance in about 10%
[NEW] LuaBindings: Bindings-generator supports to bind namespace for lua.
[FIX] Wrong arithmetic of child's position in ParallaxNode::addChild()
[FIX] CocoStudio: TestColliderDetector in ArmatureTest can't work.
[FIX] Crash if file doesn't exist when using FileUtils::getStringFromFile.
[FIX] If setting a shorter string than before while using LabelAtlas, the effect will be wrong.

View File

@ -1 +1 @@
447e7ba37294e6da0df2e02f5a62f30fb15e3272
986d41d9721f8079f005999caa9fb0053ea11321

View File

@ -165,9 +165,6 @@ bool Director::init(void)
_renderer = new Renderer;
_console = new Console;
// create autorelease pool
PoolManager::sharedPoolManager()->push();
return true;
}
@ -193,9 +190,8 @@ Director::~Director(void)
delete _renderer;
delete _console;
// pop the autorelease pool
PoolManager::sharedPoolManager()->pop();
PoolManager::purgePoolManager();
// clean auto release pool
PoolManager::destroyInstance();
// delete _lastUpdate
CC_SAFE_DELETE(_lastUpdate);
@ -1049,7 +1045,7 @@ void DisplayLinkDirector::mainLoop()
drawScene();
// release the objects
PoolManager::sharedPoolManager()->pop();
PoolManager::getInstance()->getCurrentPool()->clear();
}
}

View File

@ -81,7 +81,7 @@ static id s_sharedDirectorCaller;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
cocos2d::Director::getInstance()->drawScene();
cocos2d::PoolManager::sharedPoolManager()->pop();
cocos2d::PoolManager::getInstance()->getCurrentPool()->clear();
[[CCEventDispatcher sharedDispatcher] dispatchQueuedEvents];
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:nil];

View File

@ -27,16 +27,26 @@ THE SOFTWARE.
NS_CC_BEGIN
static PoolManager* s_pPoolManager = NULL;
AutoreleasePool::AutoreleasePool()
:_name("")
{
_managedObjectArray.reserve(150);
PoolManager::getInstance()->push(this);
}
AutoreleasePool::AutoreleasePool(const std::string &name)
:_name(name)
{
_managedObjectArray.reserve(150);
PoolManager::getInstance()->push(this);
}
AutoreleasePool::~AutoreleasePool()
{
CCLOGINFO("deallocing AutoreleasePool: %p", this);
_managedObjectArray.clear();
PoolManager::getInstance()->pop();
}
void AutoreleasePool::addObject(Object* object)
@ -44,40 +54,26 @@ void AutoreleasePool::addObject(Object* object)
_managedObjectArray.pushBack(object);
CCASSERT(object->_reference > 1, "reference count should be greater than 1");
++(object->_autoReleaseCount);
object->release(); // no ref count, in this case autorelease pool added.
}
void AutoreleasePool::removeObject(Object* object)
{
for (unsigned int i = 0; i < object->_autoReleaseCount; ++i)
{
_managedObjectArray.eraseObject(object, false);
}
}
void AutoreleasePool::clear()
{
if (!_managedObjectArray.empty())
{
//CCAutoreleasePool* pReleasePool;
#ifdef _DEBUG
int nIndex = _managedObjectArray.size() - 1;
#endif
for(const auto &obj : _managedObjectArray) {
--(obj->_autoReleaseCount);
//(*it)->release();
//delete (*it);
#ifdef _DEBUG
nIndex--;
#endif
}
_managedObjectArray.clear();
}
}
void AutoreleasePool::dump()
{
CCLOG("autorelease pool: %s, number of managed object %d\n", _name.c_str(), static_cast<int>(_managedObjectArray.size()));
CCLOG("%20s%20s%20s", "Object pointer", "Object id", "reference count");
for (const auto &obj : _managedObjectArray)
{
CCLOG("%20p%20u%20u\n", obj, obj->_ID, obj->retainCount());
}
}
//--------------------------------------------------------------------
//
@ -85,105 +81,67 @@ void AutoreleasePool::clear()
//
//--------------------------------------------------------------------
PoolManager* PoolManager::sharedPoolManager()
PoolManager* PoolManager::s_singleInstance = nullptr;
PoolManager* PoolManager::getInstance()
{
if (s_pPoolManager == NULL)
if (s_singleInstance == nullptr)
{
s_pPoolManager = new PoolManager();
s_singleInstance = new PoolManager();
// Add the first auto release pool
s_singleInstance->_curReleasePool = new AutoreleasePool("cocos2d autorelease pool");
s_singleInstance->_releasePoolStack.push(s_singleInstance->_curReleasePool);
}
return s_pPoolManager;
return s_singleInstance;
}
void PoolManager::purgePoolManager()
void PoolManager::destroyInstance()
{
CC_SAFE_DELETE(s_pPoolManager);
delete s_singleInstance;
s_singleInstance = nullptr;
}
PoolManager::PoolManager()
{
_releasePoolStack.reserve(150);
_curReleasePool = 0;
}
PoolManager::~PoolManager()
{
CCLOGINFO("deallocing PoolManager: %p", this);
finalize();
// we only release the last autorelease pool here
_curReleasePool = 0;
_releasePoolStack.erase(0);
}
void PoolManager::finalize()
{
if (!_releasePoolStack.empty())
while (!_releasePoolStack.empty())
{
for(const auto &pool : _releasePoolStack) {
pool->clear();
}
AutoreleasePool* pool = _releasePoolStack.top();
_releasePoolStack.pop();
delete pool;
}
}
void PoolManager::push()
AutoreleasePool* PoolManager::getCurrentPool() const
{
AutoreleasePool* pool = new AutoreleasePool(); //ref = 1
return _curReleasePool;
}
void PoolManager::push(AutoreleasePool *pool)
{
_releasePoolStack.push(pool);
_curReleasePool = pool;
_releasePoolStack.pushBack(pool); //ref = 2
pool->release(); //ref = 1
}
void PoolManager::pop()
{
if (! _curReleasePool)
// Can not pop the pool that created by engine
CC_ASSERT(_releasePoolStack.size() >= 1);
_releasePoolStack.pop();
// Should update _curReleasePool if a temple pool is released
if (_releasePoolStack.size() > 1)
{
return;
_curReleasePool = _releasePoolStack.top();
}
ssize_t count = _releasePoolStack.size();
_curReleasePool->clear();
if (count > 1)
{
_releasePoolStack.erase(count-1);
// if(nCount > 1)
// {
// _curReleasePool = _releasePoolStack.at(count - 2);
// return;
// }
_curReleasePool = _releasePoolStack.at(count - 2);
}
/*_curReleasePool = NULL;*/
}
void PoolManager::removeObject(Object* object)
{
CCASSERT(_curReleasePool, "current auto release pool should not be null");
_curReleasePool->removeObject(object);
}
void PoolManager::addObject(Object* object)
{
getCurReleasePool()->addObject(object);
}
AutoreleasePool* PoolManager::getCurReleasePool()
{
if(!_curReleasePool)
{
push();
}
CCASSERT(_curReleasePool, "current auto release pool should not be null");
return _curReleasePool;
}
NS_CC_END

View File

@ -25,6 +25,8 @@ THE SOFTWARE.
#ifndef __AUTORELEASEPOOL_H__
#define __AUTORELEASEPOOL_H__
#include <stack>
#include <string>
#include "CCObject.h"
#include "CCVector.h"
@ -35,24 +37,21 @@ NS_CC_BEGIN
* @{
*/
class CC_DLL AutoreleasePool : public Object
class CC_DLL AutoreleasePool
{
/**
* The underlying array of object managed by the pool.
*
* Although Array retains the object once when an object is added, proper
* Object::release() is called outside the array to make sure that the pool
* does not affect the managed object's reference count. So an object can
* be destructed properly by calling Object::release() even if the object
* is in the pool.
*/
Vector<Object*> _managedObjectArray;
public:
/**
* @warn Don't create an auto release pool in heap, create it in stack.
* @js NA
* @lua NA
*/
AutoreleasePool();
/**
* Create an autorelease pool with specific name. This name is useful for debugging.
*/
AutoreleasePool(const std::string &name);
/**
* @js NA
* @lua NA
@ -72,15 +71,6 @@ public:
*/
void addObject(Object *object);
/**
* Remove a given object from this pool.
*
* @param object The object to be removed from the pool.
* @js NA
* @lua NA
*/
void removeObject(Object *object);
/**
* Clear the autorelease pool.
*
@ -90,88 +80,70 @@ public:
* @lua NA
*/
void clear();
/**
* Dump the objects that are put into autorelease pool. It is used for debugging.
*
* The result will look like:
* Object pointer address object id reference count
*
*/
void dump();
private:
/**
* The underlying array of object managed by the pool.
*
* Although Array retains the object once when an object is added, proper
* Object::release() is called outside the array to make sure that the pool
* does not affect the managed object's reference count. So an object can
* be destructed properly by calling Object::release() even if the object
* is in the pool.
*/
Vector<Object*> _managedObjectArray;
std::string _name;
};
class CC_DLL PoolManager
{
Vector<AutoreleasePool*> _releasePoolStack;
AutoreleasePool *_curReleasePool;
AutoreleasePool *getCurReleasePool();
public:
/**
* @js NA
* @lua NA
*/
static PoolManager* sharedPoolManager();
CC_DEPRECATED_ATTRIBUTE static PoolManager* sharedPoolManager() { return getInstance(); }
static PoolManager* getInstance();
/**
* @js NA
* @lua NA
*/
static void purgePoolManager();
CC_DEPRECATED_ATTRIBUTE static void purgePoolManager() { destroyInstance(); }
static void destroyInstance();
/**
* @js NA
* @lua NA
* Get current auto release pool, there is at least one auto release pool that created by engine.
* You can create your own auto release pool at demand, which will be put into auto releae pool stack.
*/
PoolManager();
/**
* @js NA
* @lua NA
*/
~PoolManager();
AutoreleasePool *getCurrentPool() const;
/**
* Clear all the AutoreleasePool on the pool stack.
* @js NA
* @lua NA
*/
void finalize();
/**
* Push a new AutoreleasePool to the pool stack.
* @js NA
* @lua NA
*/
void push();
/**
* Pop one AutoreleasePool from the pool stack.
*
* This method will ensure that there is at least one AutoreleasePool on
* the stack.
*
* The AutoreleasePool being poped is destructed.
* @js NA
* @lua NA
*/
void pop();
/**
* Remove a given object from the current autorelease pool.
*
* @param object The object to be removed.
*
* @see AutoreleasePool::removeObject
* @js NA
* @lua NA
*/
void removeObject(Object *object);
/**
* Add a given object to the current autorelease pool.
*
* @param object The object to add.
*
* @see AutoreleasePool::addObject
* @js NA
* @lua NA
*/
void addObject(Object *object);
/**
* @js NA
* @lua NA
*/
friend class AutoreleasePool;
private:
PoolManager();
~PoolManager();
void push(AutoreleasePool *pool);
void pop();
static PoolManager* s_singleInstance;
std::stack<AutoreleasePool*> _releasePoolStack;
AutoreleasePool *_curReleasePool;
};
// end of base_nodes group

View File

@ -34,7 +34,6 @@ NS_CC_BEGIN
Object::Object()
: _luaID(0)
, _reference(1) // when the object is created, the reference count of it is 1
, _autoReleaseCount(0)
{
static unsigned int uObjectCount = 0;
@ -43,13 +42,6 @@ Object::Object()
Object::~Object()
{
// if the object is managed, we should remove it
// from pool manager
if (_autoReleaseCount > 0)
{
PoolManager::sharedPoolManager()->removeObject(this);
}
// if the object is referenced by Lua engine, remove it
if (_luaID)
{
@ -67,7 +59,7 @@ Object::~Object()
Object* Object::autorelease()
{
PoolManager::sharedPoolManager()->addObject(this);
PoolManager::getInstance()->getCurrentPool()->addObject(this);
return this;
}

View File

@ -71,14 +71,12 @@ class CC_DLL Object
{
public:
/// object id, ScriptSupport need public _ID
unsigned int _ID;
unsigned int _ID;
/// Lua reference id
int _luaID;
int _luaID;
protected:
/// count of references
unsigned int _reference;
/// count of autorelease
unsigned int _autoReleaseCount;
unsigned int _reference;
public:
/**
* Constructor

View File

@ -124,6 +124,7 @@ Classes/PerformanceTest/PerformanceLabelTest.cpp \
Classes/PerformanceTest/PerformanceRendererTest.cpp \
Classes/PerformanceTest/PerformanceContainerTest.cpp \
Classes/PhysicsTest/PhysicsTest.cpp \
Classes/ReleasePoolTest/ReleasePoolTest.cpp \
Classes/RenderTextureTest/RenderTextureTest.cpp \
Classes/RotateWorldTest/RotateWorldTest.cpp \
Classes/SceneTest/SceneTest.cpp \

View File

@ -119,6 +119,7 @@ set(SAMPLE_SRC
Classes/PerformanceTest/PerformanceRendererTest.cpp
Classes/PerformanceTest/PerformanceContainerTest.cpp
Classes/PhysicsTest/PhysicsTest.cpp
Classes/ReleasePoolTest/ReleasePoolTest.cpp
Classes/RenderTextureTest/RenderTextureTest.cpp
Classes/RotateWorldTest/RotateWorldTest.cpp
Classes/SceneTest/SceneTest.cpp

View File

@ -0,0 +1,56 @@
#include "ReleasePoolTest.h"
using namespace cocos2d;
class TestObject : public Object
{
public:
};
void ReleasePoolTestScene::runThisTest()
{
// title
auto label = LabelTTF::create("AutoreasePool Test", "Arial", 32);
addChild(label, 9999);
label->setPosition(Point(VisibleRect::center().x, VisibleRect::top().y - 30));
// reference count should be added when added into auto release pool
TestObject *obj = new TestObject();
obj->autorelease();
assert(obj->retainCount() == 2);
// can invoke autorelease more than once
obj->autorelease();
assert(obj->retainCount() == 3);
// create an autorelease pool in stack
{
AutoreleasePool pool1;
obj->autorelease();
assert(obj->retainCount() == 4);
// retain, release can work together with autorelease pool
obj->retain();
assert(obj->retainCount() == 5);
obj->release();
assert(obj->retainCount() == 4);
AutoreleasePool pool2;
for (int i = 0; i < 1000; ++i)
{
TestObject *tmpObj = new TestObject();
tmpObj->autorelease();
}
pool2.dump();
}
// pool is destroyed, so the release count is minused by one
assert(obj->retainCount() == 3);
Director::getInstance()->replaceScene(this);
}

View File

@ -0,0 +1,18 @@
/*
*
*/
#ifndef __RELEASE_POOL_TEST_H__
#define __RELEASE_POOL_TEST_H__
#include "../testBasic.h"
class ReleasePoolTestScene : public TestScene
{
public:
virtual void runThisTest();
private:
};
#endif // __RELEASE_POOL_TEST_H__

View File

@ -73,6 +73,7 @@ struct {
{ "ParticleTest", [](){return new ParticleTestScene(); } },
{ "PerformanceTest", []() { return new PerformanceTestScene(); } },
{ "PhysicsTest", []() { return new PhysicsTestScene(); } },
{ "ReleasePoolTest", [](){ return new ReleasePoolTestScene(); } },
{ "RenderTextureTest", [](){return new RenderTextureScene(); } },
{ "RotateWorldTest", [](){return new RotateWorldTestScene(); } },
{ "SceneTest", [](){return new SceneTestScene();} },

View File

@ -68,5 +68,6 @@
#include "DataVisitorTest/DataVisitorTest.h"
#include "ConfigurationTest/ConfigurationTest.h"
#include "PhysicsTest/PhysicsTest.h"
#include "ReleasePoolTest/ReleasePoolTest.h"
#endif

View File

@ -190,6 +190,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\websockets\prebuilt\win32\*.*" "$
<ClCompile Include="..\Classes\PerformanceTest\PerformanceLabelTest.cpp" />
<ClCompile Include="..\Classes\PerformanceTest\PerformanceRendererTest.cpp" />
<ClCompile Include="..\Classes\PhysicsTest\PhysicsTest.cpp" />
<ClCompile Include="..\Classes\ReleasePoolTest\ReleasePoolTest.cpp" />
<ClCompile Include="..\Classes\ShaderTest\ShaderTest2.cpp" />
<ClCompile Include="..\Classes\SpineTest\SpineTest.cpp" />
<ClCompile Include="..\Classes\TexturePackerEncryptionTest\TextureAtlasEncryptionTest.cpp" />
@ -338,6 +339,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\websockets\prebuilt\win32\*.*" "$
<ClInclude Include="..\Classes\PerformanceTest\PerformanceLabelTest.h" />
<ClInclude Include="..\Classes\PerformanceTest\PerformanceRendererTest.h" />
<ClInclude Include="..\Classes\PhysicsTest\PhysicsTest.h" />
<ClInclude Include="..\Classes\ReleasePoolTest\ReleasePoolTest.h" />
<ClInclude Include="..\Classes\ShaderTest\ShaderTest2.h" />
<ClInclude Include="..\Classes\SpineTest\SpineTest.h" />
<ClInclude Include="..\Classes\TexturePackerEncryptionTest\TextureAtlasEncryptionTest.h" />

View File

@ -307,6 +307,9 @@
<Filter Include="Classes\ExtensionsTest\CocoStudioSceneTest\TriggerCode">
<UniqueIdentifier>{5ff3af4e-0610-480b-b297-8f407e12f369}</UniqueIdentifier>
</Filter>
<Filter Include="Classes\ReleasePoolTest">
<UniqueIdentifier>{f71fab28-32be-45c9-a941-9a22b5a59e51}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
@ -721,6 +724,9 @@
<ClCompile Include="..\Classes\PerformanceTest\PerformanceContainerTest.cpp">
<Filter>Classes\PerformanceTest</Filter>
</ClCompile>
<ClCompile Include="..\Classes\ReleasePoolTest\ReleasePoolTest.cpp">
<Filter>Classes\ReleasePoolTest</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="main.h">
@ -1333,5 +1339,8 @@
<ClInclude Include="..\Classes\PerformanceTest\PerformanceContainerTest.h">
<Filter>Classes\PerformanceTest</Filter>
</ClInclude>
<ClInclude Include="..\Classes\ReleasePoolTest\ReleasePoolTest.h">
<Filter>Classes\ReleasePoolTest</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -145,26 +145,6 @@ bool AppDelegate::applicationDidFinishLaunching()
return true;
}
void handle_signal(int signal) {
static int internal_state = 0;
ScriptingCore* sc = ScriptingCore::getInstance();
// should start everything back
auto director = Director::getInstance();
if (director->getRunningScene()) {
director->popToRootScene();
} else {
PoolManager::sharedPoolManager()->finalize();
if (internal_state == 0) {
//sc->dumpRoot(NULL, 0, NULL);
sc->start();
internal_state = 1;
} else {
sc->runScript("hello.js");
internal_state = 0;
}
}
}
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground()
{

View File

@ -126,26 +126,6 @@ bool AppDelegate::applicationDidFinishLaunching()
return true;
}
void handle_signal(int signal) {
static int internal_state = 0;
ScriptingCore* sc = ScriptingCore::getInstance();
// should start everything back
auto director = Director::getInstance();
if (director->getRunningScene()) {
director->popToRootScene();
} else {
PoolManager::sharedPoolManager()->finalize();
if (internal_state == 0) {
//sc->dumpRoot(NULL, 0, NULL);
sc->start();
internal_state = 1;
} else {
sc->runScript("hello.js");
internal_state = 0;
}
}
}
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground()
{

View File

@ -68,26 +68,6 @@ bool AppDelegate::applicationDidFinishLaunching()
return true;
}
void handle_signal(int signal) {
static int internal_state = 0;
ScriptingCore* sc = ScriptingCore::getInstance();
// should start everything back
auto director = Director::getInstance();
if (director->getRunningScene()) {
director->popToRootScene();
} else {
PoolManager::sharedPoolManager()->finalize();
if (internal_state == 0) {
//sc->dumpRoot(NULL, 0, NULL);
sc->start();
internal_state = 1;
} else {
sc->runScript("hello.js");
internal_state = 0;
}
}
}
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground()
{

View File

@ -121,26 +121,6 @@ bool AppDelegate::applicationDidFinishLaunching()
return true;
}
void handle_signal(int signal) {
static int internal_state = 0;
ScriptingCore* sc = ScriptingCore::getInstance();
// should start everything back
auto director = Director::getInstance();
if (director->getRunningScene()) {
director->popToRootScene();
} else {
PoolManager::sharedPoolManager()->finalize();
if (internal_state == 0) {
//sc->dumpRoot(NULL, 0, NULL);
sc->start();
internal_state = 1;
} else {
sc->runScript("hello.js");
internal_state = 0;
}
}
}
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground()
{

View File

@ -65,26 +65,6 @@ bool AppDelegate::applicationDidFinishLaunching()
return true;
}
void handle_signal(int signal) {
static int internal_state = 0;
ScriptingCore* sc = ScriptingCore::getInstance();
// should start everything back
auto director = Director::getInstance();
if (director->getRunningScene()) {
director->popToRootScene();
} else {
PoolManager::sharedPoolManager()->finalize();
if (internal_state == 0) {
//sc->dumpRoot(NULL, 0, NULL);
sc->start();
internal_state = 1;
} else {
sc->runScript("hello.js");
internal_state = 0;
}
}
}
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground()
{