1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

vcmi: split selectors from HeroBonus.h

This commit is contained in:
Konstantin 2023-04-30 22:55:04 +03:00
parent 29c76fb9bf
commit 3df5a8e415
9 changed files with 251 additions and 214 deletions

View File

@ -29,6 +29,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/bonuses/BonusList.cpp
${MAIN_LIB_DIR}/bonuses/BonusParams.cpp
${MAIN_LIB_DIR}/bonuses/BonusSelector.cpp
${MAIN_LIB_DIR}/bonuses/CBonusProxy.cpp
${MAIN_LIB_DIR}/bonuses/CBonusSystemNode.cpp
${MAIN_LIB_DIR}/bonuses/HeroBonus.cpp
@ -311,6 +312,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/bonuses/BonusList.h
${MAIN_LIB_DIR}/bonuses/BonusParams.h
${MAIN_LIB_DIR}/bonuses/BonusSelector.h
${MAIN_LIB_DIR}/bonuses/CBonusProxy.h
${MAIN_LIB_DIR}/bonuses/CBonusSystemNode.h
${MAIN_LIB_DIR}/bonuses/HeroBonus.h

View File

@ -10,6 +10,7 @@
#pragma once
#include "HeroBonus.h"
#include "BonusSelector.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -11,6 +11,7 @@
#include "StdInc.h"
#include "BonusParams.h"
#include "BonusSelector.h"
#include "../ResourceSet.h"

View File

@ -0,0 +1,89 @@
/*
* BonusSelector.cpp, 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
*
*/
#include "StdInc.h"
#include "BonusSelector.h"
VCMI_LIB_NAMESPACE_BEGIN
namespace Selector
{
DLL_LINKAGE CSelectFieldEqual<Bonus::BonusType> & type()
{
static CSelectFieldEqual<Bonus::BonusType> stype(&Bonus::type);
return stype;
}
DLL_LINKAGE CSelectFieldEqual<TBonusSubtype> & subtype()
{
static CSelectFieldEqual<TBonusSubtype> ssubtype(&Bonus::subtype);
return ssubtype;
}
DLL_LINKAGE CSelectFieldEqual<CAddInfo> & info()
{
static CSelectFieldEqual<CAddInfo> sinfo(&Bonus::additionalInfo);
return sinfo;
}
DLL_LINKAGE CSelectFieldEqual<Bonus::BonusSource> & sourceType()
{
static CSelectFieldEqual<Bonus::BonusSource> ssourceType(&Bonus::source);
return ssourceType;
}
DLL_LINKAGE CSelectFieldEqual<Bonus::BonusSource> & targetSourceType()
{
static CSelectFieldEqual<Bonus::BonusSource> ssourceType(&Bonus::targetSourceType);
return ssourceType;
}
DLL_LINKAGE CSelectFieldEqual<Bonus::LimitEffect> & effectRange()
{
static CSelectFieldEqual<Bonus::LimitEffect> seffectRange(&Bonus::effectRange);
return seffectRange;
}
DLL_LINKAGE CWillLastTurns turns;
DLL_LINKAGE CWillLastDays days;
CSelector DLL_LINKAGE typeSubtype(Bonus::BonusType Type, TBonusSubtype Subtype)
{
return type()(Type).And(subtype()(Subtype));
}
CSelector DLL_LINKAGE typeSubtypeInfo(Bonus::BonusType type, TBonusSubtype subtype, const CAddInfo & info)
{
return CSelectFieldEqual<Bonus::BonusType>(&Bonus::type)(type)
.And(CSelectFieldEqual<TBonusSubtype>(&Bonus::subtype)(subtype))
.And(CSelectFieldEqual<CAddInfo>(&Bonus::additionalInfo)(info));
}
CSelector DLL_LINKAGE source(Bonus::BonusSource source, ui32 sourceID)
{
return CSelectFieldEqual<Bonus::BonusSource>(&Bonus::source)(source)
.And(CSelectFieldEqual<ui32>(&Bonus::sid)(sourceID));
}
CSelector DLL_LINKAGE sourceTypeSel(Bonus::BonusSource source)
{
return CSelectFieldEqual<Bonus::BonusSource>(&Bonus::source)(source);
}
CSelector DLL_LINKAGE valueType(Bonus::ValueType valType)
{
return CSelectFieldEqual<Bonus::ValueType>(&Bonus::valType)(valType);
}
DLL_LINKAGE CSelector all([](const Bonus * b){return true;});
DLL_LINKAGE CSelector none([](const Bonus * b){return false;});
}
VCMI_LIB_NAMESPACE_END

