cocos2dx C++自定义线程安全消息管理

前端之家收集整理的这篇文章主要介绍了cocos2dx C++自定义线程安全消息管理前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

一、背景

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

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

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

二、思路

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

@H_403_15@
然后,我们定义一个消息管理类。他里面有消息容器。去容纳每一个消息。 @H_403_15@
管理类对外暴漏的接口只有添加消息和发送消息。具体内容需要自己实现。 @H_403_15@
@H_403_15@
最后,将消息容器每次操作加锁即可。一个可以重复利用的,多线消息处理机制就完成了。 @H_403_15@

@H_403_15@

三、代码

文件

  1. /**************************************************************
  2. * Copyright (c) 2014-11-12 by real.Xm
  3. * Blog Address: http://blog.csdn.net/q229827701
  4. * Email: 229827701@qq.com
  5. **************************************************************/
  6.  
  7. #ifndef __XMESSAGE__H
  8. #define __XMESSAGE__H
  9.  
  10.  
  11. #include "cocos2d.h"
  12. class XMessage;
  13. class CC_DLL MessageMsg : public cocos2d::Ref
  14. {
  15. public:
  16. MessageMsg();
  17. virtual ~MessageMsg();
  18. static MessageMsg* getInstance();
  19. bool addObserver(const std::string &msgName,cocos2d::Ref* target,cocos2d::SEL_CallFuncO selector,cocos2d::Ref* msgContent = nullptr);
  20. bool postMessage(const std::string &msgName,cocos2d::Ref* msgContent);
  21. bool removeObserverByName(const std::string &msgName,cocos2d::Ref* target = nullptr);
  22. bool removeAllObservers(cocos2d::Ref* target);
  23. protected:
  24. XMessage* getMessageByName(const std::string &msgName) const;
  25. private:
  26. //message container
  27. cocos2d::Vector<XMessage*> _msgContainer;
  28. };
  29. class CC_DLL XMessage: public cocos2d::Ref
  30. {
  31. public:
  32. XMessage(const std::string &msgName,cocos2d::Ref* msgContent);
  33. ~XMessage();
  34. void handerMessage(cocos2d::Ref* msgContent);
  35. CC_SYNTHESIZE_READONLY(std::string,_msgName,MessageName);//message name
  36. CC_SYNTHESIZE_READONLY(cocos2d::Ref*,_target,Target); //target
  37. CC_SYNTHESIZE_READONLY(cocos2d::SEL_CallFuncO,_selector,Selector);//function
  38. CC_SYNTHESIZE_READONLY(cocos2d::Ref*,_msgContent,MessageConent);//function args
  39. };
  40.  
  41. #endif // !_XMESSAGE_H

@H_403_15@

实现文件

@H_403_15@

@H_403_15@
  1. #include "XMessageManger.h"
  2.  
  3. std::mutex _ContainerMutex;
  4. static MessageMsg* _Manager = nullptr;
  5. MessageMsg::MessageMsg()
  6. {
  7.  
  8. }
  9.  
  10. MessageMsg::~MessageMsg()
  11. {
  12. _msgContainer.clear();
  13. }
  14.  
  15. MessageMsg* MessageMsg::getInstance()
  16. {
  17. if (!_Manager)
  18. {
  19. _Manager = new MessageMsg;
  20. }
  21. return _Manager;
  22. }
  23.  
  24. bool MessageMsg::addObserver( const std::string &msgName,cocos2d::Ref* msgContent /*= nullptr*/ )
  25. {
  26. if (!getMessageByName(msgName))
  27. {
  28. auto msg = new XMessage(msgName,target,selector,msgContent);
  29. IF_NULL_RETURN_FALSE(msg);
  30. msg->autorelease();
  31. std::lock_guard<std::mutex> ul(_ContainerMutex);
  32. _msgContainer.pushBack(msg);
  33. return true;
  34. }
  35. return false;
  36. }
  37.  
  38. bool MessageMsg::postMessage( const std::string &msgName,cocos2d::Ref* msgContent )
  39. {
  40. auto msg = getMessageByName(msgName);
  41. if (msg)
  42. {
  43. msg->handerMessage(msgContent);
  44. return true;
  45. }
  46. return false;
  47. }
  48.  
  49. XMessage* MessageMsg::getMessageByName( const std::string &msgName ) const
  50. {
  51. std::lock_guard<std::mutex> ul(_ContainerMutex);
  52. for (auto &msg : _msgContainer)
  53. {
  54. if (msgName == msg->getMessageName())
  55. {
  56. return msg;
  57. }
  58. }
  59. return nullptr;
  60. }
  61.  
  62. bool MessageMsg::removeObserverByName( const std::string &msgName,cocos2d::Ref* target /*= nullptr*/ )
  63. {
  64. std::lock_guard<std::mutex> ul(_ContainerMutex);
  65. for (auto &msg : _msgContainer)
  66. {
  67. if (msgName == msg->getMessageName()
  68. &&(target == msg->getTarget()||!target))
  69. {
  70. _msgContainer.eraSEObject(msg,true);
  71. return true;
  72. }
  73. }
  74. return false;
  75. }
  76.  
  77. bool MessageMsg::removeAllObservers( cocos2d::Ref* target )
  78. {
  79. std::lock_guard<std::mutex> ul(_ContainerMutex);
  80. for (auto &msg : _msgContainer)
  81. {
  82. if (target == msg->getTarget())
  83. {
  84. _msgContainer.eraSEObject(msg,true);
  85. return true;
  86. }
  87. }
  88. return false;
  89. }
  90.  
  91. //////////////////////////////////////////////////////////////////////////
  92. /// XMessage Class
  93. /////////////////////////////////////////////////////////////////////////
  94.  
  95. XMessage::XMessage( const std::string &msgName,cocos2d::Ref* msgContent )
  96. :_msgName(msgName),_target(target),_selector(selector),_msgContent(msgContent)
  97. {
  98.  
  99. }
  100.  
  101. XMessage::~XMessage()
  102. {
  103.  
  104. }
  105.  
  106. void XMessage::handerMessage( cocos2d::Ref* msgContent )
  107. {
  108. if (_target)
  109. {
  110. if (msgContent) {
  111. (_target->*_selector)(msgContent);
  112. } else {
  113. (_target->*_selector)(msgContent);
  114. }
  115. }
  116. }


@H_403_15@

@H_403_15@

@H_403_15@

四、申明

本文原创,为尊重原创,转载时请注明出处。 @H_403_15@
http://blog.csdn.net/q229827701/article/details/41042147 @H_403_15@

猜你在找的Cocos2d-x相关文章