19 #include "common/ThreadPool.h"
21 #include "common/ExecutionTime.h"
22 #include <unordered_map>
29 typedef std::shared_ptr<AI> AIPtr;
42 typedef std::unordered_map<CharacterId, AIPtr> AIMap;
43 typedef std::vector<AIPtr> AIScheduleList;
44 typedef std::vector<CharacterId> CharacterIdList;
45 typedef AIMap::const_iterator AIMapConstIter;
46 typedef AIMap::iterator AIMapIter;
49 const std::string _name;
51 AIScheduleList _scheduledAdd;
52 AIScheduleList _scheduledRemove;
53 CharacterIdList _scheduledDestroy;
55 ReadWriteLock _lock {
"zone"};
56 ReadWriteLock _scheduleLock {
"zone-schedulelock"};
58 mutable ThreadPool _threadPool;
66 bool doAddAI(
const AIPtr& ai);
70 bool doRemoveAI(
const AIPtr& ai);
78 bool doDestroyAI(
const CharacterId&
id);
81 Zone(
const std::string& name,
int threadCount = std::min(1u, std::thread::hardware_concurrency())) :
82 _name(name), _debug(false), _threadPool(threadCount) {
92 void update(int64_t dt);
100 bool addAI(
const AIPtr& ai);
106 template<
class Collection>
107 bool addAIs(
const Collection& ais) {
111 ScopedWriteLock scopedLock(_scheduleLock);
112 _scheduledAdd.insert(_scheduledAdd.end(), ais.begin(), ais.end());
121 bool removeAI(
const AIPtr& ai);
127 template<
class Collection>
128 bool removeAIs(
const Collection& ais) {
132 ScopedWriteLock scopedLock(_scheduleLock);
133 _scheduledRemove.insert(_scheduledRemove.end(), ais.begin(), ais.end());
144 bool destroyAI(
const CharacterId&
id);
149 const std::string& getName()
const;
157 void setDebug(
bool debug);
158 bool isDebug ()
const;
160 GroupMgr& getGroupMgr();
162 const GroupMgr& getGroupMgr()
const;
171 inline AIPtr getAI(CharacterId
id)
const {
172 ScopedReadLock scopedLock(_lock);
173 auto i = _ais.find(
id);
174 if (i == _ais.end()) {
177 const AIPtr& ai = i->second;
192 template<
typename Func>
193 inline bool executeAsync(CharacterId
id,
const Func& func)
const {
194 const AIPtr& ai = getAI(
id);
198 executeAsync(ai, func);
210 template<
typename Func>
211 inline auto executeAsync(
const AIPtr& ai,
const Func& func)
const
212 -> std::future<typename std::result_of<Func(const AIPtr&)>::type> {
213 return _threadPool.enqueue(func, ai);
216 template<
typename Func>
217 inline auto execute(
const AIPtr& ai,
const Func& func)
const
218 ->
typename std::result_of<Func(const AIPtr&)>::type {
222 template<
typename Func>
223 inline auto execute(
const AIPtr& ai, Func& func)
224 ->
typename std::result_of<Func(const AIPtr&)>::type {
233 template<
typename Func>
234 inline auto execute(CharacterId
id,
const Func& func)
const
235 ->
typename std::result_of<Func(const AIPtr&)>::type {
236 return execute(getAI(
id), func);
244 template<
typename Func>
245 inline auto execute(CharacterId
id, Func& func)
246 ->
typename std::result_of<Func(const AIPtr&)>::type {
247 return execute(getAI(
id), func);
257 template<
typename Func>
258 void executeParallel(Func& func) {
259 std::vector<std::future<void> > results;
263 for (
auto i = copy.begin(); i != copy.end(); ++i) {
264 const AIPtr& ai = i->second;
265 results.emplace_back(executeAsync(ai, func));
267 for (
auto & result: results) {
279 template<
typename Func>
280 void executeParallel(
const Func& func)
const {
281 std::vector<std::future<void> > results;
285 for (
auto i = copy.begin(); i != copy.end(); ++i) {
286 const AIPtr& ai = i->second;
287 results.emplace_back(executeAsync(ai, func));
289 for (
auto & result: results) {
300 template<
typename Func>
301 void execute(
const Func& func)
const {
305 for (
auto i = copy.begin(); i != copy.end(); ++i) {
306 const AIPtr& ai = i->second;
317 template<
typename Func>
318 void execute(Func& func) {
322 for (
auto i = copy.begin(); i != copy.end(); ++i) {
323 const AIPtr& ai = i->second;
328 inline std::size_t size()
const {
329 ScopedReadLock scopedLock(_lock);
334 inline void Zone::setDebug (
bool debug) {
338 inline bool Zone::isDebug ()
const {
342 inline const std::string& Zone::getName()
const {
346 inline GroupMgr& Zone::getGroupMgr() {
347 return _groupManager;
350 inline const GroupMgr& Zone::getGroupMgr()
const {
351 return _groupManager;
354 inline bool Zone::doAddAI(
const AIPtr& ai) {
358 const CharacterId&
id = ai->getCharacter()->getId();
359 if (_ais.find(
id) != _ais.end()) {
362 _ais.insert(std::make_pair(
id, ai));
367 inline bool Zone::doRemoveAI(
const AIPtr& ai) {
371 const CharacterId&
id = ai->getCharacter()->getId();
372 AIMapIter i = _ais.find(
id);
373 if (i == _ais.end()) {
376 i->second->setZone(
nullptr);
377 _groupManager.removeFromAllGroups(i->second);
382 inline bool Zone::doDestroyAI(
const CharacterId&
id) {
383 AIMapIter i = _ais.find(
id);
384 if (i == _ais.end()) {
391 inline bool Zone::addAI(
const AIPtr& ai) {
395 ScopedWriteLock scopedLock(_scheduleLock);
396 _scheduledAdd.push_back(ai);
400 inline bool Zone::destroyAI(
const CharacterId&
id) {
401 ScopedWriteLock scopedLock(_scheduleLock);
402 _scheduledDestroy.push_back(
id);
406 inline bool Zone::removeAI(
const AIPtr& ai) {
410 ScopedWriteLock scopedLock(_scheduleLock);
411 _scheduledRemove.push_back(ai);
415 inline void Zone::update(int64_t dt) {
417 AIScheduleList scheduledRemove;
418 AIScheduleList scheduledAdd;
419 CharacterIdList scheduledDestroy;
421 ScopedWriteLock scopedLock(_scheduleLock);
422 scheduledAdd.swap(_scheduledAdd);
423 scheduledRemove.swap(_scheduledRemove);
424 scheduledDestroy.swap(_scheduledDestroy);
426 ScopedWriteLock scopedLock(_lock);
427 for (
const AIPtr& ai : scheduledAdd) {
430 scheduledAdd.clear();
431 for (
const AIPtr& ai : scheduledRemove) {
434 scheduledRemove.clear();
435 for (
auto id : scheduledDestroy) {
438 scheduledDestroy.clear();
441 auto func = [&] (
const AIPtr& ai) {
445 ai->update(dt, _debug);
446 ai->getBehaviour()->execute(ai, dt);
448 executeParallel(func);
449 _groupManager.update(dt);
Maintains the groups a AI can be in.
Definition: GroupMgr.h:27