void Application::start() { try { if (!mOgreView->setup(Input::getSingleton(), mMainLoopController, mSession->getEventService())) { //The setup was cancelled, return. return; } } catch (const std::exception& ex) { std::cerr << "==== Error during startup ====\n\r\t" << ex.what() << "\n" << std::endl; S_LOG_CRITICAL("Error during startup." << ex); return; } catch (ShutdownException& ex2) { //Note that a ShutdownException is not an error. It just means that the user closed the application during startup. We should therefore just exit, as intended. S_LOG_INFO("ShutdownException caught: " << ex2.getReason()); return; } catch (...) { std::cerr << "==== Error during startup ====\n\r\tUnknown fatal error during startup. Something went wrong which caused a shutdown. Check the log file for more information." << std::endl; S_LOG_CRITICAL("Unknown fatal error during startup."); return; } Input::getSingleton().startInteraction(); startScripting(); mainLoop(); }
void LoggedInState::avatar_transferRequest(const Eris::TransferInfo& transferInfo, const Eris::Avatar* avatar) { TransferInfoStringSerializer serializer; std::string teleportFilePath(EmberServices::getSingleton().getConfigService().getHomeDirectory(BaseDirType_DATA) + "teleports"); std::fstream teleportsFile(teleportFilePath.c_str(), std::ios_base::in); TransferInfoStringSerializer::TransferInfoStore transferObjects; if (teleportsFile.good()) { serializer.deserialize(transferObjects, teleportsFile); } teleportsFile.close(); AvatarTransferInfo avatarTransferInfo(avatar->getEntity()->getName(), WFMath::TimeStamp::now(), transferInfo); transferObjects.push_back(avatarTransferInfo); std::fstream teleportsOutputFile(teleportFilePath.c_str(), std::ios_base::out); if (teleportsOutputFile.good()) { serializer.serialize(transferObjects, teleportsOutputFile); } else { S_LOG_CRITICAL("Could not write teleports info to file. This means that the teleported character cannot be claimed."); } teleportsOutputFile.close(); mTransferEvent = new Eris::TimedEvent(mAccount.getConnection()->getEventService(), boost::posix_time::seconds(0), [=](){ this->transfer(transferInfo); }); }
void LoggedInState::removeTransferInfo(const AvatarTransferInfo& transferInfo) { TransferInfoStringSerializer serializer; const std::string teleportFilePath(EmberServices::getSingleton().getConfigService().getHomeDirectory(BaseDirType_DATA) + "teleports"); std::fstream teleportsFile(teleportFilePath.c_str(), std::ios_base::in); TransferInfoStringSerializer::TransferInfoStore transferObjects; if (teleportsFile.good()) { serializer.deserialize(transferObjects, teleportsFile); } else { return; } teleportsFile.close(); //Find the transfer info amongst the persisted ones and remove it. for (AvatarTransferInfoStore::iterator I = transferObjects.begin(); I != transferObjects.end(); ++I) { AvatarTransferInfo& info = *I; const Eris::TransferInfo& transferInfo = info.getTransferInfo(); if (transferInfo.getHost() == mAccount.getConnection()->getHost() && transferInfo.getPort() == mAccount.getConnection()->getPort()) { transferObjects.erase(I); } } std::fstream teleportsOutputFile(teleportFilePath.c_str(), std::ios_base::out); if (teleportsOutputFile.good()) { serializer.serialize(transferObjects, teleportsOutputFile); } else { S_LOG_CRITICAL("Could not write teleports info to file. This means that the teleported character cannot be claimed."); } teleportsOutputFile.close(); }
void World::View_gotAvatarCharacter(Eris::Entity* entity) { if (entity) { EmberEntity& emberEntity = static_cast<EmberEntity&>(*entity); //Set up the third person avatar camera and switch to it. mAvatar = new Avatar(emberEntity, *mScene, mMainCamera->getCameraSettings(), *(mTerrainManager->getTerrainAdapter())); mAvatarCameraMotionHandler = new AvatarCameraMotionHandler(*mAvatar); mAvatar->getCameraMount().setMotionHandler(mAvatarCameraMotionHandler); mMovementController = new MovementController(*mAvatar, *mMainCamera, *mTerrainManager); mMainCamera->setMovementProvider(mMovementController); mMainCamera->attachToMount(&mAvatar->getCameraMount()); if (mAvatar->isAdmin()) { mAvatarCameraWarper = new AvatarCameraWarper(*mMovementController, *mMainCamera, mView); } emberEntity.BeingDeleted.connect(sigc::mem_fun(*this, &World::avatarEntity_BeingDeleted)); mSignals.EventMovementControllerCreated.emit(); mSignals.EventCreatedAvatarEntity.emit(emberEntity); mTerrainManager->startPaging(); EventGotAvatar(); } else { S_LOG_CRITICAL("Somehow got a null avatar entity."); } }
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); }
void TaskExecutor::run() { while (mActive) { TaskUnit* taskUnit = mTaskQueue.fetchNextTask(); //If the queue returns a null pointer, it means that the queue is being shut down, and this executor is expected to exit its main processing loop. if (taskUnit) { try { TaskExecutionContext context(*this, *taskUnit); taskUnit->executeInBackgroundThread(context); mTaskQueue.addProcessedTask(taskUnit); } catch (const std::exception& ex) { S_LOG_CRITICAL("Error when executing task in background." << ex); delete taskUnit; } catch (...) { S_LOG_CRITICAL("Unknown error when executing task in background."); delete taskUnit; } } else { break; } } }
unsigned int FoliageLayer::_populateGrassList(PageInfo /*page*/, float *posBuff, unsigned int grassCount) { unsigned int finalGrassCount = 0; if (mLatestPlantsResult) { const PlantAreaQueryResult::PlantStore& store = mLatestPlantsResult->getStore(); for (PlantAreaQueryResult::PlantStore::const_iterator I = store.begin(); I != store.end(); ++I) { if (finalGrassCount == grassCount) { break; } *posBuff++ = I->position.x; *posBuff++ = I->position.z; *posBuff++ = I->scale.x; *posBuff++ = I->orientation; finalGrassCount++; } } else { S_LOG_CRITICAL("_populateGrassList called without mLatestPlantsResult being set. This should never happen."); } return finalGrassCount; }
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; } }
/** Configures the application - returns false if the user chooses to abandon configuration. */ Ogre::Root* OgreSetup::configure(void) { ConfigService& configService(EmberServices::getSingleton().getConfigService()); createOgreSystem(); #ifndef BUILD_WEBEMBER bool success = false; bool suppressConfig = false; if (configService.itemExists("ogre", "suppressconfigdialog")) { suppressConfig = static_cast<bool>(configService.getValue("ogre", "suppressconfigdialog")); } try { success = mRoot->restoreConfig(); if (!success || !suppressConfig) { success = showConfigurationDialog(); } } catch (const std::exception& ex) { S_LOG_WARNING("Error when showing config dialog. Will try to remove ogre.cfg file and retry." << ex); unlink((EmberServices::getSingleton().getConfigService().getHomeDirectory() + "/ogre.cfg").c_str()); try { success = mRoot->showConfigDialog(); } catch (const std::exception& ex) { S_LOG_CRITICAL("Could not configure Ogre. Will shut down." << ex); } } if (!success) { return false; } mRenderWindow = mRoot->initialise(true, "Ember"); #else //BUILD_WEBEMBER == true //In webember we will disable the config dialog. //Also we will use fixed resolution and windowed mode. try { mRoot->restoreConfig(); } catch (const std::exception& ex) { //this isn't a problem, we will set the needed functions manually. } Ogre::RenderSystem* renderer = mRoot->getRenderSystem(); #ifdef _WIN32 //on windows, the default renderer is directX, we will force OpenGL. renderer = mRoot->getRenderSystemByName("OpenGL Rendering Subsystem"); if (renderer != NULL) { mRoot->setRenderSystem(renderer); } else { S_LOG_WARNING("OpenGL RenderSystem not found. Starting with default RenderSystem."); renderer = mRoot->getRenderSystem(); } #endif // _WIN32 renderer->setConfigOption("Video Mode", "800 x 600"); renderer->setConfigOption("Full Screen", "no"); mRoot->initialise(false, "Ember"); Ogre::NameValuePairList options; if (configService.itemExists("ogre", "windowhandle")) { //set the owner window std::string windowhandle = configService.getValue("ogre", "windowhandle"); options["parentWindowHandle"] = windowhandle; //put it in the top left corner options["top"] = "0"; options["left"] = "0"; } mRenderWindow = mRoot->createRenderWindow("Ember",800,600,false,&options); #endif // BUILD_WEBEMBER #ifdef _WIN32 //do some FPU fiddling, since we need the correct settings for stuff like mercator (which uses fractals etc.) to work _fpreset(); _controlfp(_PC_64, _MCW_PC); _controlfp(_RC_NEAR , _MCW_RC); #endif mRenderWindow->setActive(true); mRenderWindow->setAutoUpdated(true); mRenderWindow->setVisible(true); setStandardValues(); // Create new scene manager factory mSceneManagerFactory = new EmberPagingSceneManagerFactory(); // Register our factory mRoot->addSceneManagerFactory(mSceneManagerFactory); return mRoot; }
/** Configures the application - returns false if the user chooses to abandon configuration. */ Ogre::Root* OgreSetup::configure() { delete mConfigListenerContainer; mConfigListenerContainer = new ConfigListenerContainer(); mConfigListenerContainer->registerConfigListener("ogre", "loglevel", sigc::mem_fun(*this, &OgreSetup::Config_ogreLogChanged), true); ConfigService& configService(EmberServices::getSingleton().getConfigService()); createOgreSystem(); #ifndef BUILD_WEBEMBER bool success = false; bool suppressConfig = false; if (configService.itemExists("ogre", "suppressconfigdialog")) { suppressConfig = static_cast<bool>(configService.getValue("ogre", "suppressconfigdialog")); } try { success = mRoot->restoreConfig(); if (!success || !suppressConfig) { success = showConfigurationDialog(); } } catch (const std::exception& ex) { S_LOG_WARNING("Error when showing config dialog. Will try to remove ogre.cfg file and retry." << ex); unlink((EmberServices::getSingleton().getConfigService().getHomeDirectory(BaseDirType_CONFIG) + "ogre.cfg").c_str()); try { Ogre::ConfigDialog* dlg = OGRE_NEW Ogre::ConfigDialog(); success = mRoot->showConfigDialog(dlg); OGRE_DELETE dlg; } catch (const std::exception& ex) { S_LOG_CRITICAL("Could not configure Ogre. Will shut down." << ex); } } if (!success) { return nullptr; } // we start by trying to figure out what kind of resolution the user has selected, and whether full screen should be used or not unsigned int height = 768, width = 1024; bool fullscreen = false; parseWindowGeometry(mRoot->getRenderSystem()->getConfigOptions(), width, height, fullscreen); bool handleOpenGL = false; #ifdef __APPLE__ handleOpenGL = true; #endif std::string windowId = Input::getSingleton().createWindow(width, height, fullscreen, true, true, handleOpenGL); mRoot->initialise(false, "Ember"); Ogre::NameValuePairList misc; #ifdef __APPLE__ misc["currentGLContext"] = Ogre::String("true"); misc["macAPI"] = Ogre::String("cocoa"); #else //We should use "externalWindowHandle" on Windows, and "parentWindowHandle" on Linux. #ifdef _WIN32 misc["externalWindowHandle"] = windowId; #else misc["parentWindowHandle"] = windowId; #endif #endif mRenderWindow = mRoot->createRenderWindow("MainWindow", width, height, fullscreen, &misc); Input::getSingleton().EventSizeChanged.connect(sigc::mem_fun(*this, &OgreSetup::input_SizeChanged)); registerOpenGLContextFix(); if (mSaveShadersToCache) { Ogre::GpuProgramManager::getSingleton().setSaveMicrocodesToCache(true); std::string cacheFilePath = configService.getHomeDirectory(BaseDirType_CACHE) + "/gpu-" VERSION ".cache"; if (std::ifstream(cacheFilePath).good()) { try { auto cacheStream = mRoot->openFileStream(cacheFilePath); if (cacheStream) { Ogre::GpuProgramManager::getSingleton().loadMicrocodeCache(cacheStream); } } catch (...) { S_LOG_WARNING("Error when trying to open GPU cache file."); } } } #else //BUILD_WEBEMBER == true //In webember we will disable the config dialog. //Also we will use fixed resolution and windowed mode. try { mRoot->restoreConfig(); } catch (const std::exception& ex) { //this isn't a problem, we will set the needed functions manually. } Ogre::RenderSystem* renderer = mRoot->getRenderSystem(); #ifdef _WIN32 //on windows, the default renderer is directX, we will force OpenGL. Ogre::RenderSystem* renderer = mRoot->getRenderSystemByName("OpenGL Rendering Subsystem"); if(renderer != nullptr) { mRoot->setRenderSystem(renderer); } else { S_LOG_WARNING("OpenGL RenderSystem not found. Starting with default RenderSystem."); renderer = mRoot->getRenderSystem(); } #endif // _WIN32 renderer->setConfigOption("Video Mode", "800 x 600"); renderer->setConfigOption("Full Screen", "no"); mRoot->initialise(false, "Ember"); Ogre::NameValuePairList options; if (configService.itemExists("ogre", "windowhandle")) { //set the owner window std::string windowhandle = configService.getValue("ogre", "windowhandle"); options["parentWindowHandle"] = windowhandle; //put it in the top left corner options["top"] = "0"; options["left"] = "0"; } mRenderWindow = mRoot->createRenderWindow("Ember",800,600,false,&options); mOgreWindowProvider = new OgreWindowProvider(*mRenderWindow); Input::getSingleton().attach(mOgreWindowProvider); #endif // BUILD_WEBEMBER mRenderWindow->setActive(true); mRenderWindow->setAutoUpdated(true); mRenderWindow->setVisible(true); setStandardValues(); mConfigListenerContainer->registerConfigListener("ogre", "profiler", [&](const std::string& section, const std::string& key, varconf::Variable& variable) { if (variable.is_bool()) { auto* profiler = Ogre::Profiler::getSingletonPtr(); if (profiler) { if ((bool) variable) { auto& resourceGroupMgr = Ogre::ResourceGroupManager::getSingleton(); if (!resourceGroupMgr.resourceGroupExists("Profiler")) { resourceGroupMgr.addResourceLocation(OGRE_MEDIA_DIR"/packs/profiler.zip", "Zip", "Profiler", true); resourceGroupMgr.addResourceLocation(OGRE_MEDIA_DIR"/packs/SdkTrays.zip", "Zip", "Profiler", true); resourceGroupMgr.initialiseResourceGroup("Profiler"); } } if (profiler->getEnabled() != (bool) variable) { profiler->reset(); profiler->setEnabled((bool) variable); } } } }); // Create new scene manager factory //mSceneManagerFactory = new EmberPagingSceneManagerFactory(); //// Register our factory //mRoot->addSceneManagerFactory(mSceneManagerFactory); return mRoot; }