コード例 #1
0
ファイル: Application.cpp プロジェクト: LawrenceWeng/ember
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);
}
コード例 #2
0
ファイル: TaskQueue.cpp プロジェクト: angkorcn/ember
void TaskQueue::pollProcessedTasks(TimeFrame timeFrame)
{
	TaskUnitQueue processedCopy;
	{
		std::unique_lock<std::mutex> l(mProcessedQueueMutex);
		processedCopy = mProcessedTaskUnits;
		if (!mProcessedTaskUnits.empty()) {
			mProcessedTaskUnits = TaskUnitQueue();
		}
	}
	while (!processedCopy.empty()) {

		TaskUnit* taskUnit = processedCopy.front();
		processedCopy.pop();
		try {
			taskUnit->executeInMainThread();
		} catch (const std::exception& ex) {
			S_LOG_FAILURE("Error when executing task in main thread." << ex);
		} catch (...) {
			S_LOG_FAILURE("Unknown error when executing task in main thread.");
		}
		try {
			delete taskUnit;
		} catch (const std::exception& ex) {
			S_LOG_FAILURE("Error when deleting task in main thread." << ex);
		} catch (...) {
			S_LOG_FAILURE("Unknown error when deleting task in main thread.");
		}
		//Try to keep the time spent here each frame down, to keep the framerate up.
		if (!timeFrame.isTimeLeft()) {
			break;
		}
	}
	//If there are any unprocessed tasks, put them back at the front of the queue.
	if (!processedCopy.empty()) {
		std::unique_lock<std::mutex> l(mProcessedQueueMutex);
		TaskUnitQueue queueCopy(mProcessedTaskUnits);
		mProcessedTaskUnits = processedCopy;
		while (!queueCopy.empty()) {
			mProcessedTaskUnits.push(queueCopy.front());
			queueCopy.pop();
		}
	}
}
コード例 #3
0
void FrameTimeRecorder::frameCompleted(const TimeFrame& timeFrame, unsigned int frameActionMask)
{
	if (frameActionMask & MainLoopController::FA_GRAPHICS) {

		mAccumulatedFrameTimes += timeFrame.getElapsedTime();
		mAccumulatedFrames++;

		if (mAccumulatedFrameTimes >= mRequiredTimeSamples) {

			mTimePerFrameStore.push_back(mAccumulatedFrameTimes / mAccumulatedFrames);
			mAccumulatedFrameTimes = boost::posix_time::seconds(0);
			mAccumulatedFrames = 0;

			boost::posix_time::time_duration averageTimePerFrame = std::accumulate(mTimePerFrameStore.begin(), mTimePerFrameStore.end(), boost::posix_time::time_duration()) / mTimePerFrameStore.size();
			EventAverageTimePerFrameUpdated(averageTimePerFrame);

		}
	}
}
void ModelDefinitionManager::pollBackgroundLoaders(const TimeFrame& timeFrame)
{
	if (mBackgroundLoaders.size()) {
		TimedLog timedLog("ModelDefinitionManager::pollBackgroundLoaders", true);
		for (BackgroundLoaderStore::iterator I = mBackgroundLoaders.begin(); I != mBackgroundLoaders.end();)
		{
			BackgroundLoaderStore::iterator I_copy = I;
			ModelBackgroundLoader* loader(*I);
			++I;
			if (loader->poll(timeFrame)) {
				mBackgroundLoaders.erase(I_copy);
				loader->reloadModel();
				timedLog.report();
			}
			if (!timeFrame.isTimeLeft()) {
				break;
			}
		}
	}
}
コード例 #5
0
ファイル: Application.cpp プロジェクト: angkorcn/ember
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;
	}
}
コード例 #6
0
bool ModelBackgroundLoader::poll(const TimeFrame& timeFrame)
{
#if OGRE_THREAD_SUPPORT
	if (mState == LS_UNINITIALIZED) {
		//Start to load the meshes
		for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) {
			Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName()));
			if (meshPtr.isNull() || !meshPtr->isPrepared()) {
				try {
					Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().prepare(Ogre::MeshManager::getSingleton().getResourceType(), (*I_subModels)->getMeshName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener());
					if (ticket) {
						addTicket(ticket);
					}
				} catch (const std::exception& ex) {
					S_LOG_FAILURE("Could not load the mesh " << (*I_subModels)->getMeshName() << " when loading model " << mModel.getName() << "." << ex);
					continue;
				}
			}
		}
		mState = LS_MESH_PREPARING;
		return poll(timeFrame);
	} else if (mState == LS_MESH_PREPARING) {
		if (areAllTicketsProcessed()) {
			mState = LS_MESH_PREPARED;
			return poll(timeFrame);
		}
	} else if (mState == LS_MESH_PREPARED) {
		for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) {
			Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName()));
			if (!meshPtr.isNull()) {
				if (!meshPtr->isLoaded()) {
#if OGRE_THREAD_SUPPORT == 1
					Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().load(Ogre::MeshManager::getSingleton().getResourceType(), meshPtr->getName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener());
					if (ticket) {
						//						meshPtr->setBackgroundLoaded(true);
						addTicket(ticket);
					}
#else
					if (!timeFrame.isTimeLeft()) {
						return false;
					}
					try {
						meshPtr->load();
					} catch (const std::exception& ex) {
						S_LOG_FAILURE("Could not load the mesh " << meshPtr->getName() << " when loading model " << mModel.getName() << "." << ex);
						continue;
					}
#endif
				}
			}
		}
		mState = LS_MESH_LOADING;
		return poll(timeFrame);
	} else if (mState == LS_MESH_LOADING) {
		if (areAllTicketsProcessed()) {
			mState = LS_MESH_LOADED;
			return poll(timeFrame);
		}
	} else if (mState == LS_MESH_LOADED) {

		for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) {
			Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName()));
			if (!meshPtr.isNull()) {
				if (meshPtr->isLoaded()) {
					Ogre::Mesh::SubMeshIterator subMeshI = meshPtr->getSubMeshIterator();
					while (subMeshI.hasMoreElements()) {
						Ogre::SubMesh* submesh(subMeshI.getNext());
						Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(submesh->getMaterialName()));
						if (materialPtr.isNull() || !materialPtr->isPrepared()) {
//							S_LOG_VERBOSE("Preparing material " << materialPtr->getName());
							Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().prepare(Ogre::MaterialManager::getSingleton().getResourceType(),submesh->getMaterialName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener());
							if (ticket) {
								addTicket(ticket);
							}
						}
					}
				}
			}
			for (PartDefinitionsStore::const_iterator I_parts = (*I_subModels)->getPartDefinitions().begin(); I_parts != (*I_subModels)->getPartDefinitions().end(); ++I_parts) {
				if ((*I_parts)->getSubEntityDefinitions().size() > 0) {
					for (SubEntityDefinitionsStore::const_iterator I_subEntities = (*I_parts)->getSubEntityDefinitions().begin(); I_subEntities != (*I_parts)->getSubEntityDefinitions().end(); ++I_subEntities) {
						const std::string& materialName = (*I_subEntities)->getMaterialName();
						if (materialName != "") {
							Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(materialName));
							if (materialPtr.isNull() || !materialPtr->isPrepared()) {
//								S_LOG_VERBOSE("Preparing material " << materialName);
								Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().prepare(Ogre::MaterialManager::getSingleton().getResourceType(), materialName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener());
								if (ticket) {
									addTicket(ticket);
								}
							}
						}
					}
				}
			}
		}

		mState = LS_MATERIAL_PREPARING;
		return poll(timeFrame);
	} else if (mState == LS_MATERIAL_PREPARING) {
		if (areAllTicketsProcessed()) {
			mState = LS_MATERIAL_PREPARED;
			return poll(timeFrame);
		}
	} else if (mState == LS_MATERIAL_PREPARED) {
		for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) {
			Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName()));
			Ogre::Mesh::SubMeshIterator subMeshI = meshPtr->getSubMeshIterator();
			while (subMeshI.hasMoreElements()) {
				Ogre::SubMesh* submesh(subMeshI.getNext());
				Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(submesh->getMaterialName()));
				if (!materialPtr.isNull() && !materialPtr->isLoaded()) {

#if OGRE_THREAD_SUPPORT == 1
					Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().load(Ogre::MaterialManager::getSingleton().getResourceType(), materialPtr->getName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener());
					if (ticket) {
						//						materialPtr->setBackgroundLoaded(true);
						addTicket(ticket);
					}
#else
					Ogre::Material::TechniqueIterator techIter = materialPtr->getSupportedTechniqueIterator();
					while (techIter.hasMoreElements()) {
						Ogre::Technique* tech = techIter.getNext();
						Ogre::Technique::PassIterator passIter = tech->getPassIterator();
						while (passIter.hasMoreElements()) {
							Ogre::Pass* pass = passIter.getNext();
							Ogre::Pass::TextureUnitStateIterator tusIter = pass->getTextureUnitStateIterator();
							while (tusIter.hasMoreElements()) {
								Ogre::TextureUnitState* tus = tusIter.getNext();
								unsigned int frames = tus->getNumFrames();
								for (unsigned int i = 0; i < frames; ++i) {
									if (!timeFrame.isTimeLeft()) {
										return false;
									}
									//This will automatically load the texture.
//									S_LOG_VERBOSE("Loading texture " << tus->getTextureName());
									Ogre::TexturePtr texturePtr = tus->_getTexturePtr(i);
								}
							}
						}
					}
					if (!timeFrame.isTimeLeft()) {
						return false;
					}
//					S_LOG_VERBOSE("Loading material " << materialPtr->getName());
					materialPtr->load();
#endif

				}
			}
			for (PartDefinitionsStore::const_iterator I_parts = (*I_subModels)->getPartDefinitions().begin(); I_parts != (*I_subModels)->getPartDefinitions().end(); ++I_parts) {
				if ((*I_parts)->getSubEntityDefinitions().size() > 0) {
					for (SubEntityDefinitionsStore::const_iterator I_subEntities = (*I_parts)->getSubEntityDefinitions().begin(); I_subEntities != (*I_parts)->getSubEntityDefinitions().end(); ++I_subEntities) {
						const std::string& materialName = (*I_subEntities)->getMaterialName();
						if (materialName != "") {
							Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(materialName));
							if (!materialPtr.isNull() && !materialPtr->isLoaded()) {
#if OGRE_THREAD_SUPPORT == 1
								Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().load(Ogre::MaterialManager::getSingleton().getResourceType(), materialPtr->getName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener());
								if (ticket) {
									addTicket(ticket);
								}
#else
								Ogre::Material::TechniqueIterator techIter = materialPtr->getSupportedTechniqueIterator();
								while (techIter.hasMoreElements()) {
									Ogre::Technique* tech = techIter.getNext();
									Ogre::Technique::PassIterator passIter = tech->getPassIterator();
									while (passIter.hasMoreElements()) {
										Ogre::Pass* pass = passIter.getNext();
										Ogre::Pass::TextureUnitStateIterator tusIter = pass->getTextureUnitStateIterator();
										while (tusIter.hasMoreElements()) {
											Ogre::TextureUnitState* tus = tusIter.getNext();
											unsigned int frames = tus->getNumFrames();
											for (unsigned int i = 0; i < frames; ++i) {
												if (!timeFrame.isTimeLeft()) {
													return false;
												}
												//This will automatically load the texture.
//												S_LOG_VERBOSE("Loading texture " << tus->getTextureName());
												Ogre::TexturePtr texturePtr = tus->_getTexturePtr(i);
											}
										}
									}
								}
								if (!timeFrame.isTimeLeft()) {
									return false;
								}
//								S_LOG_VERBOSE("Loading material " << materialPtr->getName());
								materialPtr->load();
#endif
							}
						}
					}
				}
			}
		}

		mState = LS_MATERIAL_LOADING;
		return poll(timeFrame);
	} else if (mState == LS_MATERIAL_LOADING) {
		if (areAllTicketsProcessed()) {
			mState = LS_DONE;
			return true;
		}

	} else {
		return true;
	}
	return false;
#else
	//If there's no threading support, just return here.
	return true;
#endif
}