diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index 61ad544dd..61140b495 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -26,6 +26,7 @@ #include "menu_state_keysetup.h" #include "video_player.h" #include "compression_utils.h" +#include "cache_manager.h" #include "leak_dumper.h" @@ -375,6 +376,11 @@ void Game::endGame() { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] ==== END GAME ==== getCurrentPixelByteCount() = %llu\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(long long unsigned int)renderer.getCurrentPixelByteCount()); if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"==== END GAME ====\n"); + FileCRCPreCacheThread * &preCacheCRCThreadPtr = CacheManager::getCachedItem< FileCRCPreCacheThread * >(GameConstants::preCacheThreadCacheLookupKey); + if(preCacheCRCThreadPtr != NULL) { + preCacheCRCThreadPtr->setPauseForGame(false); + } + //this->program->reInitGl(); //renderer.reinitAll(); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); @@ -444,6 +450,11 @@ Game::~Game() { Lang::getInstance().setAllowNativeLanguageTechtree(true); + FileCRCPreCacheThread * &preCacheCRCThreadPtr = CacheManager::getCachedItem< FileCRCPreCacheThread * >(GameConstants::preCacheThreadCacheLookupKey); + if(preCacheCRCThreadPtr != NULL) { + preCacheCRCThreadPtr->setPauseForGame(false); + } + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] ==== END GAME ==== getCurrentPixelByteCount() = %llu\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(long long unsigned int)renderer.getCurrentPixelByteCount()); if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"==== END GAME ====\n"); @@ -976,6 +987,11 @@ void Game::load(int loadTypes) { perfList.push_back(perfBuf); } + FileCRCPreCacheThread * &preCacheCRCThreadPtr = CacheManager::getCachedItem< FileCRCPreCacheThread * >(GameConstants::preCacheThreadCacheLookupKey); + if(preCacheCRCThreadPtr != NULL) { + preCacheCRCThreadPtr->setPauseForGame(true); + } + std::map > > loadedFileList; originalDisplayMsgCallback = NetworkInterface::getDisplayMessageFunction(); NetworkInterface::setDisplayMessageFunction(ErrorDisplayMessage); diff --git a/source/glest_game/game/game_constants.h b/source/glest_game/game/game_constants.h index 776d1c7ba..e52b8d478 100644 --- a/source/glest_game/game/game_constants.h +++ b/source/glest_game/game/game_constants.h @@ -153,6 +153,7 @@ public: static const char *OBSERVER_SLOTNAME; static const char *RANDOMFACTION_SLOTNAME; + static const char *preCacheThreadCacheLookupKey; static const char *playerTextureCacheLookupKey; static const char *ircClientCacheLookupKey; static const char *factionPreviewTextureCacheLookupKey; diff --git a/source/glest_game/global/config.cpp b/source/glest_game/global/config.cpp index 3ec39e334..736d86fae 100644 --- a/source/glest_game/global/config.cpp +++ b/source/glest_game/global/config.cpp @@ -50,6 +50,7 @@ const char *GameConstants::folder_path_screenshots = "screens/"; const char *GameConstants::OBSERVER_SLOTNAME = "*Observer*"; const char *GameConstants::RANDOMFACTION_SLOTNAME = "*Random*"; +const char *GameConstants::preCacheThreadCacheLookupKey = "preCacheThreadCache"; const char *GameConstants::ircClientCacheLookupKey = "ircClientCache"; const char *GameConstants::playerTextureCacheLookupKey = "playerTextureCache"; const char *GameConstants::factionPreviewTextureCacheLookupKey = "factionPreviewTextureCache"; diff --git a/source/glest_game/main/main.cpp b/source/glest_game/main/main.cpp index 05268cbe7..e18c1a276 100644 --- a/source/glest_game/main/main.cpp +++ b/source/glest_game/main/main.cpp @@ -5289,9 +5289,14 @@ int glestMain(int argc, char** argv) { //printf("### In [%s::%s Line: %d] precache thread enabled = %d SystemFlags::VERBOSE_MODE_ENABLED = %d\n",__FILE__,__FUNCTION__,__LINE__,startCRCPrecacheThread,SystemFlags::VERBOSE_MODE_ENABLED); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] precache thread enabled = %d\n",__FILE__,__FUNCTION__,__LINE__,startCRCPrecacheThread); if(startCRCPrecacheThread == true) { - vector techDataPaths = config.getPathListForType(ptTechs); static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); - preCacheThread = new FileCRCPreCacheThread(); + vector techDataPaths = config.getPathListForType(ptTechs); + + FileCRCPreCacheThread * &preCacheCRCThreadPtr = CacheManager::getCachedItem< FileCRCPreCacheThread * >(GameConstants::preCacheThreadCacheLookupKey); + if(preCacheCRCThreadPtr == NULL) { + preCacheCRCThreadPtr = new FileCRCPreCacheThread(); + } + preCacheThread = preCacheCRCThreadPtr; preCacheThread->setUniqueID(mutexOwnerId); preCacheThread->setTechDataPaths(techDataPaths); //preCacheThread->setFileCRCPreCacheThreadCallbackInterface(&preCacheThreadGame); diff --git a/source/glest_game/menu/menu_state_scenario.cpp b/source/glest_game/menu/menu_state_scenario.cpp index 6726454be..9af716162 100644 --- a/source/glest_game/menu/menu_state_scenario.cpp +++ b/source/glest_game/menu/menu_state_scenario.cpp @@ -311,7 +311,11 @@ void MenuStateScenario::update() { return; } if(this->autoloadScenarioName != "") { - loadScenarioInfo(Scenario::getScenarioPath(dirList, this->autoloadScenarioName), &scenarioInfo ); + string scenarioPath = Scenario::getScenarioPath(dirList, this->autoloadScenarioName); + + //printf("[%s:%s] Line: %d this->autoloadScenarioName [%s] scenarioPath [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->autoloadScenarioName.c_str(),scenarioPath.c_str()); + + loadScenarioInfo(scenarioPath, &scenarioInfo ); if(scenarioInfo.namei18n != "") { this->autoloadScenarioName = scenarioInfo.namei18n; } @@ -385,6 +389,9 @@ void MenuStateScenario::setScenario(int i) { void MenuStateScenario::loadScenarioInfo(string file, ScenarioInfo *scenarioInfo) { bool isTutorial = Scenario::isGameTutorial(file); + + //printf("[%s:%s] Line: %d file [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,file.c_str()); + Scenario::loadScenarioInfo(file, scenarioInfo, isTutorial); cleanupPreviewTexture(); diff --git a/source/glest_game/world/scenario.cpp b/source/glest_game/world/scenario.cpp index 2552a357e..92e67a276 100644 --- a/source/glest_game/world/scenario.cpp +++ b/source/glest_game/world/scenario.cpp @@ -201,10 +201,12 @@ void Scenario::loadScenarioInfo(string file, ScenarioInfo *scenarioInfo, bool is if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] file [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,file.c_str()); //printf("In [%s::%s Line: %d] file [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,file.c_str()); + //printf("[%s:%s] Line: %d file [%s]\n",__FILE__,__FUNCTION__,__LINE__,file.c_str()); Lang &lang= Lang::getInstance(); string scenarioDir = cutLastFile(formatPath(file)); string scenarioName = extractLastDirectoryFromPath(scenarioDir); scenarioDir = cutLastFile(scenarioDir); + //printf("[%s:%s] Line: %d scenarioDir [%s] scenarioName [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioDir.c_str(),scenarioName.c_str()); XmlTree xmlTree; xmlTree.load(file,Properties::getTagReplacementValues()); diff --git a/source/shared_lib/include/platform/common/simple_threads.h b/source/shared_lib/include/platform/common/simple_threads.h index 2f0e5a1bc..9f6b67610 100644 --- a/source/shared_lib/include/platform/common/simple_threads.h +++ b/source/shared_lib/include/platform/common/simple_threads.h @@ -47,6 +47,10 @@ protected: Mutex mutexPendingTextureList; vector pendingTextureList; + Mutex mutexPauseForGame; + bool pauseForGame; + std::vector preCacheWorkerThreadList; + void addPendingTexture(Texture2D *texture); void addPendingTextureList(vector textureList); @@ -60,6 +64,9 @@ public: vector getPendingTextureList(int maxTexturesToGet); virtual bool canShutdown(bool deleteSelfIfShutdownDelayed); + + void setPauseForGame(bool pauseForGame); + bool getPauseForGame(); }; // ===================================================== diff --git a/source/shared_lib/sources/platform/common/simple_threads.cpp b/source/shared_lib/sources/platform/common/simple_threads.cpp index a22c7f8b6..22aa490a3 100644 --- a/source/shared_lib/sources/platform/common/simple_threads.cpp +++ b/source/shared_lib/sources/platform/common/simple_threads.cpp @@ -30,6 +30,7 @@ const static double PAUSE_SECONDS_BETWEEN_WORKERS = 15; FileCRCPreCacheThread::FileCRCPreCacheThread() : BaseThread() { techDataPaths.clear(); workerThreadTechPaths.clear(); + preCacheWorkerThreadList.clear(); processTechCB = NULL; uniqueID = "FileCRCPreCacheThread"; } @@ -39,10 +40,30 @@ FileCRCPreCacheThread::FileCRCPreCacheThread(vector techDataPaths, FileCRCPreCacheThreadCallbackInterface *processTechCB) { this->techDataPaths = techDataPaths; this->workerThreadTechPaths = workerThreadTechPaths; + preCacheWorkerThreadList.clear(); this->processTechCB = processTechCB; uniqueID = "FileCRCPreCacheThread"; } +void FileCRCPreCacheThread::setPauseForGame(bool pauseForGame) { + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(&mutexPauseForGame,mutexOwnerId); + this->pauseForGame = pauseForGame; + + for(unsigned int index = 0; index < preCacheWorkerThreadList.size(); ++index) { + FileCRCPreCacheThread *worker = preCacheWorkerThreadList[index]; + if(worker != NULL) { + worker->setPauseForGame(this->pauseForGame); + } + } +} + +bool FileCRCPreCacheThread::getPauseForGame() { + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(&mutexPauseForGame,mutexOwnerId); + return this->pauseForGame; +} + bool FileCRCPreCacheThread::canShutdown(bool deleteSelfIfShutdownDelayed) { bool ret = (getExecutingTask() == false); if(ret == false && deleteSelfIfShutdownDelayed == true) { @@ -70,7 +91,6 @@ void FileCRCPreCacheThread::execute() { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"FILE CRC PreCache thread is running threadControllerMode = %d\n",threadControllerMode); try { - std::vector preCacheWorkerThreadList; if(threadControllerMode == true) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("********************** CRC Controller thread START **********************\n"); time_t elapsedTime = time(NULL); @@ -121,6 +141,8 @@ void FileCRCPreCacheThread::execute() { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] workerIdx = %u, currentWorkerMax = %u, endConsumerIndex = %u\n",__FILE__,__FUNCTION__,__LINE__,workerIdx,currentWorkerMax,endConsumerIndex); // Pause before launching this worker thread + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("About to process CRC for factions waiting...\n"); + time_t pauseTime = time(NULL); while(getQuitStatus() == false && difftime(time(NULL),pauseTime) <= PAUSE_SECONDS_BETWEEN_WORKERS) { @@ -131,6 +153,7 @@ void FileCRCPreCacheThread::execute() { break; } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Starting CRC for faction workers...\n"); FileCRCPreCacheThread *workerThread = new FileCRCPreCacheThread(techDataPaths, @@ -138,7 +161,12 @@ void FileCRCPreCacheThread::execute() { this->processTechCB); static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); workerThread->setUniqueID(mutexOwnerId); + workerThread->setPauseForGame(this->getPauseForGame()); + static string mutexOwnerId2 = CODE_AT_LINE; + MutexSafeWrapper safeMutexPause(&mutexPauseForGame,mutexOwnerId2); preCacheWorkerThreadList.push_back(workerThread); + safeMutexPause.ReleaseLock(); + workerThread->start(); consumedWorkers += currentWorkerMax; @@ -181,16 +209,22 @@ void FileCRCPreCacheThread::execute() { } } else if(workerThread->getRunningStatus() == false) { - sleep(10); + sleep(25); + + static string mutexOwnerId2 = CODE_AT_LINE; + MutexSafeWrapper safeMutexPause(&mutexPauseForGame,mutexOwnerId2); + delete workerThread; preCacheWorkerThreadList[idx] = NULL; + + safeMutexPause.ReleaseLock(); } } } if( getQuitStatus() == false && hasRunningWorkerThread == true) { - sleep(10); + sleep(25); } else if(getQuitStatus() == true) { for(unsigned int idx = 0; idx < preCacheWorkerThreadList.size(); idx++) { @@ -216,6 +250,8 @@ void FileCRCPreCacheThread::execute() { } else { try { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\tStarting CRC for faction worker thread for techs: %d...\n",(int)workerThreadTechPaths.size()); + for(unsigned int idx = 0; idx < workerThreadTechPaths.size(); idx++) { string techName = this->workerThreadTechPaths[idx]; if(getQuitStatus() == true) { @@ -238,6 +274,18 @@ void FileCRCPreCacheThread::execute() { //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("--------------------- CRC worker thread running for tech [%s] ---------------------------\n",techName.c_str()); if(getQuitStatus() == false) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\tAbout to process CRC for techName [%s]\n",techName.c_str()); + + // Do not process CRC's while game in progress + if(getPauseForGame() == true) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\tGame in progress so waiting to process CRC for techName [%s]\n",techName.c_str()); + for(;getPauseForGame() == true && + getQuitStatus() == false;) { + sleep(25); + } + } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\tStart Processing CRC for techName [%s]\n",techName.c_str()); + int32 techCRC = getFolderTreeContentsCheckSumRecursively(techDataPaths, string("/") + techName + string("/*"), ".xml", NULL, true); //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] cached CRC value for Tech [%s] is [%d] took %.3f seconds.\n",__FILE__,__FUNCTION__,__LINE__,techName.c_str(),techCRC,difftime(time(NULL),elapsedTime)); @@ -253,10 +301,27 @@ void FileCRCPreCacheThread::execute() { } } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\tStarting CRC for faction worker thread for results: %d...\n",(int)results.size()); if(results.empty() == true) { - for(unsigned int factionIdx = 0; factionIdx < results.size(); ++factionIdx) { + for(unsigned int factionIdx = 0; + factionIdx < results.size(); + ++factionIdx) { string factionName = results[factionIdx]; + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\t\tAbout to process CRC for factionName [%s]\n",factionName.c_str()); + + // Do not process CRC's while game in progress + if(getPauseForGame() == true) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\t\tGame in progress so waiting to process CRC for factionName [%s]\n",factionName.c_str()); + for(;getPauseForGame() == true && + getQuitStatus() == false;) { + sleep(25); + } + } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\t\tStart Processing CRC for factionName [%s]\n",factionName.c_str()); + int32 factionCRC = getFolderTreeContentsCheckSumRecursively(techDataPaths, "/" + techName + "/factions/" + factionName + "/*", ".xml", NULL, true); + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\t\tDone Processing CRC for factionName [%s]\n",factionName.c_str()); } }