14 #include <unordered_map>
15 #include <unordered_set>
29 struct AveragePositionFunctor {
30 glm::vec3 operator()(
const glm::vec3& result,
const AIPtr& ai) {
35 typedef std::unordered_set<AIPtr> GroupMembersSet;
36 typedef GroupMembersSet::iterator GroupMembersSetIter;
37 typedef GroupMembersSet::const_iterator GroupMembersSetConstIter;
42 GroupMembersSet members;
46 typedef std::unordered_multimap<AIPtr, GroupId> GroupMembers;
47 typedef std::unordered_map<GroupId, Group> Groups;
48 typedef Groups::const_iterator GroupsConstIter;
49 typedef Groups::iterator GroupsIter;
51 GroupMembersSet _empty;
54 GroupMembers _groupMembers;
76 bool add(GroupId
id,
const AIPtr& ai);
78 void update(int64_t deltaTime);
93 bool remove(GroupId id,
const AIPtr& ai);
125 template<
typename Func>
126 void visit(GroupId
id, Func& func)
const {
128 const GroupsConstIter& i = _groups.find(
id);
129 if (i == _groups.end()) {
132 for (GroupMembersSetConstIter it = i->second.members.begin(); it != i->second.members.end(); ++it) {
133 const AIPtr& chr = *it;
155 bool isInGroup(GroupId
id,
const AIPtr& ai)
const;
164 inline void GroupMgr::update(int64_t) {
165 ScopedReadLock scopedLock(_lock);
166 for (
auto i = _groups.begin(); i != _groups.end(); ++i) {
167 Group& group = i->second;
168 glm::vec3 averagePosition(0.0f);
170 ScopedReadLock lock(_groupLock);
171 averagePosition = std::accumulate(group.members.begin(), group.members.end(), glm::vec3(0.0f), AveragePositionFunctor());
172 averagePosition *= 1.0f / (float) group.members.size();
174 ScopedWriteLock lock(_groupLock);
175 group.position = averagePosition;
181 GroupsIter i = _groups.find(
id);
182 if (i == _groups.end()) {
185 i = _groups.insert(std::pair<GroupId, Group>(
id, group)).first;
188 Group& group = i->second;
190 std::pair<GroupMembersSetIter, bool> ret = group.members.insert(ai);
192 _groupMembers.insert(GroupMembers::value_type(ai,
id));
200 const GroupsIter& i = _groups.find(
id);
201 if (i == _groups.end()) {
204 Group& group = i->second;
205 GroupMembersSetIter si;
208 si = group.members.find(ai);
209 if (si == group.members.end()) {
215 group.members.erase(si);
216 if (group.members.empty()) {
218 }
else if (group.leader == ai) {
219 group.leader = *group.members.begin();
223 auto range = _groupMembers.equal_range(ai);
224 for (
auto it = range.first; it != range.second; ++it) {
225 if (it->second ==
id) {
226 _groupMembers.erase(it);
234 std::list<GroupId> groups;
237 auto range = _groupMembers.equal_range(ai);
238 for (
auto it = range.first; it != range.second; ++it) {
239 groups.push_back(it->second);
242 for (GroupId groupId : groups) {
250 const GroupsConstIter& i = _groups.find(
id);
251 if (i == _groups.end()) {
256 return i->second.leader;
261 const GroupsConstIter& i = _groups.find(
id);
262 if (i == _groups.end()) {
263 return VEC3_INFINITE;
267 return i->second.position;
272 const GroupsConstIter& i = _groups.find(
id);
273 if (i == _groups.end()) {
277 return i->second.leader == ai;
282 const GroupsConstIter& i = _groups.find(
id);
283 if (i == _groups.end()) {
287 return static_cast<int>(std::distance(i->second.members.begin(), i->second.members.end()));
292 return _groupMembers.find(ai) != _groupMembers.end();
297 auto range = _groupMembers.equal_range(ai);
298 for (
auto it = range.first; it != range.second; ++it) {
299 if (it->second ==
id) {
bool isInGroup(GroupId id, const AIPtr &ai) const
Definition: GroupMgr.h:295
Maintains the groups a AI can be in.
Definition: GroupMgr.h:27
int getGroupSize(GroupId id) const
Definition: GroupMgr.h:280
bool add(GroupId id, const AIPtr &ai)
Adds a new group member to the given GroupId. If the group does not yet exists, it it created and the...
Definition: GroupMgr.h:179
bool removeFromAllGroups(const AIPtr &ai)
Use this method to remove a AI instance from all the group it is part of. Useful if you e...
Definition: GroupMgr.h:233
bool remove(GroupId id, const AIPtr &ai)
Removes a group member from the given GroupId. If the member is the group leader, a new leader will b...
Definition: GroupMgr.h:198
bool isGroupLeader(GroupId id, const AIPtr &ai) const
Definition: GroupMgr.h:270
glm::vec3 getPosition(GroupId id) const
Returns the average position of the group.
Definition: GroupMgr.h:259
AIPtr getLeader(GroupId id) const
Definition: GroupMgr.h:248
bool isInAnyGroup(const AIPtr &ai) const
Definition: GroupMgr.h:290
void visit(GroupId id, Func &func) const
Visit all the group members of the given group until the functor returns false.
Definition: GroupMgr.h:126