156
lib/bonuses/BonusSelector.h Normal file
View File

@ -0,0 +1,156 @@
/*
* BonusSelector.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 "HeroBonus.h"
VCMI_LIB_NAMESPACE_BEGIN
class CSelector : std::function<bool(const Bonus*)>
{
using TBase = std::function<bool(const Bonus*)>;
public:
CSelector() = default;
template<typename T>
CSelector(const T &t, //SFINAE trick -> include this c-tor in overload resolution only if parameter is class
//(includes functors, lambdas) or function. Without that VC is going mad about ambiguities.
typename std::enable_if < boost::mpl::or_ < std::is_class<T>, std::is_function<T >> ::value>::type *dummy = nullptr)
: TBase(t)
{}
CSelector(std::nullptr_t)
{}
CSelector And(CSelector rhs) const
{
//lambda may likely outlive "this" (it can be even a temporary) => we copy the OBJECT (not pointer)
auto thisCopy = *this;
return [thisCopy, rhs](const Bonus *b) mutable { return thisCopy(b) && rhs(b); };
}
CSelector Or(CSelector rhs) const
{
auto thisCopy = *this;
return [thisCopy, rhs](const Bonus *b) mutable { return thisCopy(b) || rhs(b); };
}
CSelector Not() const
{
auto thisCopy = *this;
return [thisCopy](const Bonus *b) mutable { return !thisCopy(b); };
}
bool operator()(const Bonus *b) const
{
return TBase::operator()(b);
}
operator bool() const
{
return !!static_cast<const TBase&>(*this);
}
};
template<typename T>
class CSelectFieldEqual
{
T Bonus::*ptr;
public:
CSelectFieldEqual(T Bonus::*Ptr)
: ptr(Ptr)
{
}
CSelector operator()(const T &valueToCompareAgainst) const
{
auto ptr2 = ptr; //We need a COPY because we don't want to reference this (might be outlived by lambda)
return [ptr2, valueToCompareAgainst](const Bonus *bonus)
{
return bonus->*ptr2 == valueToCompareAgainst;
};
}
};
class DLL_LINKAGE CWillLastTurns
{
public:
int turnsRequested;
bool operator()(const Bonus *bonus) const
{
return turnsRequested <= 0 //every present effect will last zero (or "less") turns
|| !Bonus::NTurns(bonus) //so do every not expriing after N-turns effect
|| bonus->turnsRemain > turnsRequested;
}
CWillLastTurns& operator()(const int &setVal)
{
turnsRequested = setVal;
return *this;
}
};
class DLL_LINKAGE CWillLastDays
{
public:
int daysRequested;
bool operator()(const Bonus *bonus) const
{
if(daysRequested <= 0 || Bonus::Permanent(bonus) || Bonus::OneBattle(bonus))
return true;
else if(Bonus::OneDay(bonus))
return false;
else if(Bonus::NDays(bonus) || Bonus::OneWeek(bonus))
{
return bonus->turnsRemain > daysRequested;
}
return false; // TODO: ONE_WEEK need support for turnsRemain, but for now we'll exclude all unhandled durations
}
CWillLastDays& operator()(const int &setVal)
{
daysRequested = setVal;
return *this;
}
};
namespace Selector
{
extern DLL_LINKAGE CSelectFieldEqual<Bonus::BonusType> & type();
extern DLL_LINKAGE CSelectFieldEqual<TBonusSubtype> & subtype();
extern DLL_LINKAGE CSelectFieldEqual<CAddInfo> & info();
extern DLL_LINKAGE CSelectFieldEqual<Bonus::BonusSource> & sourceType();
extern DLL_LINKAGE CSelectFieldEqual<Bonus::BonusSource> & targetSourceType();
extern DLL_LINKAGE CSelectFieldEqual<Bonus::LimitEffect> & effectRange();
extern DLL_LINKAGE CWillLastTurns turns;
extern DLL_LINKAGE CWillLastDays days;
CSelector DLL_LINKAGE typeSubtype(Bonus::BonusType Type, TBonusSubtype Subtype);
CSelector DLL_LINKAGE typeSubtypeInfo(Bonus::BonusType type, TBonusSubtype subtype, const CAddInfo & info);
CSelector DLL_LINKAGE source(Bonus::BonusSource source, ui32 sourceID);
CSelector DLL_LINKAGE sourceTypeSel(Bonus::BonusSource source);
CSelector DLL_LINKAGE valueType(Bonus::ValueType valType);
/**
* Selects all bonuses
* Usage example: Selector::all.And(<functor>).And(<functor>)...)
*/
extern DLL_LINKAGE CSelector all;
/**
* Selects nothing
* Usage example: Selector::none.Or(<functor>).Or(<functor>)...)
*/
extern DLL_LINKAGE CSelector none;
}
VCMI_LIB_NAMESPACE_END

