Client.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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. public:
  107. std::map<PlayerColor, std::shared_ptr<CGameInterface>> playerint;
  108. std::map<PlayerColor, std::shared_ptr<CBattleGameInterface>> battleints;
  109. std::map<PlayerColor, std::vector<std::shared_ptr<IBattleEventsReceiver>>> additionalBattleInts;
  110. std::unique_ptr<BattleAction> currentBattleAction;
  111. CClient();
  112. ~CClient();
  113. const Services * services() const override;
  114. const BattleCb * battle(const BattleID & battle) const override;
  115. const GameCb * game() const override;
  116. vstd::CLoggerBase * logger() const override;
  117. events::EventBus * eventBus() const override;
  118. CGameState & gameState() { return *gamestate; }
  119. const CGameState & gameState() const { return *gamestate; }
  120. IGameInfoCallback & gameInfo();
  121. void newGame(std::shared_ptr<CGameState> gameState);
  122. void loadGame(std::shared_ptr<CGameState> gameState);
  123. void endNetwork();
  124. void finishGameplay();
  125. void endGame();
  126. void initMapHandler();
  127. void initPlayerEnvironments();
  128. void initPlayerInterfaces();
  129. std::string aiNameForPlayer(const PlayerSettings & ps, bool battleAI, bool alliedToHuman) const; //empty means no AI -> human
  130. std::string aiNameForPlayer(bool battleAI, bool alliedToHuman) const;
  131. void installNewPlayerInterface(std::shared_ptr<CGameInterface> gameInterface, PlayerColor color, bool battlecb = false);
  132. void installNewBattleInterface(std::shared_ptr<CBattleGameInterface> battleInterface, PlayerColor color, bool needCallback = true);
  133. //Set of metrhods that allows adding more interfaces for this player that'll receive game event call-ins.
  134. void registerBattleInterface(std::shared_ptr<IBattleEventsReceiver> battleEvents, PlayerColor color);
  135. void unregisterBattleInterface(std::shared_ptr<IBattleEventsReceiver> battleEvents, PlayerColor color);
  136. ThreadSafeVector<int> waitingRequest;
  137. void handlePack(CPackForClient & pack); //applies the given pack and deletes it
  138. int sendRequest(const CPackForServer & request, PlayerColor player, bool waitTillRealize) override; //returns ID given to that request
  139. std::optional<BattleAction> makeSurrenderRetreatDecision(PlayerColor player, const BattleID & battleID, const BattleStateInfoForRetreat & battleState) override;
  140. void battleStarted(const BattleID & battle);
  141. void battleFinished(const BattleID & battleID);
  142. void startPlayerBattleAction(const BattleID & battleID, PlayerColor color);
  143. friend class CCallback; //handling players actions
  144. friend class CBattleCallback; //handling players actions
  145. void removeGUI() const;
  146. private:
  147. std::map<PlayerColor, std::shared_ptr<CBattleCallback>> battleCallbacks; //callbacks given to player interfaces
  148. std::map<PlayerColor, std::shared_ptr<CPlayerEnvironment>> playerEnvironments;
  149. #if SCRIPTING_ENABLED
  150. std::shared_ptr<scripting::PoolImpl> clientScripts;
  151. #endif
  152. std::unique_ptr<events::EventBus> clientEventBus;
  153. void reinitScripting();
  154. };