void testSimpleTaskRunAndPoll() { int counter = 0; { Tasks::TaskQueue taskQueue(1); taskQueue.enqueueTask(new CounterTask(counter)); //200 ms should be enough... This isn't deterministic though. std::this_thread::sleep_for(std::chrono::milliseconds(200)); taskQueue.pollProcessedTasks(TimeFrame(boost::posix_time::milliseconds(100000))); CPPUNIT_ASSERT(counter == 0); } }
void Application::mainLoop() { DesiredFpsListener desiredFpsListener; Eris::EventService& eventService = mSession->getEventService(); Input& input(Input::getSingleton()); do { try { Log::sCurrentFrameStartMilliseconds = microsec_clock::local_time(); unsigned int frameActionMask = 0; TimeFrame timeFrame = TimeFrame(boost::posix_time::microseconds(desiredFpsListener.getMicrosecondsPerFrame())); bool updatedRendering = mOgreView->renderOneFrame(timeFrame); if (updatedRendering) { frameActionMask |= MainLoopController::FA_GRAPHICS; frameActionMask |= MainLoopController::FA_INPUT; } else { input.processInput(); frameActionMask |= MainLoopController::FA_INPUT; } if (mWorldView) { mWorldView->update(); } mServices->getSoundService().cycle(); frameActionMask |= MainLoopController::FA_SOUND; //Keep on running IO and handlers until we need to render again eventService.processEvents(timeFrame.getRemainingTime(), mShouldQuit); mMainLoopController.EventFrameProcessed(timeFrame, frameActionMask); } catch (const std::exception& ex) { S_LOG_CRITICAL("Got exception, shutting down." << ex); throw; } catch (...) { S_LOG_CRITICAL("Got unknown exception, shutting down."); throw; } } while (!mShouldQuit); }
TaskQueue::~TaskQueue() { { std::unique_lock<std::mutex> l(mUnprocessedQueueMutex); mActive = false; } mUnprocessedQueueCond.notify_all(); //Join all executors. Since the queue is shutting down they will all exit their main loop if there are no more tasks to process. for (TaskExecutorStore::iterator I = mExecutors.begin(); I != mExecutors.end(); ++I) { TaskExecutor* executor = *I; executor->join(); delete executor; } //Finally we must process all of the tasks in our main loop. This of course requires that this instance is destroyed from the main loop. pollProcessedTasks(TimeFrame(boost::posix_time::seconds(60))); assert(mProcessedTaskUnits.empty()); assert(mUnprocessedTaskUnits.empty()); }
void Application::mainLoopStep(long minMicrosecondsPerFrame) { TimeFrame timeFrame = TimeFrame(boost::posix_time::microseconds(minMicrosecondsPerFrame)); Input& input(Input::getSingleton()); ptime currentTime; unsigned int frameActionMask = 0; try { if (mPollEris) { currentTime = microsec_clock::local_time(); mMainLoopController.EventStartErisPoll.emit((currentTime - mLastTimeErisPollStart).total_microseconds() / 1000000.0f); mLastTimeErisPollStart = currentTime; Eris::PollDefault::poll(0); if (mWorldView) { mWorldView->update(); } currentTime = microsec_clock::local_time(); mMainLoopController.EventEndErisPoll.emit((currentTime - mLastTimeErisPollEnd).total_microseconds() / 1000000.0f); mLastTimeErisPollEnd = currentTime; frameActionMask |= MainLoopController::FA_ERIS; } currentTime = microsec_clock::local_time(); mMainLoopController.EventBeforeInputProcessing.emit((currentTime - mLastTimeInputProcessingStart).total_microseconds() / 1000000.0f); mLastTimeInputProcessingStart = currentTime; input.processInput(); frameActionMask |= MainLoopController::FA_INPUT; currentTime = microsec_clock::local_time(); mMainLoopController.EventAfterInputProcessing.emit((currentTime - mLastTimeInputProcessingEnd).total_microseconds() / 1000000.0f); mLastTimeInputProcessingEnd = currentTime; bool updatedRendering = mOgreView->renderOneFrame(timeFrame); if (updatedRendering) { frameActionMask |= MainLoopController::FA_GRAPHICS; } mServices->getSoundService().cycle(); frameActionMask |= MainLoopController::FA_SOUND; mMainLoopController.EventFrameProcessed(timeFrame, frameActionMask); //If we should cap the fps so that each frame should take a minimum amount of time, //we need to see if we should sleep a little. if (minMicrosecondsPerFrame > 0) { if (timeFrame.isTimeLeft()) { try { boost::this_thread::sleep(timeFrame.getRemainingTime()); } catch (const boost::thread_interrupted& ex) { } } } mLastTimeMainLoopStepEnded = microsec_clock::local_time(); } catch (const std::exception& ex) { S_LOG_CRITICAL("Got exception, shutting down." << ex); throw; } catch (const std::string& ex) { S_LOG_CRITICAL("Got exception, shutting down. " << ex); throw; } catch (...) { S_LOG_CRITICAL("Got unknown exception."); throw; } }