TrueReality  v0.1.1912
SystemManager.cpp
Go to the documentation of this file.
1 /*
2 * True Reality Open Source Game and Simulation Engine
3 * Copyright © 2021 Acid Rain Studios LLC
4 *
5 * This library is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU Lesser General Public License as published by the Free
7 * Software Foundation; either version 3.0 of the License, or (at your option)
8 * any later version.
9 *
10 * This library is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 * details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library; if not, write to the Free Software Foundation, Inc.,
17 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * @author Maxim Serebrennik
20 */
21 
23 
26 #include <trManager/DirectorBase.h>
27 #include <trManager/EntityType.h>
28 #include <trManager/Invokable.h>
30 #include <trUtil/Logging/Log.h>
31 #include <trBase/SmrtPtr.h>
32 
33 
34 #include <string>
35 
36 namespace trManager
37 {
38  const trUtil::RefStr SystemManager::CLASS_TYPE = trUtil::RefStr("trManager::SystemManager");
39 
40  // System Manager singleton holder
42 
43 
45  SystemManager::SystemManager(const std::string name) : BaseClass(name)
46  {
47  }
48 
51  {
52  }
53 
56  {
57  if (!mInstance.Valid())
58  {
59  mInstance = new SystemManager();
60  }
61  return *mInstance;
62  }
63 
65  const std::string& SystemManager::GetType() const
66  {
67  return CLASS_TYPE;
68  }
69 
72  {
74  return true;
75  }
76 
79  {
81  return true;
82  }
83 
86  {
87  //Send messages to Directors
88  SendMessageToDirectors(message);
89 
90  //Sends the passed in message to appropriate actors
91  SendMessageToActors(message);
92 
93  //Sends the passed in message to Entities that are listening for intercepts.
94  SendMessageToListeners(message);
95  }
96 
99  {
100  //Go through all stored messages and send them out...
101  while (!mMessageQueue.empty())
102  {
103  ProcessMessage(*mMessageQueue.front().Get());
104 
105  //Removed the handled message
106  mMessageQueue.pop();
107  }
108  }
109 
112  {
113  //Go through all stored messages and send them out...
114  while (!mNetworkMessageQueue.empty())
115  {
116  //Send messages to Directors
118 
119  //Removed the handled message
120  mNetworkMessageQueue.pop();
121  }
122  }
123 
125  void SystemManager::RegisterForMessage(const std::string& messageType, EntityBase& listeningActor, const std::string& invokableName)
126  {
127  //Determine what kind of entity we are dealing with.
128  if (listeningActor.GetEntityType() == EntityType::ACTOR)
129  {
130  RegisterMsgWithMsgVectorMap(messageType, listeningActor, invokableName, mEntityGlobalMsgRegistrationMap);
131  }
132  else if (listeningActor.GetEntityType() == EntityType::ACTOR_MODULE)
133  {
134  RegisterMsgWithMsgVectorMap(messageType, listeningActor, invokableName, mEntityGlobalMsgRegistrationMap);
135  }
136  else if (listeningActor.GetEntityType() == EntityType::DIRECTOR)
137  {
138  RegisterMsgWithMsgMap(messageType, listeningActor, invokableName, mDirectorGlobalMsgRegistrationMap);
139  }
140  }
141 
143  void SystemManager::UnregisterFromMessage(const std::string& messageType, EntityBase& listeningActor)
144  {
145  //Determine what kind of entity we are dealing with.
146  if (listeningActor.GetEntityType() == EntityType::ACTOR)
147  {
149  }
150  else if (listeningActor.GetEntityType() == EntityType::ACTOR_MODULE)
151  {
153  }
154  else if (listeningActor.GetEntityType() == EntityType::DIRECTOR)
155  {
156  UnregisterMsgFromMsgMap(messageType, listeningActor, mDirectorGlobalMsgRegistrationMap);
157  }
158  }
159 
161  void SystemManager::RegisterForMessagesAboutEntity(EntityBase& listeningEntity, const trBase::UniqueId& aboutEntityId, const std::string & invokableName)
162  {
163  //Find the vector with message registrations, or create a new one
164  std::vector<EntityInvokablePair>* msgRegistrantsPtr = &mListenerRegistrationMap[aboutEntityId];
165 
166  //Check if we already have this entity with this invokable registered
167  bool registrantFound = false;
168  for (unsigned int i = 0; i < msgRegistrantsPtr->size(); ++i)
169  {
170  if (msgRegistrantsPtr->at(i).first == &listeningEntity)
171  {
172  registrantFound = true;
173  LOG_W("The Entity: " + listeningEntity.GetName() + " attempted to register for messages about an actor through invokable: " + invokableName + ". It is already registered through invokable: " + msgRegistrantsPtr->at(i).second)
174  break;
175  }
176  }
177 
178  //If the registration does not exist, make one and create an Invokable
179  if (!registrantFound)
180  {
181  //Register the Entity-Invokable pair
182  msgRegistrantsPtr->push_back(EntityInvokablePair(trBase::SmrtPtr<EntityBase>(&listeningEntity), invokableName));
183  LOG_D("Registering Entity: " + listeningEntity.GetName() + " for messages about an actor through invokable: " + invokableName)
184  }
185  }
186 
189  {
190  //Find if this actor has listeners
191  UUIDRegistrationVectorMap::iterator it = mListenerRegistrationMap.find(aboutEntityId);
192  if (it != mListenerRegistrationMap.end())
193  {
194  //Find if the entity is registered
195  std::vector<EntityInvokablePair>* msgRegistrantsPtr = &it->second;
196  for (unsigned int i = 0; i < msgRegistrantsPtr->size(); ++i)
197  {
198  //Unregister the entity
199  if (msgRegistrantsPtr->at(i).first == &listeningEntity)
200  {
201  msgRegistrantsPtr->erase(msgRegistrantsPtr->begin() + i);
202  LOG_D("Unregistered Entity: " + listeningEntity.GetName() + " from listening to messages about an actor.")
203  break;
204  }
205  }
206 
207  //If no more entities are registered for this message, remove message entry
208  if (msgRegistrantsPtr->size() == 0)
209  {
210  mListenerRegistrationMap.erase(it);
211  }
212  }
213  else
214  {
215  LOG_W("Invalid attempt to unregister the Entity: " + listeningEntity.GetName() + " from listening to messages about an actor.")
216  }
217  }
218 
221  {
222  //Check if the actor is already registered
223  if (FindActor(actor.GetUUID()) != nullptr)
224  {
225  std::string errorText = "An actor/actor module with the same ID is already registered with the System Manager.";
226  LOG_E(errorText);
227  throw trUtil::ExceptionInvalidParameter(errorText, __FILE__, __LINE__);
228  return false;
229  }
230 
231  //Add the actor to the storage containers.
232  trBase::SmrtPtr<trManager::EntityBase> newActor = &actor;
233 
234  mActorList.push_back(newActor);
235  mActorIDMap[actor.GetUUID()] = newActor;
236 
237  //Set the director registration status
238  actor.SetSystemManager(this);
239  actor.SetRegistration(true);
240 
241  //Call the OnAddedToSysMan callback.
242  actor.OnAddedToSysMan();
243 
244  //Notify everyone that a new Entity was added
245  SendMessage(*new trManager::MessageEntityRegistered(&GetUUID(), &actor.GetUUID(), &actor.GetType(), &actor.GetName()));
246  LOG_D("Registered " + actor.GetName() + " of type: " + actor.GetType() + " with System Manager.")
247 
248  return true;
249  }
250 
253  {
254  //Find the Actor instance with the same passed in reference
255  ActorList::iterator found;
256  for (found = mActorList.begin(); found != mActorList.end(); ++found)
257  {
258  if (found->Get() == &actor)
259  {
260  //We found the actor we need
261  break;
262  }
263  }
264 
265  if (found != mActorList.end())
266  {
267  //Add the entity to the delete list.
268  mEntityDeleteList.push_back(trBase::SmrtPtr<trManager::EntityBase>(static_cast<trManager::EntityBase*>(found->Get())));
269 
270  UnregisterActorFromGlobalMessages(*found->Get()); // Unregister the entity from all messages
271  UnregisterEntityFromAboutMessages(*found->Get()); // Unregister the entity from all About messages
272 
273  mActorIDMap.erase((*found)->GetUUID()); // Erase the node from the list by ID key
274  mActorList.erase(found); // Erase the node from the list
275 
276  //Notify everyone that an Entity was removed
277  SendMessage(*new trManager::MessageEntityUnregistered(&GetUUID(), &actor.GetUUID(), &actor.GetType(), &actor.GetName()));
278  LOG_D("Unregistered " + actor.GetName() + " of type: " + actor.GetType() + " from System Manager.")
279 
280  return true;
281  }
282  else
283  {
284  LOG_W("Attempted to unregister a none registered Actor: " + actor.GetName())
285  return false;
286  }
287  }
288 
291  {
292  return UnregisterActor(*FindActor(id));
293  }
294 
297  {
298  while (!mActorList.empty())
299  {
300  UnregisterActor(*mActorList.back());
301  }
302  return true;
303  }
304 
307  {
308  ActorIDMap::const_iterator it = mActorIDMap.find(id);
309  if (it != mActorIDMap.end()) //Make sure we have a found value and are not at the end
310  {
311  //Return the stored value
312  return it->second.Get();
313  }
314  else
315  {
316  return nullptr;
317  }
318  }
319 
321  std::vector<trManager::EntityBase*> SystemManager::FindActorsByType(const std::string& actorType)
322  {
323  std::vector<trManager::EntityBase*> actorList;
324 
326  {
327  if (i->GetType() == actorType)
328  {
329  if (i->GetEntityType() == EntityType::ACTOR)
330  {
331  actorList.push_back(i);
332  }
333  }
334  }
335 
336  return actorList;
337  }
338 
340  std::vector<trManager::EntityBase*> SystemManager::FindActorsByName(const std::string& actorName)
341  {
342  std::vector<trManager::EntityBase*> actorList;
343 
345  {
346  if (i->GetName() == actorName)
347  {
348  if (i->GetEntityType() == EntityType::ACTOR)
349  {
350  actorList.push_back(i);
351  }
352  }
353  }
354 
355  return actorList;
356  }
357 
360  {
361  //Check to see if we need to skip the Directors
362  if (!message.GetIsDirect())
363  {
364  EntityInvokableMap* entityInvokableMapPtr = nullptr;
365  EntityInvokableMap::iterator entityInvokableIt;
366 
367  //Find this messages listener list
368  MessageRegistrationMap::iterator listenerIt;
369  listenerIt = mDirectorGlobalMsgRegistrationMap.find(const_cast<std::string*>(&message.GetMessageType()));
370 
371  //Send messages to all Directors in the list
374  {
375  //Make sure the director is not sending a message to itself
376  if (dir->GetUUID() != *message.GetFromActorID())
377  {
378  directorRef = static_cast<trManager::EntityBase*>(dir.Get());
379 
380  //If the listener list is not empty
381  if (listenerIt != mDirectorGlobalMsgRegistrationMap.end())
382  {
383  //Find if the entity is registered
384  entityInvokableMapPtr = &listenerIt->second;
385 
386  //Check if the Director is in the listener list
387  entityInvokableIt = entityInvokableMapPtr->find(directorRef);
388  if (entityInvokableIt != entityInvokableMapPtr->end())
389  {
390  //If the director is on the list, send the message to the registered Invokable
391  CallInvokable(message, entityInvokableIt->second, *directorRef);
392  }
393  else
394  {
395  //If the Director is not in the listener list, send the message to the default OnMessage function
396  CallInvokable(message, EntityBase::ON_MESSAGE_INVOKABLE, *directorRef);
397  }
398  }
399  else
400  {
401  //If the messages listener list is empty, use the directors default OnMessage function
402  CallInvokable(message, EntityBase::ON_MESSAGE_INVOKABLE, *directorRef);
403  }
404  }
405  }
406  }
407  }
408 
411  {
412  //Find this messages listener list
413  MessageRegistrationVectorMap::iterator listenerIt = mEntityGlobalMsgRegistrationMap.find(const_cast<std::string*>(&message.GetMessageType()));
414 
415  //Check if anyone registered for this message
416  if (listenerIt != mEntityGlobalMsgRegistrationMap.end())
417  {
418  //Go through the listener list, and send the message to each listening actor
419  std::vector<EntityInvokablePair>* listenerList = &listenerIt->second;
420  for (EntityInvokablePair ent : *listenerList)
421  {
422  //Make sure the entity is not sending a message to itself
423  if (ent.first->GetUUID() != *message.GetFromActorID())
424  {
425  CallInvokable(message, ent.second, *ent.first.Get());
426  }
427  }
428  }
429  }
430 
433  {
434  if (message.GetAboutActorID() != nullptr)
435  {
436  //Find this messages listener list
437  UUIDRegistrationVectorMap::iterator listenerIt = mListenerRegistrationMap.find(*message.GetAboutActorID());
438 
439  //Check if anyone registered for this message
440  if (listenerIt != mListenerRegistrationMap.end())
441  {
442  //Go through the listener list, and send the message to each listening actor
443  std::vector<EntityInvokablePair>* listenerList = &listenerIt->second;
444  for (EntityInvokablePair ent : *listenerList)
445  {
446  //Make sure the entity is not sending a message to itself
447  if (ent.first->GetUUID() != *message.GetFromActorID())
448  {
449  CallInvokable(message, ent.second, *ent.first.Get());
450  }
451  }
452  }
453  }
454  }
455 
458  {
459  MessageRegistrationVectorMap::iterator it;
460 
461  //Find if this message has listeners
462  it = mEntityGlobalMsgRegistrationMap.find(const_cast<std::string*>(&message.GetMessageType()));
463  if (it != mEntityGlobalMsgRegistrationMap.end())
464  {
465  //Create an invokable pointer
466  trManager::Invokable* invokablePtr = nullptr;
467 
468  //Get the vector of registered Entities for the message <entity, invokableName>
469  std::vector<EntityInvokablePair>* msgRegistrantsPtr = &it->second;
470 
471  for (unsigned int i = 0; i < msgRegistrantsPtr->size(); ++i)
472  {
473  //Grab a hold of the entity in a smart pointer
474  trBase::SmrtPtr<trManager::EntityBase> actor = msgRegistrantsPtr->at(i).first;
475 
476  if (actor->IsRegistered())
477  {
478  //Get the Invokable from the Entity by passing the Invokables name.
479  invokablePtr = actor->GetInvokable(msgRegistrantsPtr->at(i).second);
480 
481  if (invokablePtr != nullptr)
482  {
483  invokablePtr->Invoke(message);
484  }
485  }
486 
487  }
488  }
489  }
490 
492  void SystemManager::CallInvokable(const trManager::MessageBase& message, const std::string& invokableName, trManager::EntityBase& entity)
493  {
494  Invokable* invokablePtr = entity.GetInvokable(invokableName);
495 
496  //Check if requested Invokable exists
497  if (invokablePtr != nullptr)
498  {
499  LOG_D("Calling Invokable: " + invokablePtr->GetName() + " on " + entity.GetName())
500  invokablePtr->Invoke(message);
501  }
502  else
503  {
504  LOG_E("Invokable: " + invokableName + " was called, but the Entity: " + entity.GetName() + " does not have an invokable by that name.")
505  }
506  }
507 
510  {
511  std::vector<EntityInvokablePair>* msgRegistrantsPtr = nullptr;
512 
513  //Iterate through the Message-EntityInvokablePair registration map for each message type
514  //MessageRegistrationVectorMap::iterator listenerIt
515  for (auto&& listenerIt = mEntityGlobalMsgRegistrationMap.begin(); listenerIt != mEntityGlobalMsgRegistrationMap.end();)
516  {
517  //Iterate through the vector of Entities-Invokables
518  msgRegistrantsPtr = &listenerIt->second;
519  for (unsigned int i = 0; i<msgRegistrantsPtr->size(); ++i)
520  {
521  //If we found a matching entity registration, delete it
522  if (msgRegistrantsPtr->at(i).first == &actor)
523  {
524  msgRegistrantsPtr->erase(msgRegistrantsPtr->begin() + i);
525  break;
526  }
527  }
528 
529  //If the Entities-Invokables vector is empty, the message registration should be removed.
530  if (msgRegistrantsPtr->empty())
531  {
532  listenerIt = mEntityGlobalMsgRegistrationMap.erase(listenerIt);
533  }
534  else
535  {
536  ++listenerIt;
537  }
538  }
539  }
540 
543  {
544  if (director.GetEntityType() == EntityType::DIRECTOR)
545  {
546  //Iterate through the Message-Entity registration map
547  //MessageRegistrationMap::iterator listenerIt
548  for (auto&& listenerIt = mDirectorGlobalMsgRegistrationMap.begin(); listenerIt != mDirectorGlobalMsgRegistrationMap.end();)
549  {
550  //Iterate through Entity-Invokable map that relates to the given message
551  //EntityInvokableMap::iterator directorIt
552  for (auto&& directorIt = listenerIt->second.begin(); directorIt != listenerIt->second.end();)
553  {
554  //If we found a matching director registration, delete it
555  if (directorIt->first->GetUUID() == director.GetUUID())
556  {
557  //Delete the registration, and exit the loop since there should be only one entity registration per message
558  directorIt = listenerIt->second.erase(directorIt);
559  break;
560  }
561  else
562  {
563  ++directorIt;
564  }
565  }
566 
567  //If we just deleted the last registrant for this message, delete the message registration
568  if (listenerIt->second.empty())
569  {
570  listenerIt = mDirectorGlobalMsgRegistrationMap.erase(listenerIt);
571  }
572  else
573  {
574  ++listenerIt;
575  }
576  }
577  }
578  else
579  {
580  LOG_E("The Entity: " + director.GetName() + " is not a Director.")
581  }
582  }
583 
586  {
587  std::vector<EntityInvokablePair>* msgRegistrantsPtr = nullptr;
588 
589  //Iterate through all Entities one by one to access their listener lists.
590  for (auto&& listenerIt = mListenerRegistrationMap.begin(); listenerIt != mListenerRegistrationMap.end();)
591  {
592  //Iterate through the vector of Entities-Invokables
593  msgRegistrantsPtr = &listenerIt->second;
594  for (unsigned int i = 0; i<msgRegistrantsPtr->size(); ++i)
595  {
596  //If we found a matching entity registration, delete it
597  if (msgRegistrantsPtr->at(i).first == &listeningEntity)
598  {
599  msgRegistrantsPtr->erase(msgRegistrantsPtr->begin() + i);
600  break;
601  }
602  }
603 
604  //If the Entities-Invokables vector is empty, the message registration should be removed.
605  if (msgRegistrantsPtr->empty())
606  {
607  listenerIt = mListenerRegistrationMap.erase(listenerIt);
608  }
609  else
610  {
611  ++listenerIt;
612  }
613  }
614  }
615 
617  void SystemManager::RegisterMsgWithMsgVectorMap(const std::string& messageType, EntityBase& listeningEntity, const std::string& invokableName, MessageRegistrationVectorMap& messageMap)
618  {
619  //Find the vector with message registrations, or create a new one
620  std::vector<EntityInvokablePair>* msgRegistrantsPtr = &messageMap[const_cast<std::string*>(&messageType)];
621 
622  //Check if we already have this entity with this invokable registered
623  bool registrantFound = false;
624  for (unsigned int i = 0; i < msgRegistrantsPtr->size(); ++i)
625  {
626  if (msgRegistrantsPtr->at(i).first == &listeningEntity)
627  {
628  registrantFound = true;
629  LOG_W("The Entity: " + listeningEntity.GetName() + " attempted to register for message: " + messageType + " through invokable: " + invokableName + ". It is already registered through invokable: " + msgRegistrantsPtr->at(i).second)
630  break;
631  }
632  }
633 
634  //If the registration does not exist, make one and create an Invokable
635  if (!registrantFound)
636  {
637  //Register the Entity-Invokable pair
638  msgRegistrantsPtr->push_back(EntityInvokablePair(trBase::SmrtPtr<EntityBase>(&listeningEntity), invokableName));
639  LOG_D("Registering Entity: " + listeningEntity.GetName() + " for message: " + messageType + " through invokable: " + invokableName)
640  }
641  }
642 
644  void SystemManager::UnregisterMsgFromMsgVectorMap(const std::string& messageType, EntityBase& listeningEntity, MessageRegistrationVectorMap& messageMap)
645  {
646  //Find if this message has listeners
647  MessageRegistrationVectorMap::iterator it = messageMap.find(const_cast<std::string*>(&messageType));
648  if (it != messageMap.end())
649  {
650  //Find if the entity is registered
651  std::vector<EntityInvokablePair>* msgRegistrantsPtr = &it->second;
652  for (unsigned int i = 0; i < msgRegistrantsPtr->size(); ++i)
653  {
654  //Unregister the entity
655  if (msgRegistrantsPtr->at(i).first == &listeningEntity)
656  {
657  msgRegistrantsPtr->erase(msgRegistrantsPtr->begin() + i);
658  LOG_D("Unregistered Entity: " + listeningEntity.GetName() + " from message: " + messageType)
659  break;
660  }
661  }
662 
663  //If no more entities are registered for this message, remove message entry
664  if (msgRegistrantsPtr->size() == 0)
665  {
666  messageMap.erase(it);
667  }
668  }
669  else
670  {
671  LOG_W("Invalid attempt to unregister the Entity: " + listeningEntity.GetName() + " from message: " + messageType)
672  }
673  }
674 
676  void SystemManager::RegisterMsgWithMsgMap(const std::string& messageType, EntityBase& listeningEntity, const std::string& invokableName, MessageRegistrationMap& messageMap)
677  {
678  //Find the map with message registrations, or create a new one
679  EntityInvokableMap* entityInvokableMapPtr = &messageMap[const_cast<std::string*>(&messageType)];
680 
681  //Check if we already have this entity with this invokable registered
682  trBase::SmrtPtr<trManager::EntityBase> listeningEnt = &listeningEntity;
683  EntityInvokableMap::iterator it = entityInvokableMapPtr->find(listeningEnt);
684  if (it == entityInvokableMapPtr->end())
685  {
686  //If the registration does not exist, make one.
687  entityInvokableMapPtr->insert(std::make_pair(listeningEnt, invokableName));
688  LOG_D("Registering Entity: " + listeningEnt->GetName() + " for message: " + messageType + " through invokable: " + invokableName)
689  }
690  else
691  {
692  LOG_W("The Entity: " + listeningEnt->GetName() + " attempted to register for message: " + messageType + " through invokable: " + invokableName + ". It is already registered through invokable: " + it->second)
693  }
694  }
695 
697  void SystemManager::UnregisterMsgFromMsgMap(const std::string& messageType, EntityBase& listeningEntity, MessageRegistrationMap& messageMap)
698  {
699  //Find the map with message registrations
700  MessageRegistrationMap::iterator it = messageMap.find(const_cast<std::string*>(&messageType));
701  if (it != messageMap.end())
702  {
703  //If message registration exists, check if the given Entity is registered
704  EntityInvokableMap* entityMap = &it->second;
705  for (EntityInvokableMap::iterator i = entityMap->begin(); i != entityMap->end(); ++i)
706  {
707  if (i->first == &listeningEntity)
708  {
709  //If the given entity is registered, delete it
710  entityMap->erase(i);
711  LOG_D("Unregistered Entity: " + listeningEntity.GetName() + " from message: " + messageType)
712 
713  //If this was the last registration in the map, delete the whole map
714  if (entityMap->empty())
715  {
716  messageMap.erase(it);
717  }
718  break;
719  }
720  else
721  {
722  LOG_W("Invalid attempt to unregister the Entity: " + listeningEntity.GetName() + " from message: " + messageType)
723  }
724  }
725  }
726  else
727  {
728  LOG_W("Invalid attempt to unregister the Entity: " + listeningEntity.GetName() + " from message: " + messageType)
729  }
730  }
731 
734  {
735  if (director.GetEntityType() == EntityType::DIRECTOR)
736  {
737  //Check if the director is already registered
738  if (FindDirector(director.GetName()) != nullptr)
739  {
740  std::string errorText = "A director with the name: " + director.GetName() + " is already registered with the System Manager.";
741  LOG_E(errorText);
742  throw trUtil::ExceptionInvalidParameter(errorText, __FILE__, __LINE__);
743  return false;
744  }
745 
746  //Set the director Priority, overwriting anything that was there.
747  static_cast<trManager::DirectorBase*>(&director)->SetDirectorPriority(&priority);
748 
749  //Add the director to the storage containers.
750  trBase::SmrtPtr<trManager::EntityBase> newDirector = &director;
751 
752  mDirectorList.push_back(newDirector);
753  mDirectorIDMap[director.GetUUID()] = newDirector;
754  mDirectorNameMap[director.GetName()] = newDirector;
755 
756  mDirectorList.sort(DirectorBase::CompareComponentPriority); //Sort the Director List
757 
758  // Set the director registration status
759  director.SetSystemManager(this);
760  director.SetRegistration(true);
761 
762  //Call the OnAddedToSysMan callback.
763  director.OnAddedToSysMan();
764 
765  //Notify everyone that a new Entity was added
766  SendMessage(*new trManager::MessageEntityRegistered(&GetUUID(), &director.GetUUID(), &director.GetType(), &director.GetName()));
767  LOG_D("Registered " + director.GetName() + " of type: " + director.GetType() + " with System Manager.")
768 
769  return true;
770  }
771  else
772  {
773  LOG_E("The Entity: " + director.GetName() + " is not a Director.")
774  return false;
775  }
776  }
777 
780  {
781  if (director.GetEntityType() == EntityType::DIRECTOR)
782  {
783  // Find the Director instance with the same passed in reference
784  //DirectorList::iterator found = std::find(mDirectorList.end(), mDirectorList.begin(), &director);
785  DirectorList::iterator found;
786  for (found = mDirectorList.begin(); found != mDirectorList.end(); ++found)
787  {
788  if (found->Get() == &director)
789  {
790  //We found the director we need
791  break;
792  }
793  }
794 
795  if (found != mDirectorList.end())
796  {
797  //Add the entity to the delete list.
798  mEntityDeleteList.push_back(trBase::SmrtPtr<trManager::EntityBase>(static_cast<trManager::EntityBase*>(found->Get())));
799 
800  UnregisterDirectorFromGlobalMessages(*found->Get());// Unregister the director from all messages
801  UnregisterEntityFromAboutMessages(*found->Get()); // Unregister the director from all About messages
802 
803  mDirectorIDMap.erase((*found)->GetUUID()); // Erase the node from the list by ID key
804  mDirectorNameMap.erase((*found)->GetName()); // Erase the node from the list by Name key
805  mDirectorList.erase(found); // Erase the node from the list
806 
807  //Notify everyone that an Entity was removed
808  SendMessage(*new trManager::MessageEntityUnregistered(&GetUUID(), &director.GetUUID(), &director.GetType(), &director.GetName()));
809  LOG_D("Unregistered " + director.GetName() + " of type: " + director.GetType() + " from System Manager.")
810 
811  return true;
812  }
813  else
814  {
815  LOG_W("Attempted to unregister a none registered Director: " + director.GetName())
816  return false;
817  }
818  }
819  else
820  {
821  LOG_E("The EntityBase: " + director.GetName() + " is not a Director.")
822  return false;
823  }
824  }
825 
828  {
829  return UnregisterDirector(*FindDirector(id));
830  }
831 
834  {
835  while (!mDirectorList.empty())
836  {
838  }
839  }
840 
843  {
844  DirectorIDMap::const_iterator it = mDirectorIDMap.find(id);
845  if (it != mDirectorIDMap.end()) //Make sure we have a found value and are not at the end
846  {
847  //Return the stored value
848  return it->second.Get();
849  }
850  else
851  {
852  return nullptr;
853  }
854  }
855 
857  trManager::EntityBase* SystemManager::FindDirector(const std::string& name) const
858  {
859  DirectorNameMap::const_iterator it = mDirectorNameMap.find(name);
860  if (it != mDirectorNameMap.end()) //Make sure we have a found value and are not at the end
861  {
862  //Return the stored value
863  return it->second.Get();
864  }
865  else
866  {
867  return nullptr;
868  }
869  }
870 
872  std::vector<trManager::EntityBase*> SystemManager::FindDirectors(const std::string& type) const
873  {
874  std::vector<trManager::EntityBase*> directorList;
875 
877  {
878  if (i->GetType() == type)
879  {
880  directorList.push_back(i);
881  }
882  }
883 
884  return directorList;
885  }
886 
889  {
890  for (int i = static_cast<int>(mEntityDeleteList.size()-1); i >= 0 ; --i)
891  {
892  // Set the entities De-registration options
893  mEntityDeleteList[i]->SetSystemManager(nullptr);
894  mEntityDeleteList[i]->SetRegistration(false);
895  mEntityDeleteList[i]->OnRemovedFromSysMan();
896  mEntityDeleteList.pop_back();
897  }
898  }
899 
902  {
903  LOG_D("Shutting down System Manager")
904 
905  LOG_D("Processing Last Messages")
906  ProcessMessages(); //Send all left over messages before shutting down
907 
908  LOG_D("Unregistering All Directors")
909  UnregisterAllDirectors(); //Unregister all Directors
910 
911  LOG_D("Unregistering All Actors and Actor Modules")
912  UnregisterAllActors(); //Unregister all Actors and Actor Modules
913 
914  LOG_D("Removing all marked entities")
916  }
917 }
virtual void UnregisterActorFromGlobalMessages(trManager::EntityBase &actor)
Unregisters the actor/actor module from all messages that have registrations.
virtual const std::string & GetName()
Returns this instances name.
Definition: Base.cpp:49
Sets the priority for a Director instance.
virtual const std::string & GetMessageType() const =0
Returns the Message type.
This class creates a GUID, or a Unique ID that is used through out TR to identify and distinguish one...
Definition: UniqueId.h:42
static trManager::SystemManager & GetInstance()
Holds the class type name for efficient comparisons.
virtual void CallInvokable(const trManager::MessageBase &message, const std::string &invokableName, trManager::EntityBase &entity)
Utility function.
virtual void SetSystemManager(trManager::SystemManager *sysMan)
This method is used by the System Manager to pass the Entity an instance if itself when it is registe...
Definition: EntityBase.cpp:48
const std::string & GetName() const
Definition: Invokable.h:118
static const EntityType ACTOR_MODULE
Definition: EntityType.h:44
A message that is sent out when an entity is unregistered from the System Manager.
An Invokable is a queriable method interface that can be added to a trManager::ActorBase Invoking the...
Definition: Invokable.h:84
A string wrapper that will make sure that all of the strings with the same value will point to the sa...
Definition: RefStr.h:50
static const trUtil::RefStr CLASS_TYPE
Adds an easy and swappable access to the base class.
Definition: SystemManager.h:52
void RegisterMsgWithMsgMap(const std::string &messageType, EntityBase &listeningEntity, const std::string &invokableName, MessageRegistrationMap &messageMap)
Registers the message with message map.
A director base.
Definition: DirectorBase.h:39
virtual void UnregisterEntityFromAboutMessages(trManager::EntityBase &listeningEntity)
Unregisters the entity from about messages about another actor.
DirectorIDMap mDirectorIDMap
System Manager class is a singleton that is responsible for all message routing and basic operations ...
Definition: SystemManager.h:46
virtual bool RegisterDirector(trManager::EntityBase &director, trManager::DirectorPriority &priority=trManager::DirectorPriority::NORMAL)
Adds a director to the list of components the system manager will communicate with.
virtual bool UnregisterActor(trManager::EntityBase &actor)
Disconnects the actor from the System Manager.
A message that is sent out when a new entity is registered with the System Manager.
virtual void UnregisterAllDirectors()
Unregisters all the directors from System Manager.
virtual trManager::EntityBase * FindDirector(const trBase::UniqueId &id) const
Finds and returns the director with the given ID.
virtual void ProcessMessages()
Sends out all the messages from the message queue.
DirectorNameMap mDirectorNameMap
virtual const std::string & GetType() const override
Returns the class type.
static bool CompareComponentPriority(const trBase::SmrtPtr< trManager::EntityBase > &first, const trBase::SmrtPtr< trManager::EntityBase > &second)
Local function used to compare priorities of Directors.
#define LOG_W(msg)
Log a WARNING message.
Definition: Log.h:156
This class is part of the internal garbage collection system.
Definition: SmrtClass.h:38
virtual bool RegisterActor(trManager::EntityBase &actor)
Registers an Actor or Actor Module with the System Manager.
static const EntityType ACTOR
Definition: EntityType.h:42
virtual bool SendNetworkMessage(const trManager::MessageBase &message)
Send a Network message to an Actor, Actor Module, or a Director.
virtual void UnregisterFromMessage(const std::string &messageType, EntityBase &listeningActor)
Unregister an actor that is listening for a given message.
virtual bool UnregisterDirector(trManager::EntityBase &director)
Disconnects the director from System Manager.
virtual const trBase::UniqueId * GetAboutActorID() const
Returns the ID of the actor this message is about, or sent to.
Definition: MessageBase.cpp:79
virtual std::vector< trManager::EntityBase * > FindDirectors(const std::string &type) const
Finds and returns all the Directors of a given type.
virtual void RemoveMarkedEntities()
Removes all entities that were marked to be unregistered.
virtual void RegisterForMessagesAboutEntity(EntityBase &listeningEntity, const trBase::UniqueId &aboutEntityId, const std::string &invokableName)
Registers for messages about a specific actor.
static const trUtil::RefStr ON_MESSAGE_INVOKABLE
Holds the class type name for efficient comparisons.
Definition: EntityBase.h:54
virtual void ProcessMessage(const trManager::MessageBase &message)
Immediately processes the passed in message.
virtual void UnregisterDirectorFromGlobalMessages(trManager::EntityBase &director)
Unregisters the director from all messages that have registrations.
virtual const trBase::UniqueId * GetFromActorID() const
Returns the ID of the actor the message was sent from.
Definition: MessageBase.cpp:73
std::queue< trBase::SmrtPtr< const trManager::MessageBase > > mMessageQueue
virtual std::vector< trManager::EntityBase * > FindActorsByName(const std::string &actorName)
Searches for all actors by a given name.
UUIDRegistrationVectorMap mListenerRegistrationMap
MessageRegistrationMap mDirectorGlobalMsgRegistrationMap
void Invoke(const trManager::MessageBase &message)
Invoke this.
Definition: Invokable.cpp:42
virtual void SendMessageToActors(const trManager::MessageBase &message)
Sends the passed in message to appropriate actors.
virtual bool SendMessage(const trManager::MessageBase &message)
Send a message to an Actor, Actor Module, or a Director.
#define LOG_E(msg)
Log an ERROR message.
Definition: Log.h:165
trManager::Invokable * GetInvokable(const std::string &name)
Gets a registered invokable.
Definition: EntityBase.cpp:102
virtual void SendMessageToListeners(const trManager::MessageBase &message)
Sends a message to entities that are listening for messages about other actors.
MessageRegistrationVectorMap mEntityGlobalMsgRegistrationMap
void UnregisterMsgFromMsgVectorMap(const std::string &messageType, EntityBase &listeningEntity, MessageRegistrationVectorMap &messageMap)
Un register message from a given message map.
bool Valid() const
Returns True if the smart pointer has a valid internal pointer set.
Definition: SmrtPtr.h:103
virtual const trBase::UniqueId & GetUUID(void)
Returns the instances Universally Unique ID.
Definition: Base.cpp:67
virtual void SendGlobalyRegisteredMessage(const trManager::MessageBase &message)
Sends out a message to all entities who had a global registration for it.
void RegisterMsgWithMsgVectorMap(const std::string &messageType, EntityBase &listeningEntity, const std::string &invokableName, MessageRegistrationVectorMap &messageMap)
Registers the message with a given message map.
virtual const bool & IsRegistered()
Returns True if the Instance is registered with a System Manager.
Definition: EntityBase.h:107
virtual trManager::EntityBase * FindActor(const trBase::UniqueId &id)
Searches for an actor or actor module with the given ID.
static const EntityType DIRECTOR
Definition: EntityType.h:43
virtual void RegisterForMessage(const std::string &messageType, EntityBase &listeningActor, const std::string &invokableName)
Registers an actor for messages.
std::pair< trBase::SmrtPtr< trManager::EntityBase >, std::string > EntityInvokablePair
virtual void UnregisterFromMessagesAboutEntity(EntityBase &listeningEntity, const trBase::UniqueId &aboutEntityId)
Unregisters from messages about a specific actor.
const EntityType & GetEntityType()
Returns the Entity Type, which is usually a Director, Actor, or an Actor module.
Definition: EntityBase.cpp:42
virtual void SendMessageToDirectors(const trManager::MessageBase &message)
Send the passed in message to all registered Directors.
SystemManager(const std::string name=CLASS_TYPE)
Ctor.
virtual void ProcessNetworkMessages()
Sends out all the network messages from the message queue.
virtual const std::string & GetType() const override=0
Returns the class type.
This serves as the base class for the Entity class and removes a circular dependency between Entity a...
Definition: EntityBase.h:46
virtual void SetRegistration(bool isRegistered)
Is set to True by the System Manager when the class instance is registered with it.
Definition: EntityBase.cpp:60
virtual const bool & GetIsDirect() const
Returns True if this message is a direct message and skips all Directors.
Definition: MessageBase.cpp:85
Exception used for methods invalid parameters.
virtual std::vector< trManager::EntityBase * > FindActorsByType(const std::string &actorType)
Searches for all actors of a given type.
virtual void ShutDown()
Shuts down the System Manager and unregisters all entities.
virtual bool UnregisterAllActors()
Unregisters all actors from the System Manager.
This is the base class for all the messages in TR.
Definition: MessageBase.h:40
#define LOG_D(msg)
Log a DEBUG message.
Definition: Log.h:138
std::vector< trBase::SmrtPtr< trManager::EntityBase > > mEntityDeleteList
static trBase::SmrtPtr< trManager::SystemManager > mInstance
virtual void OnAddedToSysMan()
Called by the System Manager when EntityBase Registration is complete.
Definition: EntityBase.h:100
void UnregisterMsgFromMsgMap(const std::string &messageType, EntityBase &listeningEntity, MessageRegistrationMap &messageMap)
Un register message from message map.
std::queue< trBase::SmrtPtr< const trManager::MessageBase > > mNetworkMessageQueue