CCTaskManager, CCTask, CCTaskWithCallback and CCMutex

Hi community. My project badly needs a multithread support for AI and resource preloading. Thread solution is not the best way for mobile devices. This is why i started implementation of couple of useful classes. Class maybe not 100 stably yet but I’m working on it.
Sorry for code without comments.

h2. Classes

*CCTaskManager* - thread-safe singleton that has his own thread pool and task queue. Use 1 mutex and 1 semaphore for synchronization
<pre>
class CC_DLL CCTaskManager: public CCObject
{

public:
void StartTaskQueue( CCTask* task);
static CCTaskManager* sharedTaskManager();

protected:
CCTaskManager();
virtual ~CCTaskManager();
bool init ();
static CCTaskManager* g_sharedTaskManager;

deque\<CCTask\*\> d\_taskQueue;
sem\_t sem;
CCMutex\* p\_queueProtector;  
vector\<pthread\_t\> l\_threadPool;

static void\* ThreadWork( void \* );

};
</pre>

*CCTask* - abstract class that is executed by CCTaskManager. You can inherent from this class to create complex tasks.

<pre>
class CC_DLL CCTask: public CCObject
{
public:
virtual void Run() = 0;
};
</pre>

*CCTaskWithCallback* - this is my implementation of CCTask. It has 3 features:

* It provides callback i UI thread (dangerous because i use CCCallFuncO and running it on current Scene).

<pre>
CCAction* callbackAction = CCCallFuncO::create( p_callbackOwner, s_callbackSelector , result);
CCDirector::sharedDirector()->getRunningScene()->runAction(callbackAction);
</pre>

* It takes CCObject* as data for task delegate.

* It returns CCObject* as result to callback function.

<pre>
class CC_DLL CCTaskWithCallback: public CCTask
{
public:
CCTaskWithCallback();
virtual ~CCTaskWithCallback();

virtual void Run();

static CCTaskWithCallback\* create( SEL\_O\_CallFuncO runner, CCObject\* runnerOwner, CCObject\* data = NULL );
static CCTaskWithCallback\* create( SEL\_O\_CallFuncO runner, CCObject\* runnerOwner, CCObject\* data,
    SEL\_CallFuncO callback, CCObject\* callbackOwner );

protected:
virtual bool init( SEL_O_CallFuncO runner, CCObject* caller, CCObject* data = NULL );
virtual bool init( SEL_O_CallFuncO runner, CCObject* caller, CCObject* data,
SEL_CallFuncO callback, CCObject* callbackOwner );

SEL\_O\_CallFuncO s\_runSelector;
SEL\_CallFuncO s\_callbackSelector;

CCObject\* p\_runOwner;
CCObject\* p\_callbackOwner;
CCObject\* p\_runData;

};
</pre>

*CCMutex* - wrapper pthread mutex. If somebody wants it can be implemented different for other platform. For Windows it is lighter to use critical sections, and for POSIX i recommend futex + atomic. Not use about iOS.

<pre>
class CC_DLL CCMutex: public CCObject
{
public:
CCMutex();
~CCMutex();

static CCMutex\* create( );

virtual bool init( );

int Lock();
int TryLock();
int Unlock();

protected:
pthread_mutex_t m_realMutex;

};
</pre>

h2. Problems:

* Cocos2d-x doesn’t have doesn’t have a delegate type that i CCTaskWithCallback needs so we need to add new one
<pre>
typedef CCObject* (CCObject::*SEL_O_CallFuncO)(CCObject*);
</pre>

* All CC***Cache class are not thread-safe so code fails like with 80 chance, but it work fine with my AI code.

  • I don’t have time and knowledge to implement lua analog.

Perspectives

With CCTaskManger and CCMutex (CCSemaphore can be implemented too) we can’t easily implement async methods to load any type of resources. It may not sound that cool for 1 core device, but we all know that 2~4 core are coming for average devices.

Please comment if you are interesting in my work or you can help me with cocos CC*****Cache classes.