Modificator.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. * Modificator.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 "../GameConstants.h"
  12. #include "../int3.h"
  13. #include "Zone.h"
  14. #include "threadpool/MapProxy.h"
  15. class RmgMap;
  16. class CMapGenerator;
  17. class Zone;
  18. class MapProxy;
  19. #define MODIFICATOR(x) x(Zone & z, RmgMap & m, CMapGenerator & g): Modificator(z, m, g) {setName(#x);}
  20. #define DEPENDENCY(x) dependency(zone.getModificator<x>());
  21. #define POSTFUNCTION(x) postfunction(zone.getModificator<x>());
  22. #define DEPENDENCY_ALL(x) for(auto & z : map.getZones()) \
  23. { \
  24. dependency(z.second->getModificator<x>()); \
  25. }
  26. #define POSTFUNCTION_ALL(x) for(auto & z : map.getZones()) \
  27. { \
  28. postfunction(z.second->getModificator<x>()); \
  29. }
  30. VCMI_LIB_NAMESPACE_BEGIN
  31. class Modificator
  32. {
  33. public:
  34. Modificator() = delete;
  35. Modificator(Zone & zone, RmgMap & map, CMapGenerator & generator);
  36. virtual void init() {/*override to add dependencies*/}
  37. virtual char dump(const int3 &);
  38. virtual ~Modificator() = default;
  39. void setName(const std::string & n);
  40. const std::string & getName() const;
  41. bool isReady();
  42. bool isFinished();
  43. void run();
  44. void dependency(Modificator * modificator);
  45. void postfunction(Modificator * modificator);
  46. protected:
  47. RmgMap & map;
  48. std::shared_ptr<MapProxy> mapProxy;
  49. CMapGenerator & generator;
  50. Zone & zone;
  51. bool finished = false;
  52. mutable boost::recursive_mutex externalAccessMutex; //Used to communicate between Modificators
  53. using RecursiveLock = boost::unique_lock<boost::recursive_mutex>;
  54. using Lock = boost::unique_lock<boost::shared_mutex>;
  55. template <typename TModificator>
  56. std::vector<RecursiveLock> tryLockAll()
  57. {
  58. std::vector<RecursiveLock> locks;
  59. for (auto & zone : map.getZones())
  60. {
  61. if (auto * m = zone.second->getModificator<TModificator>())
  62. {
  63. RecursiveLock lock(m->externalAccessMutex, boost::try_to_lock_t{});
  64. if (lock.owns_lock())
  65. {
  66. locks.emplace_back(std::move(lock));
  67. }
  68. else //return empty
  69. {
  70. return std::vector<RecursiveLock>();
  71. }
  72. }
  73. }
  74. return locks;
  75. }
  76. private:
  77. virtual void process() = 0;
  78. std::string name;
  79. std::list<Modificator*> preceeders; //must be ordered container
  80. mutable boost::shared_mutex mx; //Used only for task scheduling
  81. void dump();
  82. };
  83. VCMI_LIB_NAMESPACE_END