cocos2d-x 3.2線程安全的消息中心

本文章參考了某個博友的文章,具體的記不清楚了,望見諒!
//
//  MsgManager.h
//  MsgManager
//
//  Created by sky on 14-11-21.
//
//  線程安全的消息中心

#ifndef __MsgManager__MsgManager__
#define __MsgManager__MsgManager__

#include <stdio.h>
#include
 "cocos2d.h"
USING_NS_CC;

//消息體
class CC_DLL Message :public Ref
{
public:
    Message(
const std::string &msgName,Ref* target,SEL_CallFuncO selector,Ref* msgContent);
   
 virtual ~Message();
   
 void handerMessage(Ref*msgContent);
   
 CC_SYNTHESIZE_READONLY(std::string, m_msgName, MessageName);
   
 CC_SYNTHESIZE_READONLY(Ref*, m_target, Target);
   
 CC_SYNTHESIZE_READONLY(SEL_CallFuncO, m_selector, Selector);
   
 CC_SYNTHESIZE_READONLY(Ref*, m_msgContent, MessageContent); //function args
};


//消息管理
classCC_DLL MsgManager:publicRef
{
public:
    MsgManager();
   
   
 virtual ~MsgManager();
   
   
 staticMsgManager* getInstance();
   
   
 //多個對象可以監聽同一個名字的消息
   
 bool addObserver(conststd::string &msgName,Ref*target,SEL_CallFuncO selector,Ref* msgContent=nullptr);
   
   
 void postMessage(conststd::string& msgName);

   
 void postMessage(conststd::string& msgName,Ref*msgContent);
   
   
 //如果target爲空則移除所有名字爲msgName的消息
   
 void removeObserverByName(conststd::string& msgName,Ref*target=nullptr);
   
   
 //移除一個對象的所有監聽
   
 void removeAllObserver(Ref* target);
   
protected:
   
 Message* getMessageByNameAndTarget(conststd::string &msgName,Ref* target) const;

private:
   
 Vector<Message*> m_msgContainer;
};


#endif /* defined(__MsgManager__MsgManager__) */


//
//  MsgManager.cpp
//  MsgManager
//
//  Created by sky on 14-11-21.
//
//

#include "MsgManager.h"

#pragma mark--消息體
Message::Message(const std::string &msgName,Ref* target,SEL_CallFuncO selector,Ref* msgContent):m_msgName(msgName),
                m_target(target),
                m_selector(selector),
                m_msgContent(msgContent)
               
{
}
Message::~Message()
{
}

void Message::handerMessage(cocos2d::Ref *msgContent)
{
   
 if (m_target)
    {
        (m_target ->* m_selector)(msgContent);
    }
}

#pragma mark--消息管理
static MsgManager* instance = nullptr;
std::mutex containerMutex;

MsgManager::MsgManager()
{
}
MsgManager::~MsgManager()
{
    m_msgContainer.clear();
}

MsgManager* MsgManager::getInstance()
{
   
 if (!instance)
    {
        instance =
 new MsgManager();
    }
   
 return instance;
}

bool MsgManager::addObserver(const std::string &msgName, cocos2d::Ref *target, SEL_CallFuncO selector,Ref *msgContent)
{
    std::lock_guard<std::mutex> ul(containerMutex);

   
 if (!getMessageByNameAndTarget(msgName,target))
    {
       
 auto msg = new Message(msgName,target,selector,msgContent);
       
 if (!msg)
        {
           
 returnfalse;
            CC_SAFE_DELETE(msg);
        }
        msg -> autorelease();
        m_msgContainer.pushBack(msg);
        CCLOG(
"msgCount:%lu",m_msgContainer.size());
       
       
 return true;
    }
   
 return false;
}

void MsgManager::postMessage(const std::string &msgName, cocos2d::Ref *msgContent)
{
    std::lock_guard<std::mutex> ul(containerMutex);
   
 for(auto &msg : m_msgContainer)
    {
       
 if (msgName==msg->getMessageName())
        {
            msg -> handerMessage(msgContent);
        }
    }
}

void MsgManager::postMessage(const std::string &msgName)
{
    postMessage(msgName,
nullptr);
}

Message* MsgManager::getMessageByNameAndTarget(
const std::string &msgName, cocos2d::Ref *target) const
{
   
 for(auto &msg : m_msgContainer)
    {
       
 if (msgName==msg->getMessageName() && target==msg->getTarget())
        {
           
 return msg;
        }
    }
   
 return nullptr;
}

void MsgManager::removeObserverByName(const std::string &msgName,Ref *target)
{
    std::lock_guard<std::mutex> ui(containerMutex);
   
 for(auto &msg : m_msgContainer)
    {
       
 if (msgName == msg->getMessageName() && (target==msg->getTarget()||!target))
        {
            m_msgContainer.eraseObject(msg,
true);  //?
        }
    }
}

void MsgManager::removeAllObserver(cocos2d::Ref *target)
{
    std::lock_guard<std::mutex> ul(containerMutex);
   
 for (auto &msg : m_msgContainer)
    {
       
 if (target==msg->getTarget())
        {
            m_msgContainer.eraseObject(msg,
true);
        }
    }
}

發佈了32 篇原創文章 · 獲贊 23 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章