mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-26 08:41:13 +02:00
103 lines
2.4 KiB
C++
103 lines
2.4 KiB
C++
/*
|
|
* 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<x>());
|
|
#define POSTFUNCTION(x) postfunction(zone.getModificator<x>());
|
|
#define DEPENDENCY_ALL(x) for(auto & z : map.getZones()) \
|
|
{ \
|
|
dependency(z.second->getModificator<x>()); \
|
|
}
|
|
#define POSTFUNCTION_ALL(x) for(auto & z : map.getZones()) \
|
|
{ \
|
|
postfunction(z.second->getModificator<x>()); \
|
|
}
|
|
|
|
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> mapProxy;
|
|
CMapGenerator & generator;
|
|
Zone & zone;
|
|
|
|
bool finished = false;
|
|
|
|
mutable boost::recursive_mutex externalAccessMutex; //Used to communicate between Modificators
|
|
using RecursiveLock = boost::unique_lock<boost::recursive_mutex>;
|
|
using Lock = boost::unique_lock<boost::shared_mutex>;
|
|
|
|
template <typename TModificator>
|
|
std::vector<RecursiveLock> tryLockAll()
|
|
{
|
|
std::vector<RecursiveLock> locks;
|
|
for (auto & zone : map.getZones())
|
|
{
|
|
if (auto * m = zone.second->getModificator<TModificator>())
|
|
{
|
|
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<RecursiveLock>();
|
|
}
|
|
}
|
|
}
|
|
return locks;
|
|
}
|
|
|
|
private:
|
|
virtual void process() = 0;
|
|
|
|
std::string name;
|
|
|
|
std::list<Modificator*> preceeders; //must be ordered container
|
|
|
|
mutable boost::shared_mutex mx; //Used only for task scheduling
|
|
|
|
void dump();
|
|
};
|
|
|
|
VCMI_LIB_NAMESPACE_END |