#include <stdlib.h> // atoi() atof() abs() system()
#include <signal.h> // signal()
+#include <string.h>
#include <iostream>
#include <fstream>
#include <simgear/misc/sg_path.hxx>
#include <simgear/misc/strutils.hxx>
#include <simgear/threads/SGQueue.hxx>
-#include <simgear/scene/tgdb/TileCache.hxx>
#include <simgear/misc/sg_dir.hxx>
-#include <OpenThreads/Thread>
#ifdef HAVE_SVN_CLIENT_H
# ifdef HAVE_LIBSVN_CLIENT_1
///////////////////////////////////////////////////////////////////////////////
// SGTerraSync::SvnThread /////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
-class SGTerraSync::SvnThread : public OpenThreads::Thread
+class SGTerraSync::SvnThread : public SGThread
{
public:
SvnThread();
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;}
volatile int _updated_tile_count;
volatile int _success_count;
volatile int _consecutive_errors;
+ volatile int _allowed_errors;
private:
virtual void run();
_updated_tile_count(0),
_success_count(0),
_consecutive_errors(0),
+ _allowed_errors(6),
#ifdef HAVE_SVN_CLIENT_H
_use_built_in(true),
#endif
<< status
<< "Directory: '" << _local_dir << "'.");
- OpenThreads::Thread::start();
+ SGThread::start();
return true;
}
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,
_busy = false;
}
- if (_consecutive_errors >= 5)
+ if ((_allowed_errors >= 0)&&
+ (_consecutive_errors >= _allowed_errors))
{
_stalled = true;
_stop = true;
last_lat(NOWHERE),
last_lon(NOWHERE),
_terraRoot(root->getNode("/sim/terrasync",true)),
- _tile_cache(NULL)
+ _refreshCb(NULL),
+ _userCbData(NULL)
{
_svnThread = new SvnThread();
}
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();
}
_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()
_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()
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())
void SGTerraSync::refreshScenery(SGPath path,const string& relativeDir)
{
// find tiles to be refreshed
- if (_tile_cache)
+ if (_refreshCb)
{
path.append(relativeDir);
if (path.exists())
{
// reload scenery tile
long index = atoi(tileList[i].file().c_str());
- _tile_cache->refresh_tile(index);
+ _refreshCb(_userCbData, index);
}
}
}
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()
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;
}