StateMachine.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * Author: Patrick-Christopher Mattulat
  3. * Company: Lynar Studios
  4. * E-Mail: webmaster@lynarstudios.com
  5. * Created: 2020-09-05
  6. * Changed: 2021-04-23
  7. *
  8. * */
  9. #include <ls_std/logic/StateMachine.hpp>
  10. #include <ls_std/exception/IllegalArgumentException.hpp>
  11. ls_std::StateMachine::StateMachine(const std::string& _name) : ls_std::Class("StateMachine")
  12. {
  13. this->_assignName(_name);
  14. }
  15. bool ls_std::StateMachine::addState(const std::shared_ptr<ls_std::State> &_state)
  16. {
  17. bool wasAdded{};
  18. if (_state == nullptr)
  19. {
  20. throw ls_std::IllegalArgumentException{};
  21. }
  22. else
  23. {
  24. if (!this->_hasState(_state->getId()))
  25. {
  26. wasAdded = this->states.insert({_state->getId(), _state}).second;
  27. }
  28. }
  29. return wasAdded;
  30. }
  31. std::shared_ptr<ls_std::State> ls_std::StateMachine::getCurrentState()
  32. {
  33. return this->currentState;
  34. }
  35. std::vector<ls_std::StateId> ls_std::StateMachine::getMemory()
  36. {
  37. return this->memory;
  38. }
  39. std::string ls_std::StateMachine::getName()
  40. {
  41. return this->name;
  42. }
  43. std::unordered_map<ls_std::StateId, std::shared_ptr<ls_std::State>> ls_std::StateMachine::getStates()
  44. {
  45. return this->states;
  46. }
  47. bool ls_std::StateMachine::hasState(const ls_std::StateId &_id)
  48. {
  49. return this->_hasState(_id);
  50. }
  51. bool ls_std::StateMachine::proceed()
  52. {
  53. std::vector<ls_std::StateId> nextValidStates = this->_getNextValidStates();
  54. bool onlyOneWayToGo = nextValidStates.size() == 1;
  55. if (onlyOneWayToGo)
  56. {
  57. this->currentState = this->states[nextValidStates.at(0)];
  58. this->_remember(nextValidStates.at(0));
  59. }
  60. return onlyOneWayToGo;
  61. }
  62. void ls_std::StateMachine::setMemory(const std::vector<ls_std::StateId>& _memory)
  63. {
  64. this->_assignMemory(_memory);
  65. }
  66. void ls_std::StateMachine::setName(const std::string& _name)
  67. {
  68. this->_assignName(_name);
  69. }
  70. bool ls_std::StateMachine::setStartState(const ls_std::StateId &_id)
  71. {
  72. bool startStateSet{};
  73. if (_id.empty())
  74. {
  75. throw ls_std::IllegalArgumentException{};
  76. }
  77. else
  78. {
  79. if (this->_hasState(_id))
  80. {
  81. this->currentState = this->states[_id];
  82. this->_remember(_id);
  83. startStateSet = true;
  84. }
  85. }
  86. return startStateSet;
  87. }
  88. void ls_std::StateMachine::_assignMemory(const std::vector<ls_std::StateId> &_memory)
  89. {
  90. if (_memory.empty())
  91. {
  92. throw ls_std::IllegalArgumentException{};
  93. }
  94. this->memory = _memory;
  95. }
  96. void ls_std::StateMachine::_assignName(const std::string &_name)
  97. {
  98. if (_name.empty())
  99. {
  100. throw ls_std::IllegalArgumentException{};
  101. }
  102. this->name = _name;
  103. }
  104. std::vector<ls_std::StateId> ls_std::StateMachine::_getNextValidStates()
  105. {
  106. std::vector<ls_std::StateId> validStates{};
  107. for (const auto &state : this->currentState->getConnectedStates())
  108. {
  109. if (state.second->isPassable())
  110. {
  111. validStates.push_back(state.second->getStateId());
  112. }
  113. }
  114. return validStates;
  115. }
  116. void ls_std::StateMachine::_remember(const ls_std::StateId &_id)
  117. {
  118. this->memory.push_back(_id);
  119. }
  120. bool ls_std::StateMachine::_hasState(const ls_std::StateId &_id)
  121. {
  122. return this->states.find(_id) != this->states.end();
  123. }