• 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);
    }

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

  • 相关阅读:
    【 Java框架】Spring的核心IOC源码分析
    小猪学设计模式——模板方法模式
    小猪学设计模式——工厂模式之抽象工厂
    小猪学设计模式——工厂模式之工厂方法模式
    小猪学设计模式——工厂模式之简单工厂(静态工厂)
    HTML5 Server-sent Events ASP.NET向Web客户端推送信息
    jquery.min.map 404 (Not Found)
    C# HTTP 断点续传
    C#操作JSON字符串
    Visual Studio 解决Windows Web服务框架中出现了无法识别的错误
  • 原文地址:https://www.cnblogs.com/kaisne/p/3474821.html
Copyright © 2020-2023  润新知