展会信息港展会大全

cocos2dx C++自定义线程安全消息管理
来源:互联网   发布日期:2015-09-27 14:58:49   浏览:2312次  

导读: 一、背景 由于cocos2dx本身的NotificationCenter是没有进行线程安全处理的,所以当我们在cocos2dx里面使用多线程进行消息同步的时候, 会出现问题。那么为了解决这个问...

一、背景

由于cocos2dx本身的NotificationCenter是没有进行线程安全处理的,所以当我们在cocos2dx里面使用多线程进行消息同步的时候,

会出现问题。那么为了解决这个问题,我们只需要进行线程安全锁定即可。

为了不修改源码,我模仿NotificationCenter,自定义了一个消息管理。

二、思路

首先,我们定义一个消息体的数据类型 Message。他里面存储有消息名称Name,消息处理函数,消息目标,消息内容。

然后,我们定义一个消息管理类。他里面有消息容器。去容纳每一个消息。

管理类对外暴漏的接口只有添加消息和发送消息。具体内容需要自己实现。

最后,将消息容器每次操作加锁即可。一个可以重复利用的,多线消息处理机制就完成了。

三、代码

头文件:

/**************************************************************

* Copyright (c) 2014-11-12 by real.Xm

* Blog Address: http://blog.csdn.net/q229827701

* Email: 229827701@qq.com

**************************************************************/

#ifndef __XMESSAGE__H

#define __XMESSAGE__H

#include "cocos2d.h"

class XMessage;

class CC_DLL MessageMsg : public cocos2d::Ref

{

public:

MessageMsg();

virtual ~MessageMsg();

static MessageMsg* getInstance();

bool addObserver(const std::string &msgName,cocos2d::Ref* target,

cocos2d::SEL_CallFuncO selector,cocos2d::Ref* msgContent = nullptr);

bool postMessage(const std::string &msgName,cocos2d::Ref* msgContent);

bool removeObserverByName(const std::string &msgName,cocos2d::Ref* target = nullptr);

bool removeAllObservers(cocos2d::Ref* target);

protected:

XMessage* getMessageByName(const std::string &msgName) const;

private:

//message container

cocos2d::Vector _msgContainer;

};

class CC_DLL XMessage: public cocos2d::Ref

{

public:

XMessage(const std::string &msgName,cocos2d::Ref* target,

cocos2d::SEL_CallFuncO selector,cocos2d::Ref* msgContent);

~XMessage();

void handerMessage(cocos2d::Ref* msgContent);

CC_SYNTHESIZE_READONLY(std::string,_msgName,MessageName);//message name

CC_SYNTHESIZE_READONLY(cocos2d::Ref*,_target,Target);//target

CC_SYNTHESIZE_READONLY(cocos2d::SEL_CallFuncO,_selector,Selector);//function

CC_SYNTHESIZE_READONLY(cocos2d::Ref*,_msgContent,MessageConent);//function args

};

#endif // !_XMESSAGE_H

实现文件

#include "XMessageManger.h"

std::mutex _ContainerMutex;

static MessageMsg* _Manager = nullptr;

MessageMsg::MessageMsg()

{

}

MessageMsg::~MessageMsg()

{

_msgContainer.clear();

}

MessageMsg* MessageMsg::getInstance()

{

if (!_Manager)

{

_Manager = new MessageMsg;

}

return _Manager;

}

bool MessageMsg::addObserver( const std::string &msgName,cocos2d::Ref* target,cocos2d::SEL_CallFuncO selector,cocos2d::Ref* msgContent /*= nullptr*/ )

{

if (!getMessageByName(msgName))

{

auto msg = new XMessage(msgName,target,selector,msgContent);

IF_NULL_RETURN_FALSE(msg);

msg->autorelease();

std::lock_guard<:mutex> ul(_ContainerMutex);

_msgContainer.pushBack(msg);

return true;

}

return false;

}

bool MessageMsg::postMessage( const std::string &msgName,cocos2d::Ref* msgContent )

{

auto msg = getMessageByName(msgName);

if (msg)

{

msg->handerMessage(msgContent);

return true;

}

return false;

}

XMessage* MessageMsg::getMessageByName( const std::string &msgName ) const

{

std::lock_guard<:mutex> ul(_ContainerMutex);

for (auto &msg : _msgContainer)

{

if (msgName == msg->getMessageName())

{

return msg;

}

}

return nullptr;

}

bool MessageMsg::removeObserverByName( const std::string &msgName,cocos2d::Ref* target /*= nullptr*/ )

{

std::lock_guard<:mutex> ul(_ContainerMutex);

for (auto &msg : _msgContainer)

{

if (msgName == msg->getMessageName()

&&(target == msg->getTarget()||!target))

{

_msgContainer.eraseObject(msg,true);

return true;

}

}

return false;

}

bool MessageMsg::removeAllObservers( cocos2d::Ref* target )

{

std::lock_guard<:mutex> ul(_ContainerMutex);

for (auto &msg : _msgContainer)

{

if (target == msg->getTarget())

{

_msgContainer.eraseObject(msg,true);

return true;

}

}

return false;

}

//////////////////////////////////////////////////////////////////////////

///XMessage Class

/////////////////////////////////////////////////////////////////////////

XMessage::XMessage( const std::string &msgName,cocos2d::Ref* target,

cocos2d::SEL_CallFuncO selector,cocos2d::Ref* msgContent )

:_msgName(msgName),_target(target),_selector(selector),_msgContent(msgContent)

{

}

XMessage::~XMessage()

{

}

void XMessage::handerMessage( cocos2d::Ref* msgContent )

{

if (_target)

{

if (msgContent) {

(_target->*_selector)(msgContent);

} else {

(_target->*_selector)(msgContent);

}

}

}

四、申明

本文原创,为尊重原创,转载时请注明出处。

http://blog.csdn.net/q229827701/article/details/41042147

赞助本站

人工智能实验室
AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港