CCConsole.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /****************************************************************************
  2. Copyright (c) 2013-2016 Chukong Technologies Inc.
  3. Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
  4. http://www.cocos2d-x.org
  5. Permission is hereby granted, free of charge, to any person obtaining a copy
  6. of this software and associated documentation files (the "Software"), to deal
  7. in the Software without restriction, including without limitation the rights
  8. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. copies of the Software, and to permit persons to whom the Software is
  10. furnished to do so, subject to the following conditions:
  11. The above copyright notice and this permission notice shall be included in
  12. all copies or substantial portions of the Software.
  13. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. THE SOFTWARE.
  20. ****************************************************************************/
  21. #ifndef __CCCONSOLE_H__
  22. #define __CCCONSOLE_H__
  23. /// @cond DO_NOT_SHOW
  24. #if defined(_MSC_VER) || defined(__MINGW32__)
  25. #include <BaseTsd.h>
  26. #include <WinSock2.h>
  27. #ifndef __SSIZE_T
  28. #define __SSIZE_T
  29. typedef SSIZE_T ssize_t;
  30. #endif // __SSIZE_T
  31. #else
  32. #include <sys/select.h>
  33. #endif
  34. #include <thread>
  35. #include <vector>
  36. #include <unordered_map>
  37. #include <functional>
  38. #include <string>
  39. #include <mutex>
  40. #include <stdarg.h>
  41. #include "base/CCRef.h"
  42. #include "base/ccMacros.h"
  43. #include "platform/CCPlatformMacros.h"
  44. NS_CC_BEGIN
  45. /// The max length of CCLog message.
  46. static const int MAX_LOG_LENGTH = 16*1024;
  47. /**
  48. @brief Output Debug message.
  49. */
  50. void CC_DLL log(const char * format, ...) CC_FORMAT_PRINTF(1, 2);
  51. /** Console is helper class that lets the developer control the game from TCP connection.
  52. Console will spawn a new thread that will listen to a specified TCP port.
  53. Console has a basic token parser. Each token is associated with an std::function<void(int)>.
  54. If the std::function<> needs to use the cocos2d API, it needs to call
  55. ```
  56. scheduler->performFunctionInCocosThread( ... );
  57. ```
  58. */
  59. class CC_DLL Console
  60. : public Ref
  61. {
  62. public:
  63. /** Console Utils */
  64. class Utility {
  65. public:
  66. // Trimming functions
  67. static std::string& ltrim(std::string& s);
  68. static std::string& rtrim(std::string& s);
  69. static std::string& trim(std::string& s);
  70. // split
  71. static std::vector<std::string>& split(const std::string& s, char delim, std::vector<std::string>& elems);
  72. static std::vector<std::string> split(const std::string& s, char delim);
  73. /** Checks myString is a floating-point type. */
  74. static bool isFloat(const std::string& myString);
  75. /** send a message to console */
  76. static ssize_t sendToConsole(int fd, const void* buffer, size_t length, int flags = 0);
  77. /** my dprintf() */
  78. static ssize_t mydprintf(int sock, const char *format, ...);
  79. /** send prompt string to console */
  80. static void sendPrompt(int fd);
  81. /** set a new string for the prompt. */
  82. static void setPrompt(const std::string &prompt);
  83. /** get the prompt string. */
  84. static const std::string& getPrompt();
  85. private:
  86. static std::string _prompt; /*!< prompt */
  87. };
  88. /** Command Struct */
  89. class CC_DLL Command
  90. {
  91. public:
  92. using Callback = std::function<void(int fd, const std::string& args)>;
  93. /** Constructor */
  94. Command();
  95. Command(const std::string& name, const std::string& help);
  96. Command(const std::string& name, const std::string& help, const Callback& callback);
  97. /** Copy constructor */
  98. Command(const Command& o);
  99. /** Move constructor */
  100. Command(Command&& o);
  101. /** Destructor */
  102. ~Command();
  103. /** Copy operator */
  104. Command& operator=(const Command& o);
  105. /** Move operator */
  106. Command& operator=(Command&& o);
  107. /** add callback */
  108. void addCallback(const Callback& callback);
  109. /** add sub command */
  110. void addSubCommand(const Command& subCmd);
  111. /** get sub command */
  112. const Command* getSubCommand(const std::string& subCmdName) const;
  113. /** delete sub command */
  114. void delSubCommand(const std::string& subCmdName);
  115. /** help command handler */
  116. void commandHelp(int fd, const std::string& args);
  117. /** generic command handler */
  118. void commandGeneric(int fd, const std::string& args);
  119. /** Gets the name of the current command */
  120. const std::string& getName() const { return _name; }
  121. /** Gets the help information of the current command */
  122. const std::string& getHelp() const { return _help; }
  123. private:
  124. std::string _name;
  125. std::string _help;
  126. Callback _callback;
  127. std::unordered_map<std::string, Command*> _subCommands;
  128. };
  129. /** Constructor */
  130. Console();
  131. /** Destructor */
  132. virtual ~Console();
  133. /** starts listening to specified TCP port */
  134. bool listenOnTCP(int port);
  135. /** starts listening to specified file descriptor */
  136. bool listenOnFileDescriptor(int fd);
  137. /** stops the Console. 'stop' will be called at destruction time as well */
  138. void stop();
  139. /** add custom command */
  140. void addCommand(const Command& cmd);
  141. void addSubCommand(const std::string& cmdName, const Command& subCmd);
  142. void addSubCommand(Command& cmd, const Command& subCmd);
  143. /** get custom command */
  144. const Command* getCommand(const std::string& cmdName);
  145. const Command* getSubCommand(const std::string& cmdName, const std::string& subCmdName);
  146. const Command* getSubCommand(const Command& cmd, const std::string& subCmdName);
  147. /** delete custom command */
  148. void delCommand(const std::string& cmdName);
  149. void delSubCommand(const std::string& cmdName, const std::string& subCmdName);
  150. void delSubCommand(Command& cmd, const std::string& subCmdName);
  151. /** log something in the console */
  152. void log(const char *buf);
  153. /**
  154. * set bind address
  155. *
  156. * @address : 127.0.0.1
  157. */
  158. void setBindAddress(const std::string &address);
  159. /** Checks whether the server for console is bound with ipv6 address */
  160. bool isIpv6Server() const;
  161. /** The command separator */
  162. CC_SYNTHESIZE(char, _commandSeparator, CommandSeparator);
  163. protected:
  164. // Main Loop
  165. void loop();
  166. // Helpers
  167. ssize_t readline(int fd, char *buf, size_t maxlen);
  168. ssize_t readBytes(int fd, char* buffer, size_t maxlen, bool* more);
  169. bool parseCommand(int fd);
  170. void performCommand(int fd, const std::string& command);
  171. void addClient();
  172. // create a map of command.
  173. void createCommandAllocator();
  174. void createCommandConfig();
  175. void createCommandDebugMsg();
  176. void createCommandDirector();
  177. void createCommandExit();
  178. void createCommandFileUtils();
  179. void createCommandFps();
  180. void createCommandHelp();
  181. void createCommandProjection();
  182. void createCommandResolution();
  183. void createCommandSceneGraph();
  184. void createCommandTexture();
  185. void createCommandTouch();
  186. void createCommandUpload();
  187. void createCommandVersion();
  188. // Add commands here
  189. void commandAllocator(int fd, const std::string& args);
  190. void commandConfig(int fd, const std::string& args);
  191. void commandDebugMsg(int fd, const std::string& args);
  192. void commandDebugMsgSubCommandOnOff(int fd, const std::string& args);
  193. void commandDirectorSubCommandPause(int fd, const std::string& args);
  194. void commandDirectorSubCommandResume(int fd, const std::string& args);
  195. void commandDirectorSubCommandStop(int fd, const std::string& args);
  196. void commandDirectorSubCommandStart(int fd, const std::string& args);
  197. void commandDirectorSubCommandEnd(int fd, const std::string& args);
  198. void commandExit(int fd, const std::string& args);
  199. void commandFileUtils(int fd, const std::string& args);
  200. void commandFileUtilsSubCommandFlush(int fd, const std::string& args);
  201. void commandFps(int fd, const std::string& args);
  202. void commandFpsSubCommandOnOff(int fd, const std::string& args);
  203. void commandHelp(int fd, const std::string& args);
  204. void commandProjection(int fd, const std::string& args);
  205. void commandProjectionSubCommand2d(int fd, const std::string& args);
  206. void commandProjectionSubCommand3d(int fd, const std::string& args);
  207. void commandResolution(int fd, const std::string& args);
  208. void commandResolutionSubCommandEmpty(int fd, const std::string& args);
  209. void commandSceneGraph(int fd, const std::string& args);
  210. void commandTextures(int fd, const std::string& args);
  211. void commandTexturesSubCommandFlush(int fd, const std::string& args);
  212. void commandTouchSubCommandTap(int fd, const std::string& args);
  213. void commandTouchSubCommandSwipe(int fd, const std::string& args);
  214. void commandUpload(int fd);
  215. void commandVersion(int fd, const std::string& args);
  216. // file descriptor: socket, console, etc.
  217. int _listenfd;
  218. int _maxfd;
  219. std::vector<int> _fds;
  220. std::thread _thread;
  221. fd_set _read_set;
  222. bool _running;
  223. bool _endThread;
  224. bool _isIpv6Server;
  225. std::unordered_map<std::string, Command*> _commands;
  226. // strings generated by cocos2d sent to the remote console
  227. bool _sendDebugStrings;
  228. std::mutex _DebugStringsMutex;
  229. std::vector<std::string> _DebugStrings;
  230. intptr_t _touchId;
  231. std::string _bindAddress;
  232. private:
  233. CC_DISALLOW_COPY_AND_ASSIGN(Console);
  234. // helper functions
  235. int printSceneGraph(int fd, Node* node, int level);
  236. void printSceneGraphBoot(int fd);
  237. void printFileUtils(int fd);
  238. /** send help message to console */
  239. static void sendHelp(int fd, const std::unordered_map<std::string, Command*>& commands, const char* msg);
  240. };
  241. NS_CC_END
  242. /// @endcond
  243. #endif /* defined(__CCCONSOLE_H__) */