mirror of https://github.com/axmolengine/axmol.git
Merge pull request #2978 from dumganhar/minggo-iss2305-replace-pthread
Merge PR https://github.com/cocos2d/cocos2d-x/pull/2969
This commit is contained in:
commit
38f89b7101
|
@ -6,7 +6,8 @@ env:
|
|||
- PLATFORM=linux DEBUG=1
|
||||
# Since switching to C++11 only the ARM version of the nactive client
|
||||
# port currently builds. TODO(sbc): Re-enable all architectures.
|
||||
- PLATFORM=nacl DEBUG=1 NACL_ARCH=arm
|
||||
# Disabled travis-ci build for native client port since it doesn't support std::thread, std::mutex.
|
||||
# - PLATFORM=nacl DEBUG=1 NACL_ARCH=arm
|
||||
- PLATFORM=android
|
||||
- PLATFORM=emscripten DEBUG=1
|
||||
global:
|
||||
|
|
|
@ -200,7 +200,7 @@ public: virtual void set##funName(varType var) \
|
|||
#define CC_SAFE_DELETE_ARRAY(p) do { if(p) { delete[] (p); (p) = 0; } } while(0)
|
||||
#define CC_SAFE_FREE(p) do { if(p) { free(p); (p) = 0; } } while(0)
|
||||
#define CC_SAFE_RELEASE(p) do { if(p) { (p)->release(); } } while(0)
|
||||
#define CC_SAFE_RELEASE_NULL(p) do { if(p) { (p)->release(); (p) = 0; } } while(0)
|
||||
#define CC_SAFE_RELEASE_NULL(p) do { if(p) { (p)->release(); (p) = nullptr; } } while(0)
|
||||
#define CC_SAFE_RETAIN(p) do { if(p) { (p)->retain(); } } while(0)
|
||||
#define CC_BREAK_IF(cond) if(cond) break
|
||||
|
||||
|
|
|
@ -36,18 +36,18 @@ using namespace std;
|
|||
// Following methods are implemented in TextureCacheEmscripten.js:
|
||||
extern "C" {
|
||||
void cocos2dx_newAsyncImageLoader(int textureCache, int callback__ignored);
|
||||
void cocos2dx_asyncImageLoader_LoadImage(const char *path, AsyncStruct *asyncData);
|
||||
void cocos2dx_asyncImageLoader_LoadImage(const char *path, TextureCache::AsyncStruct *asyncData);
|
||||
void cocos2dx_shutdownAsyncImageLoader();
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
// This C interface is exposed so that the JavaScript in
|
||||
// TextureCacheEmscripten.js is able to call into these functions.
|
||||
void TextureCacheEmscripten_addImageAsyncCallBack(TextureCacheEmscripten *tc, AsyncStruct *data, unsigned char *imgData, int width, int height);
|
||||
void TextureCacheEmscripten_addImageAsyncCallBack(TextureCacheEmscripten *tc, TextureCache::AsyncStruct *data, unsigned char *imgData, int width, int height);
|
||||
void TextureCacheEmscripten_preMultiplyImageRegion( unsigned char *in, int win, int hin, unsigned char *out, int wout, int hout, int xout, int yout);
|
||||
};
|
||||
|
||||
void TextureCacheEmscripten_addImageAsyncCallBack(TextureCacheEmscripten *tc, AsyncStruct *data, unsigned char *imgData, int width, int height)
|
||||
void TextureCacheEmscripten_addImageAsyncCallBack(TextureCacheEmscripten *tc, TextureCache::AsyncStruct *data, unsigned char *imgData, int width, int height)
|
||||
{
|
||||
tc->addImageAsyncCallBack_emscripten(data, imgData, width, height);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,12 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stack>
|
||||
#include <cctype>
|
||||
#include <list>
|
||||
#include <thread>
|
||||
|
||||
#include "CCTextureCache.h"
|
||||
#include "CCTexture2D.h"
|
||||
#include "ccMacros.h"
|
||||
|
@ -31,17 +37,10 @@ THE SOFTWARE.
|
|||
#include "platform/platform.h"
|
||||
#include "platform/CCFileUtils.h"
|
||||
#include "platform/CCThread.h"
|
||||
#include "platform/CCImage.h"
|
||||
#include "support/ccUtils.h"
|
||||
#include "CCScheduler.h"
|
||||
#include "cocoa/CCString.h"
|
||||
#include <errno.h>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <cctype>
|
||||
#include <queue>
|
||||
#include <list>
|
||||
#include <pthread.h>
|
||||
|
||||
|
||||
#ifdef EMSCRIPTEN
|
||||
#include <emscripten/emscripten.h>
|
||||
|
@ -52,60 +51,136 @@ using namespace std;
|
|||
|
||||
NS_CC_BEGIN
|
||||
|
||||
typedef struct _ImageInfo
|
||||
// implementation TextureCache
|
||||
|
||||
TextureCache* TextureCache::_sharedTextureCache = nullptr;
|
||||
|
||||
|
||||
TextureCache * TextureCache::sharedTextureCache()
|
||||
{
|
||||
AsyncStruct *asyncStruct;
|
||||
Image *image;
|
||||
Image::EImageFormat imageType;
|
||||
} ImageInfo;
|
||||
|
||||
static pthread_t s_loadingThread;
|
||||
|
||||
static pthread_mutex_t s_SleepMutex;
|
||||
static pthread_cond_t s_SleepCondition;
|
||||
|
||||
static pthread_mutex_t s_asyncStructQueueMutex;
|
||||
static pthread_mutex_t s_ImageInfoMutex;
|
||||
|
||||
if (!_sharedTextureCache)
|
||||
{
|
||||
#ifdef EMSCRIPTEN
|
||||
// Hack to get ASM.JS validation (no undefined symbols allowed).
|
||||
#define pthread_cond_signal(_)
|
||||
_sharedTextureCache = new TextureCacheEmscripten();
|
||||
#else
|
||||
_sharedTextureCache = new TextureCache();
|
||||
#endif // EMSCRIPTEN
|
||||
|
||||
static unsigned long s_nAsyncRefCount = 0;
|
||||
|
||||
static bool need_quit = false;
|
||||
|
||||
static std::queue<AsyncStruct*>* s_pAsyncStructQueue = NULL;
|
||||
static std::queue<ImageInfo*>* s_pImageQueue = NULL;
|
||||
|
||||
static Image::EImageFormat computeImageFormatType(string& filename)
|
||||
{
|
||||
Image::EImageFormat ret = Image::kFmtUnKnown;
|
||||
|
||||
if ((std::string::npos != filename.find(".jpg")) || (std::string::npos != filename.find(".jpeg")))
|
||||
{
|
||||
ret = Image::kFmtJpg;
|
||||
}
|
||||
else if ((std::string::npos != filename.find(".png")) || (std::string::npos != filename.find(".PNG")))
|
||||
{
|
||||
ret = Image::kFmtPng;
|
||||
}
|
||||
else if ((std::string::npos != filename.find(".tiff")) || (std::string::npos != filename.find(".TIFF")))
|
||||
{
|
||||
ret = Image::kFmtTiff;
|
||||
}
|
||||
else if ((std::string::npos != filename.find(".webp")) || (std::string::npos != filename.find(".WEBP")))
|
||||
{
|
||||
ret = Image::kFmtWebp;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return _sharedTextureCache;
|
||||
}
|
||||
|
||||
static void* loadImage(void* data)
|
||||
TextureCache::TextureCache()
|
||||
: _asyncStructQueue(nullptr)
|
||||
, _imageInfoQueue(nullptr)
|
||||
, _needQuit(false)
|
||||
, _asyncRefCount(0)
|
||||
, _textures(new Dictionary())
|
||||
{
|
||||
AsyncStruct *pAsyncStruct = NULL;
|
||||
CCAssert(_sharedTextureCache == nullptr, "Attempted to allocate a second instance of a singleton.");
|
||||
}
|
||||
|
||||
TextureCache::~TextureCache()
|
||||
{
|
||||
CCLOGINFO("cocos2d: deallocing TextureCache: %p", this);
|
||||
|
||||
CC_SAFE_RELEASE(_textures);
|
||||
|
||||
_sharedTextureCache = nullptr;
|
||||
}
|
||||
|
||||
void TextureCache::purgeSharedTextureCache()
|
||||
{
|
||||
// notify sub thread to quick
|
||||
_sharedTextureCache->_needQuit = true;
|
||||
std::lock_guard<std::mutex> lk(_sharedTextureCache->_sleepMutex);
|
||||
_sharedTextureCache->_sleepCondition.notify_one();
|
||||
|
||||
CC_SAFE_RELEASE_NULL(_sharedTextureCache);
|
||||
}
|
||||
|
||||
const char* TextureCache::description()
|
||||
{
|
||||
return String::createWithFormat("<TextureCache | Number of textures = %u>", _textures->count())->getCString();
|
||||
}
|
||||
|
||||
Dictionary* TextureCache::snapshotTextures()
|
||||
{
|
||||
Dictionary* pRet = new Dictionary();
|
||||
DictElement* pElement = NULL;
|
||||
CCDICT_FOREACH(_textures, pElement)
|
||||
{
|
||||
pRet->setObject(pElement->getObject(), pElement->getStrKey());
|
||||
}
|
||||
pRet->autorelease();
|
||||
return pRet;
|
||||
}
|
||||
|
||||
void TextureCache::addImageAsync(const char *path, Object *target, SEL_CallFuncO selector)
|
||||
{
|
||||
CCAssert(path != NULL, "TextureCache: fileimage MUST not be NULL");
|
||||
|
||||
Texture2D *texture = NULL;
|
||||
|
||||
// optimization
|
||||
|
||||
std::string pathKey = path;
|
||||
|
||||
pathKey = FileUtils::sharedFileUtils()->fullPathForFilename(pathKey.c_str());
|
||||
texture = (Texture2D*)_textures->objectForKey(pathKey.c_str());
|
||||
|
||||
std::string fullpath = pathKey;
|
||||
if (texture != NULL)
|
||||
{
|
||||
if (target && selector)
|
||||
{
|
||||
(target->*selector)(texture);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// lazy init
|
||||
if (_asyncStructQueue == NULL)
|
||||
{
|
||||
_asyncStructQueue = new queue<AsyncStruct*>();
|
||||
_imageInfoQueue = new queue<ImageInfo*>();
|
||||
|
||||
// create a new thread to load images
|
||||
auto t = std::thread(&TextureCache::loadImage, this);
|
||||
t.detach();
|
||||
// should retain here, because sub thread use invoke TextureCache::loadImage()
|
||||
retain();
|
||||
|
||||
_needQuit = false;
|
||||
}
|
||||
|
||||
if (0 == _asyncRefCount)
|
||||
{
|
||||
Director::sharedDirector()->getScheduler()->scheduleSelector(schedule_selector(TextureCache::addImageAsyncCallBack), this, 0, false);
|
||||
}
|
||||
|
||||
++_asyncRefCount;
|
||||
|
||||
if (target)
|
||||
{
|
||||
target->retain();
|
||||
}
|
||||
|
||||
// generate async struct
|
||||
AsyncStruct *data = new AsyncStruct(fullpath, target, selector);
|
||||
|
||||
// add async struct into queue
|
||||
_asyncStructQueueMutex.lock();
|
||||
_asyncStructQueue->push(data);
|
||||
_asyncStructQueueMutex.unlock();
|
||||
|
||||
std::lock_guard<std::mutex> lk(_sleepMutex);
|
||||
_sleepCondition.notify_one();
|
||||
}
|
||||
|
||||
void TextureCache::loadImage()
|
||||
{
|
||||
AsyncStruct *pAsyncStruct = nullptr;
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
@ -113,16 +188,17 @@ static void* loadImage(void* data)
|
|||
Thread thread;
|
||||
thread.createAutoreleasePool();
|
||||
|
||||
std::queue<AsyncStruct*> *pQueue = s_pAsyncStructQueue;
|
||||
pthread_mutex_lock(&s_asyncStructQueueMutex);// get async struct from queue
|
||||
std::queue<AsyncStruct*> *pQueue = _asyncStructQueue;
|
||||
_asyncStructQueueMutex.lock();
|
||||
if (pQueue->empty())
|
||||
{
|
||||
pthread_mutex_unlock(&s_asyncStructQueueMutex);
|
||||
if (need_quit) {
|
||||
_asyncStructQueueMutex.unlock();
|
||||
if (_needQuit) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
pthread_cond_wait(&s_SleepCondition, &s_SleepMutex);
|
||||
std::unique_lock<std::mutex> lk(_sleepMutex);
|
||||
_sleepCondition.wait(lk);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -130,7 +206,7 @@ static void* loadImage(void* data)
|
|||
{
|
||||
pAsyncStruct = pQueue->front();
|
||||
pQueue->pop();
|
||||
pthread_mutex_unlock(&s_asyncStructQueueMutex);
|
||||
_asyncStructQueueMutex.unlock();
|
||||
}
|
||||
|
||||
const char *filename = pAsyncStruct->filename.c_str();
|
||||
|
@ -161,161 +237,62 @@ static void* loadImage(void* data)
|
|||
pImageInfo->imageType = imageType;
|
||||
|
||||
// put the image info into the queue
|
||||
pthread_mutex_lock(&s_ImageInfoMutex);
|
||||
s_pImageQueue->push(pImageInfo);
|
||||
pthread_mutex_unlock(&s_ImageInfoMutex);
|
||||
_imageInfoMutex.lock();
|
||||
_imageInfoQueue->push(pImageInfo);
|
||||
_imageInfoMutex.unlock();
|
||||
}
|
||||
|
||||
if( s_pAsyncStructQueue != NULL )
|
||||
if(_asyncStructQueue != nullptr)
|
||||
{
|
||||
delete s_pAsyncStructQueue;
|
||||
s_pAsyncStructQueue = NULL;
|
||||
delete s_pImageQueue;
|
||||
s_pImageQueue = NULL;
|
||||
|
||||
pthread_mutex_destroy(&s_asyncStructQueueMutex);
|
||||
pthread_mutex_destroy(&s_ImageInfoMutex);
|
||||
pthread_mutex_destroy(&s_SleepMutex);
|
||||
pthread_cond_destroy(&s_SleepCondition);
|
||||
delete _asyncStructQueue;
|
||||
_asyncStructQueue = nullptr;
|
||||
delete _imageInfoQueue;
|
||||
_imageInfoQueue = nullptr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
// should release here, because we retain it when creating a sub thread in addImageAsync()
|
||||
release();
|
||||
}
|
||||
|
||||
// implementation TextureCache
|
||||
|
||||
// TextureCache - Alloc, Init & Dealloc
|
||||
static TextureCache *g_sharedTextureCache = NULL;
|
||||
|
||||
TextureCache * TextureCache::sharedTextureCache()
|
||||
Image::EImageFormat TextureCache::computeImageFormatType(string& filename)
|
||||
{
|
||||
if (!g_sharedTextureCache)
|
||||
Image::EImageFormat ret = Image::kFmtUnKnown;
|
||||
|
||||
if ((std::string::npos != filename.find(".jpg")) || (std::string::npos != filename.find(".jpeg")))
|
||||
{
|
||||
#ifdef EMSCRIPTEN
|
||||
g_sharedTextureCache = new TextureCacheEmscripten();
|
||||
#else
|
||||
g_sharedTextureCache = new TextureCache();
|
||||
#endif // EMSCRIPTEN
|
||||
ret = Image::kFmtJpg;
|
||||
}
|
||||
return g_sharedTextureCache;
|
||||
}
|
||||
|
||||
TextureCache::TextureCache()
|
||||
{
|
||||
CCAssert(g_sharedTextureCache == NULL, "Attempted to allocate a second instance of a singleton.");
|
||||
|
||||
_textures = new Dictionary();
|
||||
}
|
||||
|
||||
TextureCache::~TextureCache()
|
||||
{
|
||||
CCLOGINFO("cocos2d: deallocing TextureCache: %p", this);
|
||||
need_quit = true;
|
||||
|
||||
pthread_cond_signal(&s_SleepCondition);
|
||||
CC_SAFE_RELEASE(_textures);
|
||||
}
|
||||
|
||||
void TextureCache::purgeSharedTextureCache()
|
||||
{
|
||||
CC_SAFE_RELEASE_NULL(g_sharedTextureCache);
|
||||
}
|
||||
|
||||
const char* TextureCache::description()
|
||||
{
|
||||
return String::createWithFormat("<TextureCache | Number of textures = %u>", _textures->count())->getCString();
|
||||
}
|
||||
|
||||
Dictionary* TextureCache::snapshotTextures()
|
||||
{
|
||||
Dictionary* pRet = new Dictionary();
|
||||
DictElement* pElement = NULL;
|
||||
CCDICT_FOREACH(_textures, pElement)
|
||||
else if ((std::string::npos != filename.find(".png")) || (std::string::npos != filename.find(".PNG")))
|
||||
{
|
||||
pRet->setObject(pElement->getObject(), pElement->getStrKey());
|
||||
ret = Image::kFmtPng;
|
||||
}
|
||||
pRet->autorelease();
|
||||
return pRet;
|
||||
}
|
||||
|
||||
void TextureCache::addImageAsync(const char *path, Object *target, SEL_CallFuncO selector)
|
||||
{
|
||||
|
||||
CCAssert(path != NULL, "TextureCache: fileimage MUST not be NULL");
|
||||
|
||||
Texture2D *texture = NULL;
|
||||
|
||||
// optimization
|
||||
|
||||
std::string pathKey = path;
|
||||
|
||||
pathKey = FileUtils::sharedFileUtils()->fullPathForFilename(pathKey.c_str());
|
||||
texture = (Texture2D*)_textures->objectForKey(pathKey.c_str());
|
||||
|
||||
std::string fullpath = pathKey;
|
||||
if (texture != NULL)
|
||||
else if ((std::string::npos != filename.find(".tiff")) || (std::string::npos != filename.find(".TIFF")))
|
||||
{
|
||||
if (target && selector)
|
||||
{
|
||||
(target->*selector)(texture);
|
||||
}
|
||||
|
||||
return;
|
||||
ret = Image::kFmtTiff;
|
||||
}
|
||||
|
||||
// lazy init
|
||||
if (s_pAsyncStructQueue == NULL)
|
||||
{
|
||||
s_pAsyncStructQueue = new queue<AsyncStruct*>();
|
||||
s_pImageQueue = new queue<ImageInfo*>();
|
||||
|
||||
pthread_mutex_init(&s_asyncStructQueueMutex, NULL);
|
||||
pthread_mutex_init(&s_ImageInfoMutex, NULL);
|
||||
pthread_mutex_init(&s_SleepMutex, NULL);
|
||||
pthread_cond_init(&s_SleepCondition, NULL);
|
||||
pthread_create(&s_loadingThread, NULL, loadImage, NULL);
|
||||
|
||||
need_quit = false;
|
||||
}
|
||||
|
||||
if (0 == s_nAsyncRefCount)
|
||||
else if ((std::string::npos != filename.find(".webp")) || (std::string::npos != filename.find(".WEBP")))
|
||||
{
|
||||
Director::sharedDirector()->getScheduler()->scheduleSelector(schedule_selector(TextureCache::addImageAsyncCallBack), this, 0, false);
|
||||
ret = Image::kFmtWebp;
|
||||
}
|
||||
|
||||
++s_nAsyncRefCount;
|
||||
|
||||
if (target)
|
||||
{
|
||||
target->retain();
|
||||
}
|
||||
|
||||
// generate async struct
|
||||
AsyncStruct *data = new AsyncStruct(fullpath, target, selector);
|
||||
|
||||
// add async struct into queue
|
||||
pthread_mutex_lock(&s_asyncStructQueueMutex);
|
||||
s_pAsyncStructQueue->push(data);
|
||||
pthread_mutex_unlock(&s_asyncStructQueueMutex);
|
||||
|
||||
pthread_cond_signal(&s_SleepCondition);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void TextureCache::addImageAsyncCallBack(float dt)
|
||||
{
|
||||
// the image is generated in loading thread
|
||||
std::queue<ImageInfo*> *imagesQueue = s_pImageQueue;
|
||||
std::queue<ImageInfo*> *imagesQueue = _imageInfoQueue;
|
||||
|
||||
pthread_mutex_lock(&s_ImageInfoMutex);
|
||||
_imageInfoMutex.lock();
|
||||
if (imagesQueue->empty())
|
||||
{
|
||||
pthread_mutex_unlock(&s_ImageInfoMutex);
|
||||
_imageInfoMutex.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
ImageInfo *pImageInfo = imagesQueue->front();
|
||||
imagesQueue->pop();
|
||||
pthread_mutex_unlock(&s_ImageInfoMutex);
|
||||
_imageInfoMutex.unlock();
|
||||
|
||||
AsyncStruct *pAsyncStruct = pImageInfo->asyncStruct;
|
||||
Image *pImage = pImageInfo->image;
|
||||
|
@ -326,17 +303,13 @@ void TextureCache::addImageAsyncCallBack(float dt)
|
|||
|
||||
// generate texture in render thread
|
||||
Texture2D *texture = new Texture2D();
|
||||
#if 0 //TODO: (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
||||
texture->initWithImage(pImage, kResolutioniPhone);
|
||||
#else
|
||||
|
||||
texture->initWithImage(pImage);
|
||||
#endif
|
||||
|
||||
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
||||
// cache the texture file name
|
||||
VolatileTexture::addImageTexture(texture, filename, pImageInfo->imageType);
|
||||
#endif
|
||||
|
||||
// cache the texture
|
||||
_textures->setObject(texture, filename);
|
||||
texture->autorelease();
|
||||
|
@ -351,8 +324,8 @@ void TextureCache::addImageAsyncCallBack(float dt)
|
|||
delete pAsyncStruct;
|
||||
delete pImageInfo;
|
||||
|
||||
--s_nAsyncRefCount;
|
||||
if (0 == s_nAsyncRefCount)
|
||||
--_asyncRefCount;
|
||||
if (0 == _asyncRefCount)
|
||||
{
|
||||
Director::sharedDirector()->getScheduler()->unscheduleSelector(schedule_selector(TextureCache::addImageAsyncCallBack), this);
|
||||
}
|
||||
|
@ -368,8 +341,6 @@ Texture2D * TextureCache::addImage(const char * path)
|
|||
// Split up directory and filename
|
||||
// MUTEX:
|
||||
// Needed since addImageAsync calls this method from a different thread
|
||||
|
||||
//pthread_mutex_lock(_dictLock);
|
||||
|
||||
std::string pathKey = path;
|
||||
|
||||
|
@ -380,7 +351,7 @@ Texture2D * TextureCache::addImage(const char * path)
|
|||
}
|
||||
texture = (Texture2D*)_textures->objectForKey(pathKey.c_str());
|
||||
|
||||
std::string fullpath = pathKey; // (FileUtils::sharedFileUtils()->fullPathFromRelativePath(path));
|
||||
std::string fullpath = pathKey;
|
||||
if (! texture)
|
||||
{
|
||||
std::string lowerCase(pathKey);
|
||||
|
@ -448,7 +419,6 @@ Texture2D * TextureCache::addImage(const char * path)
|
|||
|
||||
CC_SAFE_RELEASE(pImage);
|
||||
|
||||
//pthread_mutex_unlock(_dictLock);
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,11 +27,16 @@ THE SOFTWARE.
|
|||
#ifndef __CCTEXTURE_CACHE_H__
|
||||
#define __CCTEXTURE_CACHE_H__
|
||||
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
|
||||
#include "cocoa/CCObject.h"
|
||||
#include "cocoa/CCDictionary.h"
|
||||
#include "textures/CCTexture2D.h"
|
||||
#include <string>
|
||||
|
||||
#include "platform/CCImage.h"
|
||||
|
||||
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
||||
#include "platform/CCImage.h"
|
||||
|
@ -40,19 +45,6 @@ THE SOFTWARE.
|
|||
|
||||
NS_CC_BEGIN
|
||||
|
||||
class AsyncStruct
|
||||
{
|
||||
public:
|
||||
AsyncStruct(const std::string& fn, Object *t, SEL_CallFuncO s) : filename(fn), target(t), selector(s) {}
|
||||
|
||||
std::string filename;
|
||||
Object *target;
|
||||
SEL_CallFuncO selector;
|
||||
};
|
||||
|
||||
class Lock;
|
||||
class Image;
|
||||
|
||||
/**
|
||||
* @addtogroup textures
|
||||
* @{
|
||||
|
@ -64,15 +56,6 @@ class Image;
|
|||
*/
|
||||
class CC_DLL TextureCache : public Object
|
||||
{
|
||||
protected:
|
||||
Dictionary* _textures;
|
||||
//pthread_mutex_t *_dictLock;
|
||||
|
||||
|
||||
private:
|
||||
/// todo: void addImageWithAsyncObject(AsyncObject* async);
|
||||
void addImageAsyncCallBack(float dt);
|
||||
|
||||
public:
|
||||
|
||||
TextureCache();
|
||||
|
@ -105,18 +88,8 @@ public:
|
|||
* Supported image extensions: .png, .jpg
|
||||
* @since v0.8
|
||||
*/
|
||||
|
||||
virtual void addImageAsync(const char *path, Object *target, SEL_CallFuncO selector);
|
||||
|
||||
/* Returns a Texture2D object given an CGImageRef image
|
||||
* If the image was not previously loaded, it will create a new Texture2D object and it will return it.
|
||||
* Otherwise it will return a reference of a previously loaded image
|
||||
* The "key" parameter will be used as the "key" for the cache.
|
||||
* If "key" is nil, then a new texture will be created each time.
|
||||
* @since v0.8
|
||||
*/
|
||||
|
||||
// todo: CGImageRef Texture2D* addCGImage(CGImageRef image, string & key);
|
||||
/** Returns a Texture2D object given an UIImage image
|
||||
* If the image was not previously loaded, it will create a new Texture2D object and it will return it.
|
||||
* Otherwise it will return a reference of a previously loaded image
|
||||
|
@ -129,6 +102,7 @@ public:
|
|||
@since v0.99.5
|
||||
*/
|
||||
Texture2D* textureForKey(const char* key);
|
||||
|
||||
/** Purges the dictionary of loaded textures.
|
||||
* Call this method if you receive the "Memory Warning"
|
||||
* In the short term: it will free some resources preventing your app from being killed
|
||||
|
@ -176,6 +150,47 @@ public:
|
|||
It's only useful when the value of CC_ENABLE_CACHE_TEXTURE_DATA is 1
|
||||
*/
|
||||
static void reloadAllTextures();
|
||||
|
||||
private:
|
||||
void addImageAsyncCallBack(float dt);
|
||||
void loadImage();
|
||||
Image::EImageFormat computeImageFormatType(std::string& filename);
|
||||
|
||||
public:
|
||||
struct AsyncStruct
|
||||
{
|
||||
public:
|
||||
AsyncStruct(const std::string& fn, Object *t, SEL_CallFuncO s) : filename(fn), target(t), selector(s) {}
|
||||
|
||||
std::string filename;
|
||||
Object *target;
|
||||
SEL_CallFuncO selector;
|
||||
};
|
||||
|
||||
protected:
|
||||
typedef struct _ImageInfo
|
||||
{
|
||||
AsyncStruct *asyncStruct;
|
||||
Image *image;
|
||||
Image::EImageFormat imageType;
|
||||
} ImageInfo;
|
||||
|
||||
std::queue<AsyncStruct*>* _asyncStructQueue;
|
||||
std::queue<ImageInfo*>* _imageInfoQueue;
|
||||
|
||||
std::mutex _asyncStructQueueMutex;
|
||||
std::mutex _imageInfoMutex;
|
||||
|
||||
std::mutex _sleepMutex;
|
||||
std::condition_variable _sleepCondition;
|
||||
|
||||
bool _needQuit;
|
||||
|
||||
int _asyncRefCount;
|
||||
|
||||
Dictionary* _textures;
|
||||
|
||||
static TextureCache *_sharedTextureCache;
|
||||
};
|
||||
|
||||
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
APP_STL := gnustl_static
|
||||
APP_CPPFLAGS := -frtti -DCOCOS2D_JAVASCRIPT=1 -std=c++11
|
||||
APP_CPPFLAGS += -DCOCOS2D_DEBUG=1 -DCC_ENABLE_CHIPMUNK_INTEGRATION=1
|
||||
APP_CPPFLAGS += -DCOCOS2D_DEBUG=1 -DCC_ENABLE_CHIPMUNK_INTEGRATION=1
|
||||
NDK_TOOLCHAIN_VERSION=4.7
|
|
@ -1,2 +1,3 @@
|
|||
APP_STL := gnustl_static
|
||||
APP_CPPFLAGS := -frtti -DCOCOS2D_DEBUG=1 -std=c++11
|
||||
APP_CPPFLAGS := -frtti -DCOCOS2D_DEBUG=1 -std=c++11
|
||||
NDK_TOOLCHAIN_VERSION=4.7
|
|
@ -1,2 +1,3 @@
|
|||
APP_STL := gnustl_static
|
||||
APP_CPPFLAGS := -frtti -DCOCOS2D_DEBUG=1 -std=c++11
|
||||
APP_CPPFLAGS := -frtti -DCOCOS2D_DEBUG=1 -std=c++11
|
||||
NDK_TOOLCHAIN_VERSION=4.7
|
|
@ -1,2 +1,3 @@
|
|||
APP_STL := gnustl_static
|
||||
APP_CPPFLAGS := -frtti -DCC_ENABLE_CHIPMUNK_INTEGRATION=1 -DCOCOS2D_DEBUG=1 -std=c++11
|
||||
NDK_TOOLCHAIN_VERSION=4.7
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
APP_STL := gnustl_static
|
||||
APP_CPPFLAGS := -frtti -DCOCOS2D_JAVASCRIPT=1 -std=c++11
|
||||
APP_CPPFLAGS += -DCOCOS2D_DEBUG=1 -DCC_ENABLE_CHIPMUNK_INTEGRATION=1
|
||||
APP_CPPFLAGS += -DCOCOS2D_DEBUG=1 -DCC_ENABLE_CHIPMUNK_INTEGRATION=
|
||||
NDK_TOOLCHAIN_VERSION=4.7
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
APP_STL := gnustl_static
|
||||
APP_CPPFLAGS := -frtti -DCOCOS2D_JAVASCRIPT=1 -std=c++11
|
||||
APP_CPPFLAGS += -DCOCOS2D_DEBUG=1 -DCC_ENABLE_CHIPMUNK_INTEGRATION=1
|
||||
NDK_TOOLCHAIN_VERSION=4.7
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
APP_STL := gnustl_static
|
||||
APP_CPPFLAGS := -frtti -DCOCOS2D_JAVASCRIPT= -std=c++11
|
||||
APP_CPPFLAGS += -DCOCOS2D_DEBUG=1 -DCC_ENABLE_CHIPMUNK_INTEGRATION=1
|
||||
NDK_TOOLCHAIN_VERSION=4.7
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
APP_STL := gnustl_static
|
||||
APP_CPPFLAGS := -frtti -DCOCOS2D_JAVASCRIPT=1 -std=c++11
|
||||
APP_CPPFLAGS += -DCOCOS2D_DEBUG=1 -DCC_ENABLE_CHIPMUNK_INTEGRATION=1
|
||||
NDK_TOOLCHAIN_VERSION=4.7
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
APP_STL := gnustl_static
|
||||
APP_CPPFLAGS := -frtti -DCOCOS2D_JAVASCRIPT=1 -std=c++11
|
||||
APP_CPPFLAGS += -DCOCOS2D_DEBUG=1 -DCC_ENABLE_CHIPMUNK_INTEGRATION=1
|
||||
NDK_TOOLCHAIN_VERSION=4.7
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
APP_STL := gnustl_static
|
||||
APP_CPPFLAGS := -frtti -DCOCOS2D_DEBUG=1 -std=c++11
|
||||
APP_CPPFLAGS += -fexceptions
|
||||
NDK_TOOLCHAIN_VERSION=4.7
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
APP_STL := gnustl_static
|
||||
APP_CPPFLAGS := -frtti -DCOCOS2D_DEBUG=1 -std=c++11
|
||||
APP_CPPFLAGS += -fexceptions
|
||||
NDK_TOOLCHAIN_VERSION=4.7
|
||||
|
|
|
@ -53,15 +53,15 @@
|
|||
|
||||
#define BYTE_CODE_FILE_EXT ".jsc"
|
||||
|
||||
pthread_t debugThread;
|
||||
string inData;
|
||||
string outData;
|
||||
vector<string> queue;
|
||||
pthread_mutex_t g_qMutex;
|
||||
pthread_mutex_t g_rwMutex;
|
||||
bool vmLock = false;
|
||||
jsval frame = JSVAL_NULL, script = JSVAL_NULL;
|
||||
int clientSocket;
|
||||
static pthread_t debugThread;
|
||||
static string inData;
|
||||
static string outData;
|
||||
static vector<string> g_queue;
|
||||
static pthread_mutex_t g_qMutex;
|
||||
static pthread_mutex_t g_rwMutex;
|
||||
static bool vmLock = false;
|
||||
static jsval frame = JSVAL_NULL, script = JSVAL_NULL;
|
||||
static int clientSocket = -1;
|
||||
|
||||
// server entry point for the bg thread
|
||||
void* serverEntryPoint(void*);
|
||||
|
@ -69,16 +69,16 @@ void* serverEntryPoint(void*);
|
|||
js_proxy_t *_native_js_global_ht = NULL;
|
||||
js_proxy_t *_js_native_global_ht = NULL;
|
||||
js_type_class_t *_js_global_type_ht = NULL;
|
||||
char *_js_log_buf = NULL;
|
||||
static char *_js_log_buf = NULL;
|
||||
|
||||
std::vector<sc_register_sth> registrationList;
|
||||
static std::vector<sc_register_sth> registrationList;
|
||||
|
||||
// name ~> JSScript map
|
||||
std::map<std::string, JSScript*> filename_script;
|
||||
static std::map<std::string, JSScript*> filename_script;
|
||||
// port ~> socket map
|
||||
std::map<int,int> ports_sockets;
|
||||
static std::map<int,int> ports_sockets;
|
||||
// name ~> globals
|
||||
std::map<std::string, js::RootedObject*> globals;
|
||||
static std::map<std::string, js::RootedObject*> globals;
|
||||
|
||||
static void executeJSFunctionFromReservedSpot(JSContext *cx, JSObject *obj,
|
||||
jsval &dataVal, jsval &retval) {
|
||||
|
@ -1714,11 +1714,11 @@ jsval ccaffinetransform_to_jsval(JSContext* cx, AffineTransform& t)
|
|||
|
||||
void SimpleRunLoop::update(float dt) {
|
||||
pthread_mutex_lock(&g_qMutex);
|
||||
while (queue.size() > 0) {
|
||||
vector<string>::iterator first = queue.begin();
|
||||
while (g_queue.size() > 0) {
|
||||
vector<string>::iterator first = g_queue.begin();
|
||||
string str = *first;
|
||||
ScriptingCore::getInstance()->debugProcessInput(str);
|
||||
queue.erase(first);
|
||||
g_queue.erase(first);
|
||||
}
|
||||
pthread_mutex_unlock(&g_qMutex);
|
||||
}
|
||||
|
@ -1933,11 +1933,11 @@ JSBool JSBDebug_LockExecution(JSContext* cx, unsigned argc, jsval* vp)
|
|||
while (vmLock) {
|
||||
// try to read the input, if there's anything
|
||||
pthread_mutex_lock(&g_qMutex);
|
||||
while (queue.size() > 0) {
|
||||
vector<string>::iterator first = queue.begin();
|
||||
while (g_queue.size() > 0) {
|
||||
vector<string>::iterator first = g_queue.begin();
|
||||
string str = *first;
|
||||
ScriptingCore::getInstance()->debugProcessInput(str);
|
||||
queue.erase(first);
|
||||
g_queue.erase(first);
|
||||
}
|
||||
pthread_mutex_unlock(&g_qMutex);
|
||||
sched_yield();
|
||||
|
@ -1959,7 +1959,7 @@ JSBool JSBDebug_UnlockExecution(JSContext* cx, unsigned argc, jsval* vp)
|
|||
|
||||
void processInput(string data) {
|
||||
pthread_mutex_lock(&g_qMutex);
|
||||
queue.push_back(string(data));
|
||||
g_queue.push_back(string(data));
|
||||
pthread_mutex_unlock(&g_qMutex);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
APP_STL := gnustl_static
|
||||
APP_CPPFLAGS := -frtti -DCC_ENABLE_CHIPMUNK_INTEGRATION=1 -DCOCOS2D_DEBUG=1
|
||||
NDK_TOOLCHAIN_VERSION=4.7
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
APP_STL := gnustl_static
|
||||
APP_CPPFLAGS := -frtti -DCOCOS2D_JAVASCRIPT=1
|
||||
APP_CPPFLAGS += -DCOCOS2D_DEBUG=1 -DCC_ENABLE_CHIPMUNK_INTEGRATION=1
|
||||
NDK_TOOLCHAIN_VERSION=4.7
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
APP_STL := gnustl_static
|
||||
APP_CPPFLAGS := -frtti -DCOCOS2D_DEBUG=1 -DCC_ENABLE_CHIPMUNK_INTEGRATION=1
|
||||
APP_CPPFLAGS += -fexceptions
|
||||
NDK_TOOLCHAIN_VERSION=4.7
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 716d9156b845173f14e38fae10a76c54a11b64ef
|
||||
Subproject commit 6a45a0770c4e6075f20d5049c88e3cb5f8aa83eb
|
|
@ -7,10 +7,10 @@ prefix = cocos2dx
|
|||
# all classes will be embedded in that namespace
|
||||
target_namespace = cc
|
||||
|
||||
android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.6/include
|
||||
android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/include
|
||||
android_flags = -D_SIZE_T_DEFINED_
|
||||
|
||||
clang_headers = -I%(clangllvmdir)s/lib/clang/3.1/include
|
||||
clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include
|
||||
clang_flags = -nostdinc -x c++ -std=c++11
|
||||
|
||||
cocos_headers = -I%(cocosdir)s/cocos2dx/include -I%(cocosdir)s/cocos2dx/platform -I%(cocosdir)s/cocos2dx/platform/android -I%(cocosdir)s/cocos2dx -I%(cocosdir)s/cocos2dx/kazmath/include
|
||||
|
|
|
@ -7,10 +7,10 @@ prefix = cocos2dx_extension
|
|||
# all classes will be embedded in that namespace
|
||||
target_namespace = cc
|
||||
|
||||
android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.6/include
|
||||
android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/include
|
||||
android_flags = -D_SIZE_T_DEFINED_
|
||||
|
||||
clang_headers = -I%(clangllvmdir)s/lib/clang/3.1/include
|
||||
clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include
|
||||
clang_flags = -nostdinc -x c++ -std=c++11
|
||||
|
||||
cocos_headers = -I%(cocosdir)s/cocos2dx/include -I%(cocosdir)s/cocos2dx/platform -I%(cocosdir)s/cocos2dx/platform/android -I%(cocosdir)s/cocos2dx -I%(cocosdir)s/cocos2dx/kazmath/include -I%(cocosdir)s/extensions
|
||||
|
|
|
@ -20,8 +20,8 @@ if [ -z "${NDK_ROOT+aaa}" ]; then
|
|||
fi
|
||||
|
||||
if [ -z "${CLANG_ROOT+aaa}" ]; then
|
||||
# ... if CLANG_ROOT is not set, use "$HOME/bin/clang+llvm-3.1"
|
||||
CLANG_ROOT="$HOME/bin/clang+llvm-3.1"
|
||||
# ... if CLANG_ROOT is not set, use "$HOME/bin/clang+llvm-3.3"
|
||||
CLANG_ROOT="$HOME/bin/clang+llvm-3.3"
|
||||
fi
|
||||
|
||||
if [ -z "${PYTHON_BIN+aaa}" ]; then
|
||||
|
|
|
@ -6,6 +6,10 @@ set -e
|
|||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
COCOS2DX_ROOT="$DIR"/../..
|
||||
HOST_NAME=""
|
||||
LLVM_VERSION=""
|
||||
LLVM_PACKAGE=""
|
||||
LLVM_PACKAGE_SUFFIX=""
|
||||
|
||||
mkdir -p $HOME/bin
|
||||
pushd $HOME/bin
|
||||
|
||||
|
@ -28,18 +32,27 @@ install_android_ndk()
|
|||
|
||||
install_llvm()
|
||||
{
|
||||
LLVM_VERSION="3.3"
|
||||
if [ "$PLATFORM"x = "ios"x ]; then
|
||||
HOST_NAME="apple-darwin11"
|
||||
LLVM_PACKAGE="clang+llvm-3.3-x86_64-apple-darwin12"
|
||||
LLVM_PACKAGE_SUFFIX=".tar.gz"
|
||||
else
|
||||
HOST_NAME="linux-ubuntu_12.04"
|
||||
LLVM_PACKAGE="clang+llvm-3.3-Ubuntu-13.04-x86_64-linux-gnu"
|
||||
LLVM_PACKAGE_SUFFIX=".tar.bz2"
|
||||
fi
|
||||
# Download llvm3.1
|
||||
echo "Download clang+llvm-3.1-x86_64-${HOST_NAME}.tar.gz"
|
||||
curl -O http://llvm.org/releases/3.1/clang+llvm-3.1-x86_64-${HOST_NAME}.tar.gz
|
||||
echo "Decompress clang+llvm-3.1-x86_64-${HOST_NAME}.tar.gz ..."
|
||||
tar xzf clang+llvm-3.1-x86_64-${HOST_NAME}.tar.gz
|
||||
|
||||
# Download llvm
|
||||
echo "Download ${LLVM_PACKAGE} ..."
|
||||
curl -O http://llvm.org/releases/${LLVM_VERSION}/${LLVM_PACKAGE}${LLVM_PACKAGE_SUFFIX}
|
||||
echo "Decompress ${LLVM_PACKAGE} ..."
|
||||
if [ "$PLATFORM"x = "ios"x ]; then
|
||||
tar xzf ${LLVM_PACKAGE}${LLVM_PACKAGE_SUFFIX}
|
||||
else
|
||||
tar xjf ${LLVM_PACKAGE}${LLVM_PACKAGE_SUFFIX}
|
||||
fi
|
||||
|
||||
# Rename llvm
|
||||
mv clang+llvm-3.1-x86_64-${HOST_NAME} clang+llvm-3.1
|
||||
mv ${LLVM_PACKAGE} clang+llvm-${LLVM_VERSION}
|
||||
}
|
||||
|
||||
install_llvm_3_2()
|
||||
|
|
Loading…
Reference in New Issue