本文共 3929 字,大约阅读时间需要 13 分钟。
1、分析下update类型,即每帧都调用的定时器,如何实现:
//CCScheduler中的成员变量struct _listEntry *m_pUpdates0List; // list priority == 0-->>存放update类型定时器的结构// A list double-linked list used for "updates with priority"typedef struct _listEntry{ struct _listEntry *prev, *next; CCObject *target; // not retained (retained by hashUpdateEntry) int priority; bool paused; bool markedForDeletion; // selector will no longer be called and entry will be removed at end of the next tick} tListEntry;
2、添加update类型的定时器 /** Schedules the 'update' selector for a given target with a given priority. The 'update' selector will be called every frame. The lower the priority, the earlier it is called. @since v0.99.3 @lua NA */ void scheduleUpdateForTarget(CCObject *pTarget, int nPriority, bool bPaused); -->> void CCScheduler::scheduleUpdateForTarget(CCObject *pTarget, int nPriority, bool bPaused){ //先判断是否已经加入 tHashUpdateEntry *pHashElement = NULL; HASH_FIND_INT(m_pHashForUpdates, &pTarget, pHashElement); if (pHashElement) {#if COCOS2D_DEBUG >= 1 CCAssert(pHashElement->entry->markedForDeletion,"");#endif // TODO: check if priority has changed! pHashElement->entry->paused = bPaused; pHashElement->entry->markedForDeletion = false; return; } //根据优先级加入到不同的链表中 // most of the updates are going to be 0, that's way there // is an special list for updates with priority 0 if (nPriority == 0) { appendIn(&m_pUpdates0List, pTarget, bPaused); } else if (nPriority < 0) { priorityIn(&m_pUpdatesNegList, pTarget, nPriority, bPaused); } else { // priority > 0 priorityIn(&m_pUpdatesPosList, pTarget, nPriority, bPaused); }}-->>分析下appendIn(&m_pUpdates0List, pTarget, bPaused)这个,其他连个类似,只不过加入了优先级的概念,需要根据优先级确定插入位置,但是都为加入到快速查找哈希链表中,而且同样会retain。void CCScheduler::appendIn(_listEntry **ppList, CCObject *pTarget, bool bPaused){ //分配tListEntry tListEntry *pListElement = (tListEntry *)malloc(sizeof(*pListElement)); pListElement->target = pTarget; pListElement->paused = bPaused; pListElement->markedForDeletion = false; //添加进列表 DL_APPEND(*ppList, pListElement); //添加到快速查找哈希链表中 // update hash entry for quicker access tHashUpdateEntry *pHashElement = (tHashUpdateEntry *)calloc(sizeof(*pHashElement), 1); pHashElement->target = pTarget; pTarget->retain(); //有一次retain对象的操作,会影响对象的释放 pHashElement->list = ppList; pHashElement->entry = pListElement; HASH_ADD_INT(m_pHashForUpdates, target, pHashElement);}3、移除update类型的定时器 /** Unschedules the update selector for a given target @since v0.99.3 @lua NA */ void unscheduleUpdateForTarget(const CCObject *pTarget); -->> void CCScheduler::unscheduleUpdateForTarget(const CCObject *pTarget){ if (pTarget == NULL) { return; } //如果哈希表中有 tHashUpdateEntry *pElement = NULL; HASH_FIND_INT(m_pHashForUpdates, &pTarget, pElement); if (pElement) { if (m_bUpdateHashLocked) { pElement->entry->markedForDeletion = true; //标记为移除 } else { this->removeUpdateFromHash(pElement->entry);//真正的移除 } }}-->>void CCScheduler::removeUpdateFromHash(struct _listEntry *entry){ tHashUpdateEntry *element = NULL; HASH_FIND_INT(m_pHashForUpdates, &entry->target, element); if (element) { // list entry,从链表移除 DL_DELETE(*element->list, element->entry); free(element->entry); // hash entry,从哈希表移除 CCObject* pTarget = element->target; HASH_DEL(m_pHashForUpdates, element); free(element); // target#release should be the last one to prevent // a possible double-free. eg: If the [target dealloc] might want to remove it itself from there pTarget->release(); //对对象执行一次release操作 }}
转载地址:http://ttsmi.baihongyu.com/