class CC_DLL CCCopying
{
public:
virtual CCObject* copyWithZone(CCZone* pZone);
};
class CC_DLL CCObject : public CCCopying
{
public:
// object id, CCScriptSupport need public m_uID
unsigned int m_uID;
// Lua reference id
int m_nLuaID;
protected:
// count of references
unsigned int m_uReference;
// count of autorelease
unsigned int m_uAutoReleaseCount;
public:
CCObject(void);
virtual ~CCObject(void);
void release(void);
void retain(void);
CCObject* autorelease(void);
CCObject* copy(void);
bool isSingleReference(void) const;
unsigned int retainCount(void) const;
virtual bool isEqual(const CCObject* pObject);
virtual void acceptVisitor(CCDataVisitor &visitor);
virtual void update(float dt) {CC_UNUSED_PARAM(dt);};
friend class CCAutoreleasePool;
};
typedef void (CCObject::*SEL_SCHEDULE)(float);
typedef void (CCObject::*SEL_CallFunc)();
typedef void (CCObject::*SEL_CallFuncN)(CCNode*);
typedef void (CCObject::*SEL_CallFuncND)(CCNode*, void*);
typedef void (CCObject::*SEL_CallFuncO)(CCObject*);
typedef void (CCObject::*SEL_MenuHandler)(CCObject*);
typedef void (CCObject::*SEL_EventHandler)(CCEvent*);
typedef int (CCObject::*SEL_Compare)(CCObject*);
#define schedule_selector(_SELECTOR) (SEL_SCHEDULE)(&_SELECTOR)
#define callfunc_selector(_SELECTOR) (SEL_CallFunc)(&_SELECTOR)
#define callfuncN_selector(_SELECTOR) (SEL_CallFuncN)(&_SELECTOR)
#define callfuncND_selector(_SELECTOR) (SEL_CallFuncND)(&_SELECTOR)
#define callfuncO_selector(_SELECTOR) (SEL_CallFuncO)(&_SELECTOR)
#define menu_selector(_SELECTOR) (SEL_MenuHandler)(&_SELECTOR)
#define event_selector(_SELECTOR) (SEL_EventHandler)(&_SELECTOR)
#define compare_selector(_SELECTOR) (SEL_Compare)(&_SELECTOR)
CCObject* CCCopying::copyWithZone(CCZone *pZone)
{
CC_UNUSED_PARAM(pZone);
CCAssert(0, "not implement");
return 0;
}
CCObject::CCObject(void)
: m_nLuaID(0)
, m_uReference(1) // when the object is created, the reference count of it is 1
, m_uAutoReleaseCount(0)
{
static unsigned int uObjectCount = 0;
// 用来统计对象id
m_uID = ++uObjectCount;
}
CCObject::~CCObject(void)
{
// 如果这个对象被管理,我们要从管理池中将他移除
if (m_uAutoReleaseCount > 0)
{
CCPoolManager::sharedPoolManager()->removeObject(this);
}
// 若该对象被lua引擎使用则移除之
if (m_nLuaID)
{
CCScriptEngineManager::sharedManager()->getScriptEngine()->removeScriptObjectByCCObject(this);
}
else
{
CCScriptEngineProtocol* pEngine = CCScriptEngineManager::sharedManager()->getScriptEngine();
if (pEngine != NULL && pEngine->getScriptType() == kScriptTypeJavascript)
{
pEngine->removeScriptObjectByCCObject(this);
}
}
}
CCObject* CCObject::copy()
{
// 实现这个对象拷贝
return copyWithZone(0);
}
void CCObject::release(void)
{
// 减少引用计数,在引用计数为0时删除该对象
CCAssert(m_uReference > 0, "reference count should greater than 0");
--m_uReference;
if (m_uReference == 0)
{
delete this;
}
}
void CCObject::retain(void)
{
CCAssert(m_uReference > 0, "reference count should greater than 0");
// 增加引用计数
++m_uReference;
}
CCObject* CCObject::autorelease(void)
{
// 将该对象加入管理池中,最后自动释放
CCPoolManager::sharedPoolManager()->addObject(this);
return this;
}
bool CCObject::isSingleReference(void) const
{
// 引用计数是否单例
return m_uReference == 1;
}
unsigned int CCObject::retainCount(void) const
{
// 返回引用计数
return m_uReference;
}
bool CCObject::isEqual(const CCObject *pObject)
{
return this == pObject;
}
void CCObject::acceptVisitor(CCDataVisitor &visitor)
{
visitor.visitObject(this);
}