X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fscene%2Ftsync%2Fterrasync.cxx;h=e4ae8ff8ad0a7ce35f7ee6a395e9f72e12a67abb;hb=ae0b8eb3b3943690d0788dde316b1c152390f1fd;hp=0f99d4e508c739aaeafa5f64362539a21c7d274e;hpb=8cb716fe8e411a8cc8e4fe868e9718509754a673;p=simgear.git diff --git a/simgear/scene/tsync/terrasync.cxx b/simgear/scene/tsync/terrasync.cxx index 0f99d4e5..e4ae8ff8 100644 --- a/simgear/scene/tsync/terrasync.cxx +++ b/simgear/scene/tsync/terrasync.cxx @@ -45,6 +45,7 @@ #include // atoi() atof() abs() system() #include // signal() +#include #include #include @@ -58,9 +59,7 @@ #include #include #include -#include #include -#include #ifdef HAVE_SVN_CLIENT_H # ifdef HAVE_LIBSVN_CLIENT_1 @@ -140,7 +139,7 @@ public: /////////////////////////////////////////////////////////////////////////////// // SGTerraSync::SvnThread ///////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// -class SGTerraSync::SvnThread : public OpenThreads::Thread +class SGTerraSync::SvnThread : public SGThread { public: SvnThread(); @@ -161,6 +160,7 @@ public: void setLocalDir(string dir) { _local_dir = stripPath(dir);} string getLocalDir() { return _local_dir;} void setUseSvn(bool use_svn) { _use_svn = use_svn;} + void setAllowedErrorCount(int errors) {_allowed_errors = errors;} #ifdef HAVE_SVN_CLIENT_H void setUseBuiltin(bool built_in) { _use_built_in = built_in;} @@ -174,6 +174,7 @@ public: volatile int _updated_tile_count; volatile int _success_count; volatile int _consecutive_errors; + volatile int _allowed_errors; private: virtual void run(); @@ -221,6 +222,7 @@ SGTerraSync::SvnThread::SvnThread() : _updated_tile_count(0), _success_count(0), _consecutive_errors(0), + _allowed_errors(6), #ifdef HAVE_SVN_CLIENT_H _use_built_in(true), #endif @@ -343,7 +345,7 @@ bool SGTerraSync::SvnThread::start() << status << "Directory: '" << _local_dir << "'."); - OpenThreads::Thread::start(); + SGThread::start(); return true; } @@ -486,7 +488,18 @@ bool SGTerraSync::SvnThread::syncTreeExternal(const char* dir) command = buf.str(); #endif SG_LOG(SG_TERRAIN,SG_DEBUG, "sync command '" << command << "'"); + +#ifdef SG_WINDOWS + // tbd: does Windows support "popen"? int rc = system( command.c_str() ); +#else + FILE* pipe = popen( command.c_str(), "r"); + int rc=-1; + // wait for external process to finish + if (pipe) + rc = pclose(pipe); +#endif + if (rc) { SG_LOG(SG_TERRAIN,SG_ALERT, @@ -544,7 +557,8 @@ void SGTerraSync::SvnThread::run() _busy = false; } - if (_consecutive_errors >= 5) + if ((_allowed_errors >= 0)&& + (_consecutive_errors >= _allowed_errors)) { _stalled = true; _stop = true; @@ -658,7 +672,8 @@ SGTerraSync::SGTerraSync(SGPropertyNode_ptr root) : last_lat(NOWHERE), last_lon(NOWHERE), _terraRoot(root->getNode("/sim/terrasync",true)), - _tile_cache(NULL) + _refreshCb(NULL), + _userCbData(NULL) { _svnThread = new SvnThread(); } @@ -672,8 +687,8 @@ SGTerraSync::~SGTerraSync() void SGTerraSync::init() { - _refresh_display = _terraRoot->getNode("refresh-display",true); - _terraRoot->getNode("built-in-svn-available",true)->setBoolValue(svn_built_in_available); + _refreshDisplay = _terraRoot->getNode("refresh-display",true); + _terraRoot->setBoolValue("built-in-svn-available",svn_built_in_available); reinit(); } @@ -691,22 +706,32 @@ void SGTerraSync::reinit() _svnThread->setSvnServer(_terraRoot->getStringValue("svn-server","")); _svnThread->setRsyncServer(_terraRoot->getStringValue("rsync-server","")); _svnThread->setLocalDir(_terraRoot->getStringValue("scenery-dir","")); + _svnThread->setAllowedErrorCount(_terraRoot->getIntValue("max-errors",5)); #ifdef HAVE_SVN_CLIENT_H _svnThread->setUseBuiltin(_terraRoot->getBoolValue("use-built-in-svn",true)); #else - _terraRoot->getNode("use-built-in-svn",true)->setBoolValue(false); + _terraRoot->setBoolValue("use-built-in-svn",false); #endif _svnThread->setUseSvn(_terraRoot->getBoolValue("use-svn",true)); _svnThread->setExtSvnUtility(_terraRoot->getStringValue("ext-svn-utility","svn")); if (_svnThread->start()) + { syncAirportsModels(); + if (last_lat != NOWHERE && last_lon != NOWHERE) + { + // reschedule most recent position + int lat = last_lat; + int lon = last_lon; + last_lat = NOWHERE; + last_lon = NOWHERE; + schedulePosition(lat, lon); + } + } } - _stalled_node->setBoolValue(_svnThread->_stalled); - last_lat = NOWHERE; - last_lon = NOWHERE; + _stalledNode->setBoolValue(_svnThread->_stalled); } void SGTerraSync::bind() @@ -724,9 +749,9 @@ void SGTerraSync::bind() _terraRoot->getNode("use-built-in-svn", true)->setAttribute(SGPropertyNode::USERARCHIVE,false); _terraRoot->getNode("use-svn", true)->setAttribute(SGPropertyNode::USERARCHIVE,false); // stalled is used as a signal handler (to connect listeners triggering GUI pop-ups) - _stalled_node = _terraRoot->getNode("stalled", true); - _stalled_node->setBoolValue(_svnThread->_stalled); - _stalled_node->setAttribute(SGPropertyNode::PRESERVE,true); + _stalledNode = _terraRoot->getNode("stalled", true); + _stalledNode->setBoolValue(_svnThread->_stalled); + _stalledNode->setAttribute(SGPropertyNode::PRESERVE,true); } void SGTerraSync::unbind() @@ -753,10 +778,10 @@ void SGTerraSync::update(double) SG_LOG(SG_TERRAIN,SG_ALERT, "Automatic scenery download/synchronization has stopped."); } - _stalled_node->setBoolValue(_svnThread->_stalled); + _stalledNode->setBoolValue(_svnThread->_stalled); } - if (!_refresh_display->getBoolValue()) + if (!_refreshDisplay->getBoolValue()) return; while (_svnThread->hasNewTiles()) @@ -773,7 +798,7 @@ void SGTerraSync::update(double) void SGTerraSync::refreshScenery(SGPath path,const string& relativeDir) { // find tiles to be refreshed - if (_tile_cache) + if (_refreshCb) { path.append(relativeDir); if (path.exists()) @@ -787,7 +812,7 @@ void SGTerraSync::refreshScenery(SGPath path,const string& relativeDir) { // reload scenery tile long index = atoi(tileList[i].file().c_str()); - _tile_cache->refresh_tile(index); + _refreshCb(_userCbData, index); } } } @@ -795,17 +820,19 @@ void SGTerraSync::refreshScenery(SGPath path,const string& relativeDir) bool SGTerraSync::isIdle() {return _svnThread->isIdle();} -void SGTerraSync::setTileCache(TileCache* tile_cache) +void SGTerraSync::setTileRefreshCb(SGTerraSyncCallback refreshCb, void* userCbData) { - _tile_cache = tile_cache; + _refreshCb = refreshCb; + _userCbData = userCbData; } void SGTerraSync::syncAirportsModels() { - static const char bounds[] = "KZAJ"; - for( unsigned i = 0; i < sizeof(bounds)/sizeof(bounds[0])/2; i+= 2 ) + static const char* bounds = "MZAJKL"; // airport sync order: K-L, A-J, M-Z + // note "request" method uses LIFO order, i.e. processes most recent request first + for( unsigned i = 0; i < strlen(bounds)/2; i++ ) { - for ( char synced_other = bounds[i]; synced_other <= bounds[i+1]; synced_other++ ) + for ( char synced_other = bounds[2*i]; synced_other <= bounds[2*i+1]; synced_other++ ) { ostringstream dir; dir << "Airports/" << synced_other; @@ -896,46 +923,49 @@ void SGTerraSync::syncAreas( int lat, int lon, int lat_dir, int lon_dir ) bool SGTerraSync::schedulePosition(int lat, int lon) { + bool Ok = false; + // Ignore messages where the location does not change if ( lat != last_lat || lon != last_lon ) { - SG_LOG(SG_TERRAIN,SG_DEBUG, "Requesting scenery update for position " << - lat << "," << lon); - int lat_dir, lon_dir, dist; - if ( last_lat == NOWHERE || last_lon == NOWHERE ) - { - lat_dir = lon_dir = 0; - } else + if (_svnThread->_running) { - dist = lat - last_lat; - if ( dist != 0 ) - { - lat_dir = dist / abs(dist); - } - else + SG_LOG(SG_TERRAIN,SG_DEBUG, "Requesting scenery update for position " << + lat << "," << lon); + int lat_dir=0; + int lon_dir=0; + if ( last_lat != NOWHERE && last_lon != NOWHERE ) { - lat_dir = 0; - } - dist = lon - last_lon; - if ( dist != 0 ) - { - lon_dir = dist / abs(dist); - } else - { - lon_dir = 0; + int dist = lat - last_lat; + if ( dist != 0 ) + { + lat_dir = dist / abs(dist); + } + else + { + lat_dir = 0; + } + dist = lon - last_lon; + if ( dist != 0 ) + { + lon_dir = dist / abs(dist); + } else + { + lon_dir = 0; + } } - } - SG_LOG(SG_TERRAIN,SG_DEBUG, "Scenery update for " << - "lat = " << lat << ", lon = " << lon << - ", lat_dir = " << lat_dir << ", " << - "lon_dir = " << lon_dir); - - syncAreas( lat, lon, lat_dir, lon_dir ); + SG_LOG(SG_TERRAIN,SG_DEBUG, "Scenery update for " << + "lat = " << lat << ", lon = " << lon << + ", lat_dir = " << lat_dir << ", " << + "lon_dir = " << lon_dir); + syncAreas( lat, lon, lat_dir, lon_dir ); + Ok = true; + } last_lat = lat; last_lon = lon; - return true; } - return false; + + return Ok; }