/* * Modificator.h, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * * License: GNU General Public License v2.0 or later * Full text of license available in license.txt file, in main folder * */ #pragma once #include "../GameConstants.h" #include "../int3.h" #include "Zone.h" #include "threadpool/MapProxy.h" class RmgMap; class CMapGenerator; class Zone; class MapProxy; #define MODIFICATOR(x) x(Zone & z, RmgMap & m, CMapGenerator & g): Modificator(z, m, g) {setName(#x);} #define DEPENDENCY(x) dependency(zone.getModificator()); #define POSTFUNCTION(x) postfunction(zone.getModificator()); #define DEPENDENCY_ALL(x) for(auto & z : map.getZones()) \ { \ dependency(z.second->getModificator()); \ } #define POSTFUNCTION_ALL(x) for(auto & z : map.getZones()) \ { \ postfunction(z.second->getModificator()); \ } VCMI_LIB_NAMESPACE_BEGIN class Modificator { public: Modificator() = delete; Modificator(Zone & zone, RmgMap & map, CMapGenerator & generator); virtual void init() {/*override to add dependencies*/} virtual char dump(const int3 &); virtual ~Modificator() = default; void setName(const std::string & n); const std::string & getName() const; bool isReady(); bool isFinished(); void run(); void dependency(Modificator * modificator); void postfunction(Modificator * modificator); protected: RmgMap & map; std::shared_ptr mapProxy; CMapGenerator & generator; Zone & zone; bool finished = false; mutable boost::recursive_mutex externalAccessMutex; //Used to communicate between Modificators using RecursiveLock = boost::unique_lock; using Lock = boost::unique_lock; template std::vector tryLockAll() { std::vector locks; for (auto & zone : map.getZones()) { if (auto * m = zone.second->getModificator()) { RecursiveLock lock(m->externalAccessMutex, boost::try_to_lock_t{}); if (lock.owns_lock()) { locks.emplace_back(std::move(lock)); } else //return empty { return std::vector(); } } } return locks; } private: virtual void process() = 0; std::string name; std::list preceeders; //must be ordered container mutable boost::shared_mutex mx; //Used only for task scheduling void dump(); }; VCMI_LIB_NAMESPACE_END