RemoteConsoleCore.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #include <AzCore/Socket/AzSocket_fwd.h>
  10. #include <AzCore/std/containers/map.h>
  11. #include <AzCore/std/containers/list.h>
  12. #include <AzCore/std/containers/vector.h>
  13. #include <AzCore/std/parallel/condition_variable.h>
  14. #include <AzCore/std/parallel/mutex.h>
  15. #include <AzCore/std/parallel/thread.h>
  16. #include <AzCore/std/string/string.h>
  17. extern const int defaultRemoteConsolePort;
  18. /////////////////////////////////////////////////////////////////////////////////////////////
  19. // IRemoteEvent
  20. //
  21. // remote events
  22. // EConsoleEventType must be unique, also make sure order is same on clients!
  23. // each package starts with ASCII ['0' + EConsoleEventType]
  24. // not more supported than 256 - '0'!
  25. //
  26. /////////////////////////////////////////////////////////////////////////////////////////////
  27. enum EConsoleEventType
  28. {
  29. eCET_Noop = 0,
  30. eCET_Req,
  31. eCET_LogMessage,
  32. eCET_LogWarning,
  33. eCET_LogError,
  34. eCET_ConsoleCommand,
  35. eCET_AutoCompleteList,
  36. eCET_AutoCompleteListDone,
  37. eCET_Strobo_GetThreads,
  38. eCET_Strobo_ThreadAdd,
  39. eCET_Strobo_ThreadDone,
  40. eCET_Strobo_GetResult,
  41. eCET_Strobo_ResultStart,
  42. eCET_Strobo_ResultDone,
  43. eCET_Strobo_StatStart,
  44. eCET_Strobo_StatAdd,
  45. eCET_Strobo_ThreadInfoStart,
  46. eCET_Strobo_ThreadInfoAdd,
  47. eCET_Strobo_SymStart,
  48. eCET_Strobo_SymAdd,
  49. eCET_Strobo_CallstackStart,
  50. eCET_Strobo_CallstackAdd,
  51. eCET_GameplayEvent,
  52. eCET_Strobo_FrameInfoStart,
  53. eCET_Strobo_FrameInfoAdd,
  54. eCET_ConnectMessage,
  55. };
  56. struct SRemoteEventFactory;
  57. struct IRemoteEvent
  58. {
  59. virtual ~IRemoteEvent() {}
  60. IRemoteEvent(EConsoleEventType type)
  61. : m_type(type) {}
  62. EConsoleEventType GetType() const { return m_type; }
  63. virtual IRemoteEvent* Clone() = 0;
  64. protected:
  65. friend struct SRemoteEventFactory;
  66. virtual void WriteToBuffer(char* buffer, int& size, int maxsize) = 0;
  67. virtual IRemoteEvent* CreateFromBuffer(const char* buffer, int size) = 0;
  68. private:
  69. EConsoleEventType m_type;
  70. };
  71. /////////////////////////////////////////////////////////////////////////////////////////////
  72. // Event implementations
  73. //
  74. // implementations for simple data packages
  75. //
  76. /////////////////////////////////////////////////////////////////////////////////////////////
  77. template <EConsoleEventType T>
  78. struct SNoDataEvent
  79. : public IRemoteEvent
  80. {
  81. SNoDataEvent()
  82. : IRemoteEvent(T) {};
  83. IRemoteEvent* Clone() override { return new SNoDataEvent<T>(); }
  84. protected:
  85. void WriteToBuffer([[maybe_unused]] char* buffer, int& size, [[maybe_unused]] int maxsize) override { size = 0; }
  86. IRemoteEvent* CreateFromBuffer([[maybe_unused]] const char* buffer, [[maybe_unused]] int size) override { return Clone(); }
  87. };
  88. /////////////////////////////////////////////////////////////////////////////////////////////
  89. template <EConsoleEventType T>
  90. struct SStringEvent
  91. : public IRemoteEvent
  92. {
  93. SStringEvent(AZStd::string_view data)
  94. : IRemoteEvent(T)
  95. , m_data(data) {};
  96. IRemoteEvent* Clone() override { return new SStringEvent<T>(GetData()); }
  97. const char* GetData() const { return m_data.c_str(); }
  98. protected:
  99. void WriteToBuffer(char* buffer, int& size, int maxsize) override
  100. {
  101. const char* data = GetData();
  102. size = min((int)strlen(data), maxsize);
  103. memcpy(buffer, data, size);
  104. }
  105. IRemoteEvent* CreateFromBuffer(const char* buffer, [[maybe_unused]] int size) override { return new SStringEvent<T>(buffer); }
  106. private:
  107. AZStd::string m_data;
  108. };
  109. /////////////////////////////////////////////////////////////////////////////////////////////
  110. // SRemoteEventFactory
  111. //
  112. // remote event factory
  113. //
  114. /////////////////////////////////////////////////////////////////////////////////////////////
  115. struct SRemoteEventFactory
  116. {
  117. static SRemoteEventFactory* GetInst() { static SRemoteEventFactory inst; return &inst; }
  118. IRemoteEvent* CreateEventFromBuffer(const char* buffer, int size);
  119. void WriteToBuffer(IRemoteEvent* pEvent, char* buffer, int& size, int maxsize);
  120. private:
  121. SRemoteEventFactory();
  122. ~SRemoteEventFactory();
  123. void RegisterEvent(IRemoteEvent* pEvent);
  124. private:
  125. typedef AZStd::map<EConsoleEventType, IRemoteEvent*> TPrototypes;
  126. TPrototypes m_prototypes;
  127. };
  128. typedef AZStd::list<IRemoteEvent*> TEventBuffer;
  129. /////////////////////////////////////////////////////////////////////////////////////////////
  130. // SRemoteThreadedObject
  131. //
  132. // Simple runnable-like threaded object
  133. //
  134. /////////////////////////////////////////////////////////////////////////////////////////////
  135. struct SRemoteThreadedObject
  136. {
  137. virtual ~SRemoteThreadedObject() = default;
  138. void Start(const char* name);
  139. void WaitForThread();
  140. virtual void Run() = 0;
  141. virtual void Terminate() = 0;
  142. private:
  143. void ThreadFunction();
  144. AZStd::thread m_thread;
  145. };
  146. /////////////////////////////////////////////////////////////////////////////////////////////
  147. // SRemoteServer
  148. //
  149. // Server thread
  150. //
  151. /////////////////////////////////////////////////////////////////////////////////////////////
  152. struct SRemoteClient;
  153. struct SRemoteServer
  154. : public SRemoteThreadedObject
  155. {
  156. SRemoteServer()
  157. : m_socket(AZ_SOCKET_INVALID) {}
  158. void StartServer();
  159. void StopServer();
  160. void AddEvent(IRemoteEvent* pEvent);
  161. void GetEvents(TEventBuffer& buffer);
  162. void Terminate() override;
  163. void Run() override;
  164. private:
  165. bool WriteBuffer(SRemoteClient* pClient, char* buffer, int& size);
  166. bool ReadBuffer(const char* buffer, int data);
  167. void ClientDone(SRemoteClient* pClient);
  168. private:
  169. struct SRemoteClientInfo
  170. {
  171. SRemoteClientInfo(SRemoteClient* client)
  172. : pClient(client)
  173. , pEvents(new TEventBuffer) {}
  174. SRemoteClient* pClient;
  175. TEventBuffer* pEvents;
  176. };
  177. typedef AZStd::vector<SRemoteClientInfo> TClients;
  178. TClients m_clients;
  179. AZSOCKET m_socket;
  180. AZStd::recursive_mutex m_mutex;
  181. TEventBuffer m_eventBuffer;
  182. AZStd::condition_variable_any m_stopCondition;
  183. volatile bool m_bAcceptClients;
  184. friend struct SRemoteClient;
  185. };
  186. /////////////////////////////////////////////////////////////////////////////////////////////
  187. // SRemoteClient
  188. //
  189. // Client thread
  190. //
  191. /////////////////////////////////////////////////////////////////////////////////////////////
  192. struct SRemoteClient
  193. : public SRemoteThreadedObject
  194. {
  195. SRemoteClient(SRemoteServer* pServer)
  196. : m_pServer(pServer)
  197. , m_socket(AZ_SOCKET_INVALID) {}
  198. void StartClient(AZSOCKET socket);
  199. void StopClient();
  200. void Terminate() override;
  201. void Run() override;
  202. private:
  203. bool RecvPackage(char* buffer, int& size);
  204. bool SendPackage(const char* buffer, int size);
  205. void FillAutoCompleteList(AZStd::vector<AZStd::string>& list);
  206. private:
  207. SRemoteServer* m_pServer;
  208. AZSOCKET m_socket;
  209. };