您的位置:首页 > 移动开发 > Cocos引擎

cocos2d-x CCNotificationCenter一个优化想法

2013-12-14 23:07 330 查看
void CCNotificationCenter::postNotification(const char *name, CCObject *object)
{
CCArray* ObserversCopy = CCArray::createWithCapacity(m_observers->count());
ObserversCopy->addObjectsFromArray(m_observers);
CCObject* obj = NULL;
CCARRAY_FOREACH(ObserversCopy, obj)
{
CCNotificationObserver* observer = (CCNotificationObserver*) obj;
if (!observer)
continue;

if (!strcmp(name,observer->getName()) && (observer->getObject() == object || observer->getObject() == NULL || object == NULL))
observer->performSelector(object);
}

if (m_scriptHandler)
{
CCScriptEngineProtocol* engine = CCScriptEngineManager::sharedManager()->getScriptEngine();
engine->executeNotificationEvent(this, name);
}
}


从上面代码中可以看到发送消息的时候是遍历所有的Observer,这样对于频繁发送消息的时候,非常低效率。我的想法是修改CCNotificationCenter的 CCArray *m_observers 为 CCDictionary * m_observers(key为消息,value是一个CCSet *),因为CCNotificationCenter使用过程中更多是面向消息。

修改后的代码如下:

//
// internal functions
//
bool CCNotificationCenter::observerExisted(CCObject *target,const char *name)
{
CCSet* mgsObservers = (CCSet*)m_observersDic->objectForKey(name);
if (mgsObservers) {
for (CCSetIterator iter = mgsObservers->begin(); iter != mgsObservers->end(); iter++ ){
CCNotificationObserver* observer = (CCNotificationObserver*) (* iter);
if (observer->getTarget() == target)
return true;
}
}
return false;
}

//
// observer functions
//
void CCNotificationCenter::addObserver(CCObject *target,
SEL_CallFuncO selector,
const char *name,
CCObject *obj)
{
if (this->observerExisted(target, name))
return;

CCNotificationObserver *observer = new CCNotificationObserver(target, selector, name, obj);
observer->autorelease();
CCSet* mgsObservers = (CCSet*)m_observersDic->objectForKey(name);
if(!mgsObservers){
mgsObservers = CCSet::create();
m_observersDic->setObject(mgsObservers, name);
}
mgsObservers->addObject(observer);
}

void CCNotificationCenter::removeObserver(CCObject *target,const char *name)
{
CCSet* mgsObservers = (CCSet*)m_observersDic->objectForKey(name);
if(mgsObservers){
for (CCSetIterator iter = mgsObservers->begin(); iter != mgsObservers->end(); iter++ ){
CCNotificationObserver* observer = (CCNotificationObserver*) (* iter);
if (observer->getTarget() == target){
mgsObservers->removeObject(observer);
return;
}
}
}
}

int CCNotificationCenter::removeAllObservers(CCObject *target)
{
int removeCount = 0;
CCDictElement* pElement = NULL;
CCDICT_FOREACH(m_observersDic, pElement)
{
CCSet* mgsObservers = (CCSet*)pElement->getObject();
for (CCSetIterator iter = mgsObservers->begin(); iter != mgsObservers->end();){
CCNotificationObserver* observer = (CCNotificationObserver*) (* iter);
if (observer->getTarget() == target){
mgsObservers->removeObject(observer);
removeCount ++ ;
}else{
iter++
}
}
}
return removeCount;

}

void CCNotificationCenter::postNotification(const char *name, CCObject *object)
{
CCSet* mgsObservers = (CCSet*)m_observersDic->objectForKey(name);
if(mgsObservers){
for (CCSetIterator iter = mgsObservers->begin(); iter != mgsObservers->end(); iter++ ){
CCNotificationObserver* observer = (CCNotificationObserver*) (* iter);
if ((observer->getObject() == object ||
observer->getObject() == NULL ||
object == NULL)){
observer->performSelector(object);
}
}
}

if (m_scriptHandler)
{
CCScriptEngineProtocol* engine = CCScriptEngineManager::sharedManager()->getScriptEngine();
engine->executeNotificationEvent(this, name);
}
}

void CCNotificationCenter::postNotification(const char *name)
{
this->postNotification(name,NULL);
}


本文原创,转载请注明原文地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: