/* -------------------------------------------------------------------------------- */
-class MetarDataHandler {
-public:
- virtual void handleMetarData( const std::string & data ) = 0;
- virtual void handleMetarFailure() = 0;
-};
-
-class MetarRequester {
-public:
- virtual void requestMetar( MetarDataHandler * metarDataHandler, const std::string & id ) = 0;
-};
+class MetarRequester;
/* -------------------------------------------------------------------------------- */
-class LiveMetarProperties : public MetarProperties, MetarDataHandler {
+class LiveMetarProperties : public MetarProperties {
public:
LiveMetarProperties( SGPropertyNode_ptr rootNode, MetarRequester * metarRequester, int maxAge );
virtual ~LiveMetarProperties();
typedef SGSharedPtr<LiveMetarProperties> LiveMetarProperties_ptr;
+class MetarRequester {
+public:
+ virtual void requestMetar( LiveMetarProperties_ptr metarDataHandler, const std::string & id ) = 0;
+};
+
+
LiveMetarProperties::LiveMetarProperties( SGPropertyNode_ptr rootNode, MetarRequester * metarRequester, int maxAge ) :
MetarProperties( rootNode ),
_timeToLive(0.0),
try {
m = new FGMetar(data.c_str());
}
- catch( sg_io_exception ) {
+ catch( sg_io_exception &) {
SG_LOG( SG_ENVIRONMENT, SG_WARN, "Can't parse metar: " << data );
_failure = true;
return;
void addMetarAtPath(const string& propPath, const string& icao);
void removeMetarAtPath(const string& propPath);
+
+ typedef std::vector<LiveMetarProperties_ptr> MetarPropertiesList;
+ MetarPropertiesList::iterator findMetarAtPath(const string &propPath);
protected:
void bind();
void unbind();
bool _enabled;
bool _wasEnabled;
simgear::TiedPropertyList _tiedProperties;
- typedef std::vector<LiveMetarProperties_ptr> MetarPropertiesList;
MetarPropertiesList _metarProperties;
MetarRequester* _requester;
void BasicRealWxController::addMetarAtPath(const string& propPath, const string& icao)
{
// check for duplicate entries
- BOOST_FOREACH( LiveMetarProperties_ptr p, _metarProperties ) {
- if( p->get_root_node()->getPath() == propPath ) {
- // already exists
- if (p->getStationId() != icao) {
- p->setStationId(icao);
- p->resetTimeToLive();
- }
-
- return;
+ MetarPropertiesList::iterator it = findMetarAtPath(propPath);
+ if( it != _metarProperties.end() ) {
+ SG_LOG( SG_ENVIRONMENT, SG_INFO, "Reusing metar properties at " << propPath << " for " << icao);
+ // already exists
+ if ((*it)->getStationId() != icao) {
+ (*it)->setStationId(icao);
+ (*it)->resetTimeToLive();
}
- } // of exitsing metar properties iteration
+ return;
+ }
SGPropertyNode_ptr metarNode = fgGetNode(propPath, true);
- SG_LOG( SG_ENVIRONMENT, SG_INFO, "Adding metar properties at " << propPath );
+ SG_LOG( SG_ENVIRONMENT, SG_INFO, "Adding metar properties at " << propPath << " for " << icao);
LiveMetarProperties_ptr p(new LiveMetarProperties( metarNode, _requester, getMetarMaxAgeMin() ));
_metarProperties.push_back(p);
p->setStationId(icao);
void BasicRealWxController::removeMetarAtPath(const string &propPath)
{
- MetarPropertiesList::iterator it = _metarProperties.begin();
- for (; it != _metarProperties.end(); ++it) {
- LiveMetarProperties_ptr p(*it);
- if( p->get_root_node()->getPath() == propPath ) {
- _metarProperties.erase(it);
- // final ref will drop, and delete the MetarProperties, when we return
- return;
- }
+ MetarPropertiesList::iterator it = findMetarAtPath( propPath );
+ if( it != _metarProperties.end() ) {
+ SG_LOG(SG_ENVIRONMENT, SG_INFO, "removing metar properties at " << propPath);
+ _metarProperties.erase(it);
+ } else {
+ SG_LOG(SG_ENVIRONMENT, SG_WARN, "no metar properties at " << propPath);
}
-
- SG_LOG(SG_ENVIRONMENT, SG_WARN, "no metar properties at " << propPath);
+}
+
+BasicRealWxController::MetarPropertiesList::iterator BasicRealWxController::findMetarAtPath(const string &propPath)
+{
+ // don not compare unprocessed property path
+ // /foo/bar[0]/baz equals /foo/bar/baz
+ SGPropertyNode_ptr n = fgGetNode(propPath,false);
+ if( false == n.valid() ) // trivial: node does not exist
+ return _metarProperties.end();
+
+ MetarPropertiesList::iterator it = _metarProperties.begin();
+ while( it != _metarProperties.end() &&
+ (*it)->get_root_node()->getPath() != n->getPath() )
+ ++it;
+
+ return it;
}
void BasicRealWxController::checkNearbyMetar()
NoaaMetarRealWxController( SGPropertyNode_ptr rootNode );
// implementation of MetarRequester
- virtual void requestMetar( MetarDataHandler * metarDataHandler, const std::string & id );
+ virtual void requestMetar( LiveMetarProperties_ptr metarDataHandler, const std::string & id );
virtual ~NoaaMetarRealWxController()
{
void NoaaMetarRealWxController::requestMetar
(
- MetarDataHandler* metarDataHandler,
+ LiveMetarProperties_ptr metarDataHandler,
const std::string& id
)
{
public simgear::HTTP::MemoryRequest
{
public:
- NoaaMetarGetRequest( MetarDataHandler* metarDataHandler,
+ NoaaMetarGetRequest( LiveMetarProperties_ptr metarDataHandler,
const std::string& stationId ):
MemoryRequest(NOAA_BASE_URL + stationId + ".TXT"),
_metarDataHandler(metarDataHandler)
}
private:
- MetarDataHandler * _metarDataHandler;
+ LiveMetarProperties_ptr _metarDataHandler;
};
string upperId = boost::to_upper_copy(id);