7 #include "imstkSimulationManager.h" 8 #include "imstkMacros.h" 9 #include "imstkTimer.h" 10 #include "imstkViewer.h" 14 DISABLE_WARNING_PADDING
15 #include <tbb/task_group.h> 21 SimulationManager::start()
26 for (
auto module : m_modules)
28 connect<Event>(module, &Module::end,
29 std::static_pointer_cast<SimulationManager>(shared_from_this()),
30 &SimulationManager::requestStop);
40 adaptiveModule->init();
43 for (
auto viewer : m_viewers)
49 tbb::task_group tasks;
52 if (m_threadType == ThreadingType::TBB)
56 tasks.run([
this, module]() { runModuleParallel(module); });
60 else if (m_threadType == ThreadingType::STL)
62 for (
size_t i = 0; i < m_asyncModules.size(); i++)
64 std::shared_ptr<Module> module = m_asyncModules[i];
65 threads[i] = std::thread(std::bind(&SimulationManager::runModuleParallel,
this, module));
72 postEvent(Event(SimulationManager::starting()));
78 double accumulator = 0.0;
84 for (
auto module : m_viewers)
86 m_running[module.get()] =
true;
88 for (
auto module : m_syncModules)
90 m_running[module.get()] =
true;
92 for (
auto module : m_adaptiveModules)
94 m_running[module.get()] =
true;
99 const int newState = simState;
100 if (newState == ModuleDriverStopped)
106 const double passedTime = timer.getTimeElapsed();
109 if (newState == ModuleDriverPaused)
115 accumulator += passedTime;
120 m_numSteps =
static_cast<int>(accumulator / desiredDt_ms);
122 accumulator = accumulator - m_numSteps * desiredDt_ms;
130 m_dt += accumulator / m_numSteps;
143 for (
auto syncModule : m_syncModules)
145 syncModule->setDt(
m_dt);
146 syncModule->update();
149 for (
auto adaptiveModule : m_adaptiveModules)
151 adaptiveModule->setDt(
m_dt);
152 for (
int currStep = 0; currStep < m_numSteps; currStep++)
155 for (
auto viewer : m_viewers)
157 viewer->processEvents();
159 adaptiveModule->update();
163 for (
auto viewer : m_viewers)
165 viewer->setDt(m_numSteps *
m_dt);
172 postEvent(Event(SimulationManager::ending()));
174 if (m_threadType == ThreadingType::TBB)
177 else if (m_threadType == ThreadingType::STL)
179 for (
size_t i = 0; i < threads.size(); i++)
185 for (
auto module : m_modules)
187 m_running[module.get()] =
false;
197 if (std::shared_ptr<Viewer> viewer = std::dynamic_pointer_cast<Viewer>(module))
199 m_viewers.push_back(viewer);
203 if (module->getExecutionType() == Module::ExecutionType::SEQUENTIAL)
205 m_syncModules.push_back(module);
207 else if (module->getExecutionType() == Module::ExecutionType::PARALLEL)
209 m_asyncModules.push_back(module);
211 else if (module->getExecutionType() == Module::ExecutionType::ADAPTIVE)
213 m_adaptiveModules.push_back(module);
222 m_syncModules.clear();
223 m_asyncModules.clear();
224 m_adaptiveModules.clear();
228 SimulationManager::runModuleParallel(std::shared_ptr<Module> module)
234 m_running[module.get()] =
true;
235 while (m_running[module.get()])
238 const int newState = simState;
239 if (newState == ModuleDriverStopped)
241 m_running[module.get()] =
false;
243 else if (newState == ModuleDriverRunning)
245 std::shared_ptr<Viewer> viewer = std::dynamic_pointer_cast<
Viewer>(module);
246 if (viewer !=
nullptr)
248 viewer->processEvents();
257 SimulationManager::requestStop(
Event* e)
260 if (module !=
nullptr)
262 requestStatus(ModuleDriverStopped);
263 m_running[module] =
false;
double m_desiredDt
Desired timestep.
Base class for events which contain a type, priority, and data priority defaults to 0 and uses a grea...
virtual void addModule(std::shared_ptr< Module > module)
Add a module to run.
void addModule(std::shared_ptr< Module > module) override
Add a module to run.
virtual void clearModules()
Remove all modules.
std::vector< std::shared_ptr< Module > > m_adaptiveModules
Modules that update adpatively to keep up with real time.
std::vector< std::shared_ptr< Module > > m_asyncModules
Modules that run on completely other threads without restraint.
Base class for viewer that manages render window and the renderers Creates backend-specific renderers...
std::vector< std::shared_ptr< Module > > m_syncModules
Modules called once per update.
bool m_useRemainderTimeDivide
Whether to divide out remainder time or not.
double m_dt
Actual timestep.
void clearModules() override
Remove all modules.
void waitForInit()
Wait for all modules to init.
void postEvent(const T &e)
Emits the event Direct observers will be immediately called, in sync Queued observers will receive th...
Base class for imstk module system. A module defines something that is updated, and can be paused/res...