Selaa lähdekoodia

vcmi: split selectors from HeroBonus.h

Konstantin 2 vuotta sitten
vanhempi
sitoutus
3df5a8e415

+ 2 - 0
cmake_modules/VCMI_lib.cmake

@@ -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

+ 1 - 0
lib/bonuses/BonusList.h

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

+ 1 - 0
lib/bonuses/BonusParams.cpp

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

+ 89 - 0
lib/bonuses/BonusSelector.cpp

@@ -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 - 0
lib/bonuses/BonusSelector.h

@@ -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

+ 1 - 0
lib/bonuses/CBonusProxy.h

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

+ 0 - 73
lib/bonuses/HeroBonus.cpp

@@ -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)

+ 0 - 141
lib/bonuses/HeroBonus.h

@@ -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;

+ 1 - 0
lib/spells/effects/UnitEffect.cpp

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