zoukankan      html  css  js  c++  java
  • cocos2d-x CCNotificationCenter一个优化想法

     1 void CCNotificationCenter::postNotification(const char *name, CCObject *object)
     2 {
     3     CCArray* ObserversCopy = CCArray::createWithCapacity(m_observers->count());
     4     ObserversCopy->addObjectsFromArray(m_observers);
     5     CCObject* obj = NULL;
     6     CCARRAY_FOREACH(ObserversCopy, obj)
     7     {
     8         CCNotificationObserver* observer = (CCNotificationObserver*) obj;
     9         if (!observer)
    10             continue;
    11         
    12         if (!strcmp(name,observer->getName()) && (observer->getObject() == object || observer->getObject() == NULL || object == NULL))
    13             observer->performSelector(object);
    14     }
    15 
    16     if (m_scriptHandler)
    17     {
    18         CCScriptEngineProtocol* engine = CCScriptEngineManager::sharedManager()->getScriptEngine();
    19         engine->executeNotificationEvent(this, name);
    20     }
    21 }

    从上面代码中可以看到发送消息的时候是遍历所有的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);
    }

     本文原创,转载请注明原文地址

  • 相关阅读:
    欧拉定理 (证明+在求逆元上的应用)
    【转】弱校的ACM奋斗史
    SDUT 2412 (单调队列 + dp)
    做SRM感想。。。
    平面图中最小割向最短路的转化
    HDU 4533
    黑书上的DP 30题
    POJ【数论/组合/博弈论】题目列表
    HDU 4534 郑厂长系列故事——新闻净化
    SRM 571
  • 原文地址:https://www.cnblogs.com/kaisne/p/3474821.html
Copyright © 2011-2022 走看看