File: UnitHandler.h

package info (click to toggle)
spring 105.0.1%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 108,860 kB
  • sloc: cpp: 467,785; ansic: 302,607; python: 12,925; java: 12,201; awk: 5,889; sh: 2,371; xml: 655; perl: 405; php: 276; objc: 194; makefile: 75; sed: 2
file content (117 lines) | stat: -rw-r--r-- 4,007 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */

#ifndef UNITHANDLER_H
#define UNITHANDLER_H

#include <array>
#include <vector>

#include "Sim/Misc/GlobalConstants.h"
#include "Sim/Misc/SimObjectIDPool.h"
#include "System/creg/STL_Map.h"

struct UnitDef;
class CUnit;
class CBuilderCAI;

class CUnitHandler
{
	CR_DECLARE_STRUCT(CUnitHandler)

public:
	CUnitHandler(): idPool(MAX_UNITS) {}

	void Init();
	void Kill();

	void DeleteScripts();

	void Update();
	bool AddUnit(CUnit* unit);

	bool CanAddUnit(int id) const {
		// do we want to be assigned a random ID and are any left in pool?
		if (id < 0)
			return (!idPool.IsEmpty());
		// is this ID not already in use *and* has it been recycled by pool?
		if (id < MaxUnits())
			return (units[id] == nullptr && idPool.HasID(id));
		// AddUnit will not make new room for us
		return false;
	}

	unsigned int NumUnitsByTeam      (int teamNum               ) const { return (unitsByDefs[teamNum][        0].size()); }
	unsigned int NumUnitsByTeamAndDef(int teamNum, int unitDefID) const { return (unitsByDefs[teamNum][unitDefID].size()); }
	unsigned int MaxUnits() const { return maxUnits; }
	unsigned int CalcMaxUnits() const;

	float MaxUnitRadius() const { return maxUnitRadius; }

	/// Returns true if a unit of type unitID can be built, false otherwise
	bool CanBuildUnit(const UnitDef* unitdef, int team) const;
	bool GarbageCollectUnit(unsigned int id);

	void AddBuilderCAI(CBuilderCAI*);
	void RemoveBuilderCAI(CBuilderCAI*);

	void ChangeUnitTeam(CUnit* unit, int oldTeamNum, int newTeamNum);

	// note: negative ID's are implicitly converted
	CUnit* GetUnitUnsafe(unsigned int id) const { return units[id]; }
	CUnit* GetUnit(unsigned int id) const { return ((id < MaxUnits())? units[id]: nullptr); }

	static CUnit* NewUnit(const UnitDef* ud);

	const std::vector<CUnit*>& GetActiveUnits() const { return activeUnits; }
	      std::vector<CUnit*>& GetActiveUnits()       { return activeUnits; }

	const std::vector<CUnit*>& GetUnitsByTeam      (int teamNum               ) const { return unitsByDefs[teamNum][        0]; }
	const std::vector<CUnit*>& GetUnitsByTeamAndDef(int teamNum, int unitDefID) const { return unitsByDefs[teamNum][unitDefID]; }

	std::vector<CUnit*>& GetUnitsByTeam      (int teamNum               ) { return unitsByDefs[teamNum][        0]; }
	std::vector<CUnit*>& GetUnitsByTeamAndDef(int teamNum, int unitDefID) { return unitsByDefs[teamNum][unitDefID]; }

	const spring::unordered_map<unsigned int, CBuilderCAI*>& GetBuilderCAIs() const { return builderCAIs; }

private:
	void InsertActiveUnit(CUnit* unit);
	bool QueueDeleteUnit(CUnit* unit);
	void QueueDeleteUnits();
	void DeleteUnit(CUnit* unit);
	void DeleteUnits();
	void SlowUpdateUnits();
	void UpdateUnitMoveTypes();
	void UpdateUnitLosStates();
	void UpdateUnits();
	void UpdateUnitWeapons();

private:
	SimObjectIDPool idPool;

	std::vector<CUnit*> units;                                           ///< used to get units from IDs (0 if not created)
	std::array<std::vector<std::vector<CUnit*>>, MAX_TEAMS> unitsByDefs; ///< units sorted by team and unitDef

	std::vector<CUnit*> activeUnits;                                     ///< used to get all active units
	std::vector<CUnit*> unitsToBeRemoved;                                ///< units that will be removed at start of next update

	spring::unordered_map<unsigned int, CBuilderCAI*> builderCAIs;


	size_t activeSlowUpdateUnit = 0;  ///< first unit of batch that will be SlowUpdate'd this frame
	size_t activeUpdateUnit = 0;      ///< first unit of batch that will be SlowUpdate'd this frame


	///< global unit-limit (derived from the per-team limit)
	///< units.size() is equal to this and constant at runtime
	unsigned int maxUnits = 0;

	///< largest radius of any unit added so far (some
	///< spatial query filters in GameHelper use this)
	float maxUnitRadius = 0.0f;

	bool inUpdateCall = false;
};

extern CUnitHandler unitHandler;

#endif /* UNITHANDLER_H */