在网络通信部分,我们新开启了一个线程,当从服务端接收到数据的时候,在这个线程中,我们将接收到的数据解码解码后通过CCNotificationCenter发送出去:
void SCmd134::execute(string msg) { m_sMsg = msg; msgpack::unpack(&msgList, m_sMsg.c_str(), m_sMsg.size()); msgpack::object obj = msgList.get(); obj.convert(this); CCNotificationCenter::sharedNotificationCenter()->postNotification("-134", this); }
由于CCNotificationCenter不是线程安全的,在多线程的环境中,不可能直接在分离的线程中调用CCNotificationCenter::sharedNotificationCenter()->postNotification发送消息。 参考《Cocos2d-x高级开发教程》第16章并发编程,我们需要建立一个线程安全的消息队列。
void SCmd134::execute(string msg) { m_sMsg = msg; msgpack::unpack(&msgList, m_sMsg.c_str(), m_sMsg.size()); msgpack::object obj = msgList.get(); obj.convert(this); MTNotificationQueue::sharedNotificationQueue()->postNotification("-134", this); }
《Cocos2d-x高级开发教程》教程中的MT Queue 如下,需要的可以粘贴使用:
#ifndef __MTNotificationQueue_h #define __MTNotificationQueue_h #include "cocos2d.h" #include#include "ThreadConstants.h" USING_NS_CC; using namespace std; class MTNotificationQueue : public CCObject { static MTNotificationQueue * mInstance; class CGarbo { public: ~CGarbo() { if (MTNotificationQueue::mInstance) delete MTNotificationQueue::mInstance; mInstance = NULL; } }; static CGarbo Garbo; typedef struct { string name; CCObject* object; } NotificationArgs; vector notifications; MTNotificationQueue(void); public: static MTNotificationQueue* sharedNotificationQueue(); void postNotifications(float dt); ~MTNotificationQueue(void); void postNotification(const char* name, CCObject* object); }; #endif
#include "MTNotificationQueue.h" pthread_mutex_t sharedNotificationQueueLock; class LifeManager_PThreadMutex { pthread_mutex_t* mutex; public: LifeManager_PThreadMutex(pthread_mutex_t* mut) : mutex(mut) { pthread_mutex_init(mutex, NULL); } ~LifeManager_PThreadMutex() { pthread_mutex_destroy(mutex); } }__LifeManager_sharedNotificationQueueLock(&sharedNotificationQueueLock); class LifeCircleMutexLocker { pthread_mutex_t* mutex; public: LifeCircleMutexLocker(pthread_mutex_t* aMutex) : mutex(aMutex) { pthread_mutex_lock(mutex); } ~LifeCircleMutexLocker(){ pthread_mutex_unlock(mutex); } }; #define LifeCircleMutexLock(mutex) LifeCircleMutexLocker __locker__(mutex) MTNotificationQueue* MTNotificationQueue::mInstance = NULL; MTNotificationQueue::MTNotificationQueue(void) { } MTNotificationQueue::~MTNotificationQueue(void) { } MTNotificationQueue* MTNotificationQueue::sharedNotificationQueue() { if (!mInstance) { mInstance = new MTNotificationQueue(); } return mInstance; } void MTNotificationQueue::postNotifications(float dt) { LifeCircleMutexLock(&sharedNotificationQueueLock); for(uint16_t i = 0; i < notifications.size(); i++) { NotificationArgs &arg = notifications[i]; CCNotificationCenter::sharedNotificationCenter()-> postNotification(arg.name.c_str(), arg.object); } notifications.clear(); } void MTNotificationQueue::postNotification(const char* name, CCObject* object) { LifeCircleMutexLock(&sharedNotificationQueueLock); NotificationArgs arg; arg.name = name; if(object != NULL) arg.object = object; //object->copy(); else arg.object = NULL; notifications.push_back(arg); }
CCDirector::sharedDirector()->getScheduler()->scheduleSelector( schedule_selector(MTNotificationQueue::postNotifications), MTNotificationQueue::sharedNotificationQueue(), 1.0 / 60.0, false);