Client.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. * Client.h, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #pragma once
  11. #include <memory>
  12. #include <vcmi/Environment.h>
  13. #include "../lib/callback/IClient.h"
  14. #include "../lib/callback/CGameInfoCallback.h"
  15. #include "../lib/ConditionalWait.h"
  16. #include "../lib/ResourceSet.h"
  17. VCMI_LIB_NAMESPACE_BEGIN
  18. struct CPackForClient;
  19. struct CPackForServer;
  20. class IBattleEventsReceiver;
  21. class CBattleGameInterface;
  22. class CGameInterface;
  23. class BattleAction;
  24. class BattleInfo;
  25. struct BankConfig;
  26. class CCallback;
  27. class CBattleCallback;
  28. #if SCRIPTING_ENABLED
  29. namespace scripting
  30. {
  31. class PoolImpl;
  32. }
  33. #endif
  34. namespace events
  35. {
  36. class EventBus;
  37. }
  38. VCMI_LIB_NAMESPACE_END
  39. class CClient;
  40. class CBaseForCLApply;
  41. template<typename T>
  42. class ThreadSafeVector
  43. {
  44. using TLock = std::unique_lock<std::mutex>;
  45. std::vector<T> items;
  46. std::mutex mx;
  47. std::condition_variable cond;
  48. std::atomic<bool> isTerminating = false;
  49. public:
  50. void requestTermination()
  51. {
  52. isTerminating = true;
  53. clear();
  54. }
  55. void clear()
  56. {
  57. TLock lock(mx);
  58. items.clear();
  59. cond.notify_all();
  60. }
  61. void pushBack(const T & item)
  62. {
  63. assert(!isTerminating);
  64. TLock lock(mx);
  65. items.push_back(item);
  66. cond.notify_all();
  67. }
  68. void waitWhileContains(const T & item)
  69. {
  70. TLock lock(mx);
  71. cond.wait(lock, [this, &item](){ return !vstd::contains(items, item);});
  72. if (isTerminating)
  73. throw TerminationRequestedException();
  74. }
  75. bool tryRemovingElement(const T & item) //returns false if element was not present
  76. {
  77. assert(!isTerminating);
  78. TLock lock(mx);
  79. auto itr = vstd::find(items, item);
  80. if(itr == items.end()) //not in container
  81. {
  82. return false;
  83. }
  84. items.erase(itr);
  85. cond.notify_all();
  86. return true;
  87. }
  88. };
  89. class CPlayerEnvironment : public Environment
  90. {
  91. public:
  92. PlayerColor player;
  93. CClient * cl;
  94. std::shared_ptr<CCallback> mainCallback;
  95. CPlayerEnvironment(PlayerColor player_, CClient * cl_, std::shared_ptr<CCallback> mainCallback_);
  96. const Services * services() const override;
  97. vstd::CLoggerBase * logger() const override;
  98. events::EventBus * eventBus() const override;
  99. const BattleCb * battle(const BattleID & battle) const override;
  100. const GameCb * game() const override;
  101. };
  102. /// Class which handles client - server logic
  103. class CClient : public Environment, public IClient
  104. {
  105. std::shared_ptr<CGameState> gamestate;
  106. int requestCounter = 1;
  107. public:
  108. std::map<PlayerColor, std::shared_ptr<CGameInterface>> playerint;
  109. std::map<PlayerColor, std::shared_ptr<CBattleGameInterface>> battleints;
  110. std::map<PlayerColor, std::vector<std::shared_ptr<IBattleEventsReceiver>>> additionalBattleInts;
  111. std::unique_ptr<BattleAction> currentBattleAction;
  112. CClient();
  113. ~CClient();
  114. const Services * services() const override;
  115. const BattleCb * battle(const BattleID & battle) const override;
  116. const GameCb * game() const override;
  117. vstd::CLoggerBase * logger() const override;
  118. events::EventBus * eventBus() const override;
  119. std::shared_ptr<CGameState> gameStatePtr() { return gamestate; }
  120. CGameState & gameState() { return *gamestate; }
  121. const CGameState & gameState() const { return *gamestate; }
  122. IGameInfoCallback & gameInfo();
  123. void newGame(std::shared_ptr<CGameState> gameState);
  124. void loadGame(std::shared_ptr<CGameState> gameState);
  125. void endNetwork();
  126. void finishGameplay();
  127. void endGame();
  128. void initMapHandler();
  129. void initPlayerEnvironments();
  130. void initPlayerInterfaces();
  131. std::string aiNameForPlayer(const PlayerSettings & ps, bool battleAI, bool alliedToHuman) const; //empty means no AI -> human
  132. std::string aiNameForPlayer(bool battleAI, bool alliedToHuman) const;
  133. void installNewPlayerInterface(std::shared_ptr<CGameInterface> gameInterface, PlayerColor color, bool battlecb = false);
  134. void installNewBattleInterface(std::shared_ptr<CBattleGameInterface> battleInterface, PlayerColor color, bool needCallback = true);
  135. //Set of metrhods that allows adding more interfaces for this player that'll receive game event call-ins.
  136. void registerBattleInterface(std::shared_ptr<IBattleEventsReceiver> battleEvents, PlayerColor color);
  137. void unregisterBattleInterface(std::shared_ptr<IBattleEventsReceiver> battleEvents, PlayerColor color);
  138. ThreadSafeVector<int> waitingRequest;
  139. void handlePack(CPackForClient & pack); //applies the given pack and deletes it
  140. int sendRequest(const CPackForServer & request, PlayerColor player, bool waitTillRealize) override; //returns ID given to that request
  141. std::optional<BattleAction> makeSurrenderRetreatDecision(PlayerColor player, const BattleID & battleID, const BattleStateInfoForRetreat & battleState) override;
  142. void battleStarted(const BattleID & battle);
  143. void battleFinished(const BattleID & battleID);
  144. void startPlayerBattleAction(const BattleID & battleID, PlayerColor color);
  145. friend class CCallback; //handling players actions
  146. friend class CBattleCallback; //handling players actions
  147. void removeGUI() const;
  148. private:
  149. std::map<PlayerColor, std::shared_ptr<CBattleCallback>> battleCallbacks; //callbacks given to player interfaces
  150. std::map<PlayerColor, std::shared_ptr<CPlayerEnvironment>> playerEnvironments;
  151. #if SCRIPTING_ENABLED
  152. std::shared_ptr<scripting::PoolImpl> clientScripts;
  153. #endif
  154. std::unique_ptr<events::EventBus> clientEventBus;
  155. void reinitScripting();
  156. };