//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
#include <simgear/structure/subsystem_mgr.hxx>
#include <simgear/environment/metar.hxx>
+#if defined(ENABLE_THREADS)
+# include <simgear/threads/SGThread.hxx>
+# include <simgear/threads/SGQueue.hxx>
+#endif
+
#ifdef SG_HAVE_STD_INCLUDES
# include <cmath>
#else
# include <math.h>
#endif
+#include <queue>
#include <vector>
+SG_USING_STD(queue);
SG_USING_STD(vector);
class SGPropertyNode;
#include "environment.hxx"
+#include "fgmetar.hxx"
\f
virtual void setEnvironment (FGEnvironment * environment);
- virtual FGEnvironment * getEnvironment () const { return _environment; }
+ virtual const FGEnvironment * getEnvironment () const { return _environment; }
virtual void setLongitudeDeg (double lon_deg);
virtual void setLatitudeDeg (double lat_deg);
};
+// A convenience wrapper around FGMetar
+struct FGMetarResult {
+ string icao;
+ FGMetar *m;
+};
+
+
\f
/**
- * Interplation controller using the SGMetar class
+ * Interplation controller using the FGMetar class
*/
class FGMetarEnvironmentCtrl : public FGEnvironmentCtrl
{
virtual void init ();
virtual void reinit ();
virtual void update (double delta_time_sec);
+ virtual void setEnvironment (FGEnvironment * environment);
private:
+ FGInterpolateEnvironmentCtrl *env;
+
+ string _icao;
+ float station_elevation_ft;
+ float search_interval_sec;
+ float same_station_interval_sec;
+ float search_elapsed;
+ float fetch_elapsed;
+ const FGAirport *last_apt;
+ SGPropertyNode *proxy_host;
+ SGPropertyNode *proxy_port;
+ SGPropertyNode *proxy_auth;
+ SGPropertyNode *metar_max_age;
+
+ FGMetarResult fetch_data( const string &icao );
+ virtual void update_metar_properties( const FGMetar *m );
+ void update_env_config();
- struct bucket {
- double altitude_ft;
- FGEnvironment environment;
- bool operator< (const bucket &b) const;
+private:
+
+#if defined(ENABLE_THREADS)
+ /**
+ * FIFO queue which holds a pointer to the fetched metar data.
+ */
+ SGBlockingQueue < string > request_queue;
+
+ /**
+ * FIFO queue which holds a pointer to the fetched metar data.
+ */
+ SGLockedQueue < FGMetarResult > result_queue;
+#else
+ /**
+ * FIFO queue which holds a pointer to the fetched metar data.
+ */
+ queue < string > request_queue;
+
+ /**
+ * FIFO queue which holds a pointer to the fetched metar data.
+ */
+ queue < FGMetarResult > result_queue;
+#endif
+
+#if defined(ENABLE_THREADS)
+ /**
+ * This class represents the thread of execution responsible for
+ * fetching the metar data.
+ */
+ class MetarThread : public SGThread
+ {
+ public:
+ MetarThread( FGMetarEnvironmentCtrl* f ) : fetcher(f) {}
+ ~MetarThread() {}
+
+ /**
+ * Fetche the metar data from the NOAA.
+ */
+ void run();
+
+ private:
+ FGMetarEnvironmentCtrl *fetcher;
+
+ private:
+ // not implemented.
+ MetarThread();
+ MetarThread( const MetarThread& );
+ MetarThread& operator=( const MetarThread& );
};
- char *_icao;
- SGPropertyNode * _base_wind_speed_node;
- SGPropertyNode * _gust_wind_speed_node;
+ friend class MetarThread;
- double _current_wind_speed_kt;
- double _delta_wind_speed_kt;
+ /**
+ * Metar data fetching thread.
+ */
+ MetarThread* thread;
- void read_table (const char *icao);
- void do_interpolate (vector<bucket *> &table, double altitude_ft,
- FGEnvironment * environment);
+ void thread_stop();
+#endif // ENABLE_THREADS
+
+ int _error_count;
+ int _stale_count;
+ double _dt;
+ double _error_dt;
};
#endif // _ENVIRONMENT_CTRL_HXX