View File

@ -11,6 +11,7 @@
#pragma once
#include "HeroBonus.h"
#include "BonusSelector.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -354,79 +354,6 @@ std::shared_ptr<Bonus> Bonus::addPropagator(const TPropagatorPtr & Propagator)
return this->shared_from_this();
}
namespace Selector
{
DLL_LINKAGE CSelectFieldEqual<Bonus::BonusType> & type()
{
static CSelectFieldEqual<Bonus::BonusType> stype(&Bonus::type);
return stype;
}
DLL_LINKAGE CSelectFieldEqual<TBonusSubtype> & subtype()
{
static CSelectFieldEqual<TBonusSubtype> ssubtype(&Bonus::subtype);
return ssubtype;
}
DLL_LINKAGE CSelectFieldEqual<CAddInfo> & info()
{
static CSelectFieldEqual<CAddInfo> sinfo(&Bonus::additionalInfo);
return sinfo;
}
DLL_LINKAGE CSelectFieldEqual<Bonus::BonusSource> & sourceType()
{
static CSelectFieldEqual<Bonus::BonusSource> ssourceType(&Bonus::source);
return ssourceType;
}
DLL_LINKAGE CSelectFieldEqual<Bonus::BonusSource> & targetSourceType()
{
static CSelectFieldEqual<Bonus::BonusSource> ssourceType(&Bonus::targetSourceType);
return ssourceType;
}
DLL_LINKAGE CSelectFieldEqual<Bonus::LimitEffect> & effectRange()
{
static CSelectFieldEqual<Bonus::LimitEffect> seffectRange(&Bonus::effectRange);
return seffectRange;
}
DLL_LINKAGE CWillLastTurns turns;
DLL_LINKAGE CWillLastDays days;
CSelector DLL_LINKAGE typeSubtype(Bonus::BonusType Type, TBonusSubtype Subtype)
{
return type()(Type).And(subtype()(Subtype));
}
CSelector DLL_LINKAGE typeSubtypeInfo(Bonus::BonusType type, TBonusSubtype subtype, const CAddInfo & info)
{
return CSelectFieldEqual<Bonus::BonusType>(&Bonus::type)(type)
.And(CSelectFieldEqual<TBonusSubtype>(&Bonus::subtype)(subtype))
.And(CSelectFieldEqual<CAddInfo>(&Bonus::additionalInfo)(info));
}
CSelector DLL_LINKAGE source(Bonus::BonusSource source, ui32 sourceID)
{
return CSelectFieldEqual<Bonus::BonusSource>(&Bonus::source)(source)
.And(CSelectFieldEqual<ui32>(&Bonus::sid)(sourceID));
}
CSelector DLL_LINKAGE sourceTypeSel(Bonus::BonusSource source)
{
return CSelectFieldEqual<Bonus::BonusSource>(&Bonus::source)(source);
}
CSelector DLL_LINKAGE valueType(Bonus::ValueType valType)
{
return CSelectFieldEqual<Bonus::ValueType>(&Bonus::valType)(valType);
}
DLL_LINKAGE CSelector all([](const Bonus * b){return true;});
DLL_LINKAGE CSelector none([](const Bonus * b){return false;});
}
DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus)
{
for(const auto & i : bonusNameMap)

View File

@ -28,50 +28,6 @@ using TLimiterPtr = std::shared_ptr<ILimiter>;
using TPropagatorPtr = std::shared_ptr<IPropagator>;
using TUpdaterPtr = std::shared_ptr<IUpdater>;
class CSelector : std::function<bool(const Bonus*)>
{
using TBase = std::function<bool(const Bonus*)>;
public:
CSelector() = default;
template<typename T>
CSelector(const T &t, //SFINAE trick -> include this c-tor in overload resolution only if parameter is class
//(includes functors, lambdas) or function. Without that VC is going mad about ambiguities.
typename std::enable_if < boost::mpl::or_ < std::is_class<T>, std::is_function<T >> ::value>::type *dummy = nullptr)
: TBase(t)
{}
CSelector(std::nullptr_t)
{}
CSelector And(CSelector rhs) const
{
//lambda may likely outlive "this" (it can be even a temporary) => we copy the OBJECT (not pointer)
auto thisCopy = *this;
return [thisCopy, rhs](const Bonus *b) mutable { return thisCopy(b) && rhs(b); };
}
CSelector Or(CSelector rhs) const
{
auto thisCopy = *this;
return [thisCopy, rhs](const Bonus *b) mutable { return thisCopy(b) || rhs(b); };
}
CSelector Not() const
{
auto thisCopy = *this;
return [thisCopy](const Bonus *b) mutable { return !thisCopy(b); };
}
bool operator()(const Bonus *b) const
{
return TBase::operator()(b);
}
operator bool() const
{
return !!static_cast<const TBase&>(*this);
}
};
class DLL_LINKAGE CAddInfo : public std::vector<si32>
{
public:
@ -464,103 +420,6 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>
DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus);
DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const BonusList &bonusList);
template<typename T>
class CSelectFieldEqual
{
T Bonus::*ptr;
public:
CSelectFieldEqual(T Bonus::*Ptr)
: ptr(Ptr)
{
}
CSelector operator()(const T &valueToCompareAgainst) const
{
auto ptr2 = ptr; //We need a COPY because we don't want to reference this (might be outlived by lambda)
return [ptr2, valueToCompareAgainst](const Bonus *bonus)
{
return bonus->*ptr2 == valueToCompareAgainst;
};
}
};
class DLL_LINKAGE CWillLastTurns
{
public:
int turnsRequested;
bool operator()(const Bonus *bonus) const
{
return turnsRequested <= 0 //every present effect will last zero (or "less") turns
|| !Bonus::NTurns(bonus) //so do every not expriing after N-turns effect
|| bonus->turnsRemain > turnsRequested;
}
CWillLastTurns& operator()(const int &setVal)
{
turnsRequested = setVal;
return *this;
}
};
class DLL_LINKAGE CWillLastDays
{
public:
int daysRequested;
bool operator()(const Bonus *bonus) const
{
if(daysRequested <= 0 || Bonus::Permanent(bonus) || Bonus::OneBattle(bonus))
return true;
else if(Bonus::OneDay(bonus))
return false;
else if(Bonus::NDays(bonus) || Bonus::OneWeek(bonus))
{
return bonus->turnsRemain > daysRequested;
}
return false; // TODO: ONE_WEEK need support for turnsRemain, but for now we'll exclude all unhandled durations
}
CWillLastDays& operator()(const int &setVal)
{
daysRequested = setVal;
return *this;
}
};
namespace Selector
{
extern DLL_LINKAGE CSelectFieldEqual<Bonus::BonusType> & type();
extern DLL_LINKAGE CSelectFieldEqual<TBonusSubtype> & subtype();
extern DLL_LINKAGE CSelectFieldEqual<CAddInfo> & info();
extern DLL_LINKAGE CSelectFieldEqual<Bonus::BonusSource> & sourceType();
extern DLL_LINKAGE CSelectFieldEqual<Bonus::BonusSource> & targetSourceType();
extern DLL_LINKAGE CSelectFieldEqual<Bonus::LimitEffect> & effectRange();
extern DLL_LINKAGE CWillLastTurns turns;
extern DLL_LINKAGE CWillLastDays days;
CSelector DLL_LINKAGE typeSubtype(Bonus::BonusType Type, TBonusSubtype Subtype);
CSelector DLL_LINKAGE typeSubtypeInfo(Bonus::BonusType type, TBonusSubtype subtype, const CAddInfo & info);
CSelector DLL_LINKAGE source(Bonus::BonusSource source, ui32 sourceID);
CSelector DLL_LINKAGE sourceTypeSel(Bonus::BonusSource source);
CSelector DLL_LINKAGE valueType(Bonus::ValueType valType);
/**
* Selects all bonuses
* Usage example: Selector::all.And(<functor>).And(<functor>)...)
*/
extern DLL_LINKAGE CSelector all;
/**
* Selects nothing
* Usage example: Selector::none.Or(<functor>).Or(<functor>)...)
*/
extern DLL_LINKAGE CSelector none;
}
extern DLL_LINKAGE const std::map<std::string, Bonus::BonusType> bonusNameMap;
extern DLL_LINKAGE const std::map<std::string, Bonus::ValueType> bonusValueMap;
extern DLL_LINKAGE const std::map<std::string, Bonus::BonusSource> bonusSourceMap;

View File

@ -13,6 +13,7 @@
#include "../ISpellMechanics.h"
#include "../../bonuses/BonusSelector.h"
#include "../../NetPacksBase.h"
#include "../../battle/CBattleInfoCallback.h"
#include "../../battle/Unit.h"