01.#pragma once 02. 03.#include <deque> 04.#include <boost/any.hpp> 05. 06.#ifdef __APPLE__ 07.#include <tr1/functional> 08.using std::tr1::function; 09.using std::tr1::bind; 10.using namespace std::tr1::placeholders; 11. 12.namespace std { 13. template<class _Ty> struct _Remove_reference 14. { 15. typedef _Ty _Type; 16. }; 17. 18. template<class _Ty> inline typename _Remove_reference<_Ty>::_Type&& move(_Ty&& _Arg) 19. { 20. return ((typename _Remove_reference<_Ty>::_Type&&)_Arg); 21. } 22.}; 23.#else 24.#include <functional> 25.using std::function; 26.using std::bind; 27.using namespace std::placeholders; 28.#endif 29. 30.#include "MySingleton.h" 31.#include "MyThread.h" 32. 33. 34. 35.class Parameter 36.{ 37.public: 38. #define PARAM_IMPL_INIT(t) Parameter(t para) { m_data = para; } 39. 40.#ifdef WIN32 41. // windows下面类型转换失败抛出异常 42. #define PARAM_IMPL_RET(t, it,value) operator t () { t ret = value; ret = boost::any_cast<it>(m_data); return std::move(ret); }; 43.#else 44. #define PARAM_IMPL_RET(t, it, value) operator t () { t ret = value; try
{ ret = boost::any_cast<it>(m_data); } catch (...) {} return std::move(ret); }; 45.#endif 46. 47. PARAM_IMPL_INIT(int); 48. PARAM_IMPL_INIT(long long); 49. PARAM_IMPL_INIT(double); 50. PARAM_IMPL_INIT(const std::string&); 51. PARAM_IMPL_INIT(boost::any); 52. 53. PARAM_IMPL_RET(bool, int, false); 54. PARAM_IMPL_RET(char, int, 0); 55. PARAM_IMPL_RET(unsigned char, int, 0); 56. PARAM_IMPL_RET(short, int, 0); 57. PARAM_IMPL_RET(unsigned short, int, 0); 58. PARAM_IMPL_RET(int, int, 0); 59. PARAM_IMPL_RET(unsigned int, int, 0); 60. PARAM_IMPL_RET(long, int, 0); 61. PARAM_IMPL_RET(unsigned long, int, 0); 62. PARAM_IMPL_RET(long long, long long, 0); 63. PARAM_IMPL_RET(unsigned long long, long long, 0); 64. PARAM_IMPL_RET(float, double, 0.0f); 65. PARAM_IMPL_RET(double, double, 0.0); 66. PARAM_IMPL_RET(std::string, std::string, ""); 67. 68. Parameter(const char* param) 69. { 70. m_data = std::string(param); 71. } 72. 73. operator boost::any() { 74. return std::move(m_data); 75. } 76.private: 77.// boost::variant<std::string, double, float, int> m_data; 78. boost::any m_data; 79.}; 80. 81.typedef function<void(uint32, Parameter, Parameter, Parameter, Parameter)> FuncCallback; 82.#define LOCK_QUEUE MyLock l(&m_mutex) 83.class CommandQueue : public MySingleton<CommandQueue> 84.{ 85.public: 86. CommandQueue() {}; 87. ~CommandQueue() {}; 88. 89. void registerHandler(uint32 command, FuncCallback callback) 90. { 91. m_eventMap[command] = callback; 92. } 93. 94. void unRegisterHandler(uint32 command) 95. { 96. auto itr = m_eventMap.find(command); 97. if (itr != m_eventMap.end()) 98. { 99. m_eventMap.erase(itr); 100. } 101. } 102. 103. void post(uint32 dwCommand) 104. { 105. COMMAND_DATA cmdData; 106. cmdData.dwCommand = dwCommand; 107. 108. LOCK_QUEUE; 109. m_queue.push_back(std::move(cmdData)); 110. } 111. 112. template<typename Type> 113. void post(uint32 dwCommand, Type data) 114. { 115. COMMAND_DATA cmdData; 116. cmdData.dwCommand = dwCommand; 117. cmdData.parameters.push_back(std::move(data)); 118. 119. LOCK_QUEUE; 120. m_queue.push_back(std::move(cmdData)); 121. }; 122. 123. template<typename Type1, typename Type2> 124. void post(uint32 dwCommand, Type1 data1, Type2 data2) 125. { 126. COMMAND_DATA cmdData; 127. cmdData.dwCommand = dwCommand; 128. cmdData.parameters.push_back(std::move(data1)); 129. cmdData.parameters.push_back(std::move(data2)); 130. 131. LOCK_QUEUE; 132. m_queue.push_back(std::move(cmdData)); 133. }; 134. 135. template<typename Type1, typename Type2, typename Type3> 136. void post(uint32 dwCommand, Type1 data1, Type2 data2, Type3 data3) 137. { 138. COMMAND_DATA cmdData; 139. cmdData.dwCommand = dwCommand; 140. cmdData.parameters = {data1, data2, data3}; 141. 142. LOCK_QUEUE; 143. m_queue.push_back(std::move(cmdData)); 144. }; 145. 146. template<typename Type1, typename Type2, typename Type3, typename Type4> 147. void post(uint32 dwCommand, Type1 data1, Type2 data2, Type3 data3, Type4 data4) 148. { 149. COMMAND_DATA cmdData; 150. cmdData.dwCommand = dwCommand; 151. cmdData.parameters = {data1, data2, data3, data4}; 152. 153. LOCK_QUEUE; 154. m_queue.push_back(cmdData); 155. }; 156. 157. void send(uint32 dwCommand) 158. { 159. auto itr = m_eventMap.find(dwCommand); 160. if (itr != m_eventMap.end()) { 161. itr->second(dwCommand, 0, 0, 0, 0); 162. } 163. }; 164. 165. template<typename Type> 166. void send(uint32 dwCommand, Type data) 167. { 168. auto itr = m_eventMap.find(dwCommand); 169. if (itr != m_eventMap.end()) { 170. itr->second(dwCommand, data, 0, 0, 0); 171. } 172. }; 173. 174. template<typename Type1, typename Type2> 175. void send(uint32 dwCommand, Type1 data1, Type2 data2) 176. { 177. auto itr = m_eventMap.find(dwCommand); 178. if (itr != m_eventMap.end()) { 179. itr->second(dwCommand, data1, data2, 0, 0); 180. } 181. }; 182. 183. template<typename Type1, typename Type2, typename Type3> 184. void send(uint32 dwCommand, Type1 data1, Type2 data2, Type3 data3) 185. { 186. auto itr = m_eventMap.find(dwCommand); 187. if (itr != m_eventMap.end()) { 188. itr->second(dwCommand, data1, data2, data3, 0); 189. } 190. }; 191. 192. template<typename Type1, typename Type2, typename Type3, typename Type4> 193. void send(uint32 dwCommand, Type1 data1, Type2 data2, Type3 data3, Type4 data4) 194. { 195. auto itr = m_eventMap.find(dwCommand); 196. if (itr != m_eventMap.end()) { 197. itr->second(dwCommand, data1, data2, data3, data4); 198. } 199. }; 200. 201. void dispatchAll() 202. { 203. LOCK_QUEUE; 204. while (!m_queue.empty()) { 205. COMMAND_DATA& cmdData = m_queue.front(); 206. int size = cmdData.parameters.size(); 207. auto itrCall = m_eventMap.find(cmdData.dwCommand); 208. switch (size) 209. { 210. case 0: 211. itrCall->second(cmdData.dwCommand, 0, 0, 0, 0); 212. break; 213. case 1: 214. itrCall->second(cmdData.dwCommand, cmdData.parameters[0], 0, 0, 0); 215. break; 216. case 2: 217. itrCall->second(cmdData.dwCommand, cmdData.parameters[0], cmdData.parameters[1], 0, 0); 218. break; 219. case 3: 220. itrCall->second(cmdData.dwCommand, cmdData.parameters[0], cmdData.parameters[1], cmdData.parameters[2], 0); 221. break; 222. case 4: 223. itrCall->second(cmdData.dwCommand, cmdData.parameters[0], cmdData.parameters[1],
cmdData.parameters[2], cmdData.parameters[3]); 224. break; 225. } 226. 227. m_queue.pop_front(); 228. } 229. } 230. 231.private: 232. struct COMMAND_DATA { 233. uint32 dwCommand; 234. std::vector<Parameter> parameters; 235. }; 236. 237. MyMutex m_mutex; // 递归锁,处理多线程异步消息抛送 238. std::deque<COMMAND_DATA> m_queue; // post异步command处理队列(都在主线程处理,每帧结束的时候执行) 239. std::map<uint32, FuncCallback> m_eventMap; // 注册的命令和回调函数映射 240.}; 241. 242.inline void reg_command(uint32 command, FuncCallback callback) 243.{ 244. CommandQueue::getSingleton().registerHandler(command, callback); 245.} 246. 247.inline void unreg_command(uint32 command) 248.{ 249. CommandQueue::getSingleton().unRegisterHandler(command); 250.} 251. 252.inline void post_command(uint32 dwCommand) 253.{ 254. CommandQueue::getSingleton().post(dwCommand); 255.} 256. 257.template<typename Type> 258.inline void post_command(uint32 dwCommand, Type data) 259.{ 260. CommandQueue::getSingleton().post(dwCommand, data); 261.} 262. 263.template<typename Type1, typename Type2> 264.inline void post_command(uint32 dwCommand, Type1 data1, Type2 data2) 265.{ 266. CommandQueue::getSingleton().post(dwCommand, data1, data2); 267.} 268. 269.template<typename Type1, typename Type2, typename Type3> 270.inline void post_command(uint32 dwCommand, Type1 data1, Type2 data2, Type3 data3) 271.{ 272. CommandQueue::getSingleton().post(dwCommand, data1, data2, data3); 273.} 274. 275.template<typename Type1, typename Type2, typename Type3, typename Type4> 276.inline void post_command(uint32 dwCommand, Type1 data1, Type2 data2, Type3 data3, Type4 data4) 277.{ 278. CommandQueue::getSingleton().post(dwCommand, data1, data2, data3, data4); 279.} 280. 281. 282. 283. 284.inline void send_command(uint32 dwCommand) 285.{ 286. CommandQueue::getSingleton().send(dwCommand); 287.} 288. 289.template<typename Type> 290.inline void send_command(uint32 dwCommand, Type data) 291.{ 292. CommandQueue::getSingleton().send(dwCommand, data); 293.} 294. 295.template<typename Type1, typename Type2> 296.inline void send_command(uint32 dwCommand, Type1 data1, Type2 data2) 297.{ 298. CommandQueue::getSingleton().send(dwCommand, data1, data2); 299.} 300. 301.template<typename Type1, typename Type2, typename Type3> 302.inline void send_command(uint32 dwCommand, Type1 data1, Type2 data2, Type3 data3) 303.{ 304. CommandQueue::getSingleton().send(dwCommand, data1, data2, data3); 305.} 306. 307.template<typename Type1, typename Type2, typename Type3, typename Type4> 308.inline void send_command(uint32 dwCommand, Type1 data1, Type2 data2, Type3 data3, Type4 data4) 309.{ 310. CommandQueue::getSingleton().send(dwCommand, data1, data2, data3, data4); 311.}
|