TDME2  1.9.200
Context.cpp
Go to the documentation of this file.
2 
3 #include <algorithm>
4 #include <deque>
5 #include <map>
6 #include <memory>
7 #include <set>
8 #include <string>
9 #include <unordered_set>
10 #include <vector>
11 
12 #include <tdme/tdme.h>
13 #include <tdme/audio/Audio.h>
14 #include <tdme/audio/AudioEntity.h>
15 #include <tdme/engine/fwd-tdme.h>
24 #include <tdme/engine/Object.h>
26 #include <tdme/engine/Transform.h>
30 #include <tdme/gui/GUI.h>
31 #include <tdme/math/Math.h>
34 #include <tdme/utilities/Console.h>
38 #include <tdme/utilities/Time.h>
39 
40 using std::copy;
41 using std::deque;
42 using std::make_unique;
43 using std::map;
44 using std::set;
45 using std::string;
46 using std::to_string;
47 using std::unique_ptr;
48 using std::unordered_set;
49 using std::vector;
50 
51 using tdme::audio::Audio;
67 using tdme::gui::GUI;
68 using tdme::math::Math;
76 
78 
79 Context::PathFindingThread::PathFindingThread(Context* context, int idx):
80  Thread("wscontext-pathfindingthread"),
81  context(context),
82  idx(idx),
83  timeStateStarted(-1LL),
84  state(STATE_IDLE),
85  alternativeEndSteps(0),
86  customTest(nullptr),
87  pathFindingMutex("pathfindingthread-mutex"),
88  pathFindingCancelMutex("pathfindingthread-cancel-mutex"),
89  worldActionsMutex("pathfindingthread-world-actions-mutex")
90 {
91  reset();
92  world = unique_ptr<World>(context->getWorld()->clone("pathfinding" + to_string(idx) + "-world-" + (context->isServer() == true?"server":"client"), context->bodyCollisionTypeIdCloneMask));
93  pathFinding = make_unique<tdme::utilities::PathFinding>(world.get(), true, 1000, 1.8f, 0.4f, 0.81f, 0.4f, context->skipOnBodyCollisionTypeIdMask, 5, 0.5f, 2.0f);
94 }
95 
97 }
98 
99 void Context::PathFindingThread::PathFindingThread::reset() {
100  this->state = STATE_IDLE;
101  this->timeStateStarted = -1LL;
102  this->logicId.clear();
103  this->startPosition.set(0.0f, 0.0f, 0.0f);
104  this->endPosition.set(0.0f, 0.0f, 0.0f);
105  this->actorId.clear();
106  this->alternativeEndSteps = 0;
107  this->customTest = nullptr;
108  this->path.clear();
109  this->flowMap = nullptr;
110  this->createFlowMap = false;
111  this->flowMapWidth = 0.0f;
112  this->flowMapDepth = 0.0f;
113  this->flowMap = nullptr;
114 }
115 
117  worldActionsMutex.lock();
118  worldActions.push_back(action);
119  worldActionsMutex.unlock();
120 }
121 
123  const string& logicId,
124  const string& actorId,
125  const Vector3& startPosition,
126  const Vector3& endPosition,
127  vector<Vector3>& path,
128  int alternativeEndSteps,
129  PathFindingCustomTest* customTest,
130  bool createFlowMap,
131  const vector<Vector3> flowMapEndPositions,
132  const float flowMapWidth,
133  const float flowMapDepth,
134  FlowMap** flowMap
135  ) {
136  if (pathFindingMutex.tryLock() == false) {
137  return State::STATE_TRYLOCK_FAILED;
138  }
139  switch(state) {
140  case STATE_IDLE:
141  break;
142  case STATE_PATHFINDING:
143  if (this->actorId != actorId) {
144  pathFindingMutex.unlock();
145  return State::STATE_PATHFINDING_OTHER;
146  }
147  pathFindingMutex.unlock();
148  return STATE_PATHFINDING;
149  case STATE_PATHFINDING_FAILED:
150  if (this->actorId != actorId) {
151  auto now = Time::getCurrentMillis();
152  if (now - timeStateStarted > 1000LL) {
153  Console::println("Context::PathFindingThread[" + to_string(idx) + "]::findPath(): path finding result timeout: " + logicId + ": resetting!");
154  reset();
155  }
156  pathFindingMutex.unlock();
157  return State::STATE_PATHFINDING_OTHER;
158  }
159  reset();
160  pathFindingMutex.unlock();
161  return STATE_PATHFINDING_FAILED;
162  case STATE_PATHFINDING_SUCCESS:
163  {
164  if (this->actorId != actorId) {
165  auto now = Time::getCurrentMillis();
166  if (now - timeStateStarted > 1000LL) {
167  Console::println("Context::PathFindingThread[" + to_string(idx) + "]::findPath(): path finding result timeout: " + logicId + ": resetting!");
168  reset();
169  }
170  pathFindingMutex.unlock();
171  return State::STATE_PATHFINDING_OTHER;
172  }
173  path = this->path;
174  if (this->endPosition.equals(endPosition) == false) {
175  Console::println("Context::PathFindingThread[" + to_string(idx) + "]::findPath(): " + actorId + ": position changed!");
176  }
177  auto returnState = endPosition.equals(this->endPosition) == true?STATE_PATHFINDING_SUCCESS:State::STATE_PATHFINDING_OTHER;
178  if (createFlowMap == true) {
179  if (returnState == false) {
180  this->flowMap->releaseReference();
181  this->flowMap = nullptr;
182  } else {
183  *flowMap = this->flowMap;
184  }
185  }
186  reset();
187  pathFindingMutex.unlock();
188  return returnState;
189  }
190  default:
191  break;
192  }
193  auto flowMapRequestIt = flowMapRequests.find(actorId);
194  if (flowMapRequestIt != flowMapRequests.end()) {
195  auto& flowMapRequest = flowMapRequestIt->second;
196  if (flowMapRequest.flowMap != nullptr) {
197  flowMapRequest.flowMap->releaseReference();
198  }
199  flowMapRequests.erase(flowMapRequestIt);
200  }
201  this->logicId = logicId;
202  this->startPosition = startPosition;
203  this->endPosition = endPosition;
204  this->actorId = actorId;
205  this->alternativeEndSteps = alternativeEndSteps;
206  this->customTest = customTest;
207  this->createFlowMap = createFlowMap;
208  this->flowMapWidth = flowMapWidth;
209  this->flowMapDepth = flowMapDepth;
210  this->flowMap = nullptr;
211  state = STATE_PATHFINDING;
212  timeStateStarted = Time::getCurrentMillis();
213  pathFindingMutex.unlock();
214  return STATE_PATHFINDING;
215 }
216 
218  if (pathFindingMutex.tryLock() == false) return FLOWMAPEXTENSIONSTATE_TRYLOCK_FAILED;
219  auto flowMapRequestIt = flowMapRequests.find(actorId);
220  if (flowMapRequestIt == flowMapRequests.end()) {
221  pathFindingMutex.unlock();
222  return FLOWMAPEXTENSIONSTATE_REQUEST_NONE;
223  }
224  auto& flowMapRequest = flowMapRequestIt->second;
225  *flowMap = flowMapRequest.flowMap;
226  flowMapRequest.flowMap = nullptr;
227  if (flowMapRequest.pathIdx >= flowMapRequest.path.size()) {
228  flowMapRequests.erase(flowMapRequestIt);
229  pathFindingMutex.unlock();
230  return FLOWMAPEXTENSIONSTATE_REQUEST_FINISHED;
231  }
232  pathFindingMutex.unlock();
233  return FLOWMAPEXTENSIONSTATE_REQUEST_NOTFINISHED;
234 }
235 
236 void Context::PathFindingThread::cancel(const string& actorId) {
237  pathFindingCancelMutex.lock();
238  cancelActorIds.push_back(actorId);
239  pathFindingCancelMutex.unlock();
240 }
241 
243  Console::println(string(context->server == true?"SERVER::":"CLIENT") + "|ws::Context::PathFindingThread[" + to_string(idx) + "]::run(): init");
244  while (isStopRequested() == false) {
245  // synch path finding physics world with world
246  context->logicsMutex->lock();
247  worldActionsMutex.lock();
248  auto worldActionsCopy = worldActions;
249  worldActions.clear();
250  worldActionsMutex.unlock();
251  if (worldActionsCopy.size() > 0) {
252  pathFinding->reset();
253  }
254  for (const auto& worldActionStruct: worldActionsCopy) {
255  if (worldActionStruct.action == WorldActionStruct::ACTION_ADDED) {
256  if ((worldActionStruct.collisionTypeId & context->bodyCollisionTypeIdCloneMask) != 0) {
257  world->addStaticRigidBody(
258  worldActionStruct.id,
259  worldActionStruct.collisionTypeId,
260  worldActionStruct.enabled,
261  worldActionStruct.transform,
262  worldActionStruct.friction,
263  worldActionStruct.boundingVolumes
264  );
265  }
266  } else
267  if (worldActionStruct.action == WorldActionStruct::ACTION_REMOVED) {
268  if (worldActionStruct.collisionTypeId & context->bodyCollisionTypeIdCloneMask != 0) {
269  world->removeBody(
270  worldActionStruct.id
271  );
272  }
273  }
274  }
275  worldActions.clear();
276  context->logicsMutex->unlock();
277 
278  // do cancelling
279  pathFindingMutex.lock();
280  pathFindingCancelMutex.lock();
281  for (const auto& actorId: cancelActorIds) {
282  switch(state) {
283  case STATE_IDLE:
284  {
285  continue;
286  }
287  default:
288  break;
289  }
290  if (this->actorId != actorId) continue;
291  auto flowMapRequestIt = flowMapRequests.find(actorId);
292  if (flowMapRequestIt != flowMapRequests.end()) {
293  auto& flowMapRequest = flowMapRequestIt->second;
294  if (flowMapRequest.flowMap != nullptr) {
295  flowMapRequest.flowMap->releaseReference();
296  }
297  flowMapRequests.erase(flowMapRequestIt);
298  }
299  reset();
300  context->getPathFinding()->notifyCancel(actorId);
301  break;
302  }
303  cancelActorIds.clear();
304  pathFindingCancelMutex.unlock();
305 
306  // do pathfinding action
307  switch(state) {
308  case STATE_PATHFINDING:
309  if (createFlowMap == true) {
310  if (pathFinding->findFlowMapPath(
311  startPosition,
312  endPosition,
313  context->bodyCollisionTypeIdMask,
314  path,
315  alternativeEndSteps/*,
316  customTest*/
317  ) == true) {
318  timeStateStarted = Time::getCurrentMillis();
319  auto pathIdx = 0;
320  if (path.size() > 20) {
321  FlowMapRequest flowMapRequest;
322  flowMapRequest.flowMapWidth = flowMapWidth;
323  flowMapRequest.flowMapDepth = flowMapDepth;
324  flowMapRequest.pathIdx = 20;
325  flowMapRequest.path = path;
326  flowMapRequest.flowMap = nullptr;
327  flowMapRequests[actorId] = flowMapRequest;
328  }
329  vector<Vector3> partialPath(Math::min(path.size() - pathIdx, 20));
330  copy(path.begin() + pathIdx, path.begin() + pathIdx + Math::min(path.size() - pathIdx, 20), partialPath.begin());
331  this->flowMap = pathFinding->createFlowMap(
332  { partialPath[partialPath.size() - 1] },
333  Vector3(),
334  flowMapWidth,
335  flowMapDepth,
336  context->bodyCollisionTypeIdMask,
337  partialPath,
338  path.size() > 20?false:true
339  );
340  state = STATE_PATHFINDING_SUCCESS;
341  } else {
342  timeStateStarted = Time::getCurrentMillis();
343  state = STATE_PATHFINDING_FAILED;
344  }
345  } else {
346  if (pathFinding->findPath(
347  startPosition,
348  endPosition,
349  context->bodyCollisionTypeIdMask,
350  path,
351  alternativeEndSteps/*,
352  customTest*/
353  ) == true) {
354  timeStateStarted = Time::getCurrentMillis();
355  state = STATE_PATHFINDING_SUCCESS;
356  } else {
357  timeStateStarted = Time::getCurrentMillis();
358  state = STATE_PATHFINDING_FAILED;
359  }
360  }
361  break;
362  default:
363  for (auto& [flowMapRequestId, flowMapRequest]: flowMapRequests) {
364  if (flowMapRequest.flowMap != nullptr) continue;
365  auto pathIdx = flowMapRequest.pathIdx - 2;
366  auto partialPathLength = Math::min(flowMapRequest.path.size() - pathIdx, 22);
367  vector<Vector3> partialPath(partialPathLength);
368  copy(flowMapRequest.path.begin() + pathIdx, flowMapRequest.path.begin() + pathIdx + partialPathLength, partialPath.begin());
369  flowMapRequest.flowMap = pathFinding->createFlowMap(
370  { partialPath[partialPath.size() - 1] },
371  Vector3(),
372  flowMapRequest.flowMapWidth,
373  flowMapRequest.flowMapDepth,
374  context->bodyCollisionTypeIdMask,
375  partialPath,
376  pathIdx >= path.size()?true:false
377  );
378  flowMapRequest.pathIdx+= Math::min(flowMapRequest.path.size() - flowMapRequest.pathIdx, 20);
379  }
380  break;
381  }
382  pathFindingMutex.unlock();
383 
384  // get some rest
385  sleep(50L);
386  }
387  Console::println(string(context->server == true?"SERVER::":"CLIENT") + "|ws::Context::PathFindingThread[" + to_string(idx) + "]::run(): done");
388 }
389 
391  pathFindingMutex.lock();
392  auto _actorId = actorId;
393  pathFindingMutex.unlock();
394  return _actorId;
395 }
396 
397 Context::PathFinding::PathFinding(Context* context, int threadCount):
398  context(context),
399  actorThreadMapMutex("wspathfinding-threadmap-mutex")
400 {
402 }
403 
405  this->threadCount = threadCount > 0?threadCount:Math::clamp(static_cast<int>(Math::ceil(Thread::getHardwareThreadCount() / 3)), 1, 4);
406 }
407 
409  threads.resize(threadCount);
410  for (auto i = 0; i < threads.size(); i++) {
411  threads[i] = make_unique<PathFindingThread>(context, i);
412  }
413  for (const auto& thread: threads) thread->start();
414 }
415 
417  for (const auto& thread: threads) thread->stop();
418  for (const auto& thread: threads) thread->join();
419  threads.clear();
420 }
421 
423  for (const auto& thread: threads) thread->addWorldAction(action);
424 }
425 
427  for (const auto& thread: threads) thread->reset();
428 }
429 
431  const string& logicId,
432  const string& actorId,
433  const Vector3& startPosition,
434  const Vector3& endPosition,
435  vector<Vector3>& path,
436  int alternativeEndSteps,
437  PathFindingCustomTest* customTest,
438  bool createFlowMap,
439  const vector<Vector3> flowMapEndPositions,
440  const float flowMapWidth,
441  const float flowMapDepth,
442  FlowMap** flowMap
443  ) {
444  actorThreadMapMutex.lock();
445  auto actorThreadMapIt = actorThreadMap.find(actorId);
446  actorThreadMapMutex.unlock();
447  auto threadIdx = actorThreadMapIt == actorThreadMap.end()?-1:actorThreadMapIt->second;
448  if (threadIdx != -1) {
449  auto threadPathFindingState = threads[threadIdx]->findPath(
450  logicId,
451  actorId,
452  startPosition,
453  endPosition,
454  path,
455  alternativeEndSteps,
456  customTest,
457  createFlowMap,
458  flowMapEndPositions,
459  flowMapWidth,
460  flowMapDepth,
461  flowMap
462  );
463  switch(threadPathFindingState) {
465  actorThreadMapMutex.lock();
466  actorThreadMap.erase(actorId);
467  actorThreadMapMutex.unlock();
468  break;
472  actorThreadMapMutex.lock();
473  actorThreadMap.erase(actorId);
474  actorThreadMapMutex.unlock();
475  break;
479  actorThreadMapMutex.lock();
480  actorThreadMap.erase(actorId);
481  actorThreadMapMutex.unlock();
484  actorThreadMapMutex.lock();
485  actorThreadMap.erase(actorId);
486  actorThreadMapMutex.unlock();
488  }
489  }
490  for (const auto& thread: threads) {
491  auto threadPathFindingState = thread->findPath(
492  logicId,
493  actorId,
494  startPosition,
495  endPosition,
496  path,
497  alternativeEndSteps,
498  customTest,
499  createFlowMap,
500  flowMapEndPositions,
501  flowMapWidth,
502  flowMapDepth,
503  flowMap
504  );
505  switch(threadPathFindingState) {
507  break;
509  break;
511  break;
513  actorThreadMapMutex.lock();
514  actorThreadMap[actorId] = thread->getThreadIdx();
515  actorThreadMapMutex.unlock();
518  actorThreadMapMutex.lock();
519  actorThreadMap.erase(actorId);
520  actorThreadMapMutex.unlock();
523  actorThreadMapMutex.lock();
524  actorThreadMap.erase(actorId);
525  actorThreadMapMutex.unlock();
527  }
528  }
530 }
531 
532 bool Context::PathFinding::getFlowMapExtension(const string& actorId, FlowMap** flowMap) {
533  *flowMap = nullptr;
534  for (const auto& thread: threads) {
535  auto lastExtensionState = thread->getFlowMapExtension(actorId, flowMap);
536  switch(lastExtensionState) {
541  }
542  }
543  return false;
544 }
545 
546 void Context::PathFinding::cancel(const string& actorId) {
547  for (const auto& thread: threads) thread->cancel(actorId);
548 }
549 
550 void Context::PathFinding::notifyCancel(const string& actorId) {
551  actorThreadMapMutex.lock();
552  actorThreadMap.erase(actorId);
553  actorThreadMapMutex.unlock();
554 }
555 
557 }
558 
559 void Context::ContextWorldListener::onAddedBody(const string& id, Body::BodyType type, uint16_t collisionTypeId, bool enabled, const Transform& transform, float restitution, float friction, float mass, const Vector3& inertiaTensor, const vector<BoundingVolume*>& boundingVolumes, bool hierarchy) {
560  if (type != Body::BODYTYPE_STATIC) return;
563  worldAction.id = id;
564  worldAction.type = type;
565  worldAction.enabled = enabled;
566  worldAction.collisionTypeId = collisionTypeId;
567  worldAction.transform = transform;
568  worldAction.restitution = restitution;
569  worldAction.friction = friction;
570  worldAction.mass = mass;
571  worldAction.inertiaTensor = inertiaTensor;
572  worldAction.boundingVolumes = boundingVolumes;
573  worldAction.hierarchy = hierarchy;
574  context->getPathFinding()->addWorldAction(worldAction);
575 }
576 
577 void Context::ContextWorldListener::onRemovedBody(const string& id, Body::BodyType type, uint16_t collisionTypeId) {
578  if (type != Body::BODYTYPE_STATIC) return;
581  worldAction.id = id;
582  worldAction.type = type;
583  worldAction.collisionTypeId = collisionTypeId;
584  context->getPathFinding()->addWorldAction(worldAction);
585 }
586 
587 void Context::ContextWorldListener::onAddedSubBody(const string& id, Body::BodyType type, uint16_t collisionTypeId, const string& subBodyParentId, const string& subBodyId, const Transform& transform, const vector<BoundingVolume*>& boundingVolumes) {
588  // TODO
589 }
590 
591 void Context::ContextWorldListener::onRemovedSubBody(const string& id, Body::BodyType type, uint16_t collisionTypeId, const string& subBodyParentId, const string& subBodyId) {
592  // TODO
593 }
594 
596  Console::println("Context::Context(): " + to_string(server));
597  timeStarted = -1;
598 }
599 
601  Console::println("Context::~Context()");
602 }
603 
605  // TODO: pathfinding could be optional
606  // world listener
607  worldListener = make_unique<ContextWorldListener>(this);
608  world->addWorldListener(worldListener.get());
609 
610  // path finding thread
611  pathFinding.start();
612 
613  //
614  timeStarted = Time::getCurrentMillis();
615 
616  //
617  initialized = true;
618 }
619 
621  Console::println("Context::shutdown()");
622  //
623  world->removeWorldListener(worldListener.get());
625  //
626  for (auto logic: logics) delete logic;
627  logics.clear();
628  logicsById.clear();
629 }
630 
631 void Context::addLogic(Logic* logic) {
632  Console::println(string(server == true?"SERVER":"CLIENT") + "|Context::addLogic(): adding '" + logic->getId() + "'");
633  // check if exists in current game logics
634  if (logicsById.find(logic->getId()) != logicsById.end()) {
635  Console::println(string(server == true?"SERVER":"CLIENT") + "|Context::addLogic(): NOT adding '" + logic->getId() + "', logic exists!");
636  return;
637  }
638  // check if exists in new game logics
639  for (auto newLogic: newLogics) {
640  if (logic->getId() == newLogic->getId()) {
641  Console::println(string(server == true?"SERVER":"CLIENT") + "|Context::addLogic(): NOT adding '" + logic->getId() + "', logic exists!");
642  return;
643  }
644  }
645  //
646  newLogics.push_back(logic);
647  // call event
648  logic->onLogicAdded();
649 }
650 
651 
652 bool Context::doProcessPacket(NetworkLogic* logic, LogicNetworkPacket& packet, const string& key) {
653  auto now = Time::getCurrentMillis();
654 
655  // clean up packet states
656  vector<string> packetsToRemove;
657  for (const auto& [packetStateId, packetState]: packetStates) {
658  if (packetState.timeCreated > now - 120000L) {
659  packetsToRemove.push_back(packetStateId);
660  }
661  }
662  for (const auto& packetToRemove: packetsToRemove) {
663  // Console::println(string(server == true?"SERVER":"CLIENT") + "|Context::doProcessPacket(): " + packetToRemove + ": removing");
664  packetStates.erase(packetToRemove);
665  }
666 
667  // add packet state or report that we have processed it already
668  string _key;
669  _key+= logic->getNetworkPacketTypeId();
670  _key+= '_';
671  _key+= logic->getId();
672  _key+= '_';
673  _key+= key;
674  auto packetStateIt = packetStates.find(_key);
675  if (packetStateIt == packetStates.end()) {
676  PacketState packetState;
677  packetState.timeCreated = now;
678  packetState.messageId = packet.getMessageId();
679  packetStates[_key] = packetState;
680  // Console::println(string(server == true?"SERVER":"CLIENT") + "|Context::doProcessPacket(): " + _key + ": new (" + to_string(packetStates.size()) + ")");
681  return true;
682  } else {
683  auto& packetState = packetStateIt->second;
684  if (packet.getMessageId() <= packetState.messageId) {
685  return packet.isReinjected() == true && packet.isProcessed() == false;
686  } else {
687  packetState.messageId = packet.getMessageId();
688  packetState.timeCreated = Time::getCurrentMillis();
689  // Console::println(string(server == true?"SERVER":"CLIENT") + "|Context::doProcessPacket(): " + _key + " " + to_string(packet.getMessageId()) + " > " + to_string(packetState.messageId) + " " + to_string(packetStates.size()) + ")");
690  return true;
691  }
692  }
693 }
694 
695 void Context::unsetProcessPacket(NetworkLogic* logic, LogicNetworkPacket& packet, const string& key) {
696  // add packet state or report that we have processed it already
697  string _key;
698  _key+= logic->getNetworkPacketTypeId();
699  _key+= '_';
700  _key+= logic->getId();
701  _key+= '_';
702  _key+= key;
703  auto packetStateIt = packetStates.find(_key);
704  if (packetStateIt != packetStates.end()) {
705  packetStates.erase(packetStateIt);
706  }
707 }
708 
709 
711 }
712 
714 }
715 
717 }
718 
720 }
Audio entity base class.
Definition: AudioEntity.h:19
Interface to audio module.
Definition: Audio.h:29
Engine main class.
Definition: Engine.h:131
Object to be used with engine class.
Definition: Object.h:60
Scene engine/physics connector.
Transform which contain scale, rotations and translation.
Definition: Transform.h:29
void onAddedSubBody(const string &id, Body::BodyType type, uint16_t collisionTypeId, const string &subBodyParentId, const string &subBodyId, const Transform &transform, const vector< BoundingVolume * > &boundingVolumes) override
Definition: Context.cpp:587
void onAddedBody(const string &id, Body::BodyType type, uint16_t collisionTypeId, bool enabled, const Transform &transform, float restitution, float friction, float mass, const Vector3 &inertiaTensor, const vector< BoundingVolume * > &boundingVolumes, bool hierarchy=false) override
Definition: Context.cpp:559
ContextWorldListener(Context *context)
Constructor.
Definition: Context.cpp:556
void onRemovedBody(const string &id, Body::BodyType type, uint16_t collisionTypeId) override
Definition: Context.cpp:577
void onRemovedSubBody(const string &id, Body::BodyType type, uint16_t collisionTypeId, const string &subBodyParentId, const string &subBodyId) override
Definition: Context.cpp:591
unique_ptr< tdme::utilities::PathFinding > pathFinding
Definition: Context.h:129
State findPath(const string &logicId, const string &actorId, const Vector3 &startPosition, const Vector3 &endPosition, vector< Vector3 > &path, int alternativeEndSteps=0, PathFindingCustomTest *customTest=nullptr, bool createFlowMap=false, const vector< Vector3 > flowMapEndPositions=vector< Vector3 >(), const float flowMapWidth=0.0, const float flowMapDepth=0.0, FlowMap **flowMap=nullptr)
Find path.
Definition: Context.cpp:122
FlowMapExtensionState getFlowMapExtension(const string &actorId, FlowMap **flowMap)
Get flow map extension.
Definition: Context.cpp:217
void cancel(const string &actorId)
Cancel.
Definition: Context.cpp:236
void addWorldAction(const WorldActionStruct &action)
Add world action.
Definition: Context.cpp:116
void reset()
Reset current path finding.
virtual ~PathFindingThread()
Public destructor.
Definition: Context.cpp:96
void notifyCancel(const string &actorId)
Notify a cancelled actor path finding.
Definition: Context.cpp:550
void setThreadCount(int threadCount)
Set thread count.
Definition: Context.cpp:404
PathFindingThread::State findPath(const string &logicId, const string &actorId, const Vector3 &startPosition, const Vector3 &endPosition, vector< Vector3 > &path, int alternativeEndSteps=0, PathFindingCustomTest *customTest=nullptr, bool createFlowMap=false, const vector< Vector3 > flowMapEndPositions=vector< Vector3 >(), const float flowMapWidth=0.0, const float flowMapDepth=0.0, FlowMap **flowMap=nullptr)
Find path.
Definition: Context.cpp:430
void start()
Start path finding.
Definition: Context.cpp:408
void addWorldAction(const Context::PathFindingThread::WorldActionStruct &action)
Add world action.
Definition: Context.cpp:422
void shutdown()
Shutdown path finding.
Definition: Context.cpp:416
void cancel(const string &actorId)
Cancel.
Definition: Context.cpp:546
bool getFlowMapExtension(const string &actorId, FlowMap **flowMap)
Get flow map extension.
Definition: Context.cpp:532
PathFinding(Context *context, int threadCount=0)
Public constructor.
Definition: Context.cpp:397
void reset()
Reset current path finding.
Definition: Context.cpp:426
unordered_map< string, PacketState > packetStates
Definition: Context.h:365
unique_ptr< ContextWorldListener > worldListener
Definition: Context.h:360
virtual void initialize()
Initialize logics.
Definition: Context.cpp:604
bool doProcessPacket(NetworkLogic *logic, LogicNetworkPacket &packet, const string &key)
Returns if to process packet or not.
Definition: Context.cpp:652
void unsetProcessPacket(NetworkLogic *logic, LogicNetworkPacket &packet, const string &key)
Unsets if to process packet or not.
Definition: Context.cpp:695
volatile bool initialized
Definition: Context.h:358
Context(bool server)
Public constructor.
Definition: Context.cpp:595
virtual void doneUpdateLogics()
Logics finalizations, which is called once per logics updates.
Definition: Context.cpp:719
vector< Logic * > newLogics
Definition: Context.h:364
virtual void initUpdateLogics()
Logics initialization, which is called once per logics updates.
Definition: Context.cpp:716
uint16_t bodyCollisionTypeIdCloneMask
Definition: Context.h:354
virtual void shutdown()
Shut down logics.
Definition: Context.cpp:620
unordered_map< string, Logic * > logicsById
Definition: Context.h:362
virtual void doneUpdateEngine()
Update engine done, which is called once per frame after calling logic updateEngine() methods.
Definition: Context.cpp:713
virtual ~Context()
Destructor.
Definition: Context.cpp:600
vector< Logic * > logics
Definition: Context.h:363
unique_ptr< World > world
Definition: Context.h:371
uint16_t skipOnBodyCollisionTypeIdMask
Definition: Context.h:353
virtual void initUpdateEngine()
Update engine initialization, which is called once per frame before calling logic updateEngine() meth...
Definition: Context.cpp:710
void addLogic(Logic *logic)
Add logic.
Definition: Context.cpp:631
virtual void onLogicAdded()
On logic added.
Definition: Logic.cpp:23
const string & getId()
Definition: Logic.h:96
virtual uint32_t getNetworkPacketTypeId()=0
Rigid body class.
Definition: Body.h:41
Dynamic physics world class.
Definition: World.h:38
World * clone(const string &id, uint16_t collisionTypeIds=~0)
Clone this world.
Definition: World.cpp:571
Scene entity definition.
Definition: SceneEntity.h:23
Scene definition.
Definition: Scene.h:50
GUI module class.
Definition: GUI.h:64
GUI screen node that represents a screen that can be rendered via GUI system.
Definition: GUIScreenNode.h:72
Standard math functions.
Definition: Math.h:19
Vector3 class representing vector3 mathematical structure and operations with x, y,...
Definition: Vector3.h:20
bool equals(const Vector3 &vector3, float tolerance=Math::EPSILON) const
Compares this vector3 with given vector3.
Definition: Vector3.h:226
Mutex implementation.
Definition: Mutex.h:19
Base class for threads.
Definition: Thread.h:20
Console class.
Definition: Console.h:29
Path finding class.
Definition: PathFinding.h:51
virtual void releaseReference()
Releases a reference, thus decrementing the counter and delete it if reference counter is zero.
Definition: Reference.h:38
String tools class.
Definition: StringTools.h:22
Time utility class.
Definition: Time.h:20
World listener which is about notifying adding or removing bodies.
Definition: WorldListener.h:23
Path finding custom test interface.