ProcessorStandard.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #include "ProcessorStandard.h"
  2. #include <iostream>
  3. namespace mdd {
  4. ProcessorStandard::ProcessorStandard(priority priorityEvaluation , int maxIterations):
  5. priorityEvaluation(priorityEvaluation),
  6. maxIterations(maxIterations)
  7. {
  8. setType("StandardProcessor");
  9. addProcessorOutput("Iterator", {0});
  10. }
  11. std::string ProcessorStandard::addModule(std::shared_ptr<IModule> module)
  12. {
  13. std::string id = ProcessorBase::addModule(module);
  14. _priority_list.emplace_back(module_priority(module));
  15. return id;
  16. }
  17. void ProcessorStandard::removeModule(std::shared_ptr<IModule> module)
  18. {
  19. ProcessorBase::removeModule(module);
  20. for (auto it = _priority_list.begin(); it != _priority_list.end(); ++it) {
  21. if (it->module_ptr == module)
  22. {
  23. _priority_list.erase(it);
  24. return;
  25. }
  26. }
  27. }
  28. std::vector<std::shared_ptr<IModule>> ProcessorStandard::getModulePriority()
  29. {
  30. std::vector <std::shared_ptr<IModule>> ret;
  31. for (auto& p : _priority_list) {
  32. ret.push_back(p.module_ptr);
  33. }
  34. return ret;
  35. }
  36. state ProcessorStandard::update() {
  37. if (priorityEvaluation != MANUAL)
  38. {
  39. //update priorities
  40. for (auto it = _priority_list.begin(); it != _priority_list.end(); ++it) {
  41. //collect connected inputs
  42. auto input_connections = it->module_ptr->getInputConnections();
  43. it->inputCounter = 0;
  44. for (auto it_c = input_connections.begin(); it_c != input_connections.end(); ++it_c) {
  45. if ((*it_c) != nullptr)
  46. {
  47. ++(it->inputCounter);
  48. }
  49. }
  50. //collect connected outputs
  51. auto output_connections = it->module_ptr->getOutputConnections();
  52. it->outputCounter = 0;
  53. for (auto it_c = output_connections.begin(); it_c != output_connections.end(); ++it_c) {
  54. if (!(*it_c).empty())
  55. {
  56. ++(it->outputCounter);
  57. }
  58. }
  59. }
  60. //sort by connections
  61. std::sort(_priority_list.begin(), _priority_list.end(), [](module_priority a, module_priority b) {
  62. if (a.inputCounter == b.inputCounter)
  63. {
  64. return a.outputCounter > b.outputCounter;
  65. }
  66. return a.inputCounter < b.inputCounter;
  67. });
  68. }
  69. typedef std::chrono::high_resolution_clock Time;
  70. //update
  71. state ret = state::UNCHANGED;
  72. state group_state = state::CHANGED;
  73. size_t restart = 0;
  74. while (group_state == state::CHANGED) {
  75. getProcessorOutput(0)->setValue()[0] += 1;
  76. getProcessorOutput(0)->resetState();
  77. group_state = state::UNCHANGED;
  78. for (int i = restart; i < _priority_list.size(); ++i) {
  79. auto t_start = Time::now();
  80. state module_state = _priority_list[i].module_ptr->update();
  81. auto t_end = Time::now();
  82. if (priorityEvaluation == TIME)
  83. {
  84. _priority_list[i].time_priority = std::round(std::log10(std::chrono::duration_cast<std::chrono::milliseconds>(t_end - t_start).count()));
  85. }
  86. if (module_state == state::CHANGED) {
  87. group_state = state::CHANGED;
  88. ret = state::CHANGED;
  89. }
  90. // ignore modules which have to initilize once in the future
  91. if (_priority_list[i].inputCounter == 0 && priorityEvaluation != MANUAL) {
  92. restart = i;
  93. }
  94. if ((priorityEvaluation == DYNAMIC || priorityEvaluation == TIME) && _priority_list.size() < i+1) {
  95. if (_priority_list[i + 1].inputCounter == _priority_list[i].inputCounter && _priority_list[i + 1].inputCounter != 0)
  96. {
  97. //collect changes
  98. for (auto it = _priority_list.begin() + i + 1; it != _priority_list.end(); ++it) {
  99. auto input_states = it->module_ptr->getInputStates();
  100. it->changeCounter = 0;
  101. for (auto it_c = input_states.begin(); it_c != input_states.end(); ++it_c) {
  102. if ((*it_c) == state::CHANGED)
  103. {
  104. ++(it->changeCounter);
  105. }
  106. }
  107. }
  108. std::sort(_priority_list.begin() + i + 1, _priority_list.end(), [](module_priority a, module_priority b) {
  109. if (a.inputCounter == b.inputCounter)
  110. {
  111. if (a.time_priority == b.time_priority)
  112. {
  113. if ((a.inputCounter - a.changeCounter) == (b.inputCounter - b.changeCounter)) {
  114. if (a.changeCounter == b.changeCounter) {
  115. return a.outputCounter > b.outputCounter;
  116. }
  117. return a.changeCounter > b.changeCounter;
  118. }
  119. return (a.inputCounter - a.changeCounter) < (b.inputCounter - b.changeCounter);
  120. }
  121. return a.time_priority < b.time_priority;
  122. }
  123. return a.inputCounter < b.inputCounter;
  124. });
  125. }
  126. }
  127. }
  128. if (maxIterations != -1 && getProcessorOutput(0)->getValue()[0] >= maxIterations)
  129. {
  130. return state::STATE_ERROR;
  131. }
  132. }
  133. return ret;
  134. }
  135. std::shared_ptr<IOutput> ProcessorStandard::getIteration(){
  136. return getProcessorOutput(0);
  137. }
  138. ProcessorStandard::module_priority::module_priority(std::shared_ptr<IModule> module, size_t inputs, size_t outputs, size_t change)
  139. {
  140. module_ptr = module;
  141. inputCounter = inputs;
  142. outputCounter = outputs;
  143. changeCounter = change;
  144. time_priority = 0;
  145. }
  146. }