#ifndef PXTASK_PXTASK_H
#define PXTASK_PXTASK_H
#include "task/PxTaskDefine.h"
#include "task/PxTaskManager.h"
#include "task/PxCpuDispatcher.h"
#include "foundation/PxAssert.h"
namespace physx
{
class PxBaseTask
{
public:
PxBaseTask() : mContextID(0), mTm(NULL) {}
virtual ~PxBaseTask() {}
virtual void run() = 0;
virtual const char* getName() const = 0;
virtual void addReference() = 0;
virtual void removeReference() = 0;
virtual int32_t getReference() const = 0;
virtual void release() = 0;
PX_FORCE_INLINE PxTaskManager* getTaskManager() const
{
return mTm;
}
PX_FORCE_INLINE void setContextId(PxU64 id) { mContextID = id; }
PX_FORCE_INLINE PxU64 getContextId() const { return mContextID; }
protected:
PxU64 mContextID; PxTaskManager* mTm;
friend class PxTaskMgr;
};
class PxTask : public PxBaseTask
{
public:
PxTask() : mTaskID(0) {}
virtual ~PxTask() {}
virtual void release()
{
PX_ASSERT(mTm);
PxTaskManager* save = mTm;
mTm = NULL;
save->taskCompleted( *this );
}
PX_INLINE void finishBefore( PxTaskID taskID )
{
PX_ASSERT(mTm);
mTm->finishBefore( *this, taskID);
}
PX_INLINE void startAfter( PxTaskID taskID )
{
PX_ASSERT(mTm);
mTm->startAfter( *this, taskID );
}
PX_INLINE void addReference()
{
PX_ASSERT(mTm);
mTm->addReference( mTaskID );
}
PX_INLINE void removeReference()
{
PX_ASSERT(mTm);
mTm->decrReference( mTaskID );
}
PX_INLINE int32_t getReference() const
{
return mTm->getReference( mTaskID );
}
PX_INLINE PxTaskID getTaskID() const
{
return mTaskID;
}
virtual void submitted()
{
}
protected:
PxTaskID mTaskID;
friend class PxTaskMgr;
};
class PxLightCpuTask : public PxBaseTask
{
public:
PxLightCpuTask()
: mCont( NULL )
, mRefCount( 0 )
{
}
virtual ~PxLightCpuTask()
{
mTm = NULL;
}
PX_INLINE void setContinuation(PxTaskManager& tm, PxBaseTask* c)
{
PX_ASSERT( mRefCount == 0 );
mRefCount = 1;
mCont = c;
mTm = &tm;
if( mCont )
{
mCont->addReference();
}
}
PX_INLINE void setContinuation( PxBaseTask* c )
{
PX_ASSERT( c );
PX_ASSERT( mRefCount == 0 );
mRefCount = 1;
mCont = c;
if( mCont )
{
mCont->addReference();
mTm = mCont->getTaskManager();
PX_ASSERT( mTm );
}
}
PX_INLINE PxBaseTask* getContinuation() const
{
return mCont;
}
PX_INLINE void removeReference()
{
mTm->decrReference(*this);
}
PX_INLINE int32_t getReference() const
{
return mRefCount;
}
PX_INLINE void addReference()
{
mTm->addReference(*this);
}
PX_INLINE void release()
{
if( mCont )
{
mCont->removeReference();
}
}
protected:
PxBaseTask* mCont; volatile int32_t mRefCount;
friend class PxTaskMgr;
};
}
#endif