mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Optimize Unit::getHexes method
This commit is contained in:
		| @@ -35,6 +35,7 @@ CStack::CStack(const CStackInstance * Base, const PlayerColor & O, int I, Battle | ||||
| 	side(Side) | ||||
| { | ||||
| 	health.init(); //??? | ||||
| 	doubleWideCached = battle::CUnitState::doubleWide(); | ||||
| } | ||||
|  | ||||
| CStack::CStack(): | ||||
| @@ -55,6 +56,7 @@ CStack::CStack(const CStackBasicDescriptor * stack, const PlayerColor & O, int I | ||||
| 	side(Side) | ||||
| { | ||||
| 	health.init(); //??? | ||||
| 	doubleWideCached = battle::CUnitState::doubleWide(); | ||||
| } | ||||
|  | ||||
| void CStack::localInit(BattleInfo * battleInfo) | ||||
| @@ -404,4 +406,30 @@ void CStack::spendMana(ServerCallback * server, const int spellCost) const | ||||
| 	server->apply(ssp); | ||||
| } | ||||
|  | ||||
| void CStack::postDeserialize(const CArmedInstance * army, const SlotID & extSlot) | ||||
| { | ||||
| 	if(extSlot == SlotID::COMMANDER_SLOT_PLACEHOLDER) | ||||
| 	{ | ||||
| 		const auto * hero = dynamic_cast<const CGHeroInstance *>(army); | ||||
| 		assert(hero); | ||||
| 		base = hero->commander; | ||||
| 	} | ||||
| 	else if(slot == SlotID::SUMMONED_SLOT_PLACEHOLDER || slot == SlotID::ARROW_TOWERS_SLOT || slot == SlotID::WAR_MACHINES_SLOT) | ||||
| 	{ | ||||
| 		//no external slot possible, so no base stack | ||||
| 		base = nullptr; | ||||
| 	} | ||||
| 	else if(!army || extSlot == SlotID() || !army->hasStackAtSlot(extSlot)) | ||||
| 	{ | ||||
| 		base = nullptr; | ||||
| 		logGlobal->warn("%s doesn't have a base stack!", typeID.toEntity(VLC)->getNameSingularTranslated()); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		base = &army->getStack(extSlot); | ||||
| 	} | ||||
|  | ||||
| 	doubleWideCached = battle::CUnitState::doubleWide(); | ||||
| } | ||||
|  | ||||
| VCMI_LIB_NAMESPACE_END | ||||
|   | ||||
							
								
								
									
										29
									
								
								lib/CStack.h
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								lib/CStack.h
									
									
									
									
									
								
							| @@ -23,7 +23,7 @@ struct BattleStackAttacked; | ||||
| class BattleInfo; | ||||
|  | ||||
| //Represents STACK_BATTLE nodes | ||||
| class DLL_LINKAGE CStack : public CBonusSystemNode, public battle::CUnitState, public battle::IUnitEnvironment | ||||
| class DLL_LINKAGE CStack final : public CBonusSystemNode, public battle::CUnitState, public battle::IUnitEnvironment | ||||
| { | ||||
| private: | ||||
| 	ui32 ID = -1; //unique ID of stack | ||||
| @@ -36,6 +36,9 @@ private: | ||||
|  | ||||
| 	SlotID slot;  //slot - position in garrison (may be 255 for neutrals/called creatures) | ||||
|  | ||||
| 	bool doubleWideCached = false; | ||||
|  | ||||
| 	void postDeserialize(const CArmedInstance * army, const SlotID & extSlot); | ||||
| public: | ||||
| 	const CStackInstance * base = nullptr; //garrison slot from which stack originates (nullptr for war machines, summoned cres, etc) | ||||
| 	 | ||||
| @@ -77,6 +80,7 @@ public: | ||||
| 	BattleSide unitSide() const override; | ||||
| 	PlayerColor unitOwner() const override; | ||||
| 	SlotID unitSlot() const override; | ||||
| 	bool doubleWide() const override { return doubleWideCached;}; | ||||
|  | ||||
| 	std::string getDescription() const override; | ||||
|  | ||||
| @@ -119,26 +123,7 @@ public: | ||||
| 			h & army; | ||||
| 			h & extSlot; | ||||
|  | ||||
| 			if(extSlot == SlotID::COMMANDER_SLOT_PLACEHOLDER) | ||||
| 			{ | ||||
| 				const auto * hero = dynamic_cast<const CGHeroInstance *>(army); | ||||
| 				assert(hero); | ||||
| 				base = hero->commander; | ||||
| 			} | ||||
| 			else if(slot == SlotID::SUMMONED_SLOT_PLACEHOLDER || slot == SlotID::ARROW_TOWERS_SLOT || slot == SlotID::WAR_MACHINES_SLOT) | ||||
| 			{ | ||||
| 				//no external slot possible, so no base stack | ||||
| 				base = nullptr; | ||||
| 			} | ||||
| 			else if(!army || extSlot == SlotID() || !army->hasStackAtSlot(extSlot)) | ||||
| 			{ | ||||
| 				base = nullptr; | ||||
| 				logGlobal->warn("%s doesn't have a base stack!", typeID.toEntity(VLC)->getNameSingularTranslated()); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				base = &army->getStack(extSlot); | ||||
| 			} | ||||
| 			postDeserialize(army, extSlot); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -146,4 +131,4 @@ private: | ||||
| 	const BattleInfo * battle; //do not serialize | ||||
| }; | ||||
|  | ||||
| VCMI_LIB_NAMESPACE_END | ||||
| VCMI_LIB_NAMESPACE_END | ||||
|   | ||||
| @@ -269,7 +269,7 @@ private: | ||||
| 	void reset(); | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE CUnitStateDetached : public CUnitState | ||||
| class DLL_LINKAGE CUnitStateDetached final : public CUnitState | ||||
| { | ||||
| public: | ||||
| 	explicit CUnitStateDetached(const IUnitInfo * unit_, const IBonusBearer * bonus_); | ||||
|   | ||||
| @@ -107,24 +107,34 @@ const BattleHexArray & Unit::getHexes(BattleHex assumedPos) const | ||||
| 	return getHexes(assumedPos, doubleWide(), unitSide()); | ||||
| } | ||||
|  | ||||
| BattleHexArray::ArrayOfBattleHexArrays Unit::precomputeUnitHexes(BattleSide side, bool twoHex) | ||||
| { | ||||
| 	BattleHexArray::ArrayOfBattleHexArrays result; | ||||
|  | ||||
| 	for (BattleHex assumedPos = 0; assumedPos < GameConstants::BFIELD_SIZE; ++assumedPos) | ||||
| 	{ | ||||
| 		BattleHexArray hexes; | ||||
| 		hexes.insert(assumedPos); | ||||
|  | ||||
| 		if(twoHex) | ||||
| 			hexes.insert(occupiedHex(assumedPos, twoHex, side)); | ||||
|  | ||||
| 		result[assumedPos.toInt()] = std::move(hexes); | ||||
| 	} | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| const BattleHexArray & Unit::getHexes(BattleHex assumedPos, bool twoHex, BattleSide side) | ||||
| { | ||||
| 	static BattleHexArray::ArrayOfBattleHexArrays precomputed[4]; | ||||
| 	static const std::array<BattleHexArray::ArrayOfBattleHexArrays, 4> precomputed = { | ||||
| 		precomputeUnitHexes(BattleSide::ATTACKER, false), | ||||
| 		precomputeUnitHexes(BattleSide::ATTACKER, true), | ||||
| 		precomputeUnitHexes(BattleSide::DEFENDER, false), | ||||
| 		precomputeUnitHexes(BattleSide::DEFENDER, true), | ||||
| 	}; | ||||
|  | ||||
| 	int index = side == BattleSide::ATTACKER ? 0 : 2; | ||||
|  | ||||
| 	if(!precomputed[index + twoHex][assumedPos.toInt()].empty()) | ||||
| 		return precomputed[index + twoHex][assumedPos.toInt()]; | ||||
|  | ||||
| 	// first run, compute | ||||
|  | ||||
| 	BattleHexArray hexes; | ||||
| 	hexes.insert(assumedPos); | ||||
|  | ||||
| 	if(twoHex) | ||||
| 		hexes.insert(occupiedHex(assumedPos, twoHex, side)); | ||||
|  | ||||
| 	precomputed[index + twoHex][assumedPos.toInt()] = std::move(hexes); | ||||
|  | ||||
| 	return precomputed[index + twoHex][assumedPos.toInt()]; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -64,6 +64,8 @@ class CUnitState; | ||||
|  | ||||
| class DLL_LINKAGE Unit : public IUnitInfo, public spells::Caster, public virtual IBonusBearer, public ACreature | ||||
| { | ||||
| 	static BattleHexArray::ArrayOfBattleHexArrays precomputeUnitHexes(BattleSide side, bool twoHex); | ||||
|  | ||||
| public: | ||||
| 	virtual ~Unit(); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user