Subversion Repository Public Repository

Divide-Framework

This repository has no backups
This repository's network speed is throttled to 100KB/sec

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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#include "Headers/AITeam.h"

#include "AI/Headers/AIEntity.h"
#include "AI/Headers/AIManager.h"
#include "AI/PathFinding/Headers/DivideCrowd.h"

#include "Core/Headers/TaskPool.h"
#include "Dynamics/Entities/Units/Headers/NPC.h"

namespace Divide {
namespace AI {

AITeam::AITeam(U32 id, AIManager& parentManager)
     : GUIDWrapper(),
       _parentManager(parentManager),
       _teamID(id)
{
    _team.clear();
    _parentManager.registerTeam(this);
}

AITeam::~AITeam()
{
    _parentManager.unregisterTeam(this);
    {
        WriteLock w1_lock(_crowdMutex);
        MemoryManager::DELETE_HASHMAP(_aiTeamCrowd);
    }
    {
        WriteLock w2_lock(_updateMutex);
        for (AITeam::TeamMap::value_type& entity : _team) {
            Attorney::AIEntityAITeam::setTeamPtr(*entity.second, nullptr);
        }
        _team.clear();
    }
}

void AITeam::addCrowd(AIEntity::PresetAgentRadius radius,
                      Navigation::NavigationMesh* navMesh) {
    DIVIDE_ASSERT(_aiTeamCrowd.find(radius) == std::end(_aiTeamCrowd),
                  "AITeam error: DtCrowd already existed for new navmesh!");
    hashAlg::emplace(_aiTeamCrowd, radius,
                     MemoryManager_NEW Navigation::DivideDtCrowd(navMesh));
}

void AITeam::removeCrowd(AIEntity::PresetAgentRadius radius) {
    AITeamCrowd::iterator it = _aiTeamCrowd.find(radius);
    DIVIDE_ASSERT(
        it != std::end(_aiTeamCrowd),
        "AITeam error: DtCrowd does not exist for specified navmesh!");
    MemoryManager::DELETE(it->second);
    _aiTeamCrowd.erase(it);
}

vectorImpl<AIEntity*> AITeam::getEntityList() const {
    vectorImpl<AIEntity*> entities;
    ReadLock r2_lock(_updateMutex);
    entities.reserve(_team.size());
    for (const AITeam::TeamMap::value_type& entity : _team) {
        entities.push_back(entity.second);
    }
    r2_lock.unlock();

    return entities;
}

bool AITeam::update(TaskPool& parentPool, const U64 deltaTime) {
    // Crowds
    ReadLock r1_lock(_crowdMutex);
    for (AITeamCrowd::value_type& it : _aiTeamCrowd) {
        it.second->update(deltaTime);
    }
    r1_lock.unlock();

    vectorImpl<AIEntity*> entities = AITeam::getEntityList();
    for (AIEntity* entity : entities) {
        if (!Attorney::AIEntityAITeam::update(*entity, deltaTime)) {
            return false;
        }
    }

    TaskHandle updateTask = CreateTask(parentPool, DELEGATE_CBK<void, const Task&>());
    for (AIEntity* entity : entities) {
        updateTask.addChildTask(CreateTask(parentPool,
                                [entity, deltaTime](const Task& parentTask)
                                {
                                    if (!Attorney::AIEntityAITeam::update(*entity, deltaTime)) {
                                        //print error;
                                    }
                                })._task)->startTask(Task::TaskPriority::HIGH);
    }

    updateTask.startTask(Task::TaskPriority::MAX);
    updateTask.wait();

    return true;
}

bool AITeam::processInput(TaskPool& parentPool, const U64 deltaTime) {
   vectorImpl<AIEntity*> entities = AITeam::getEntityList();

   TaskHandle inputTask = CreateTask(parentPool, DELEGATE_CBK<void, const Task&>());
    for (AIEntity* entity : entities) {
        inputTask.addChildTask(CreateTask(parentPool,
                               [entity, deltaTime](const Task& parentTask)
                               {
                                   if (!Attorney::AIEntityAITeam::processInput(*entity, deltaTime)) {
                                       //print error;
                                   }
                               })._task)->startTask(Task::TaskPriority::HIGH);
    }

    inputTask.startTask(Task::TaskPriority::MAX);
    inputTask.wait();

    return true;
}

bool AITeam::processData(TaskPool& parentPool, const U64 deltaTime) {
    vectorImpl<AIEntity*> entities = AITeam::getEntityList();

    TaskHandle dataTask = CreateTask(parentPool, DELEGATE_CBK<void, const Task&>());
    for (AIEntity* entity : entities) {
        dataTask.addChildTask(CreateTask(parentPool,
                              [entity, deltaTime](const Task& parentTask)
                              {
                                  if (!Attorney::AIEntityAITeam::processData(*entity, deltaTime)) {
                                      //print error;
                                  }
                              })._task)->startTask(Task::TaskPriority::HIGH);
    }

    dataTask.startTask(Task::TaskPriority::MAX);
    dataTask.wait();

    return true;
}

void AITeam::resetCrowd() {
    vectorImpl<AIEntity*> entities = AITeam::getEntityList();
    for (AIEntity* entity : entities) {
        entity->resetCrowd();
    }
}

bool AITeam::addTeamMember(AIEntity* entity) {
    if (!entity) {
        return false;
    }
    /// If entity already belongs to this team, no need to do anything
    WriteLock w_lock(_updateMutex);
    if (_team.find(entity->getGUID()) != std::end(_team)) {
        return true;
    }
    hashAlg::emplace(_team, entity->getGUID(), entity);
    Attorney::AIEntityAITeam::setTeamPtr(*entity, this);

    return true;
}

/// Removes an entity from this list
bool AITeam::removeTeamMember(AIEntity* entity) {
    if (!entity) {
        return false;
    }

    WriteLock w_lock(_updateMutex);
    if (_team.find(entity->getGUID()) != std::end(_team)) {
        _team.erase(entity->getGUID());
    }
    return true;
}

bool AITeam::addEnemyTeam(U32 enemyTeamID) {
    if (findEnemyTeamEntry(enemyTeamID) == std::end(_enemyTeams)) {
        WriteLock w_lock(_updateMutex);
        _enemyTeams.push_back(enemyTeamID);
        return true;
    }
    return false;
}

bool AITeam::removeEnemyTeam(U32 enemyTeamID) {
    vectorImpl<U32>::iterator it = findEnemyTeamEntry(enemyTeamID);
    if (it != std::end(_enemyTeams)) {
        WriteLock w_lock(_updateMutex);
        _enemyTeams.erase(it);
        return true;
    }
    return false;
}

}; // namespace AI
}; // namespace Divide

