#include "ProcessorStandard.h" #include namespace mdd { ProcessorStandard::ProcessorStandard(priority priorityEvaluation , int maxIterations): priorityEvaluation(priorityEvaluation), maxIterations(maxIterations) { setType("StandardProcessor"); addProcessorOutput("Iterator", {0}); } std::string ProcessorStandard::addModule(std::shared_ptr module) { std::string id = ProcessorBase::addModule(module); _priority_list.emplace_back(module_priority(module)); return id; } void ProcessorStandard::removeModule(std::shared_ptr module) { ProcessorBase::removeModule(module); for (auto it = _priority_list.begin(); it != _priority_list.end(); ++it) { if (it->module_ptr == module) { _priority_list.erase(it); return; } } } std::vector> ProcessorStandard::getModulePriority() { std::vector > ret; for (auto& p : _priority_list) { ret.push_back(p.module_ptr); } return ret; } state ProcessorStandard::update() { if (priorityEvaluation != MANUAL) { //update priorities for (auto it = _priority_list.begin(); it != _priority_list.end(); ++it) { //collect connected inputs auto input_connections = it->module_ptr->getInputConnections(); it->inputCounter = 0; for (auto it_c = input_connections.begin(); it_c != input_connections.end(); ++it_c) { if ((*it_c) != nullptr) { ++(it->inputCounter); } } //collect connected outputs auto output_connections = it->module_ptr->getOutputConnections(); it->outputCounter = 0; for (auto it_c = output_connections.begin(); it_c != output_connections.end(); ++it_c) { if (!(*it_c).empty()) { ++(it->outputCounter); } } } //sort by connections std::sort(_priority_list.begin(), _priority_list.end(), [](module_priority a, module_priority b) { if (a.inputCounter == b.inputCounter) { return a.outputCounter > b.outputCounter; } return a.inputCounter < b.inputCounter; }); } typedef std::chrono::high_resolution_clock Time; //update state ret = state::UNCHANGED; state group_state = state::CHANGED; size_t restart = 0; while (group_state == state::CHANGED) { getProcessorOutput(0)->setValue()[0] += 1; getProcessorOutput(0)->resetState(); group_state = state::UNCHANGED; for (int i = restart; i < _priority_list.size(); ++i) { auto t_start = Time::now(); state module_state = _priority_list[i].module_ptr->update(); auto t_end = Time::now(); if (priorityEvaluation == TIME) { _priority_list[i].time_priority = std::round(std::log10(std::chrono::duration_cast(t_end - t_start).count())); } if (module_state == state::CHANGED) { group_state = state::CHANGED; ret = state::CHANGED; } // ignore modules which have to initilize once in the future if (_priority_list[i].inputCounter == 0 && priorityEvaluation != MANUAL) { restart = i; } if ((priorityEvaluation == DYNAMIC || priorityEvaluation == TIME) && _priority_list.size() < i+1) { if (_priority_list[i + 1].inputCounter == _priority_list[i].inputCounter && _priority_list[i + 1].inputCounter != 0) { //collect changes for (auto it = _priority_list.begin() + i + 1; it != _priority_list.end(); ++it) { auto input_states = it->module_ptr->getInputStates(); it->changeCounter = 0; for (auto it_c = input_states.begin(); it_c != input_states.end(); ++it_c) { if ((*it_c) == state::CHANGED) { ++(it->changeCounter); } } } std::sort(_priority_list.begin() + i + 1, _priority_list.end(), [](module_priority a, module_priority b) { if (a.inputCounter == b.inputCounter) { if (a.time_priority == b.time_priority) { if ((a.inputCounter - a.changeCounter) == (b.inputCounter - b.changeCounter)) { if (a.changeCounter == b.changeCounter) { return a.outputCounter > b.outputCounter; } return a.changeCounter > b.changeCounter; } return (a.inputCounter - a.changeCounter) < (b.inputCounter - b.changeCounter); } return a.time_priority < b.time_priority; } return a.inputCounter < b.inputCounter; }); } } } if (maxIterations != -1 && getProcessorOutput(0)->getValue()[0] >= maxIterations) { return state::STATE_ERROR; } } return ret; } std::shared_ptr ProcessorStandard::getIteration(){ return getProcessorOutput(0); } ProcessorStandard::module_priority::module_priority(std::shared_ptr module, size_t inputs, size_t outputs, size_t change) { module_ptr = module; inputCounter = inputs; outputCounter = outputs; changeCounter = change; time_priority = 0; } }