IPCServerApp.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #include <Atomic/IO/Log.h>
  2. #include <Atomic/IO/FileSystem.h>
  3. #include <Atomic/IPC/IPCEvents.h>
  4. #include <Atomic/IPC/IPCBroker.h>
  5. #include <AtomicApp/Player/IPCPlayerAppEvents.h>
  6. #include <Atomic/Input/InputEvents.h>
  7. #include "IPCServerApp.h"
  8. #ifdef ATOMIC_PLATFORM_WINDOWS
  9. // PostMessage/PostMessageA windows macro introduced through AppBase.h
  10. #pragma push_macro("UndefPostMessage")
  11. #undef PostMessage
  12. #endif
  13. namespace Atomic
  14. {
  15. IPCServerApp::IPCServerApp(Context* context) :
  16. AppBase(context)
  17. {
  18. }
  19. IPCServerApp::~IPCServerApp()
  20. {
  21. }
  22. void IPCServerApp::Setup()
  23. {
  24. AppBase::Setup();
  25. // Register IPC system
  26. context_->RegisterSubsystem(new IPC(context_));
  27. engineParameters_["Headless"] = true;
  28. engineParameters_["LogLevel"] = LOG_INFO;
  29. }
  30. void IPCServerApp::Stop()
  31. {
  32. IPC* ipc = GetSubsystem<IPC>();
  33. if (ipc)
  34. {
  35. ipc->Shutdown();
  36. }
  37. AppBase::Stop();
  38. }
  39. bool IPCServerApp::RunIPCClient(const String& projectName, const String& projectPath, const String &addArgs)
  40. {
  41. if (clientBroker_.NotNull())
  42. return false;
  43. FileSystem* fileSystem = GetSubsystem<FileSystem>();
  44. String projectAssembly = projectName + ".dll";
  45. String projectExe = projectName + ".exe";
  46. String clientBinary = "";
  47. String resourcePath = projectPath + "Resources/" + projectAssembly;
  48. // TODO: We need to configure project as managed
  49. if (fileSystem->FileExists(resourcePath))
  50. {
  51. #ifdef ATOMIC_DEV_BUILD
  52. #ifdef ATOMIC_DEBUG
  53. clientBinary = projectPath + "AtomicNET/Debug/Bin/Desktop/" + projectExe;
  54. #else
  55. clientBinary = projectPath + "AtomicNET/Release/Bin/Desktop/" + projectExe;
  56. #endif
  57. #else
  58. // TODO: We are using the release build of the managed project here, how and when to use debug?
  59. clientBinary = projectPath + "AtomicNET/Release/Bin/Desktop/" + projectExe;
  60. #endif
  61. if (!fileSystem->FileExists(clientBinary))
  62. {
  63. ATOMIC_LOGERRORF("Managed client: %s does not exist", clientBinary.CString());
  64. return false;
  65. }
  66. }
  67. else
  68. {
  69. return false;
  70. }
  71. Vector<String> vargs;
  72. String args = ToString("--project \"%s\"", projectPath.CString());
  73. vargs = args.Split(' ');
  74. #ifdef ATOMIC_DEV_BUILD
  75. vargs.Insert(0, ToString("\"%s/Resources/\"", ATOMIC_ROOT_SOURCE_DIR));
  76. #else
  77. #ifdef ATOMIC_PLATFORM_OSX
  78. vargs.Insert(0, ToString("\"%s\"", (fileSystem->GetProgramDir() + "../Resources/").CString()));
  79. #else
  80. vargs.Insert(0, ToString("\"%s\"", (fileSystem->GetProgramDir() + "Resources/").CString()));
  81. #endif
  82. #endif
  83. vargs.Insert(0, "--resourcePrefix");
  84. if (addArgs.Length() > 0)
  85. vargs.Insert(0, addArgs.Split(' '));
  86. String dump;
  87. dump.Join(vargs, " ");
  88. ATOMIC_LOGINFOF("Launching Broker %s %s", clientBinary.CString(), dump.CString());
  89. IPC* ipc = GetSubsystem<IPC>();
  90. clientBroker_ = ipc->SpawnWorker(clientBinary, vargs);
  91. if (clientBroker_)
  92. {
  93. SubscribeToEvent(clientBroker_, E_IPCWORKERSTART, ATOMIC_HANDLER(IPCServerApp, HandleIPCWorkerStarted));
  94. SubscribeToEvent(clientBroker_, E_IPCWORKEREXIT, ATOMIC_HANDLER(IPCServerApp, HandleIPCWorkerExit));
  95. SubscribeToEvent(clientBroker_, E_IPCWORKERLOG, ATOMIC_HANDLER(IPCServerApp, HandleIPCWorkerLog));
  96. }
  97. return clientBroker_.NotNull();
  98. }
  99. void IPCServerApp::HandleIPCWorkerStarted(StringHash eventType, VariantMap& eventData)
  100. {
  101. VariantMap startupData;
  102. clientBroker_->PostMessage(E_IPCINITIALIZE, startupData);
  103. }
  104. void IPCServerApp::HandleIPCWorkerExit(StringHash eventType, VariantMap& eventData)
  105. {
  106. if (eventData[IPCWorkerExit::P_BROKER] == clientBroker_)
  107. {
  108. clientBroker_ = 0;
  109. UnsubscribeFromEvent(E_IPCWORKERSTART);
  110. UnsubscribeFromEvent(E_IPCPLAYERPAUSERESUMEREQUEST);
  111. UnsubscribeFromEvent(E_IPCPLAYERUPDATESPAUSEDRESUMED);
  112. UnsubscribeFromEvent(E_IPCPLAYERPAUSESTEPREQUEST);
  113. UnsubscribeFromEvent(E_IPCPLAYEREXITREQUEST);
  114. }
  115. else
  116. {
  117. ATOMIC_LOGERROR("IPCServerApp::HandleIPCWorkerExit - Unknown Broker");
  118. }
  119. }
  120. void IPCServerApp::HandleIPCWorkerLog(StringHash eventType, VariantMap& eventData)
  121. {
  122. using namespace IPCWorkerLog;
  123. VariantMap playerLogData;
  124. playerLogData["message"] = eventData[P_MESSAGE].GetString();
  125. playerLogData["level"] = eventData[P_LEVEL].GetInt();
  126. }
  127. void IPCServerApp::RequestTogglePlayerUpdatesPaused()
  128. {
  129. if (!clientBroker_)
  130. {
  131. return;
  132. }
  133. VariantMap noEventData;
  134. clientBroker_->PostMessage(E_PAUSERESUMEREQUESTED, noEventData);
  135. }
  136. void IPCServerApp::RequestPlayerPauseStep()
  137. {
  138. if (!clientBroker_)
  139. {
  140. return;
  141. }
  142. VariantMap noEventData;
  143. clientBroker_->PostMessage(E_PAUSESTEPREQUESTED, noEventData);
  144. }
  145. void IPCServerApp::RequestPlayerExit()
  146. {
  147. if (!clientBroker_)
  148. {
  149. return;
  150. }
  151. VariantMap noEventData;
  152. clientBroker_->PostMessage(E_EXITREQUESTED, noEventData);
  153. }
  154. }
  155. #ifdef ATOMIC_PLATFORM_WINDOWS
  156. #pragma pop_macro("UndefPostMessage")
  157. #endif