diff --git a/HelloLua/ios/HelloLua.xcodeproj/project.pbxproj.REMOVED.git-id b/HelloLua/ios/HelloLua.xcodeproj/project.pbxproj.REMOVED.git-id index c7361fa5bd..f17425294c 100644 --- a/HelloLua/ios/HelloLua.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/HelloLua/ios/HelloLua.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -8575c43b860eea3c0f02d9543e58b74073e40e6d \ No newline at end of file +f75a8c50e01404209e0c065b8d040d973cfc0fc0 \ No newline at end of file diff --git a/HelloWorld/ios/HelloWorld.xcodeproj/project.pbxproj.REMOVED.git-id b/HelloWorld/ios/HelloWorld.xcodeproj/project.pbxproj.REMOVED.git-id index 3bdf4b79f1..b0c3988f55 100644 --- a/HelloWorld/ios/HelloWorld.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/HelloWorld/ios/HelloWorld.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -c1cdd4b0d66de5127dc37f73eb9895737ca3e18d \ No newline at end of file +f9ca064a5aba796aacdc647bb44c2f8a0658707c \ No newline at end of file diff --git a/cocos2dx/include/CCTextureCache.h b/cocos2dx/include/CCTextureCache.h index 10800099e4..b377a1bac7 100755 --- a/cocos2dx/include/CCTextureCache.h +++ b/cocos2dx/include/CCTextureCache.h @@ -31,6 +31,7 @@ THE SOFTWARE. #include "CCObject.h" #include "CCMutableDictionary.h" #include "CCTexture2D.h" +#include "selector_protocol.h" #if CC_ENABLE_CACHE_TEXTTURE_DATA #include "CCImage.h" @@ -38,25 +39,23 @@ THE SOFTWARE. #endif namespace cocos2d { -class CCAsyncObject; class CCLock; class CCImage; -typedef void (*fpAsyncCallback)(CCTexture2D*, void*); - /** @brief Singleton that handles the loading of textures * Once the texture is loaded, the next time it will return * a reference of the previously loaded texture reducing GPU & CPU memory */ -class CC_DLL CCTextureCache : public CCObject +class CC_DLL CCTextureCache : public SelectorProtocol, public CCObject { protected: CCMutableDictionary * m_pTextures; - CCLock *m_pDictLock; - CCLock *m_pContextLock; + //pthread_mutex_t *m_pDictLock; + private: // @todo void addImageWithAsyncObject(CCAsyncObject* async); + void addImageAsyncCallBack(ccTime dt); public: @@ -89,7 +88,7 @@ public: * @since v0.8 */ - // @todo void addImageAsync(const char* filename, CCObject*target, fpAsyncCallback func); + void addImageAsync(const char *path, SelectorProtocol *target, SEL_CallFuncO selector); /* Returns a Texture2D object given an CGImageRef image * If the image was not previously loaded, it will create a new CCTexture2D object and it will return it. diff --git a/cocos2dx/particle_nodes/CCParticleSystem.cpp b/cocos2dx/particle_nodes/CCParticleSystem.cpp index df7fbeb223..bccbc0bf7b 100644 --- a/cocos2dx/particle_nodes/CCParticleSystem.cpp +++ b/cocos2dx/particle_nodes/CCParticleSystem.cpp @@ -141,11 +141,15 @@ CCParticleSystem * CCParticleSystem::particleWithFile(const char *plistFile) } bool CCParticleSystem::initWithFile(const char *plistFile) { + bool bRet = false; m_sPlistFile = CCFileUtils::fullPathFromRelativePath(plistFile); - CCDictionary *dict = CCFileUtils::dictionaryWithContentsOfFile(m_sPlistFile.c_str()); + CCDictionary *dict = CCFileUtils::dictionaryWithContentsOfFileThreadSafe(m_sPlistFile.c_str()); CCAssert( dict != NULL, "Particles: file not found"); - return this->initWithDictionary(dict); + bRet = this->initWithDictionary(dict); + dict->release(); + + return bRet; } bool CCParticleSystem::initWithDictionary(CCDictionary *dictionary) diff --git a/cocos2dx/platform/CCFileUtils.cpp b/cocos2dx/platform/CCFileUtils.cpp index d121215ea6..c17ec0ee16 100644 --- a/cocos2dx/platform/CCFileUtils.cpp +++ b/cocos2dx/platform/CCFileUtils.cpp @@ -98,7 +98,9 @@ public: m_pCurDict = new CCDictionary(); if(! m_pRootDict) { + // Because it will call m_pCurDict->release() later, so retain here. m_pRootDict = m_pCurDict; + m_pRootDict->retain(); } m_tState = SAX_DICT; @@ -120,7 +122,8 @@ public: CCDictionary* pPreDict = m_tDictStack.top(); pPreDict->setObject(m_pCurDict, m_sCurKey); } - m_pCurDict->autorelease(); + + m_pCurDict->release(); // record the dict state m_tStateStack.push(m_tState); @@ -285,7 +288,15 @@ std::string& CCFileUtils::ccRemoveHDSuffixFromFile(std::string& path) CCDictionary *CCFileUtils::dictionaryWithContentsOfFile(const char *pFileName) { - CCDictMaker tMaker; + CCDictionary *ret = dictionaryWithContentsOfFileThreadSafe(pFileName); + ret->autorelease(); + + return ret; +} + +CCDictionary *CCFileUtils::dictionaryWithContentsOfFileThreadSafe(const char *pFileName) +{ + CCDictMaker tMaker; return tMaker.dictionaryWithContentsOfFile(pFileName); } diff --git a/cocos2dx/platform/CCFileUtils.h b/cocos2dx/platform/CCFileUtils.h index 84334b7e25..093dd54eba 100644 --- a/cocos2dx/platform/CCFileUtils.h +++ b/cocos2dx/platform/CCFileUtils.h @@ -89,6 +89,12 @@ public: */ static CCDictionary *dictionaryWithContentsOfFile(const char *pFileName); + /* + @brief The same meaning as dictionaryWithContentsOfFile(), but it doesn't call autorelease, so the + invoker should call release(). + */ + static CCDictionary *dictionaryWithContentsOfFileThreadSafe(const char *pFileName); + /** @brief Get the writeable path @return The path that can write/read file diff --git a/cocos2dx/platform/CCThread.cpp b/cocos2dx/platform/CCThread.cpp index 90bb2322b0..b447a8794a 100644 --- a/cocos2dx/platform/CCThread.cpp +++ b/cocos2dx/platform/CCThread.cpp @@ -24,18 +24,16 @@ THE SOFTWARE. #include "CCThread.h" -#if CC_SUPPORT_MULTITHREAD +NS_CC_BEGIN; -#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) -#include "win32/CCThread_win32.cpp" -#endif // CC_PLATFORM_WIN32 +CCThread::~CCThread() +{ -#if (CC_TARGET_PLATFORM == CC_PLATFORM_WOPHONE) -#include "wophone/CCThread_wophone.cpp" -#endif // CC_PLATFORM_WOPHONE +} -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) -#include "android/CCThread_android.cpp" -#endif // CC_PLATFORM_ANDROID +void CCThread::createAutoreleasePool() +{ -#endif // CC_SUPPORT_MULTITHREAD +} + +NS_CC_END; \ No newline at end of file diff --git a/cocos2dx/platform/CCThread.h b/cocos2dx/platform/CCThread.h index 681d3fc614..0616e84f45 100644 --- a/cocos2dx/platform/CCThread.h +++ b/cocos2dx/platform/CCThread.h @@ -26,41 +26,24 @@ THE SOFTWARE. #define __CC_PLATFORM_THREAD_H__ #include "CCCommon.h" +#include "CCPlatformMacros.h" NS_CC_BEGIN; -#if CC_SUPPORT_MULTITHREAD -/** -@brief The object for mutual-exclusion synchronization. - -@warning Don't enter a CCLock twice in the same thread. -*/ -class CC_DLL CCLock +/* On iOS, should create autorelease pool when create a new thread + * and release it when the thread end. + */ +class CC_DLL CCThread { public: - CCLock(); - ~CCLock(); + CCThread() : m_pAutoreasePool(0) {} + ~CCThread(); - void lock(); - void unlock(); + void createAutoreleasePool(); private: - class Impl; - CCLock::Impl * m_pImp; + void *m_pAutoreasePool; }; -#else // CC_SUPPORT_MULTITHREAD - -class CC_DLL CCLock -{ -public: - CCLock() {} - ~CCLock() {} - - void lock() {} - void unlock() {} -}; - -#endif // CC_SUPPORT_MULTITHREAD NS_CC_END; diff --git a/cocos2dx/platform/ios/CCFileUtils_ios.mm b/cocos2dx/platform/ios/CCFileUtils_ios.mm index 4065de0a65..1404f14156 100644 --- a/cocos2dx/platform/ios/CCFileUtils_ios.mm +++ b/cocos2dx/platform/ios/CCFileUtils_ios.mm @@ -291,7 +291,16 @@ namespace cocos2d { pRet->m_sString += pszFilename; return pRet->m_sString.c_str(); } + CCDictionary *CCFileUtils::dictionaryWithContentsOfFile(const char *pFileName) + { + CCDictionary *ret = dictionaryWithContentsOfFileThreadSafe(pFileName); + ret->autorelease(); + + return ret; + } + + CCDictionary *CCFileUtils::dictionaryWithContentsOfFileThreadSafe(const char *pFileName) { NSString* pPath = [NSString stringWithUTF8String:pFileName]; NSDictionary* pDict = [NSDictionary dictionaryWithContentsOfFile:pPath]; @@ -301,9 +310,10 @@ namespace cocos2d { id value = [pDict objectForKey:key]; static_addValueToCCDict(key, value, pRet); } - pRet->autorelease(); + return pRet; } + unsigned char* CCFileUtils::getFileData(const char* pszFileName, const char* pszMode, unsigned long * pSize) { unsigned char * pBuffer = NULL; diff --git a/cocos2dx/platform/third_party/win32/pthread/pthread.h b/cocos2dx/platform/third_party/win32/pthread/pthread.h new file mode 100644 index 0000000000..f3d2dac966 --- /dev/null +++ b/cocos2dx/platform/third_party/win32/pthread/pthread.h @@ -0,0 +1,1368 @@ +/* This is an implementation of the threads API of POSIX 1003.1-2001. + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#if !defined( PTHREAD_H ) +#define PTHREAD_H + +/* + * See the README file for an explanation of the pthreads-win32 version + * numbering scheme and how the DLL is named etc. + */ +#define PTW32_VERSION 2,8,0,0 +#define PTW32_VERSION_STRING "2, 8, 0, 0\0" + +/* There are three implementations of cancel cleanup. + * Note that pthread.h is included in both application + * compilation units and also internally for the library. + * The code here and within the library aims to work + * for all reasonable combinations of environments. + * + * The three implementations are: + * + * WIN32 SEH + * C + * C++ + * + * Please note that exiting a push/pop block via + * "return", "exit", "break", or "continue" will + * lead to different behaviour amongst applications + * depending upon whether the library was built + * using SEH, C++, or C. For example, a library built + * with SEH will call the cleanup routine, while both + * C++ and C built versions will not. + */ + +/* + * Define defaults for cleanup code. + * Note: Unless the build explicitly defines one of the following, then + * we default to standard C style cleanup. This style uses setjmp/longjmp + * in the cancelation and thread exit implementations and therefore won't + * do stack unwinding if linked to applications that have it (e.g. + * C++ apps). This is currently consistent with most/all commercial Unix + * POSIX threads implementations. + */ +#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C ) +# define __CLEANUP_C +#endif + +#if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC)) +#error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler. +#endif + +/* + * Stop here if we are being included by the resource compiler. + */ +#ifndef RC_INVOKED + +#undef PTW32_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_LEVEL +#define PTW32_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_LEVEL +#define PTW32_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_LEVEL_MAX 3 + +#if !defined(PTW32_LEVEL) +#define PTW32_LEVEL PTW32_LEVEL_MAX +/* Include everything */ +#endif + +#ifdef _UWIN +# define HAVE_STRUCT_TIMESPEC 1 +# define HAVE_SIGNAL_H 1 +# undef HAVE_CONFIG_H +# pragma comment(lib, "pthread") +#endif + +/* + * ------------------------------------------------------------- + * + * + * Module: pthread.h + * + * Purpose: + * Provides an implementation of PThreads based upon the + * standard: + * + * POSIX 1003.1-2001 + * and + * The Single Unix Specification version 3 + * + * (these two are equivalent) + * + * in order to enhance code portability between Windows, + * various commercial Unix implementations, and Linux. + * + * See the ANNOUNCE file for a full list of conforming + * routines and defined constants, and a list of missing + * routines and constants not defined in this implementation. + * + * Authors: + * There have been many contributors to this library. + * The initial implementation was contributed by + * John Bossom, and several others have provided major + * sections or revisions of parts of the implementation. + * Often significant effort has been contributed to + * find and fix important bugs and other problems to + * improve the reliability of the library, which sometimes + * is not reflected in the amount of code which changed as + * result. + * As much as possible, the contributors are acknowledged + * in the ChangeLog file in the source code distribution + * where their changes are noted in detail. + * + * Contributors are listed in the CONTRIBUTORS file. + * + * As usual, all bouquets go to the contributors, and all + * brickbats go to the project maintainer. + * + * Maintainer: + * The code base for this project is coordinated and + * eventually pre-tested, packaged, and made available by + * + * Ross Johnson + * + * QA Testers: + * Ultimately, the library is tested in the real world by + * a host of competent and demanding scientists and + * engineers who report bugs and/or provide solutions + * which are then fixed or incorporated into subsequent + * versions of the library. Each time a bug is fixed, a + * test case is written to prove the fix and ensure + * that later changes to the code don't reintroduce the + * same error. The number of test cases is slowly growing + * and therefore so is the code reliability. + * + * Compliance: + * See the file ANNOUNCE for the list of implemented + * and not-implemented routines and defined options. + * Of course, these are all defined is this file as well. + * + * Web site: + * The source code and other information about this library + * are available from + * + * http://sources.redhat.com/pthreads-win32/ + * + * ------------------------------------------------------------- + */ + +/* Try to avoid including windows.h */ +#if defined(__MINGW32__) && defined(__cplusplus) +#define PTW32_INCLUDE_WINDOWS_H +#endif + +#ifdef PTW32_INCLUDE_WINDOWS_H +#include +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__) +/* + * VC++6.0 or early compiler's header has no DWORD_PTR type. + */ +typedef unsigned long DWORD_PTR; +#endif +/* + * ----------------- + * autoconf switches + * ----------------- + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#ifndef NEED_FTIME +#include +#else /* NEED_FTIME */ +/* use native WIN32 time API */ +#endif /* NEED_FTIME */ + +#if HAVE_SIGNAL_H +#include +#endif /* HAVE_SIGNAL_H */ + +#include +#include + +/* + * Boolean values to make us independent of system includes. + */ +enum { + PTW32_FALSE = 0, + PTW32_TRUE = (! PTW32_FALSE) +}; + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#ifndef PTW32_CONFIG_H +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +#ifdef NEED_ERRNO +#include "need_errno.h" +#else +#include +#endif +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Several systems don't define some error numbers. + */ +#ifndef ENOTSUP +# define ENOTSUP 48 /* This is the value in Solaris. */ +#endif + +#ifndef ETIMEDOUT +# define ETIMEDOUT 10060 /* This is the value in winsock.h. */ +#endif + +#ifndef ENOSYS +# define ENOSYS 140 /* Semi-arbitrary value */ +#endif + +#ifndef EDEADLK +# ifdef EDEADLOCK +# define EDEADLK EDEADLOCK +# else +# define EDEADLK 36 /* This is the value in MSVC. */ +# endif +#endif + +#include + +/* + * To avoid including windows.h we define only those things that we + * actually need from it. + */ +#ifndef PTW32_INCLUDE_WINDOWS_H +#ifndef HANDLE +# define PTW32__HANDLE_DEF +# define HANDLE void * +#endif +#ifndef DWORD +# define PTW32__DWORD_DEF +# define DWORD unsigned long +#endif +#endif + +#ifndef HAVE_STRUCT_TIMESPEC +#define HAVE_STRUCT_TIMESPEC 1 +struct timespec { + long tv_sec; + long tv_nsec; +}; +#endif /* HAVE_STRUCT_TIMESPEC */ + +#ifndef SIG_BLOCK +#define SIG_BLOCK 0 +#endif /* SIG_BLOCK */ + +#ifndef SIG_UNBLOCK +#define SIG_UNBLOCK 1 +#endif /* SIG_UNBLOCK */ + +#ifndef SIG_SETMASK +#define SIG_SETMASK 2 +#endif /* SIG_SETMASK */ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* + * ------------------------------------------------------------- + * + * POSIX 1003.1-2001 Options + * ========================= + * + * Options are normally set in , which is not provided + * with pthreads-win32. + * + * For conformance with the Single Unix Specification (version 3), all of the + * options below are defined, and have a value of either -1 (not supported) + * or 200112L (supported). + * + * These options can neither be left undefined nor have a value of 0, because + * either indicates that sysconf(), which is not implemented, may be used at + * runtime to check the status of the option. + * + * _POSIX_THREADS (== 200112L) + * If == 200112L, you can use threads + * + * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L) + * If == 200112L, you can control the size of a thread's + * stack + * pthread_attr_getstacksize + * pthread_attr_setstacksize + * + * _POSIX_THREAD_ATTR_STACKADDR (== -1) + * If == 200112L, you can allocate and control a thread's + * stack. If not supported, the following functions + * will return ENOSYS, indicating they are not + * supported: + * pthread_attr_getstackaddr + * pthread_attr_setstackaddr + * + * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1) + * If == 200112L, you can use realtime scheduling. + * This option indicates that the behaviour of some + * implemented functions conforms to the additional TPS + * requirements in the standard. E.g. rwlocks favour + * writers over readers when threads have equal priority. + * + * _POSIX_THREAD_PRIO_INHERIT (== -1) + * If == 200112L, you can create priority inheritance + * mutexes. + * pthread_mutexattr_getprotocol + + * pthread_mutexattr_setprotocol + + * + * _POSIX_THREAD_PRIO_PROTECT (== -1) + * If == 200112L, you can create priority ceiling mutexes + * Indicates the availability of: + * pthread_mutex_getprioceiling + * pthread_mutex_setprioceiling + * pthread_mutexattr_getprioceiling + * pthread_mutexattr_getprotocol + + * pthread_mutexattr_setprioceiling + * pthread_mutexattr_setprotocol + + * + * _POSIX_THREAD_PROCESS_SHARED (== -1) + * If set, you can create mutexes and condition + * variables that can be shared with another + * process.If set, indicates the availability + * of: + * pthread_mutexattr_getpshared + * pthread_mutexattr_setpshared + * pthread_condattr_getpshared + * pthread_condattr_setpshared + * + * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L) + * If == 200112L you can use the special *_r library + * functions that provide thread-safe behaviour + * + * _POSIX_READER_WRITER_LOCKS (== 200112L) + * If == 200112L, you can use read/write locks + * + * _POSIX_SPIN_LOCKS (== 200112L) + * If == 200112L, you can use spin locks + * + * _POSIX_BARRIERS (== 200112L) + * If == 200112L, you can use barriers + * + * + These functions provide both 'inherit' and/or + * 'protect' protocol, based upon these macro + * settings. + * + * ------------------------------------------------------------- + */ + +/* + * POSIX Options + */ +#undef _POSIX_THREADS +#define _POSIX_THREADS 200112L + +#undef _POSIX_READER_WRITER_LOCKS +#define _POSIX_READER_WRITER_LOCKS 200112L + +#undef _POSIX_SPIN_LOCKS +#define _POSIX_SPIN_LOCKS 200112L + +#undef _POSIX_BARRIERS +#define _POSIX_BARRIERS 200112L + +#undef _POSIX_THREAD_SAFE_FUNCTIONS +#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L + +#undef _POSIX_THREAD_ATTR_STACKSIZE +#define _POSIX_THREAD_ATTR_STACKSIZE 200112L + +/* + * The following options are not supported + */ +#undef _POSIX_THREAD_ATTR_STACKADDR +#define _POSIX_THREAD_ATTR_STACKADDR -1 + +#undef _POSIX_THREAD_PRIO_INHERIT +#define _POSIX_THREAD_PRIO_INHERIT -1 + +#undef _POSIX_THREAD_PRIO_PROTECT +#define _POSIX_THREAD_PRIO_PROTECT -1 + +/* TPS is not fully supported. */ +#undef _POSIX_THREAD_PRIORITY_SCHEDULING +#define _POSIX_THREAD_PRIORITY_SCHEDULING -1 + +#undef _POSIX_THREAD_PROCESS_SHARED +#define _POSIX_THREAD_PROCESS_SHARED -1 + + +/* + * POSIX 1003.1-2001 Limits + * =========================== + * + * These limits are normally set in , which is not provided with + * pthreads-win32. + * + * PTHREAD_DESTRUCTOR_ITERATIONS + * Maximum number of attempts to destroy + * a thread's thread-specific data on + * termination (must be at least 4) + * + * PTHREAD_KEYS_MAX + * Maximum number of thread-specific data keys + * available per process (must be at least 128) + * + * PTHREAD_STACK_MIN + * Minimum supported stack size for a thread + * + * PTHREAD_THREADS_MAX + * Maximum number of threads supported per + * process (must be at least 64). + * + * SEM_NSEMS_MAX + * The maximum number of semaphores a process can have. + * (must be at least 256) + * + * SEM_VALUE_MAX + * The maximum value a semaphore can have. + * (must be at least 32767) + * + */ +#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 + +#undef PTHREAD_DESTRUCTOR_ITERATIONS +#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS + +#undef _POSIX_THREAD_KEYS_MAX +#define _POSIX_THREAD_KEYS_MAX 128 + +#undef PTHREAD_KEYS_MAX +#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX + +#undef PTHREAD_STACK_MIN +#define PTHREAD_STACK_MIN 0 + +#undef _POSIX_THREAD_THREADS_MAX +#define _POSIX_THREAD_THREADS_MAX 64 + + /* Arbitrary value */ +#undef PTHREAD_THREADS_MAX +#define PTHREAD_THREADS_MAX 2019 + +#undef _POSIX_SEM_NSEMS_MAX +#define _POSIX_SEM_NSEMS_MAX 256 + + /* Arbitrary value */ +#undef SEM_NSEMS_MAX +#define SEM_NSEMS_MAX 1024 + +#undef _POSIX_SEM_VALUE_MAX +#define _POSIX_SEM_VALUE_MAX 32767 + +#undef SEM_VALUE_MAX +#define SEM_VALUE_MAX INT_MAX + + +#if __GNUC__ && ! defined (__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the DLL code, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the DLL, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#ifndef PTW32_STATIC_LIB +# ifdef PTW32_BUILD +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#else +# define PTW32_DLLPORT +#endif + +/* + * The Open Watcom C/C++ compiler uses a non-standard calling convention + * that passes function args in registers unless __cdecl is explicitly specified + * in exposed function prototypes. + * + * We force all calls to cdecl even though this could slow Watcom code down + * slightly. If you know that the Watcom compiler will be used to build both + * the DLL and application, then you can probably define this as a null string. + * Remember that pthread.h (this file) is used for both the DLL and application builds. + */ +#define PTW32_CDECL __cdecl + +#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX +# include +#else +/* + * Generic handle type - intended to extend uniqueness beyond + * that available with a simple pointer. It should scale for either + * IA-32 or IA-64. + */ +typedef struct { + void * p; /* Pointer to actual object */ + unsigned int x; /* Extra information - reuse count etc */ +} ptw32_handle_t; + +typedef ptw32_handle_t pthread_t; +typedef struct pthread_attr_t_ * pthread_attr_t; +typedef struct pthread_once_t_ pthread_once_t; +typedef struct pthread_key_t_ * pthread_key_t; +typedef struct pthread_mutex_t_ * pthread_mutex_t; +typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t; +typedef struct pthread_cond_t_ * pthread_cond_t; +typedef struct pthread_condattr_t_ * pthread_condattr_t; +#endif +typedef struct pthread_rwlock_t_ * pthread_rwlock_t; +typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t; +typedef struct pthread_spinlock_t_ * pthread_spinlock_t; +typedef struct pthread_barrier_t_ * pthread_barrier_t; +typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t; + +/* + * ==================== + * ==================== + * POSIX Threads + * ==================== + * ==================== + */ + +enum { +/* + * pthread_attr_{get,set}detachstate + */ + PTHREAD_CREATE_JOINABLE = 0, /* Default */ + PTHREAD_CREATE_DETACHED = 1, + +/* + * pthread_attr_{get,set}inheritsched + */ + PTHREAD_INHERIT_SCHED = 0, + PTHREAD_EXPLICIT_SCHED = 1, /* Default */ + +/* + * pthread_{get,set}scope + */ + PTHREAD_SCOPE_PROCESS = 0, + PTHREAD_SCOPE_SYSTEM = 1, /* Default */ + +/* + * pthread_setcancelstate paramters + */ + PTHREAD_CANCEL_ENABLE = 0, /* Default */ + PTHREAD_CANCEL_DISABLE = 1, + +/* + * pthread_setcanceltype parameters + */ + PTHREAD_CANCEL_ASYNCHRONOUS = 0, + PTHREAD_CANCEL_DEFERRED = 1, /* Default */ + +/* + * pthread_mutexattr_{get,set}pshared + * pthread_condattr_{get,set}pshared + */ + PTHREAD_PROCESS_PRIVATE = 0, + PTHREAD_PROCESS_SHARED = 1, + +/* + * pthread_barrier_wait + */ + PTHREAD_BARRIER_SERIAL_THREAD = -1 +}; + +/* + * ==================== + * ==================== + * Cancelation + * ==================== + * ==================== + */ +#define PTHREAD_CANCELED ((void *) -1) + + +/* + * ==================== + * ==================== + * Once Key + * ==================== + * ==================== + */ +#define PTHREAD_ONCE_INIT { PTW32_FALSE, 0, 0, 0} + +struct pthread_once_t_ +{ + int done; /* indicates if user function has been executed */ + void * lock; + int reserved1; + int reserved2; +}; + + +/* + * ==================== + * ==================== + * Object initialisers + * ==================== + * ==================== + */ +#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1) +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t) -2) +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t) -3) + +/* + * Compatibility with LinuxThreads + */ +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER + +#define PTHREAD_COND_INITIALIZER ((pthread_cond_t) -1) + +#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) -1) + +#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t) -1) + + +/* + * Mutex types. + */ +enum +{ + /* Compatibility with LinuxThreads */ + PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP, + /* For compatibility with POSIX */ + PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL +}; + + +typedef struct ptw32_cleanup_t ptw32_cleanup_t; + +#if defined(_MSC_VER) +/* Disable MSVC 'anachronism used' warning */ +#pragma warning( disable : 4229 ) +#endif + +typedef void (* PTW32_CDECL ptw32_cleanup_callback_t)(void *); + +#if defined(_MSC_VER) +#pragma warning( default : 4229 ) +#endif + +struct ptw32_cleanup_t +{ + ptw32_cleanup_callback_t routine; + void *arg; + struct ptw32_cleanup_t *prev; +}; + +#ifdef __CLEANUP_SEH + /* + * WIN32 SEH version of cancel cleanup. + */ + +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + ptw32_cleanup_t _cleanup; \ + \ + _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \ + _cleanup.arg = (_arg); \ + __try \ + { \ + +#define pthread_cleanup_pop( _execute ) \ + } \ + __finally \ + { \ + if( _execute || AbnormalTermination()) \ + { \ + (*(_cleanup.routine))( _cleanup.arg ); \ + } \ + } \ + } + +#else /* __CLEANUP_SEH */ + +#ifdef __CLEANUP_C + + /* + * C implementation of PThreads cancel cleanup + */ + +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + ptw32_cleanup_t _cleanup; \ + \ + ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \ + +#define pthread_cleanup_pop( _execute ) \ + (void) ptw32_pop_cleanup( _execute ); \ + } + +#else /* __CLEANUP_C */ + +#ifdef __CLEANUP_CXX + + /* + * C++ version of cancel cleanup. + * - John E. Bossom. + */ + + class PThreadCleanup { + /* + * PThreadCleanup + * + * Purpose + * This class is a C++ helper class that is + * used to implement pthread_cleanup_push/ + * pthread_cleanup_pop. + * The destructor of this class automatically + * pops the pushed cleanup routine regardless + * of how the code exits the scope + * (i.e. such as by an exception) + */ + ptw32_cleanup_callback_t cleanUpRout; + void * obj; + int executeIt; + + public: + PThreadCleanup() : + cleanUpRout( 0 ), + obj( 0 ), + executeIt( 0 ) + /* + * No cleanup performed + */ + { + } + + PThreadCleanup( + ptw32_cleanup_callback_t routine, + void * arg ) : + cleanUpRout( routine ), + obj( arg ), + executeIt( 1 ) + /* + * Registers a cleanup routine for 'arg' + */ + { + } + + ~PThreadCleanup() + { + if ( executeIt && ((void *) cleanUpRout != (void *) 0) ) + { + (void) (*cleanUpRout)( obj ); + } + } + + void execute( int exec ) + { + executeIt = exec; + } + }; + + /* + * C++ implementation of PThreads cancel cleanup; + * This implementation takes advantage of a helper + * class who's destructor automatically calls the + * cleanup routine if we exit our scope weirdly + */ +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \ + (void *) (_arg) ); + +#define pthread_cleanup_pop( _execute ) \ + cleanup.execute( _execute ); \ + } + +#else + +#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. + +#endif /* __CLEANUP_CXX */ + +#endif /* __CLEANUP_C */ + +#endif /* __CLEANUP_SEH */ + +/* + * =============== + * =============== + * Methods + * =============== + * =============== + */ + +/* + * PThread Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_attr_init (pthread_attr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy (pthread_attr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate (const pthread_attr_t * attr, + int *detachstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr (const pthread_attr_t * attr, + void **stackaddr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize (const pthread_attr_t * attr, + size_t * stacksize); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate (pthread_attr_t * attr, + int detachstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr (pthread_attr_t * attr, + void *stackaddr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize (pthread_attr_t * attr, + size_t stacksize); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam (const pthread_attr_t *attr, + struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam (pthread_attr_t *attr, + const struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy (pthread_attr_t *, + int); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy (pthread_attr_t *, + int *); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr, + int inheritsched); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(pthread_attr_t * attr, + int * inheritsched); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *, + int); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *, + int *); + +/* + * PThread Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid, + const pthread_attr_t * attr, + void *(*start) (void *), + void *arg); + +PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid); + +PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1, + pthread_t t2); + +PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr); + +PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread, + void **value_ptr); + +PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void); + +PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread); + +PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state, + int *oldstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type, + int *oldtype); + +PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void); + +PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control, + void (*init_routine) (void)); + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute); + +PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup, + void (*routine) (void *), + void *arg); +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Thread Specific Data Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key, + void (*destructor) (void *)); + +PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key); + +PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key, + const void *value); + +PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key); + + +/* + * Mutex Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t + * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, + int pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind); +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (pthread_mutexattr_t * attr, int *kind); + +/* + * Barrier Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t + * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, + int pshared); + +/* + * Mutex Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex, + const pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t *mutex, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex); + +/* + * Spinlock Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock); + +/* + * Barrier Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier, + const pthread_barrierattr_t * attr, + unsigned int count); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier); + +/* + * Condition Variable Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr, + int pshared); + +/* + * Condition Variable Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond, + const pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond, + pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond, + pthread_mutex_t * mutex, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond); + +/* + * Scheduling + */ +PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread, + int policy, + const struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread, + int *policy, + struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int); + +PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void); + +/* + * Read-Write Lock Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock, + const pthread_rwlockattr_t *attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, + int pshared); + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 + +/* + * Signal Functions. Should be defined in but MSVC and MinGW32 + * already have signal.h that don't define these. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig); + +/* + * Non-portable functions + */ + +/* + * Compatibility with Linux. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, + int kind); +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, + int *kind); + +/* + * Possibly supported by other POSIX threads implementations + */ +PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval); +PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void); + +/* + * Useful if an application wants to statically link + * the lib rather than load the DLL at run-time. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void); + +/* + * Features that are auto-detected at load/run time. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int); +enum ptw32_features { + PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */ + PTW32_ALERTABLE_ASYNC_CANCEL = 0x0002 /* Can cancel blocked threads. */ +}; + +/* + * Register a system time change with the library. + * Causes the library to perform various functions + * in response to the change. Should be called whenever + * the application's top level window receives a + * WM_TIMECHANGE message. It can be passed directly to + * pthread_create() as a new thread if desired. + */ +PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *); + +#endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX + +/* + * Returns the Win32 HANDLE for the POSIX thread. + */ +PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread); + + +/* + * Protected Methods + * + * This function blocks until the given WIN32 handle + * is signaled or pthread_cancel had been called. + * This function allows the caller to hook into the + * PThreads cancel mechanism. It is implemented using + * + * WaitForMultipleObjects + * + * on 'waitHandle' and a manually reset WIN32 Event + * used to implement pthread_cancel. The 'timeout' + * argument to TimedWait is simply passed to + * WaitForMultipleObjects. + */ +PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle); +PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle, + DWORD timeout); + +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Thread-Safe C Runtime Library Mappings. + */ +#ifndef _UWIN +# if defined(NEED_ERRNO) + PTW32_DLLPORT int * PTW32_CDECL _errno( void ); +# else +# ifndef errno +# if (defined(_MT) || defined(_DLL)) + __declspec(dllimport) extern int * __cdecl _errno(void); +# define errno (*_errno()) +# endif +# endif +# endif +#endif + +/* + * WIN32 C runtime library had been made thread-safe + * without affecting the user interface. Provide + * mappings from the UNIX thread-safe versions to + * the standard C runtime library calls. + * Only provide function mappings for functions that + * actually exist on WIN32. + */ + +#if !defined(__MINGW32__) +#define strtok_r( _s, _sep, _lasts ) \ + ( *(_lasts) = strtok( (_s), (_sep) ) ) +#endif /* !__MINGW32__ */ + +#define asctime_r( _tm, _buf ) \ + ( strcpy( (_buf), asctime( (_tm) ) ), \ + (_buf) ) + +#define ctime_r( _clock, _buf ) \ + ( strcpy( (_buf), ctime( (_clock) ) ), \ + (_buf) ) + +#define gmtime_r( _clock, _result ) \ + ( *(_result) = *gmtime( (_clock) ), \ + (_result) ) + +#define localtime_r( _clock, _result ) \ + ( *(_result) = *localtime( (_clock) ), \ + (_result) ) + +#define rand_r( _seed ) \ + ( _seed == _seed? rand() : rand() ) + + +/* + * Some compiler environments don't define some things. + */ +#if defined(__BORLANDC__) +# define _ftime ftime +# define _timeb timeb +#endif + +#ifdef __cplusplus + +/* + * Internal exceptions + */ +class ptw32_exception {}; +class ptw32_exception_cancel : public ptw32_exception {}; +class ptw32_exception_exit : public ptw32_exception {}; + +#endif + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX + +/* FIXME: This is only required if the library was built using SEH */ +/* + * Get internal SEH tag + */ +PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void); + +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +#ifndef PTW32_BUILD + +#ifdef __CLEANUP_SEH + +/* + * Redefine the SEH __except keyword to ensure that applications + * propagate our internal exceptions up to the library's internal handlers. + */ +#define __except( E ) \ + __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \ + ? EXCEPTION_CONTINUE_SEARCH : ( E ) ) + +#endif /* __CLEANUP_SEH */ + +#ifdef __CLEANUP_CXX + +/* + * Redefine the C++ catch keyword to ensure that applications + * propagate our internal exceptions up to the library's internal handlers. + */ +#ifdef _MSC_VER + /* + * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll' + * if you want Pthread-Win32 cancelation and pthread_exit to work. + */ + +#ifndef PtW32NoCatchWarn + +#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.") +#pragma message("------------------------------------------------------------------") +#pragma message("When compiling applications with MSVC++ and C++ exception handling:") +#pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads") +#pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread") +#pragma message(" cancelation and pthread_exit to work. For example:") +#pragma message("") +#pragma message(" #ifdef PtW32CatchAll") +#pragma message(" PtW32CatchAll") +#pragma message(" #else") +#pragma message(" catch(...)") +#pragma message(" #endif") +#pragma message(" {") +#pragma message(" /* Catchall block processing */") +#pragma message(" }") +#pragma message("------------------------------------------------------------------") + +#endif + +#define PtW32CatchAll \ + catch( ptw32_exception & ) { throw; } \ + catch( ... ) + +#else /* _MSC_VER */ + +#define catch( E ) \ + catch( ptw32_exception & ) { throw; } \ + catch( E ) + +#endif /* _MSC_VER */ + +#endif /* __CLEANUP_CXX */ + +#endif /* ! PTW32_BUILD */ + +#ifdef __cplusplus +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#ifdef PTW32__HANDLE_DEF +# undef HANDLE +#endif +#ifdef PTW32__DWORD_DEF +# undef DWORD +#endif + +#undef PTW32_LEVEL +#undef PTW32_LEVEL_MAX + +#endif /* ! RC_INVOKED */ + +#endif /* PTHREAD_H */ diff --git a/cocos2dx/platform/third_party/win32/pthread/sched.h b/cocos2dx/platform/third_party/win32/pthread/sched.h new file mode 100644 index 0000000000..dfb8e934af --- /dev/null +++ b/cocos2dx/platform/third_party/win32/pthread/sched.h @@ -0,0 +1,178 @@ +/* + * Module: sched.h + * + * Purpose: + * Provides an implementation of POSIX realtime extensions + * as defined in + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#ifndef _SCHED_H +#define _SCHED_H + +#undef PTW32_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_LEVEL +#define PTW32_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_LEVEL +#define PTW32_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_LEVEL_MAX 3 + +#if !defined(PTW32_LEVEL) +#define PTW32_LEVEL PTW32_LEVEL_MAX +/* Include everything */ +#endif + + +#if __GNUC__ && ! defined (__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the DLL code, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the DLL, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#ifndef PTW32_STATIC_LIB +# ifdef PTW32_BUILD +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#else +# define PTW32_DLLPORT +#endif + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#ifndef PTW32_CONFIG_H +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +#ifdef NEED_ERRNO +#include "need_errno.h" +#else +#include +#endif +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +#if defined(__MINGW32__) || defined(_UWIN) +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +/* For pid_t */ +# include +/* Required by Unix 98 */ +# include +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ +#else +typedef int pid_t; +#endif + +/* Thread scheduling policies */ + +enum { + SCHED_OTHER = 0, + SCHED_FIFO, + SCHED_RR, + SCHED_MIN = SCHED_OTHER, + SCHED_MAX = SCHED_RR +}; + +struct sched_param { + int sched_priority; +}; + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +PTW32_DLLPORT int __cdecl sched_yield (void); + +PTW32_DLLPORT int __cdecl sched_get_priority_min (int policy); + +PTW32_DLLPORT int __cdecl sched_get_priority_max (int policy); + +PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy); + +PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid); + +/* + * Note that this macro returns ENOTSUP rather than + * ENOSYS as might be expected. However, returning ENOSYS + * should mean that sched_get_priority_{min,max} are + * not implemented as well as sched_rr_get_interval. + * This is not the case, since we just don't support + * round-robin scheduling. Therefore I have chosen to + * return the same value as sched_setscheduler when + * SCHED_RR is passed to it. + */ +#define sched_rr_get_interval(_pid, _interval) \ + ( errno = ENOTSUP, (int) -1 ) + + +#ifdef __cplusplus +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#undef PTW32_LEVEL +#undef PTW32_LEVEL_MAX + +#endif /* !_SCHED_H */ + diff --git a/cocos2dx/platform/third_party/win32/pthread/semaphore.h b/cocos2dx/platform/third_party/win32/pthread/semaphore.h new file mode 100644 index 0000000000..a3330a6388 --- /dev/null +++ b/cocos2dx/platform/third_party/win32/pthread/semaphore.h @@ -0,0 +1,166 @@ +/* + * Module: semaphore.h + * + * Purpose: + * Semaphores aren't actually part of the PThreads standard. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined( SEMAPHORE_H ) +#define SEMAPHORE_H + +#undef PTW32_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_LEVEL +#define PTW32_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_LEVEL +#define PTW32_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_LEVEL_MAX 3 + +#if !defined(PTW32_LEVEL) +#define PTW32_LEVEL PTW32_LEVEL_MAX +/* Include everything */ +#endif + +#if __GNUC__ && ! defined (__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the DLL code, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the DLL, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#ifndef PTW32_STATIC_LIB +# ifdef PTW32_BUILD +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#else +# define PTW32_DLLPORT +#endif + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#ifndef PTW32_CONFIG_H +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +#ifdef NEED_ERRNO +#include "need_errno.h" +#else +#include +#endif +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +#define _POSIX_SEMAPHORES + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifndef HAVE_MODE_T +typedef unsigned int mode_t; +#endif + + +typedef struct sem_t_ * sem_t; + +PTW32_DLLPORT int __cdecl sem_init (sem_t * sem, + int pshared, + unsigned int value); + +PTW32_DLLPORT int __cdecl sem_destroy (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_trywait (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_wait (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_timedwait (sem_t * sem, + const struct timespec * abstime); + +PTW32_DLLPORT int __cdecl sem_post (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_post_multiple (sem_t * sem, + int count); + +PTW32_DLLPORT int __cdecl sem_open (const char * name, + int oflag, + mode_t mode, + unsigned int value); + +PTW32_DLLPORT int __cdecl sem_close (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_unlink (const char * name); + +PTW32_DLLPORT int __cdecl sem_getvalue (sem_t * sem, + int * sval); + +#ifdef __cplusplus +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#undef PTW32_LEVEL +#undef PTW32_LEVEL_MAX + +#endif /* !SEMAPHORE_H */ diff --git a/cocos2dx/platform/third_party/win32/third_party_versions.txt b/cocos2dx/platform/third_party/win32/third_party_versions.txt index 126396b119..e41ee7b434 100644 --- a/cocos2dx/platform/third_party/win32/third_party_versions.txt +++ b/cocos2dx/platform/third_party/win32/third_party_versions.txt @@ -4,3 +4,4 @@ libpng 1.4.5beta04 libxml2 2.7.7 OGLES 2.08.28.0634 zlib 1.2.5 +pthread 2.8.0 diff --git a/cocos2dx/platform/win32/CCThread_win32.cpp b/cocos2dx/platform/win32/CCThread_win32.cpp index 27a1c4df65..d3f5a12faa 100644 --- a/cocos2dx/platform/win32/CCThread_win32.cpp +++ b/cocos2dx/platform/win32/CCThread_win32.cpp @@ -1,70 +1 @@ -/**************************************************************************** -Copyright (c) 2010 cocos2d-x.org -http://www.cocos2d-x.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -****************************************************************************/ - -#if CCX_SUPPORT_MULTITHREAD - -#include "ccxThread.h" - -#include - -NS_CC_BEGIN; - -class CCXLock::Impl -{ -public: - Impl() { InitializeCriticalSection(&m_cs); } - ~Impl() { DeleteCriticalSection(&m_cs); } - - CRITICAL_SECTION m_cs; -}; - -CCXLock::CCXLock() -: m_pImp(new CCXLock::Impl) -{ -} - -CCXLock::~CCXLock() -{ - CC_SAFE_DELETE(m_pImp); -} - -void CCXLock::lock() -{ - if (m_pImp) - { - EnterCriticalSection(&m_pImp->m_cs); - } -} - -void CCXLock::unlock() -{ - if (m_pImp) - { - LeaveCriticalSection(&m_pImp->m_cs); - } -} - -NS_CC_END; - -#endif // CCX_SUPPORT_MULTITHREAD diff --git a/cocos2dx/proj.win32/cocos2d-win32.vcproj b/cocos2dx/proj.win32/cocos2d-win32.vcproj index 14bfb6ad5c..be096b2e3e 100644 --- a/cocos2dx/proj.win32/cocos2d-win32.vcproj +++ b/cocos2dx/proj.win32/cocos2d-win32.vcproj @@ -42,7 +42,7 @@ Disabled - ..\platform;..\platform\third_party\win32\iconv;..\platform\third_party\win32\zlib;..\platform\third_party\win32\libpng;..\platform\third_party\win32\libjpeg;..\platform\third_party\win32\libxml2;..\platform\third_party\win32\OGLES;..\include;..;%(AdditionalIncludeDirectories) + ..\platform;..\platform\third_party\win32\iconv;..\platform\third_party\win32\zlib;..\platform\third_party\win32\libpng;..\platform\third_party\win32\libjpeg;..\platform\third_party\win32\pthread;..\platform\third_party\win32\libxml2;..\platform\third_party\win32\pthread;..\platform\third_party\win32\OGLES;..\include;..;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_WINDOWS;_USRDLL;COCOS2DXWIN32_EXPORTS;GL_GLEXT_PROTOTYPES;%(PreprocessorDefinitions) true EnableFastChecks @@ -74,7 +74,7 @@ xcopy /Y /Q "$(SolutionDir)cocos2dx\platform\third_party\win32\libraries\*.*" "$ - libEGL.lib;libgles_cm.lib;libxml2.lib;libzlib.lib;libpng.lib;libjpeg.lib;libiconv.lib;%(AdditionalDependencies) + libEGL.lib;libgles_cm.lib;libxml2.lib;libzlib.lib;libpng.lib;libjpeg.lib;libiconv.lib;pthreadVCE2.lib;pthreadVCE2.lib;%(AdditionalDependencies) $(OutDir)$(ProjectName).dll $(OutDir);%(AdditionalLibraryDirectories) false @@ -95,7 +95,7 @@ xcopy /Y /Q "$(SolutionDir)cocos2dx\platform\third_party\win32\libraries\*.*" "$ - ..\platform;..\platform\third_party\win32\iconv;..\platform\third_party\win32\zlib;..\platform\third_party\win32\libpng;..\platform\third_party\win32\libjpeg;..\platform\third_party\win32\libxml2;..\platform\third_party\win32\OGLES;..\include;..;%(AdditionalIncludeDirectories) + ..\platform;..\platform\third_party\win32\iconv;..\platform\third_party\win32\zlib;..\platform\third_party\win32\libpng;..\platform\third_party\win32\libjpeg;..\platform\third_party\win32\pthread;..\platform\third_party\win32\libxml2;..\platform\third_party\win32\OGLES;..\include;..;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_WINDOWS;_USRDLL;COCOS2DXWIN32_EXPORTS;GL_GLEXT_PROTOTYPES;%(PreprocessorDefinitions) MultiThreadedDLL @@ -110,7 +110,7 @@ xcopy /Y /Q "$(SolutionDir)cocos2dx\platform\third_party\win32\libraries\*.*" "$ - libEGL.lib;libgles_cm.lib;libxml2.lib;libzlib.lib;libpng.lib;libjpeg.lib;libiconv.lib;%(AdditionalDependencies) + libEGL.lib;libgles_cm.lib;libxml2.lib;libzlib.lib;libpng.lib;libjpeg.lib;libiconv.lib;pthreadVCE2.lib;%(AdditionalDependencies) $(OutDir)$(ProjectName).dll $(OutDir);%(AdditionalLibraryDirectories) ;%(IgnoreSpecificDefaultLibraries) diff --git a/cocos2dx/sprite_nodes/CCSpriteFrameCache.cpp b/cocos2dx/sprite_nodes/CCSpriteFrameCache.cpp index 877497b060..b7eae23b38 100644 --- a/cocos2dx/sprite_nodes/CCSpriteFrameCache.cpp +++ b/cocos2dx/sprite_nodes/CCSpriteFrameCache.cpp @@ -197,9 +197,11 @@ void CCSpriteFrameCache::addSpriteFramesWithDictionary(CCDictionary *dict = CCFileUtils::dictionaryWithContentsOfFile(pszPath); + CCDictionary *dict = CCFileUtils::dictionaryWithContentsOfFileThreadSafe(pszPath); addSpriteFramesWithDictionary(dict, pobTexture); + + dict->release(); } void CCSpriteFrameCache::addSpriteFramesWithFile(const char* plist, const char* textureFileName) @@ -220,7 +222,7 @@ void CCSpriteFrameCache::addSpriteFramesWithFile(const char* plist, const char* void CCSpriteFrameCache::addSpriteFramesWithFile(const char *pszPlist) { const char *pszPath = CCFileUtils::fullPathFromRelativePath(pszPlist); - CCDictionary *dict = CCFileUtils::dictionaryWithContentsOfFile(pszPath); + CCDictionary *dict = CCFileUtils::dictionaryWithContentsOfFileThreadSafe(pszPath); string texturePath(""); @@ -261,6 +263,8 @@ void CCSpriteFrameCache::addSpriteFramesWithFile(const char *pszPlist) { CCLOG("cocos2d: CCSpriteFrameCache: Couldn't load texture"); } + + dict->release(); } void CCSpriteFrameCache::addSpriteFrame(CCSpriteFrame *pobFrame, const char *pszFrameName) @@ -316,9 +320,11 @@ void CCSpriteFrameCache::removeSpriteFrameByName(const char *pszName) void CCSpriteFrameCache::removeSpriteFramesFromFile(const char* plist) { const char* path = CCFileUtils::fullPathFromRelativePath(plist); - CCDictionary* dict = CCFileUtils::dictionaryWithContentsOfFile(path); + CCDictionary* dict = CCFileUtils::dictionaryWithContentsOfFileThreadSafe(path); removeSpriteFramesFromDictionary((CCDictionary*)dict); + + dict->release(); } void CCSpriteFrameCache::removeSpriteFramesFromDictionary(CCDictionary *dictionary) diff --git a/cocos2dx/textures/CCTextureCache.cpp b/cocos2dx/textures/CCTextureCache.cpp index fe0624699a..057d34bc0b 100644 --- a/cocos2dx/textures/CCTextureCache.cpp +++ b/cocos2dx/textures/CCTextureCache.cpp @@ -23,6 +23,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ****************************************************************************/ +#define COCOS2D_DEBUG 1 #include #include @@ -36,24 +37,70 @@ THE SOFTWARE. #include "CCFileUtils.h" #include "CCImage.h" #include "support/ccUtils.h" +#include "CCScheduler.h" +#include "pthread.h" +#include "CCThread.h" namespace cocos2d { -class CCAsyncObject : CCObject +typedef struct _AsyncStruct { -public: - fpAsyncCallback m_pfnCallback; - CCObject* m_pTarget; - std::string * m_pData; -public: - CCAsyncObject(); - ~CCAsyncObject() + std::string filename; + SelectorProtocol *target; + SEL_CallFuncO selector; +} AsyncStruct; + +static cocos2d::CCImage* s_pImageAsync; +// only allow one loading thread at a time +static pthread_mutex_t s_loadingThreadMutex; +// condition +static pthread_cond_t s_condition; +static pthread_mutex_t s_conditionMutex; +static AsyncStruct *s_pAsyncObject; + +static void* loadImage(void* data) +{ + // create autorelease pool for iOS + CCThread thread; + thread.createAutoreleasePool(); + + if (! ((AsyncStruct*)data)->filename.c_str()) { - CCLOGINFO("cocos2d: deallocing CCAsyncObject."); - CC_SAFE_DELETE(m_pTarget); - CC_SAFE_DELETE(m_pData); + return 0; } -}; + + // one loading thread at a time + pthread_mutex_lock(&s_loadingThreadMutex); + + s_pAsyncObject = (AsyncStruct*)data; + const char *filename = s_pAsyncObject->filename.c_str(); + + CCLOG("thread 0x%x is loading image %s", pthread_self(), filename); + + CCImage *tmpImage = new CCImage(); + tmpImage->initWithImageFile(filename); + s_pImageAsync = tmpImage; + + /* Wait for rendering thread to comsume the image. + * The implemntation of pthread_cond_wait() of win32 has a bug, it can not + * wait the condition at first time. + */ +#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) + static bool firstRun = true; + if (firstRun) + { + pthread_cond_wait(&s_condition, &s_conditionMutex); + firstRun = false; + } +#endif + pthread_cond_wait(&s_condition, &s_conditionMutex); + + CCLOG("thread 0x%x has pass the condition, new loading thread is avalable", pthread_self()); + + pthread_mutex_unlock(&s_loadingThreadMutex); + + return 0; +} // implementation CCTextureCache @@ -73,8 +120,6 @@ CCTextureCache::CCTextureCache() CCAssert(g_sharedTextureCache == NULL, "Attempted to allocate a second instance of a singleton."); m_pTextures = new CCMutableDictionary(); - m_pDictLock = new CCLock(); - m_pContextLock = new CCLock(); } CCTextureCache::~CCTextureCache() @@ -82,8 +127,6 @@ CCTextureCache::~CCTextureCache() CCLOGINFO("cocos2d: deallocing CCTextureCache."); CC_SAFE_RELEASE(m_pTextures); - CC_SAFE_DELETE(m_pDictLock); - CC_SAFE_DELETE(m_pContextLock); } void CCTextureCache::purgeSharedTextureCache() @@ -99,77 +142,80 @@ char * CCTextureCache::description() return ret; } - -// TextureCache - Add Images -/* @todo EAGLContext -void CCTextureCache::addImageWithAsyncObject(CCAsyncObject* async) +void CCTextureCache::addImageAsync(const char *path, SelectorProtocol *target, SEL_CallFuncO selector) { - - CCAutoreleasePool *autoreleasepool = [[CCAutoreleasePool alloc] init]; + CCAssert(path != NULL, "TextureCache: fileimage MUST not be NULL"); - // textures will be created on the main OpenGL context - // it seems that in SDK 2.2.x there can't be 2 threads creating textures at the same time - // the lock is used for this purpose: issue #472 - [contextLock lock]; - if( auxEAGLcontext == nil ) { - auxEAGLcontext = [[EAGLContext alloc] -initWithAPI:kEAGLRenderingAPIOpenGLES1 -sharegroup:[[[[CCDirector sharedDirector] openGLView] context] sharegroup]]; - - if( ! auxEAGLcontext ) - CCLOG(@"cocos2d: TextureCache: Could not create EAGL context"); - } - - if( [EAGLContext setCurrentContext:auxEAGLcontext] ) { - - // load / create the texture - CCTexture2D *tex = [self addImage:async.data]; - - // The callback will be executed on the main thread - [async.target performSelectorOnMainThread:async.selector withObject:tex waitUntilDone:NO]; - - [EAGLContext setCurrentContext:nil]; - } else { - CCLOG(@"cocos2d: TetureCache: EAGLContext error"); - } - [contextLock unlock]; - - [autoreleasepool release]; -}*/ - -/* @todo selector, NSThread -void CCTextureCache::addImageAsync(const char* filename, CCObject *target, fpAsyncCallback func) -{ - CCAssert(filename != NULL , "TextureCache: fileimage MUST not be nill"); + CCTexture2D *texture = NULL; // optimization - CCTexture2D * tex; - - if ( (tex = m_pTextures->objectForKey(filename)) ) + std::string pathKey = path; + CCFileUtils::ccRemoveHDSuffixFromFile(pathKey); - { + pathKey = CCFileUtils::fullPathFromRelativePath(pathKey.c_str()); + texture = m_pTextures->objectForKey(pathKey); - target-> + std::string fullpath = pathKey; + if (texture = m_pTextures->objectForKey(pathKey)) + { + (target->*selector)(texture); + return; + } - } + // lazy init + static bool firstRun = true; + if (firstRun) + { + pthread_mutex_init(&s_loadingThreadMutex, NULL); + pthread_mutex_init(&s_conditionMutex, NULL); + pthread_cond_init(&s_condition, NULL); + s_pImageAsync = NULL; - - if( (tex=[textures objectForKey: filename] ) ) { - [target performSelector:selector withObject:tex]; - return; - } - - // schedule the load - - CCAsyncObject *asyncObject = [[CCAsyncObject alloc] init]; - asyncObject.selector = selector; - asyncObject.target = target; - asyncObject.data = filename; - - [NSThread detachNewThreadSelector:@selector(addImageWithAsyncObject:) toTarget:self withObject:asyncObject]; - [asyncObject release]; -}*/ + CCScheduler::sharedScheduler()->scheduleSelector(schedule_selector(CCTextureCache::addImageAsyncCallBack), this, 1.0f, false); + + firstRun = false; + } + + AsyncStruct *data = new AsyncStruct(); + data->filename = fullpath.c_str(); + data->target = target; + data->selector = selector; + + // load image in a new thread + pthread_t p; + pthread_create(&p, NULL, loadImage, (void*)data); +} + +void CCTextureCache::addImageAsyncCallBack(ccTime dt) +{ + // the image is generated in loading thread + if (s_pImageAsync != NULL) + { + + SelectorProtocol *target = s_pAsyncObject->target; + SEL_CallFuncO selector = s_pAsyncObject->selector; + const char* filename = s_pAsyncObject->filename.c_str(); + + // generate texture in render thread + CCTexture2D *texture = new CCTexture2D(); + texture->initWithImage(s_pImageAsync); + + // cache the texture + m_pTextures->setObject(texture, filename); + texture->autorelease(); + + (target->*selector)(texture); + + // the object is newed in addImageAsync() and will be assigned in the loading thread + delete s_pAsyncObject; + + delete s_pImageAsync; + s_pImageAsync = NULL; + + pthread_cond_signal(&s_condition); + } +} CCTexture2D * CCTextureCache::addImage(const char * path) { @@ -180,7 +226,7 @@ CCTexture2D * CCTextureCache::addImage(const char * path) // MUTEX: // Needed since addImageAsync calls this method from a different thread - m_pDictLock->lock(); + //pthread_mutex_lock(m_pDictLock); // remove possible -HD suffix to prevent caching the same image twice (issue #1040) std::string pathKey = path; @@ -263,7 +309,8 @@ CCTexture2D * CCTextureCache::addImage(const char * path) } while (0); } - m_pDictLock->unlock(); + + //pthread_mutex_unlock(m_pDictLock); return texture; } @@ -335,30 +382,7 @@ CCTexture2D * CCTextureCache::addPVRImage(const char* path) return tex; } -/* @todo CGImageRef --(CCTexture2D*) addCGImage: (CGImageRef) imageref forKey: (string & )key -{ - CCAssert(imageref != nil, @"TextureCache: image MUST not be nill"); - CCTexture2D * tex = nil; - - // If key is nil, then create a new texture each time - if( key && (tex=[textures objectForKey: key] ) ) { - return tex; - } - - // prevents overloading the autorelease pool - UIImage *image = [[UIImage alloc] initWithCGImage:imageref]; - tex = [[CCTexture2D alloc] initWithImage: image]; - [image release]; - - if(tex && key) - [textures setObject: tex forKey:key]; - else - CCLOG(@"cocos2d: Couldn't add CGImage in CCTextureCache"); - - return [tex autorelease]; -}*/ CCTexture2D* CCTextureCache::addUIImage(CCImage *image, const char *key) { CCAssert(image != NULL && key != NULL, "TextureCache: image MUST not be nill"); @@ -367,7 +391,7 @@ CCTexture2D* CCTextureCache::addUIImage(CCImage *image, const char *key) // textureForKey() use full path,so the key should be full path std::string forKey = CCFileUtils::fullPathFromRelativePath(key); - m_pDictLock->lock(); + //m_pDictLock->lock(); do { @@ -393,7 +417,7 @@ CCTexture2D* CCTextureCache::addUIImage(CCImage *image, const char *key) } while (0); - m_pDictLock->unlock(); + //m_pDictLock->unlock(); return texture; } diff --git a/template/xcode3/cocos2d-x_app/___PROJECTNAME___.xcodeproj/project.pbxproj.REMOVED.git-id b/template/xcode3/cocos2d-x_app/___PROJECTNAME___.xcodeproj/project.pbxproj.REMOVED.git-id index f8ba15728e..6755749f14 100644 --- a/template/xcode3/cocos2d-x_app/___PROJECTNAME___.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/template/xcode3/cocos2d-x_app/___PROJECTNAME___.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -3aab8d3693dcaba52bbe6cf1d88bd085701c71bb \ No newline at end of file +84d1a5cd21bd26c8e2f08241d504b59fe40defc9 \ No newline at end of file diff --git a/template/xcode3/cocos2d-x_box2d_app/___PROJECTNAME___.xcodeproj/project.pbxproj.REMOVED.git-id b/template/xcode3/cocos2d-x_box2d_app/___PROJECTNAME___.xcodeproj/project.pbxproj.REMOVED.git-id index ea5eb78411..2497b6fd13 100644 --- a/template/xcode3/cocos2d-x_box2d_app/___PROJECTNAME___.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/template/xcode3/cocos2d-x_box2d_app/___PROJECTNAME___.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -2905515c8c42c8a1603230ed28549aa28e4ae3f1 \ No newline at end of file +36888561783556c80b0635d13bbdcc7e285fa0f3 \ No newline at end of file diff --git a/template/xcode3/cocos2d-x_chipmunk_app/___PROJECTNAME___.xcodeproj/project.pbxproj.REMOVED.git-id b/template/xcode3/cocos2d-x_chipmunk_app/___PROJECTNAME___.xcodeproj/project.pbxproj.REMOVED.git-id index 9db7519b9e..6772dc8a1f 100644 --- a/template/xcode3/cocos2d-x_chipmunk_app/___PROJECTNAME___.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/template/xcode3/cocos2d-x_chipmunk_app/___PROJECTNAME___.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -b59f29f9bd284c46876e7ecc47b74bfaf8a00aa6 \ No newline at end of file +866c5fd880bbb121951818d47d13a4ee914279ad \ No newline at end of file diff --git a/template/xcode3/cocos2d-x_lua_app/___PROJECTNAME___.xcodeproj/project.pbxproj.REMOVED.git-id b/template/xcode3/cocos2d-x_lua_app/___PROJECTNAME___.xcodeproj/project.pbxproj.REMOVED.git-id index e7491dd5d6..9b2da8e892 100644 --- a/template/xcode3/cocos2d-x_lua_app/___PROJECTNAME___.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/template/xcode3/cocos2d-x_lua_app/___PROJECTNAME___.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -60da72586f63e425b1e85a7a0cee1d798e59c843 \ No newline at end of file +6b542917dfd2180ff6c55bca6cd7b30c64c4a300 \ No newline at end of file diff --git a/tests/test.android/build_native.sh b/tests/test.android/build_native.sh index 555230edd8..aa5b1f8580 100644 --- a/tests/test.android/build_native.sh +++ b/tests/test.android/build_native.sh @@ -1,7 +1,7 @@ #!/bin/bash # set params -ANDROID_NDK_ROOT=/home/laschweinski/android/android-ndk-r5/ -COCOS2DX_ROOT=/home/laschweinski/git/cocos2d-x +ANDROID_NDK_ROOT=/cygdrive/d/programe/android/ndk/android-ndk-r5 +COCOS2DX_ROOT=/cygdrive/e/cocos2d-x TESTS_ROOT=$COCOS2DX_ROOT/tests/test.android # make sure assets is exist diff --git a/tests/test.android/jni/tests/Android.mk b/tests/test.android/jni/tests/Android.mk index 9467aa74e7..a6d356ff83 100644 --- a/tests/test.android/jni/tests/Android.mk +++ b/tests/test.android/jni/tests/Android.mk @@ -76,6 +76,7 @@ LOCAL_SRC_FILES := main.cpp \ ../../../tests/SceneTest/SceneTest.cpp \ ../../../tests/SchedulerTest/SchedulerTest.cpp \ ../../../tests/SpriteTest/SpriteTest.cpp \ +../../../tests/TextureCacheTest/TextureCacheTest.cpp \ ../../../tests/Texture2dTest/Texture2dTest.cpp \ ../../../tests/TileMapTest/TileMapTest.cpp \ ../../../tests/TouchesTest/Ball.cpp \ diff --git a/tests/test.ios/test.xcodeproj/project.pbxproj.REMOVED.git-id b/tests/test.ios/test.xcodeproj/project.pbxproj.REMOVED.git-id index 7d7174d501..2de9b05544 100644 --- a/tests/test.ios/test.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/tests/test.ios/test.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -3df87510e48dfe7e5c768dcef3f4fd6eb99a129b \ No newline at end of file +0031a29bb750c1b41620d51dbb052daa823edcd4 \ No newline at end of file diff --git a/tests/test.linux/Makefile b/tests/test.linux/Makefile index 3fc03131eb..93b89aabc9 100644 --- a/tests/test.linux/Makefile +++ b/tests/test.linux/Makefile @@ -89,6 +89,7 @@ OBJECTS = ../tests/AccelerometerTest/AccelerometerTest.o \ ../tests/SchedulerTest/SchedulerTest.o \ ../tests/SpriteTest/SpriteTest.o \ ../tests/TextInputTest/TextInputTest.o \ + ../tests/TextureCacheTest/TextureCacheTest.o \ ../tests/Texture2dTest/Texture2dTest.o \ ../tests/TileMapTest/TileMapTest.o \ ../tests/TouchesTest/Ball.o \ diff --git a/tests/test.win32/test.win32.vcproj b/tests/test.win32/test.win32.vcproj index 4ca3dacf97..92a3a0a9ef 100644 --- a/tests/test.win32/test.win32.vcproj +++ b/tests/test.win32/test.win32.vcproj @@ -1107,6 +1107,18 @@ > + + + + + + diff --git a/tests/test.win32/test.win32.vcxproj b/tests/test.win32/test.win32.vcxproj index a8a1c90b05..a06ebfa05e 100644 --- a/tests/test.win32/test.win32.vcxproj +++ b/tests/test.win32/test.win32.vcxproj @@ -124,6 +124,7 @@ + @@ -210,6 +211,7 @@ + diff --git a/tests/test.win32/test.win32.vcxproj.filters b/tests/test.win32/test.win32.vcxproj.filters index fdc48edcc0..ced8722d48 100644 --- a/tests/test.win32/test.win32.vcxproj.filters +++ b/tests/test.win32/test.win32.vcxproj.filters @@ -136,6 +136,9 @@ {178ed769-203d-47d0-92a4-de8668c4df58} + + {17b9b23c-1ef6-466e-a2ab-c558f4015698} + @@ -390,6 +393,9 @@ classes\tests\CurrentLanguageTest + + classes\tests\TextureCacheTest + @@ -704,5 +710,8 @@ classes\tests\CurrentLanguageTest + + classes\tests\TextureCacheTest + \ No newline at end of file diff --git a/tests/tests/TextureCacheTest/TextureCacheTest.cpp b/tests/tests/TextureCacheTest/TextureCacheTest.cpp new file mode 100644 index 0000000000..6bf724b2a6 --- /dev/null +++ b/tests/tests/TextureCacheTest/TextureCacheTest.cpp @@ -0,0 +1,143 @@ +// enable log +#define COCOS2D_DEBUG 1 + +#include "TextureCacheTest.h" + +TextureCacheTest::TextureCacheTest() +: m_nNumberOfSprites(24) +, m_nNumberOfLoadedSprites(0) +{ + CCSize size = CCDirector::sharedDirector()->getWinSize(); + + m_pLabelLoading = CCLabelTTF::labelWithString("loading...", "Arial", 15); + m_pLabelPercent = CCLabelTTF::labelWithString("%0", "Arial", 15); + + m_pLabelLoading->setPosition(CCPointMake(size.width / 2, size.height / 2 - 20)); + m_pLabelPercent->setPosition(CCPointMake(size.width / 2, size.height / 2 + 20)); + + this->addChild(m_pLabelLoading); + this->addChild(m_pLabelPercent); + + // load textrues + CCTextureCache::sharedTextureCache()->addImageAsync("Images/HelloWorld.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/grossini.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/grossini_dance_01.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/grossini_dance_02.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/grossini_dance_03.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/grossini_dance_04.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/grossini_dance_05.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/grossini_dance_06.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/grossini_dance_07.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/grossini_dance_08.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/grossini_dance_09.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/grossini_dance_10.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/grossini_dance_11.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/grossini_dance_12.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/grossini_dance_13.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/grossini_dance_14.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/background1.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/background2.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/background3.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/background1-hd.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/background2-hd.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/background3-hd.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/blocks.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); + CCTextureCache::sharedTextureCache()->addImageAsync("Images/blocks-hd.png", this, callfuncO_selector(TextureCacheTest::loadingCallBack)); +} + +void TextureCacheTest::loadingCallBack(CCObject *obj) +{ + ++m_nNumberOfLoadedSprites; + char tmp[10]; + sprintf(tmp,"%%%d", (int)(((float)m_nNumberOfLoadedSprites / m_nNumberOfSprites) * 100)); + m_pLabelPercent->setString(tmp); + + if (m_nNumberOfLoadedSprites == m_nNumberOfSprites) + { + this->removeChild(m_pLabelLoading, true); + this->removeChild(m_pLabelPercent, true); + addSprite(); + } +} + +void TextureCacheTest::addSprite() +{ + CCSize size = CCDirector::sharedDirector()->getWinSize(); + + // create sprites + + CCSprite *bg = CCSprite::spriteWithFile("Images/HelloWorld.png"); + bg->setPosition(CCPointMake(size.width / 2, size.height / 2)); + + CCSprite *s1 = CCSprite::spriteWithFile("Images/grossini.png"); + CCSprite *s2 = CCSprite::spriteWithFile("Images/grossini_dance_01.png"); + CCSprite *s3 = CCSprite::spriteWithFile("Images/grossini_dance_02.png"); + CCSprite *s4 = CCSprite::spriteWithFile("Images/grossini_dance_03.png"); + CCSprite *s5 = CCSprite::spriteWithFile("Images/grossini_dance_04.png"); + CCSprite *s6 = CCSprite::spriteWithFile("Images/grossini_dance_05.png"); + CCSprite *s7 = CCSprite::spriteWithFile("Images/grossini_dance_06.png"); + CCSprite *s8 = CCSprite::spriteWithFile("Images/grossini_dance_07.png"); + CCSprite *s9 = CCSprite::spriteWithFile("Images/grossini_dance_08.png"); + CCSprite *s10 = CCSprite::spriteWithFile("Images/grossini_dance_09.png"); + CCSprite *s11 = CCSprite::spriteWithFile("Images/grossini_dance_10.png"); + CCSprite *s12 = CCSprite::spriteWithFile("Images/grossini_dance_11.png"); + CCSprite *s13 = CCSprite::spriteWithFile("Images/grossini_dance_12.png"); + CCSprite *s14 = CCSprite::spriteWithFile("Images/grossini_dance_13.png"); + CCSprite *s15 = CCSprite::spriteWithFile("Images/grossini_dance_14.png"); + + // just loading textures to slow down + CCSprite *s16 = CCSprite::spriteWithFile("Images/background1.png"); + CCSprite *s17 = CCSprite::spriteWithFile("Images/background2.png"); + CCSprite *s18 = CCSprite::spriteWithFile("Images/background3.png"); + CCSprite *s19 = CCSprite::spriteWithFile("Images/background1-hd.png"); + CCSprite *s20 = CCSprite::spriteWithFile("Images/background2-hd.png"); + CCSprite *s21 = CCSprite::spriteWithFile("Images/background3-hd.png"); + CCSprite *s22 = CCSprite::spriteWithFile("Images/blocks.png"); + CCSprite *s23 = CCSprite::spriteWithFile("Images/blocks-hd.png"); + + s1->setPosition(CCPointMake(50, 50)); + s2->setPosition(CCPointMake(60, 50)); + s3->setPosition(CCPointMake(70, 50)); + s4->setPosition(CCPointMake(80, 50)); + s5->setPosition(CCPointMake(90, 50)); + s6->setPosition(CCPointMake(100, 50)); + + s7->setPosition(CCPointMake(50, 180)); + s8->setPosition(CCPointMake(60, 180)); + s9->setPosition(CCPointMake(70, 180)); + s10->setPosition(CCPointMake(80, 180)); + s11->setPosition(CCPointMake(90, 180)); + s12->setPosition(CCPointMake(100, 180)); + + s13->setPosition(CCPointMake(50, 270)); + s14->setPosition(CCPointMake(60, 270)); + s15->setPosition(CCPointMake(70, 270)); + + this->addChild(bg); + + this->addChild(s1); + this->addChild(s2); + this->addChild(s3); + this->addChild(s4); + this->addChild(s5); + this->addChild(s6); + this->addChild(s7); + this->addChild(s8); + this->addChild(s9); + this->addChild(s10); + this->addChild(s11); + this->addChild(s12); + this->addChild(s13); + this->addChild(s14); + this->addChild(s15); +} + + +void TextureCacheTestScene::runThisTest() +{ + CCLayer* pLayer = new TextureCacheTest(); + addChild(pLayer); + + CCDirector::sharedDirector()->replaceScene(this); + pLayer->release(); +} diff --git a/tests/tests/TextureCacheTest/TextureCacheTest.h b/tests/tests/TextureCacheTest/TextureCacheTest.h new file mode 100644 index 0000000000..086fcce1f9 --- /dev/null +++ b/tests/tests/TextureCacheTest/TextureCacheTest.h @@ -0,0 +1,28 @@ +#ifndef _TEXTURECACHE_TEST_H_ +#define _TEXTURECACHE_TEST_H_ + +#include "cocos2d.h" +#include "../testBasic.h" + +class TextureCacheTest : public CCLayer +{ +public: + TextureCacheTest(); + void addSprite(); + void loadingCallBack(cocos2d::CCObject *obj); + +private: + cocos2d::CCLabelTTF *m_pLabelLoading; + cocos2d::CCLabelTTF *m_pLabelPercent; + int m_nNumberOfSprites; + int m_nNumberOfLoadedSprites; + +}; + +class TextureCacheTestScene : public TestScene +{ +public: + virtual void runThisTest(); +}; + +#endif // _TEXTURECACHE_TEST_H_ diff --git a/tests/tests/controller.cpp b/tests/tests/controller.cpp index eac8212fec..6c65d7bc0c 100644 --- a/tests/tests/controller.cpp +++ b/tests/tests/controller.cpp @@ -111,7 +111,7 @@ static TestScene* CreateTestScene(int nIdx) pScene = new FontTestScene(); break; case TEST_CURRENT_LANGUAGE: pScene = new CurrentLanguageTestScene(); break; - break; + case TEST_TEXTURECACHE: pScene = new TextureCacheTestScene(); break; #endif default: diff --git a/tests/tests/tests.h b/tests/tests/tests.h index c4ee2fa49a..c62f0e466c 100644 --- a/tests/tests/tests.h +++ b/tests/tests/tests.h @@ -44,6 +44,7 @@ #include "Texture2dTest/Texture2dTest.h" #include "FontTest/FontTest.h" #include "CurrentLanguageTest/CurrentLanguageTest.h" +#include "TextureCacheTest/TextureCacheTest.h" #if (CC_TARGET_PLATFORM != CC_PLATFORM_AIRPLAY) #include "ChipmunkTest/cocos2dChipmunkDemo.h" @@ -98,6 +99,7 @@ enum TEST_BUGS, TEST_FONTS, TEST_CURRENT_LANGUAGE, + TEST_TEXTURECACHE, TESTS_COUNT, }; @@ -144,6 +146,7 @@ const std::string g_aTestNames[TESTS_COUNT] = { "BugsTest", "FontTest", "CurrentLanguageTest", + "TextureCacheTest" }; #endif