void RuntimeSystem::update(IControlValueReceiver* cvr, IModuleStatisticsReceiver* msr) { std::stack<ModuleControlBlockPtr> stack; // push the sinks (modules with no output) on the stack for (std::list<ModuleControlBlockPtr>::iterator sink = m_sinks.begin(); sink != m_sinks.end(); ++sink) { (*sink)->activate(); stack.push(*sink); } #if (ENGINE_VERBOSITY > 2) std::cout << " ***** update begins\n"; std::cout << "Pushed all m_sinks onto the stack." << std::endl; std::cout << "Number of m_sinks: " << m_sinks.size() << std::endl; #endif while (!stack.empty()) { ModuleControlBlockPtr block = stack.top(); IModule* m = block->module(); assert (block->isActive()); #if (ENGINE_VERBOSITY > 3) std::cout << "On Stack: " << m->getID() << "\n"; #endif IInput* dep = m->dependencies(); // is there a not satisfied dependency left? if (dep != 0) { IModule* temp = dep->getConnectedModule(); // is the input connected to an other module? if (temp != 0) { #if (ENGINE_VERBOSITY > 3) std::cout << " Following connection to " << temp->getID() << "\n"; #endif // check that module ModuleControlBlockPtr current = getControlBlock(temp); // 1. in case the module is on the stack we detected a cycle // the solution is to use the old value of that output // 2. the module is already updatet in this cycle // we dont want do update it again if (current->isActive()||(current->lastUpdated()==frameCount)) { // it could be that the value changed (conservative) block->setChanged(dep->getIndex()); #if (ENGINE_VERBOSITY > 3) std::cout << " [already done]" << temp->getID() << "\n"; #endif } else { #if (ENGINE_VERBOSITY > 3) std::cout << " [pushed on stack]" << temp->getID() << "\n"; #endif // we must update this module current->activate(); stack.push(current); } } } else { // all dependencies are satisfied // is a update necessary? if (!m->isDeterministic() || block->hasChanged()) { #if (ENGINE_VERBOSITY > 3) std::cout << " Updating...\n"; #endif // lets update the module unsigned long startTime = utils::Timing::getTimeInMillis(); //TODO: if an exception is caught, remove the module! try { m->update(); } catch (std::exception& e){ std::ostringstream os; os << "error at update: " << e.what() << "\n" << "module id = " << m->getID() << "\n" << "module class = " << m->module_class_name() << "\n"; m_logger->error("Runtimesystem", os.str()); } catch (...) { std::ostringstream os; os << "error at update\n" << "module id = " << m->getID() << "\n" << "module class = " << m->module_class_name() << "\n"; m_logger->error("Runtimesystem", os.str()); } unsigned long stopTime = utils::Timing::getTimeInMillis(); block->addTime(stopTime-startTime); // should we send the statistic data? // is there a receiver? // is it the right time? if (msr != 0 && (frameCount & 7) == 7) { // send statistic data msr->modExecTimeSignal(m->getID(),block->avgTime()); } // send the changes values to the controlValueReceiver // and set them there to changed sendInputValues(block,cvr,m_modules,frameCount); } else { #if (ENGINE_VERBOSITY > 3) std::cout << " Skipping update (deterministic and no " << "needed input changed)...\n"; #endif } // this module is now updated stack.pop(); block->reset(); block->updated(frameCount); } } // all sinks are uptodate we can finish now // increase the timestamp ++frameCount; #if (ENGINE_VERBOSITY > 2) std::cout << "**** update finished" << std::endl; #endif }