Commits for Divide-Framework/trunk/Source Code/AI/ActionInterface/AITeam.cpp

Diff revisions: vs.
Revision Author Commited Message
878 Diff Diff IonutCava picture IonutCava Fri 17 Mar, 2017 17:16:21 +0000

[IonutCava]
- Change AIManager from a thread owning update system to the per-agent task system

711 Diff Diff IonutCava picture IonutCava Mon 23 May, 2016 14:31:55 +0000

[IonutCava]
- More scene change fixes: pending tasks, GUI elements, etc
- Singleton removal: AIManager is a per-scene member instead of a global singleton now

670 Diff Diff IonutCava picture IonutCava Wed 06 Apr, 2016 16:21:35 +0000

[IonutCava]
- getInstance() renamed to instance() for simplicity (should really go away altogether, but that’s a different issue)
- some particle emitter threading updates

434 Diff Diff IonutCava picture IonutCava Wed 13 May, 2015 22:26:29 +0000

[Ionut]
- Simplified SceneGraph/SceneGraphNode classes:
— RAII style. Dropped load/unload
— SGN deletion callbacks are tracked by ID
— Better node deletion System
- Better scoring system with manual override:
— Key 1 adds a point to team A
— Key 2 adds a point to team B
- Safer scene pointer management in SceneManager

423 Diff Diff IonutCava picture IonutCava Wed 06 May, 2015 15:45:24 +0000

[Ionut]
- WarScene AI work

389 Diff Diff IonutCava picture IonutCava Thu 26 Mar, 2015 17:14:11 +0000

[Ionut]
- More rendering pipeline refactoring:
— Implemented temporary hack of binding a subrange of the nodebuffer to avoid using gl_BaseInstanceARB and just use gl_DrawIDARB for indexing data (works fine)
— Matrix data is only generated if we got valid rendering commands from a certain node
- Moved all *Attorney classes to an Attorney namespace
- Fixed a bug with caching uniform values in glShaderProgram
- Added some robustness checks to glUniformBuffer

351 Diff Diff IonutCava picture IonutCava Wed 11 Feb, 2015 16:39:15 +0000

[Ionut]
- Large amount of decoupling between classes by using Attorney-style classes where friendship was required.

350 Diff Diff IonutCava picture IonutCava Tue 10 Feb, 2015 16:25:39 +0000

[Ionut]
- Simplified some Util-namespace level functions by using STL algorithms where possible
- Formatted the entire codebase using clang-format with the following style: "{BasedOnStyle: Google, IndentWidth: 4}"
- Attempted to make ProfileTimer thread-safe (temp fix until std::chrono works properly in Visual Studio)

347 Diff Diff IonutCava picture IonutCava Thu 05 Feb, 2015 13:39:09 +0000

[Ionut]
- Changed all begin/end calls on containers to non-member versions
- Replaced all useless “auto” keywords from code. (“auto” only makes sense for return values for delegate functions)
- Replaced useless code in Util::Mat4::Multiply with something that makes sense

337 IonutCava picture IonutCava Wed 17 Dec, 2014 17:25:16 +0000

[Ionut]
- Replaced all tabs with 4 spaces (some spacing may be off now. no way to check all the files.)
- Moved implementation details for ParamHandler, BoundingBox, BoundingSphere and ProfileTimer to proper .inl and .cpp files. (more to follow)
- Update all forward declared enums with the required storage type (as requested by the C++11 standard)