Partial testing framework.
Compile a useful subset of FG as a shared library, and add two basic uses of this to exercise some Flightplan / RoutePath / navaid functions. The test framework can/will be expanded incrementally from here, this is just a starting point.
This commit is contained in:
parent
7adb2fa851
commit
9e122eaf81
25 changed files with 1499 additions and 113 deletions
|
@ -512,6 +512,22 @@ add_subdirectory(utils)
|
|||
add_subdirectory(src)
|
||||
add_subdirectory(man)
|
||||
|
||||
if(ENABLE_TESTS)
|
||||
# enable CTest / make test target
|
||||
message(STATUS "Tests: ENABLED")
|
||||
|
||||
include (Dart)
|
||||
enable_testing()
|
||||
if(WIN32)
|
||||
# tests disabled until shared library export is fixed on Windows
|
||||
message(STATUS "Tests disabled on Windows for the moment")
|
||||
else()
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Tests: DISABLED")
|
||||
endif(ENABLE_TESTS)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
### uninstall target
|
||||
#-----------------------------------------------------------------------------
|
||||
|
|
|
@ -26,8 +26,13 @@
|
|||
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#ifdef FG_TESTLIB
|
||||
#include <tests/fake_sgSky.hxx>
|
||||
#else
|
||||
#include <simgear/scene/sky/sky.hxx>
|
||||
#include <simgear/scene/model/particles.hxx>
|
||||
#endif
|
||||
#include <simgear/structure/event_mgr.hxx>
|
||||
|
||||
#include <Main/main.hxx>
|
||||
|
@ -47,6 +52,7 @@
|
|||
#include "gravity.hxx"
|
||||
#include "magvarmanager.hxx"
|
||||
|
||||
#ifndef FG_TESTLIB
|
||||
class FG3DCloudsListener : public SGPropertyChangeListener {
|
||||
public:
|
||||
FG3DCloudsListener( FGClouds * fgClouds );
|
||||
|
@ -60,7 +66,7 @@ private:
|
|||
};
|
||||
|
||||
FG3DCloudsListener::FG3DCloudsListener( FGClouds * fgClouds ) :
|
||||
_fgClouds( fgClouds )
|
||||
_fgClouds( fgClouds )
|
||||
{
|
||||
_enableNode = fgGetNode( "/sim/rendering/clouds3d-enable", true );
|
||||
_enableNode->addChangeListener( this );
|
||||
|
@ -77,21 +83,28 @@ void FG3DCloudsListener::valueChanged( SGPropertyNode * node )
|
|||
{
|
||||
_fgClouds->set_3dClouds( _enableNode->getBoolValue() );
|
||||
}
|
||||
#endif
|
||||
|
||||
FGEnvironmentMgr::FGEnvironmentMgr () :
|
||||
_environment(new FGEnvironment()),
|
||||
fgClouds(new FGClouds()),
|
||||
fgClouds(nullptr),
|
||||
_cloudLayersDirty(true),
|
||||
_3dCloudsEnableListener(new FG3DCloudsListener(fgClouds) ),
|
||||
_3dCloudsEnableListener(nullptr),
|
||||
_sky(globals->get_renderer()->getSky())
|
||||
{
|
||||
#ifndef FG_TESTLIB
|
||||
fgClouds = new FGClouds;
|
||||
_3dCloudsEnableListener = new FG3DCloudsListener(fgClouds);
|
||||
#endif
|
||||
set_subsystem("controller", Environment::LayerInterpolateController::createInstance( fgGetNode("/environment/config", true ) ));
|
||||
set_subsystem("realwx", Environment::RealWxController::createInstance( fgGetNode("/environment/realwx", true ) ), 1.0 );
|
||||
|
||||
set_subsystem("precipitation", new FGPrecipitationMgr);
|
||||
#ifndef FG_TESTLIB
|
||||
set_subsystem("realwx", Environment::RealWxController::createInstance( fgGetNode("/environment/realwx", true ) ), 1.0 );
|
||||
set_subsystem("terrainsampler", Environment::TerrainSampler::createInstance( fgGetNode("/environment/terrain", true ) ));
|
||||
#endif
|
||||
set_subsystem("ridgelift", new FGRidgeLift);
|
||||
|
||||
|
||||
set_subsystem("magvar", new FGMagVarManager);
|
||||
}
|
||||
|
||||
|
@ -103,23 +116,26 @@ FGEnvironmentMgr::~FGEnvironmentMgr ()
|
|||
remove_subsystem("realwx");
|
||||
remove_subsystem("controller");
|
||||
remove_subsystem("magvar");
|
||||
|
||||
delete fgClouds;
|
||||
delete _environment;
|
||||
|
||||
#ifndef FG_TESTLIB
|
||||
delete fgClouds;
|
||||
delete _3dCloudsEnableListener;
|
||||
#endif
|
||||
delete _environment;
|
||||
}
|
||||
|
||||
SGSubsystem::InitStatus FGEnvironmentMgr::incrementalInit()
|
||||
{
|
||||
|
||||
|
||||
InitStatus r = SGSubsystemGroup::incrementalInit();
|
||||
if (r == INIT_DONE) {
|
||||
#ifndef FG_TESTLIB
|
||||
fgClouds->Init();
|
||||
#endif
|
||||
globals->get_event_mgr()->addTask("updateClosestAirport", this,
|
||||
&FGEnvironmentMgr::updateClosestAirport, 30 );
|
||||
}
|
||||
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -148,10 +164,11 @@ FGEnvironmentMgr::bind ()
|
|||
_tiedProperties.Tie( "effective-visibility-m", _sky,
|
||||
&SGSky::get_visibility );
|
||||
|
||||
#ifndef FG_TESTLIB
|
||||
_tiedProperties.Tie("rebuild-layers", fgClouds,
|
||||
&FGClouds::get_update_event,
|
||||
&FGClouds::set_update_event);
|
||||
|
||||
#endif
|
||||
// _tiedProperties.Tie("turbulence/use-cloud-turbulence", &sgEnviro,
|
||||
// &SGEnviro::get_turbulence_enable_state,
|
||||
// &SGEnviro::set_turbulence_enable_state);
|
||||
|
@ -221,7 +238,6 @@ FGEnvironmentMgr::bind ()
|
|||
_tiedProperties.Tie("clouds3d-use-impostors", _sky,
|
||||
&SGSky::get_3dCloudUseImpostors,
|
||||
&SGSky::set_3dCloudUseImpostors);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -240,15 +256,16 @@ FGEnvironmentMgr::update (double dt)
|
|||
SGGeod aircraftPos(globals->get_aircraft_position());
|
||||
_environment->set_elevation_ft( aircraftPos.getElevationFt() );
|
||||
|
||||
#ifndef FG_TESTLIB
|
||||
simgear::Particles::setWindFrom( _environment->get_wind_from_heading_deg(),
|
||||
_environment->get_wind_speed_kt() );
|
||||
if( _cloudLayersDirty ) {
|
||||
_cloudLayersDirty = false;
|
||||
fgClouds->set_update_event( fgClouds->get_update_event()+1 );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
fgSetDouble( "/environment/gravitational-acceleration-mps2",
|
||||
fgSetDouble( "/environment/gravitational-acceleration-mps2",
|
||||
Environment::Gravity::instance()->getGravity(aircraftPos));
|
||||
}
|
||||
|
||||
|
@ -256,7 +273,7 @@ void
|
|||
FGEnvironmentMgr::updateClosestAirport()
|
||||
{
|
||||
SG_LOG(SG_ENVIRONMENT, SG_DEBUG, "FGEnvironmentMgr::update: updating closest airport");
|
||||
|
||||
|
||||
SGGeod pos = globals->get_aircraft_position();
|
||||
FGAirport * nearestAirport = FGAirport::findClosest(pos, 100.0);
|
||||
if( nearestAirport == NULL )
|
||||
|
|
|
@ -36,8 +36,10 @@
|
|||
class FGPrecipitationMgr : public SGSubsystem
|
||||
{
|
||||
private:
|
||||
#ifndef FG_TESTLIB
|
||||
osg::ref_ptr<osg::MatrixTransform> transform;
|
||||
osg::ref_ptr<SGPrecipitation> precipitation;
|
||||
#endif
|
||||
float getPrecipitationAtAltitudeMax(void);
|
||||
simgear::TiedPropertyList _tiedProperties;
|
||||
|
||||
|
@ -50,10 +52,9 @@ public:
|
|||
virtual void unbind ();
|
||||
virtual void init ();
|
||||
virtual void update (double dt);
|
||||
|
||||
|
||||
void setupSceneGraph(void);
|
||||
void setPrecipitationLevel(double l);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#cmakedefine ENABLE_JSBSIM
|
||||
|
||||
#define PKGLIBDIR "@FG_DATA_DIR@"
|
||||
#define FGSRCDIR "@PROJECT_SOURCE_DIR@"
|
||||
#define WEB_BROWSER "@WEB_BROWSER@"
|
||||
|
||||
// Ensure FG_HAVE_xxx always have a value
|
||||
|
|
|
@ -242,8 +242,10 @@ setFreeze (bool f)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef FG_TESTLIB
|
||||
// Pause the particle system
|
||||
simgear::Particles::setFrozen(f);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -20,25 +20,25 @@
|
|||
//
|
||||
// $Id$
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include <config.h>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
#ifndef FG_TESTLIB
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osgDB/Registry>
|
||||
#endif
|
||||
|
||||
#include <simgear/structure/commands.hxx>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/misc/sg_dir.hxx>
|
||||
#include <simgear/timing/sg_time.hxx>
|
||||
#include <simgear/ephemeris/ephemeris.hxx>
|
||||
#include <simgear/scene/material/matlib.hxx>
|
||||
#include <simgear/structure/subsystem_mgr.hxx>
|
||||
#include <simgear/structure/event_mgr.hxx>
|
||||
#include <simgear/sound/soundmgr.hxx>
|
||||
|
||||
#include <simgear/misc/ResourceManager.hxx>
|
||||
#include <simgear/props/propertyObject.hxx>
|
||||
#include <simgear/props/props_io.hxx>
|
||||
|
@ -48,14 +48,21 @@
|
|||
#include <Aircraft/controls.hxx>
|
||||
#include <Airports/runways.hxx>
|
||||
#include <Autopilot/route_mgr.hxx>
|
||||
#include <Navaids/navlist.hxx>
|
||||
|
||||
#include <GUI/gui.h>
|
||||
#include <Viewer/viewmgr.hxx>
|
||||
|
||||
#ifndef FG_TESTLIB
|
||||
#include <Scenery/scenery.hxx>
|
||||
#include <Scenery/tilemgr.hxx>
|
||||
#include <Navaids/navlist.hxx>
|
||||
#include <Viewer/renderer.hxx>
|
||||
#include <Viewer/viewmgr.hxx>
|
||||
#include <GUI/FGFontCache.hxx>
|
||||
|
||||
#include <simgear/sound/soundmgr.hxx>
|
||||
#include <simgear/scene/material/matlib.hxx>
|
||||
#endif
|
||||
|
||||
#include "globals.hxx"
|
||||
#include "locale.hxx"
|
||||
|
||||
|
@ -147,7 +154,9 @@ FGGlobals *globals = NULL;
|
|||
|
||||
// Constructor
|
||||
FGGlobals::FGGlobals() :
|
||||
#ifndef FG_TESTLIB
|
||||
renderer( new FGRenderer ),
|
||||
#endif
|
||||
subsystem_mgr( new SGSubsystemMgr ),
|
||||
event_mgr( new SGEventMgr ),
|
||||
sim_time_sec( 0.0 ),
|
||||
|
@ -195,7 +204,7 @@ FGGlobals::~FGGlobals()
|
|||
|
||||
// stop OSG threading first, to avoid thread races while we tear down
|
||||
// scene-graph pieces
|
||||
|
||||
#ifndef FG_TESTLIB
|
||||
osg::ref_ptr<osgViewer::Viewer> vw(renderer->getViewer());
|
||||
if (vw) {
|
||||
// https://code.google.com/p/flightgear-bugs/issues/detail?id=1291
|
||||
|
@ -204,10 +213,11 @@ FGGlobals::~FGGlobals()
|
|||
// GraphicsContext)
|
||||
vw->stopThreading();
|
||||
}
|
||||
|
||||
#endif
|
||||
subsystem_mgr->shutdown();
|
||||
subsystem_mgr->unbind();
|
||||
|
||||
#ifndef FG_TESTLIB
|
||||
// don't cancel the pager until after shutdown, since AIModels (and
|
||||
// potentially others) can queue delete requests on the pager.
|
||||
if (vw && vw->getDatabasePager()) {
|
||||
|
@ -223,21 +233,24 @@ FGGlobals::~FGGlobals()
|
|||
|
||||
FGFontCache::shutdown();
|
||||
fgCancelSnapShot();
|
||||
#endif
|
||||
|
||||
delete subsystem_mgr;
|
||||
subsystem_mgr = NULL; // important so ::get_subsystem returns NULL
|
||||
vw = 0; // don't delete the viewer until now
|
||||
#ifndef FG_TESTLIB
|
||||
vw = nullptr; // don't delete the viewer until now
|
||||
set_matlib(NULL);
|
||||
#endif
|
||||
|
||||
delete time_params;
|
||||
set_matlib(NULL);
|
||||
|
||||
delete channel_options_list;
|
||||
delete initial_waypoints;
|
||||
delete channellist;
|
||||
|
||||
simgear::PropertyObjectBase::setDefaultRoot(NULL);
|
||||
#ifndef FG_TESTLIB
|
||||
simgear::SGModelLib::resetPropertyRoot();
|
||||
|
||||
#endif
|
||||
delete locale;
|
||||
locale = NULL;
|
||||
|
||||
|
@ -509,12 +522,14 @@ FGGlobals::get_renderer () const
|
|||
|
||||
void FGGlobals::set_renderer(FGRenderer *render)
|
||||
{
|
||||
#ifndef FG_TESTLIB
|
||||
if (render == renderer) {
|
||||
return;
|
||||
}
|
||||
|
||||
delete renderer;
|
||||
renderer = render;
|
||||
#endif
|
||||
}
|
||||
|
||||
SGSubsystemMgr *
|
||||
|
@ -750,7 +765,11 @@ void FGGlobals::set_warp_delta( long int d )
|
|||
|
||||
FGScenery* FGGlobals::get_scenery () const
|
||||
{
|
||||
#ifdef FG_TESTLIB
|
||||
return nullptr;
|
||||
#else
|
||||
return get_subsystem<FGScenery>();
|
||||
#endif
|
||||
}
|
||||
|
||||
FGViewMgr *FGGlobals::get_viewmgr() const
|
||||
|
@ -766,7 +785,9 @@ flightgear::View* FGGlobals::get_current_view () const
|
|||
|
||||
void FGGlobals::set_matlib( SGMaterialLib *m )
|
||||
{
|
||||
#ifndef FG_TESTLIB
|
||||
matlib = m;
|
||||
#endif
|
||||
}
|
||||
|
||||
FGControls *FGGlobals::get_controls() const
|
||||
|
|
|
@ -97,10 +97,10 @@ private:
|
|||
SGPath fg_root;
|
||||
|
||||
/**
|
||||
* locations to search for (non-scenery) data.
|
||||
* locations to search for (non-scenery) data.
|
||||
*/
|
||||
PathList additional_data_paths;
|
||||
|
||||
|
||||
// Users home directory for data
|
||||
SGPath fg_home;
|
||||
// Download directory
|
||||
|
@ -118,8 +118,10 @@ private:
|
|||
// Time structure
|
||||
SGTime *time_params;
|
||||
|
||||
#ifndef FG_TESTLIB
|
||||
// Material properties library
|
||||
SGSharedPtr<SGMaterialLib> matlib;
|
||||
#endif
|
||||
|
||||
SGCommandMgr *commands;
|
||||
|
||||
|
@ -142,17 +144,17 @@ private:
|
|||
SGPropertyNode_ptr positionLon, positionLat, positionAlt;
|
||||
SGPropertyNode_ptr viewLon, viewLat, viewAlt;
|
||||
SGPropertyNode_ptr orientHeading, orientPitch, orientRoll;
|
||||
|
||||
|
||||
/**
|
||||
* helper to initialise standard properties on a new property tree
|
||||
*/
|
||||
void initProperties();
|
||||
|
||||
|
||||
void cleanupListeners();
|
||||
|
||||
|
||||
typedef std::vector<SGPropertyChangeListener*> SGPropertyChangeListenerVec;
|
||||
SGPropertyChangeListenerVec _listeners_to_cleanup;
|
||||
|
||||
|
||||
SGSharedPtr<simgear::pkg::Root> _packageRoot;
|
||||
public:
|
||||
|
||||
|
@ -161,7 +163,7 @@ public:
|
|||
|
||||
virtual FGRenderer *get_renderer () const;
|
||||
void set_renderer(FGRenderer* render);
|
||||
|
||||
|
||||
SGSubsystemMgr *get_subsystem_mgr () const;
|
||||
|
||||
SGSubsystem *get_subsystem (const char * name) const;
|
||||
|
@ -203,21 +205,21 @@ public:
|
|||
* result.
|
||||
*/
|
||||
PathList get_data_paths() const;
|
||||
|
||||
|
||||
/**
|
||||
* Get data locations which contain the file path suffix. Eg pass ing
|
||||
* 'AI/Traffic' to get all data paths which define <path>/AI/Traffic subdir
|
||||
*/
|
||||
PathList get_data_paths(const std::string& suffix) const;
|
||||
|
||||
|
||||
void append_data_path(const SGPath& path);
|
||||
|
||||
|
||||
/**
|
||||
* Given a path suffix (eg 'Textures' or 'AI/Traffic'), find the
|
||||
* first data directory which defines it.
|
||||
*/
|
||||
SGPath find_data_dir(const std::string& pathSuffix) const;
|
||||
|
||||
|
||||
const SGPath &get_fg_home () const { return fg_home; }
|
||||
void set_fg_home (const SGPath &home);
|
||||
|
||||
|
@ -245,13 +247,13 @@ public:
|
|||
* This also makes the path Nasal-readable:
|
||||
* to avoid can-read-any-file security holes, do NOT call this on paths
|
||||
* obtained from the property tree or other Nasal-writable places
|
||||
*/
|
||||
*/
|
||||
void append_fg_scenery (const SGPath &scenery);
|
||||
|
||||
void append_fg_scenery (const PathList &scenery);
|
||||
|
||||
|
||||
void clear_fg_scenery();
|
||||
|
||||
|
||||
/**
|
||||
* Allow Nasal to read a path
|
||||
*
|
||||
|
@ -276,10 +278,10 @@ public:
|
|||
* This also makes the path Nasal-readable:
|
||||
* to avoid can-read-any-file security holes, do NOT call this on paths
|
||||
* obtained from the property tree or other Nasal-writable places
|
||||
*/
|
||||
*/
|
||||
void append_aircraft_path(const SGPath& path);
|
||||
void append_aircraft_paths(const PathList& path);
|
||||
|
||||
|
||||
/**
|
||||
* Given a path to an aircraft-related resource file, resolve it
|
||||
* against the appropriate root. This means looking at the location
|
||||
|
@ -289,13 +291,13 @@ public:
|
|||
* if the path could not be resolved, an empty path is returned.
|
||||
*/
|
||||
SGPath resolve_aircraft_path(const std::string& branch) const;
|
||||
|
||||
|
||||
/**
|
||||
* Same as above, but test for non 'Aircraft/' branch paths, and
|
||||
* always resolve them against fg_root.
|
||||
*/
|
||||
SGPath resolve_maybe_aircraft_path(const std::string& branch) const;
|
||||
|
||||
|
||||
/**
|
||||
* Search in the following directories:
|
||||
*
|
||||
|
@ -317,7 +319,14 @@ public:
|
|||
inline SGTime *get_time_params() const { return time_params; }
|
||||
inline void set_time_params( SGTime *t ) { time_params = t; }
|
||||
|
||||
inline SGMaterialLib *get_matlib() const { return matlib; }
|
||||
inline SGMaterialLib *get_matlib() const
|
||||
{
|
||||
#ifdef FG_TESTLIB
|
||||
return nullptr;
|
||||
#else
|
||||
return matlib;
|
||||
#endif
|
||||
}
|
||||
void set_matlib( SGMaterialLib *m );
|
||||
|
||||
inline SGPropertyNode *get_props () { return props; }
|
||||
|
@ -327,7 +336,7 @@ public:
|
|||
* subsystems are shutdown and unbound before call this.
|
||||
*/
|
||||
void resetPropertyRoot();
|
||||
|
||||
|
||||
inline FGLocale* get_locale () { return locale; }
|
||||
|
||||
inline SGCommandMgr *get_commands () { return commands; }
|
||||
|
@ -337,11 +346,11 @@ public:
|
|||
SGVec3d get_aircraft_position_cart() const;
|
||||
|
||||
void get_aircraft_orientation(double& heading, double& pitch, double& roll);
|
||||
|
||||
|
||||
SGGeod get_view_position() const;
|
||||
|
||||
|
||||
SGVec3d get_view_position_cart() const;
|
||||
|
||||
|
||||
inline string_list *get_channel_options_list () {
|
||||
return channel_options_list;
|
||||
}
|
||||
|
@ -352,7 +361,7 @@ public:
|
|||
inline string_list *get_initial_waypoints () {
|
||||
return initial_waypoints;
|
||||
}
|
||||
|
||||
|
||||
inline void set_initial_waypoints (string_list *list) {
|
||||
initial_waypoints = list;
|
||||
}
|
||||
|
@ -363,7 +372,7 @@ public:
|
|||
FGControls *get_controls() const;
|
||||
|
||||
FGScenery * get_scenery () const;
|
||||
|
||||
|
||||
inline FGTACANList *get_channellist() const { return channellist; }
|
||||
inline void set_channellist( FGTACANList *c ) { channellist = c; }
|
||||
|
||||
|
@ -392,7 +401,7 @@ public:
|
|||
void saveUserSettings(SGPath userDatapath = SGPath());
|
||||
|
||||
void addListenerToCleanup(SGPropertyChangeListener* l);
|
||||
|
||||
|
||||
simgear::pkg::Root* packageRoot();
|
||||
void setPackageRoot(const SGSharedPtr<simgear::pkg::Root>& p);
|
||||
};
|
||||
|
|
|
@ -58,7 +58,8 @@
|
|||
|
||||
#include <GUI/gui.h>
|
||||
#include <GUI/MessageBox.hxx>
|
||||
#if defined(HAVE_QT)
|
||||
|
||||
#if defined(HAVE_QT) && !defined(FG_TESTLIB)
|
||||
#include <GUI/QtLauncher.hxx>
|
||||
#include <GUI/SetupRootDialog.hxx>
|
||||
#endif
|
||||
|
@ -236,9 +237,11 @@ void fgSetDefaults ()
|
|||
SGPropertyNode* v = globals->get_props()->getNode("/sim/version", true);
|
||||
v->setValueReadOnly("flightgear", FLIGHTGEAR_VERSION);
|
||||
v->setValueReadOnly("simgear", SG_STRINGIZE(SIMGEAR_VERSION));
|
||||
#ifndef FG_TESTLIB
|
||||
v->setValueReadOnly("openscenegraph", osgGetVersion());
|
||||
v->setValueReadOnly("openscenegraph-thread-safe-reference-counting",
|
||||
osg::Referenced::getThreadSafeReferenceCounting());
|
||||
#endif
|
||||
v->setValueReadOnly("revision", REVISION);
|
||||
v->setValueReadOnly("build-number", HUDSON_BUILD_NUMBER);
|
||||
v->setValueReadOnly("build-id", HUDSON_BUILD_ID);
|
||||
|
@ -989,12 +992,14 @@ fgOptJpgHttpd( const char * arg )
|
|||
static int
|
||||
fgOptHttpd( const char * arg )
|
||||
{
|
||||
#ifndef FG_TESTLIB
|
||||
// port may be any valid address:port notation
|
||||
// like 127.0.0.1:8080
|
||||
// or just the port 8080
|
||||
string port = simgear::strutils::strip(string(arg));
|
||||
if( port.empty() ) return FG_OPTIONS_ERROR;
|
||||
fgSetString( string(flightgear::http::PROPERTY_ROOT).append("/options/listening-port").c_str(), port );
|
||||
#endif
|
||||
return FG_OPTIONS_OK;
|
||||
}
|
||||
|
||||
|
@ -2650,7 +2655,9 @@ void Options::showVersion() const
|
|||
PathList scn = globals->get_fg_scenery();
|
||||
cout << SGPath::join(scn, &SGPath::pathListSep) << endl;
|
||||
cout << "SimGear version: " << SG_STRINGIZE(SIMGEAR_VERSION) << endl;
|
||||
#ifndef FG_TESTLIB
|
||||
cout << "OSG version: " << osgGetVersion() << endl;
|
||||
#endif
|
||||
cout << "PLIB version: " << PLIB_VERSION << endl;
|
||||
}
|
||||
|
||||
|
@ -2767,7 +2774,7 @@ void Options::setupRoot(int argc, char **argv)
|
|||
root = SGPath::fromLocal8Bit(envp);
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "set from FG_ROOT env var: fg_root = " << root );
|
||||
} else {
|
||||
#if defined(HAVE_QT)
|
||||
#if defined(HAVE_QT) && !defined(FG_TESTLIB)
|
||||
flightgear::initApp(argc, argv);
|
||||
root = SetupRootDialog::restoreUserSelectedRoot();
|
||||
#endif
|
||||
|
@ -2785,7 +2792,7 @@ void Options::setupRoot(int argc, char **argv)
|
|||
string base_version = fgBasePackageVersion(root);
|
||||
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
#if defined(HAVE_QT) && !defined(FG_TESTLIB)
|
||||
// only compare major and minor version, not the patch level.
|
||||
const int versionComp = simgear::strutils::compare_versions(FLIGHTGEAR_VERSION, base_version, 2);
|
||||
|
||||
|
|
|
@ -1069,8 +1069,8 @@ WayptRef FlightPlan::waypointFromString(const string& tgt )
|
|||
|
||||
SGGeod basePosition;
|
||||
if (_legs.empty()) {
|
||||
// route is empty, use current position
|
||||
basePosition = globals->get_aircraft_position();
|
||||
// route is empty, use departure position / aircraft position
|
||||
basePosition = _departure ? _departure->geod() : globals->get_aircraft_position();
|
||||
} else {
|
||||
basePosition = _legs.back()->waypoint()->position();
|
||||
}
|
||||
|
|
|
@ -990,10 +990,13 @@ static naRef f_geodinfo(naContext c, naRef me, int argc, naRef* args)
|
|||
SGGeod geod = SGGeod::fromDegM(lon, lat, elev);
|
||||
if(!globals->get_scenery()->get_elevation_m(geod, elev, &material))
|
||||
return naNil();
|
||||
const SGMaterial *mat = dynamic_cast<const SGMaterial *>(material);
|
||||
|
||||
naRef vec = naNewVector(c);
|
||||
naVec_append(vec, naNum(elev));
|
||||
naRef matdata = naNil();
|
||||
|
||||
#ifndef FG_TESTLIB
|
||||
const SGMaterial *mat = dynamic_cast<const SGMaterial *>(material);
|
||||
if(mat) {
|
||||
matdata = naNewHash(c);
|
||||
naRef names = naNewVector(c);
|
||||
|
@ -1009,6 +1012,7 @@ static naRef f_geodinfo(naContext c, naRef me, int argc, naRef* args)
|
|||
HASHSET("light_coverage", 14, naNum(mat->get_light_coverage()));
|
||||
}
|
||||
naVec_append(vec, matdata);
|
||||
#endif
|
||||
return vec;
|
||||
#undef HASHSET
|
||||
}
|
||||
|
|
|
@ -105,16 +105,16 @@ public:
|
|||
_gcRoot = sys->gcSave(f);
|
||||
_gcSelf = sys->gcSave(self);
|
||||
}
|
||||
|
||||
|
||||
virtual ~TimerObj()
|
||||
{
|
||||
stop();
|
||||
_sys->gcRelease(_gcRoot);
|
||||
_sys->gcRelease(_gcSelf);
|
||||
}
|
||||
|
||||
|
||||
bool isRunning() const { return _isRunning; }
|
||||
|
||||
|
||||
void stop()
|
||||
{
|
||||
if (_isRunning) {
|
||||
|
@ -140,7 +140,7 @@ public:
|
|||
if (_isRunning) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
_isRunning = true;
|
||||
if (_singleShot) {
|
||||
globals->get_event_mgr()->addEvent(_name, this, &TimerObj::invoke, _interval, _isSimTime);
|
||||
|
@ -150,7 +150,7 @@ public:
|
|||
_isSimTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// stop and then start -
|
||||
void restart(double newInterval)
|
||||
{
|
||||
|
@ -158,7 +158,7 @@ public:
|
|||
stop();
|
||||
start();
|
||||
}
|
||||
|
||||
|
||||
void invoke()
|
||||
{
|
||||
if( _singleShot )
|
||||
|
@ -170,12 +170,12 @@ public:
|
|||
naRef *args = NULL;
|
||||
_sys->callMethod(_func, _self, 0, args, naNil() /* locals */);
|
||||
}
|
||||
|
||||
|
||||
void setSingleShot(bool aSingleShot)
|
||||
{
|
||||
_singleShot = aSingleShot;
|
||||
}
|
||||
|
||||
|
||||
bool isSingleShot() const
|
||||
{ return _singleShot; }
|
||||
private:
|
||||
|
@ -240,7 +240,7 @@ FGNasalSys::FGNasalSys() :
|
|||
_globals = naNil();
|
||||
_string = naNil();
|
||||
_wrappedNodeFunc = naNil();
|
||||
|
||||
|
||||
_log = new simgear::BufferedLogCallback(SG_NASAL, SG_INFO);
|
||||
_log->truncateAt(255);
|
||||
sglog().addCallback(_log);
|
||||
|
@ -386,10 +386,10 @@ static naRef f_getprop(naContext c, naRef me, int argc, naRef* args)
|
|||
SG_LOG(SG_NASAL, SG_ALERT, "Nasal getprop: property " << p->getPath() << " is NaN");
|
||||
return naNil();
|
||||
}
|
||||
|
||||
|
||||
return naNum(dv);
|
||||
}
|
||||
|
||||
|
||||
case props::STRING:
|
||||
case props::UNSPECIFIED:
|
||||
{
|
||||
|
@ -421,11 +421,11 @@ static naRef f_setprop(naContext c, naRef me, int argc, naRef* args)
|
|||
else {
|
||||
if(!naIsNum(val))
|
||||
naRuntimeError(c, "setprop() value is not string or number");
|
||||
|
||||
|
||||
if (SGMisc<double>::isNaN(val.num)) {
|
||||
naRuntimeError(c, "setprop() passed a NaN");
|
||||
}
|
||||
|
||||
|
||||
result = p->setDoubleValue(val.num);
|
||||
}
|
||||
} catch (const string& err) {
|
||||
|
@ -457,7 +457,7 @@ static naRef f_logprint(naContext c, naRef me, int argc, naRef* args)
|
|||
{
|
||||
if (argc < 1)
|
||||
naRuntimeError(c, "no prioirty argument to logprint()");
|
||||
|
||||
|
||||
naRef priority = args[0];
|
||||
string buf;
|
||||
int n = argc;
|
||||
|
@ -506,7 +506,7 @@ static naRef f_makeTimer(naContext c, naRef me, int argc, naRef* args)
|
|||
if (!naIsNum(args[0])) {
|
||||
naRuntimeError(c, "bad interval argument to maketimer");
|
||||
}
|
||||
|
||||
|
||||
naRef func, self = naNil();
|
||||
if (naIsFunc(args[1])) {
|
||||
func = args[1];
|
||||
|
@ -514,7 +514,7 @@ static naRef f_makeTimer(naContext c, naRef me, int argc, naRef* args)
|
|||
self = args[1];
|
||||
func = args[2];
|
||||
}
|
||||
|
||||
|
||||
TimerObj* timerObj = new TimerObj(nasalSys, func, self, args[0].num);
|
||||
return nasal::to_nasal(c, timerObj);
|
||||
}
|
||||
|
@ -618,7 +618,7 @@ static naRef f_directory(naContext c, naRef me, int argc, naRef* args)
|
|||
std::string p = paths[i].file();
|
||||
naVec_append(result, naStr_fromdata(naNewString(c), p.c_str(), p.size()));
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -639,7 +639,7 @@ static naRef f_findDataDir(naContext c, naRef me, int argc, naRef* args)
|
|||
{
|
||||
if(argc != 1 || !naIsString(args[0]))
|
||||
naRuntimeError(c, "bad arguments to findDataDir()");
|
||||
|
||||
|
||||
SGPath p = globals->find_data_dir(naStr_data(args[0]));
|
||||
std::string pdata = p.utf8Str();
|
||||
return naStr_fromdata(naNewString(c), const_cast<char*>(pdata.c_str()), pdata.length());
|
||||
|
@ -656,23 +656,23 @@ public:
|
|||
globals->get_commands()->addCommandObject(_name, this);
|
||||
_gcRoot = sys->gcSave(f);
|
||||
}
|
||||
|
||||
|
||||
virtual ~NasalCommand()
|
||||
{
|
||||
_sys->gcRelease(_gcRoot);
|
||||
}
|
||||
|
||||
|
||||
virtual bool operator()(const SGPropertyNode* aNode)
|
||||
{
|
||||
_sys->setCmdArg(const_cast<SGPropertyNode*>(aNode));
|
||||
naRef args[1];
|
||||
args[0] = _sys->wrappedPropsNode(const_cast<SGPropertyNode*>(aNode));
|
||||
|
||||
|
||||
_sys->callMethod(_func, naNil(), 1, args, naNil() /* locals */);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
FGNasalSys* _sys;
|
||||
naRef _func;
|
||||
|
@ -684,7 +684,7 @@ static naRef f_addCommand(naContext c, naRef me, int argc, naRef* args)
|
|||
{
|
||||
if(argc != 2 || !naIsString(args[0]) || !naIsFunc(args[1]))
|
||||
naRuntimeError(c, "bad arguments to addcommand()");
|
||||
|
||||
|
||||
nasalSys->addCommand(args[1], naStr_data(args[0]));
|
||||
return naNil();
|
||||
}
|
||||
|
@ -693,7 +693,7 @@ static naRef f_removeCommand(naContext c, naRef me, int argc, naRef* args)
|
|||
{
|
||||
if ((argc < 1) || !naIsString(args[0]))
|
||||
naRuntimeError(c, "bad argument to removecommand()");
|
||||
|
||||
|
||||
globals->get_commands()->removeCommand(naStr_data(args[0]));
|
||||
return naNil();
|
||||
}
|
||||
|
@ -883,7 +883,7 @@ void FGNasalSys::init()
|
|||
naNewFunc(_context, naNewCCode(_context, funcs[i].func)));
|
||||
nasal::Hash io_module = nasal::Hash(_globals, _context).get<nasal::Hash>("io");
|
||||
io_module.set("open", f_open);
|
||||
|
||||
|
||||
// And our SGPropertyNode wrapper
|
||||
hashset(_globals, "props", genPropsModule());
|
||||
|
||||
|
@ -895,12 +895,14 @@ void FGNasalSys::init()
|
|||
initNasalPositioned(_globals, _context);
|
||||
initNasalPositioned_cppbind(_globals, _context);
|
||||
initNasalAircraft(_globals, _context);
|
||||
#ifndef FG_TESTLIB
|
||||
NasalClipboard::init(this);
|
||||
initNasalCanvas(_globals, _context);
|
||||
#endif
|
||||
initNasalCondition(_globals, _context);
|
||||
initNasalHTTP(_globals, _context);
|
||||
initNasalSGPath(_globals, _context);
|
||||
|
||||
|
||||
NasalTimerObj::init("Timer")
|
||||
.method("start", &TimerObj::start)
|
||||
.method("stop", &TimerObj::stop)
|
||||
|
@ -912,7 +914,7 @@ void FGNasalSys::init()
|
|||
|
||||
// Set allowed paths for Nasal I/O
|
||||
fgInitAllowedPaths();
|
||||
|
||||
|
||||
// Now load the various source files in the Nasal directory
|
||||
simgear::Dir nasalDir(SGPath(globals->get_fg_root(), "Nasal"));
|
||||
loadScriptDirectory(nasalDir);
|
||||
|
@ -934,11 +936,11 @@ void FGNasalSys::init()
|
|||
|
||||
// Pull scripts out of the property tree, too
|
||||
loadPropertyScripts();
|
||||
|
||||
|
||||
// now Nasal modules are loaded, we can do some delayed work
|
||||
postinitNasalPositioned(_globals, _context);
|
||||
postinitNasalGUI(_globals, _context);
|
||||
|
||||
|
||||
_inited = true;
|
||||
}
|
||||
|
||||
|
@ -947,36 +949,36 @@ void FGNasalSys::shutdown()
|
|||
if (!_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
shutdownNasalPositioned();
|
||||
|
||||
|
||||
map<int, FGNasalListener *>::iterator it, end = _listener.end();
|
||||
for(it = _listener.begin(); it != end; ++it)
|
||||
delete it->second;
|
||||
_listener.clear();
|
||||
|
||||
|
||||
NasalCommandDict::iterator j = _commands.begin();
|
||||
for (; j != _commands.end(); ++j) {
|
||||
globals->get_commands()->removeCommand(j->first);
|
||||
}
|
||||
_commands.clear();
|
||||
|
||||
|
||||
std::vector<FGNasalModuleListener*>::iterator k = _moduleListeners.begin();
|
||||
for(; k!= _moduleListeners.end(); ++k)
|
||||
delete *k;
|
||||
_moduleListeners.clear();
|
||||
|
||||
|
||||
naClearSaved();
|
||||
|
||||
|
||||
_string = naNil(); // will be freed by _context
|
||||
naFreeContext(_context);
|
||||
|
||||
|
||||
//setWatchedRef(_globals);
|
||||
|
||||
|
||||
// remove the recursive reference in globals
|
||||
hashset(_globals, "globals", naNil());
|
||||
_globals = naNil();
|
||||
|
||||
_globals = naNil();
|
||||
|
||||
naGC();
|
||||
_inited = false;
|
||||
}
|
||||
|
@ -987,7 +989,7 @@ naRef FGNasalSys::wrappedPropsNode(SGPropertyNode* aProps)
|
|||
nasal::Hash props = getGlobals().get<nasal::Hash>("props");
|
||||
_wrappedNodeFunc = props.get("wrapNode");
|
||||
}
|
||||
|
||||
|
||||
naRef args[1];
|
||||
args[0] = propNodeGhost(aProps);
|
||||
naContext ctx = naNewContext();
|
||||
|
@ -998,15 +1000,17 @@ naRef FGNasalSys::wrappedPropsNode(SGPropertyNode* aProps)
|
|||
|
||||
void FGNasalSys::update(double)
|
||||
{
|
||||
#ifndef FG_TESTLIB
|
||||
if( NasalClipboard::getInstance() )
|
||||
NasalClipboard::getInstance()->update();
|
||||
|
||||
#endif
|
||||
if(!_dead_listener.empty()) {
|
||||
vector<FGNasalListener *>::iterator it, end = _dead_listener.end();
|
||||
for(it = _dead_listener.begin(); it != end; ++it) delete *it;
|
||||
_dead_listener.clear();
|
||||
}
|
||||
|
||||
#ifndef FG_TESTLIB
|
||||
if (!_loadList.empty())
|
||||
{
|
||||
if( _delay_load )
|
||||
|
@ -1022,7 +1026,7 @@ void FGNasalSys::update(double)
|
|||
// (only unload one per update loop to avoid excessive lags)
|
||||
_unloadList.pop()->unload();
|
||||
}
|
||||
|
||||
#endif
|
||||
// Destroy all queued ghosts
|
||||
nasal::ghostProcessDestroyList();
|
||||
|
||||
|
@ -1045,7 +1049,7 @@ bool pathSortPredicate(const SGPath& p1, const SGPath& p2)
|
|||
return p1.file() < p2.file();
|
||||
}
|
||||
|
||||
// Loads all scripts in given directory
|
||||
// Loads all scripts in given directory
|
||||
void FGNasalSys::loadScriptDirectory(simgear::Dir nasalDir)
|
||||
{
|
||||
simgear::PathList scripts = nasalDir.children(simgear::Dir::TYPE_FILE, ".nas");
|
||||
|
@ -1211,7 +1215,7 @@ bool FGNasalSys::createModule(const char* moduleName, const char* fileName,
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// See if we already have a module hash to use. This allows the
|
||||
// user to, for example, add functions to the built-in math
|
||||
// module. Make a new one if necessary.
|
||||
|
@ -1228,7 +1232,7 @@ bool FGNasalSys::createModule(const char* moduleName, const char* fileName,
|
|||
|
||||
callWithContext(ctx, code, argc, args, locals);
|
||||
hashset(_globals, moduleName, locals);
|
||||
|
||||
|
||||
naFreeContext(ctx);
|
||||
return true;
|
||||
}
|
||||
|
@ -1240,7 +1244,7 @@ void FGNasalSys::deleteModule(const char* moduleName)
|
|||
// subsystems having Nasal objects.
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
naContext ctx = naNewContext();
|
||||
naRef modname = naNewString(ctx);
|
||||
naStr_fromdata(modname, (char*)moduleName, strlen(moduleName));
|
||||
|
@ -1443,14 +1447,18 @@ naRef FGNasalSys::removeListener(naContext c, int argc, naRef* args)
|
|||
|
||||
void FGNasalSys::registerToLoad(FGNasalModelData *data)
|
||||
{
|
||||
#ifndef FG_TESTLIB
|
||||
if( _loadList.empty() )
|
||||
_delay_load = true;
|
||||
_loadList.push(data);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FGNasalSys::registerToUnload(FGNasalModelData *data)
|
||||
{
|
||||
#ifndef FG_TESTLIB
|
||||
_unloadList.push(data);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FGNasalSys::addCommand(naRef func, const std::string& name)
|
||||
|
@ -1459,7 +1467,7 @@ void FGNasalSys::addCommand(naRef func, const std::string& name)
|
|||
SG_LOG(SG_NASAL, SG_WARN, "duplicate add of command:" << name);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
NasalCommand* cmd = new NasalCommand(this, func, name);
|
||||
_commands[name] = cmd;
|
||||
}
|
||||
|
@ -1626,5 +1634,3 @@ naRef NasalXMLVisitor::make_string(const char* s, int n)
|
|||
return naStr_fromdata(naNewString(_c), const_cast<char *>(s),
|
||||
n < 0 ? strlen(s) : n);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -155,10 +155,10 @@ private:
|
|||
//friend class FGNasalScript;
|
||||
friend class FGNasalListener;
|
||||
friend class FGNasalModuleListener;
|
||||
|
||||
#ifndef FG_TESTLIB
|
||||
SGLockedQueue<SGSharedPtr<FGNasalModelData> > _loadList;
|
||||
SGLockedQueue<SGSharedPtr<FGNasalModelData> > _unloadList;
|
||||
|
||||
#endif
|
||||
// Delay removing items of the _loadList to ensure the are already attached
|
||||
// to the scene graph (eg. enables to retrieve world position in load
|
||||
// callback).
|
||||
|
|
|
@ -1078,7 +1078,11 @@ double View::getOrientation_z() const{
|
|||
|
||||
double View::get_aspect_ratio() const
|
||||
{
|
||||
#ifdef FG_TESTLIB
|
||||
return 4.0 / 3.0;
|
||||
#else
|
||||
return flightgear::CameraGroup::getDefault()->getMasterAspectRatio();
|
||||
#endif
|
||||
}
|
||||
|
||||
double View::getLon_deg() const
|
||||
|
|
|
@ -137,6 +137,7 @@ FGViewMgr::update (double dt)
|
|||
// Update the current view
|
||||
currentView->update(dt);
|
||||
|
||||
#ifndef FG_TESTLIB
|
||||
|
||||
// update the camera now
|
||||
osg::ref_ptr<flightgear::CameraGroup> cameraGroup = flightgear::CameraGroup::getDefault();
|
||||
|
@ -144,6 +145,7 @@ FGViewMgr::update (double dt)
|
|||
toOsg(currentView->getViewOrientation()));
|
||||
cameraGroup->setCameraParameters(currentView->get_v_fov(),
|
||||
cameraGroup->getMasterAspectRatio());
|
||||
#endif
|
||||
}
|
||||
|
||||
void FGViewMgr::clear()
|
||||
|
|
105
tests/CMakeLists.txt
Normal file
105
tests/CMakeLists.txt
Normal file
|
@ -0,0 +1,105 @@
|
|||
|
||||
set(sources
|
||||
Main/options.cxx
|
||||
Main/fg_commands.cxx
|
||||
Main/fg_props.cxx
|
||||
Main/globals.cxx
|
||||
Main/locale.cxx
|
||||
Main/util.cxx
|
||||
Aircraft/controls.cxx
|
||||
Aircraft/FlightHistory.cxx
|
||||
Aircraft/flightrecorder.cxx
|
||||
Aircraft/replay.cxx
|
||||
Autopilot/route_mgr.cxx
|
||||
Airports/airport.cxx
|
||||
Airports/airport.hxx
|
||||
Airports/apt_loader.cxx
|
||||
Airports/airportdynamicsmanager.cxx
|
||||
Airports/airportdynamicsmanager.hxx
|
||||
Airports/dynamicloader.cxx
|
||||
Airports/dynamics.cxx
|
||||
Airports/xmlloader.cxx
|
||||
Airports/runwaybase.cxx
|
||||
Airports/pavement.cxx
|
||||
Airports/parking.cxx
|
||||
Airports/groundnetwork.cxx
|
||||
Airports/gnnode.cxx
|
||||
Airports/runways.cxx
|
||||
Airports/runwayprefs.cxx
|
||||
Airports/runwayprefloader.cxx
|
||||
ATC/CommStation.cxx
|
||||
# ATC/GroundController.cxx
|
||||
# ATC/atc_mgr.cxx
|
||||
Environment/atmosphere.cxx
|
||||
Environment/environment.cxx
|
||||
Environment/environment_mgr.cxx
|
||||
Environment/environment_ctrl.cxx
|
||||
Environment/presets.cxx
|
||||
Environment/gravity.cxx
|
||||
Environment/ridge_lift.cxx
|
||||
Environment/magvarmanager.cxx
|
||||
Navaids/airways.cxx
|
||||
Navaids/fixlist.cxx
|
||||
Navaids/markerbeacon.cxx
|
||||
Navaids/NavDataCache.cxx
|
||||
Navaids/navdb.cxx
|
||||
Navaids/navlist.cxx
|
||||
Navaids/navrecord.cxx
|
||||
Navaids/poidb.cxx
|
||||
Navaids/procedure.cxx
|
||||
Navaids/positioned.cxx
|
||||
Navaids/PositionedOctree.cxx
|
||||
Navaids/routePath.cxx
|
||||
Navaids/route.cxx
|
||||
Navaids/waypoint.cxx
|
||||
Navaids/FlightPlan.cxx
|
||||
Navaids/LevelDXML.cxx
|
||||
Network/HTTPClient.cxx
|
||||
Time/TimeManager.cxx
|
||||
Time/bodysolver.cxx
|
||||
Scripting/NasalSys.cxx
|
||||
Scripting/NasalCondition.cxx
|
||||
Scripting/NasalAircraft.cxx
|
||||
Scripting/NasalString.cxx
|
||||
Scripting/NasalPositioned.cxx
|
||||
Scripting/NasalPositioned_cppbind.cxx
|
||||
Scripting/nasal-props.cxx
|
||||
Scripting/NasalSGPath.cxx
|
||||
Scripting/NasalHTTP.cxx
|
||||
Viewer/view.cxx
|
||||
Viewer/viewmgr.cxx
|
||||
)
|
||||
|
||||
foreach(s ${sources})
|
||||
set_property(DIRECTORY APPEND PROPERTY fgtestlib_sources "${CMAKE_SOURCE_DIR}/src/${s}")
|
||||
endforeach()
|
||||
|
||||
set_property(DIRECTORY APPEND PROPERTY fgtestlib_sources "${CMAKE_SOURCE_DIR}/3rdparty/cjson/cJSON.c")
|
||||
|
||||
get_property(fgtestlib_sources DIRECTORY PROPERTY fgtestlib_sources)
|
||||
|
||||
add_library(fgtestlib SHARED ${fgtestlib_sources}
|
||||
unitTestHelpers.cxx
|
||||
testStubs.cxx
|
||||
fake_sgSky.cxx
|
||||
fake_sgPrecipitation.cxx
|
||||
fake_sound.cxx)
|
||||
|
||||
set_target_properties (fgtestlib
|
||||
PROPERTIES
|
||||
COMPILE_DEFINITIONS "FG_TESTLIB"
|
||||
)
|
||||
|
||||
target_link_libraries(fgtestlib SimGearCore fgsqlite3 ${PLATFORM_LIBS})
|
||||
|
||||
add_executable(fgtest fgTestDriver.cxx)
|
||||
target_link_libraries(fgtest fgtestlib)
|
||||
|
||||
# repeat this section for each unit-test executable
|
||||
add_executable(testnavs test_navaids2.cxx)
|
||||
target_link_libraries(testnavs fgtestlib)
|
||||
add_test(testnavs ${EXECUTABLE_OUTPUT_PATH}/testnavs)
|
||||
|
||||
add_executable(testflightplan test_flightplan.cxx)
|
||||
target_link_libraries(testflightplan fgtestlib)
|
||||
add_test(testflightplan ${EXECUTABLE_OUTPUT_PATH}/testflightplan)
|
17
tests/fake_sgPrecipitation.cxx
Normal file
17
tests/fake_sgPrecipitation.cxx
Normal file
|
@ -0,0 +1,17 @@
|
|||
|
||||
#include <Environment/precipitation_mgr.hxx>
|
||||
|
||||
FGPrecipitationMgr::FGPrecipitationMgr()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
FGPrecipitationMgr::~FGPrecipitationMgr()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FGPrecipitationMgr::bind () {}
|
||||
void FGPrecipitationMgr::unbind () {}
|
||||
void FGPrecipitationMgr::init () {}
|
||||
void FGPrecipitationMgr::update (double dt) {}
|
41
tests/fake_sgSky.cxx
Normal file
41
tests/fake_sgSky.cxx
Normal file
|
@ -0,0 +1,41 @@
|
|||
#include "fake_sgSky.hxx"
|
||||
|
||||
void SGSky::add_cloud_layer(SGCloudLayer *layer)
|
||||
{
|
||||
_cloudLayers.push_back(layer);
|
||||
}
|
||||
|
||||
SGCloudLayer *SGSky::get_cloud_layer(int i)
|
||||
{
|
||||
return _cloudLayers.at(i);
|
||||
}
|
||||
|
||||
int SGSky::get_cloud_layer_count() const
|
||||
{
|
||||
return _cloudLayers.size();
|
||||
}
|
||||
|
||||
void SGSky::set_clouds_enabled(bool enabled)
|
||||
{
|
||||
_3dcloudsEnabled = enabled;
|
||||
}
|
||||
|
||||
const std::string &SGCloudLayer::getCoverageString() const
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::string &SGCloudLayer::getCoverageString(SGCloudLayer::Coverage coverage)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
void SGCloudLayer::setCoverageString(const std::string &coverage)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SGCloudLayer::set_enable3dClouds(bool enable)
|
||||
{
|
||||
|
||||
}
|
338
tests/fake_sgSky.hxx
Normal file
338
tests/fake_sgSky.hxx
Normal file
|
@ -0,0 +1,338 @@
|
|||
#ifndef FG_TEST_FAKE_SGSKY_HXX
|
||||
#define FG_TEST_FAKE_SGSKY_HXX
|
||||
|
||||
#include <simgear/structure/SGReferenced.hxx>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class SGCloudLayer : public SGReferenced {
|
||||
public:
|
||||
|
||||
/**
|
||||
* This is the list of available cloud coverages/textures
|
||||
*/
|
||||
enum Coverage {
|
||||
SG_CLOUD_OVERCAST = 0,
|
||||
SG_CLOUD_BROKEN,
|
||||
SG_CLOUD_SCATTERED,
|
||||
SG_CLOUD_FEW,
|
||||
SG_CLOUD_CIRRUS,
|
||||
SG_CLOUD_CLEAR,
|
||||
SG_MAX_CLOUD_COVERAGES
|
||||
};
|
||||
|
||||
static const std::string SG_CLOUD_OVERCAST_STRING; // "overcast"
|
||||
static const std::string SG_CLOUD_BROKEN_STRING; // "broken"
|
||||
static const std::string SG_CLOUD_SCATTERED_STRING; // "scattered"
|
||||
static const std::string SG_CLOUD_FEW_STRING; // "few"
|
||||
static const std::string SG_CLOUD_CIRRUS_STRING; // "cirrus"
|
||||
static const std::string SG_CLOUD_CLEAR_STRING; // "clear"
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param tex_path the path to the set of cloud textures
|
||||
*/
|
||||
SGCloudLayer( const std::string &tex_path ) { }
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~SGCloudLayer( void ) { }
|
||||
|
||||
/** get the cloud span (in meters) */
|
||||
float getSpan_m () const
|
||||
{ return _spanM; }
|
||||
/**
|
||||
* set the cloud span
|
||||
* @param span_m the cloud span in meters
|
||||
*/
|
||||
void setSpan_m (float span_m)
|
||||
{ _spanM = span_m; }
|
||||
|
||||
/** get the layer elevation (in meters) */
|
||||
float getElevation_m () const
|
||||
{
|
||||
return _elevationM;
|
||||
}
|
||||
/**
|
||||
* set the layer elevation. Note that this specifies the bottom
|
||||
* of the cloud layer. The elevation of the top of the layer is
|
||||
* elevation_m + thickness_m.
|
||||
* @param elevation_m the layer elevation in meters
|
||||
* @param set_span defines whether it is allowed to adjust the span
|
||||
*/
|
||||
void setElevation_m (float elevation_m, bool set_span = true)
|
||||
{
|
||||
_elevationM = elevation_m;
|
||||
}
|
||||
|
||||
/** get the layer thickness */
|
||||
float getThickness_m () const
|
||||
{
|
||||
return _thicknessM;
|
||||
}
|
||||
/**
|
||||
* set the layer thickness.
|
||||
* @param thickness_m the layer thickness in meters.
|
||||
*/
|
||||
void setThickness_m (float thickness_m)
|
||||
{
|
||||
_thicknessM = thickness_m;
|
||||
}
|
||||
|
||||
/** get the layer visibility */
|
||||
float getVisibility_m() const
|
||||
{
|
||||
return _visibilityM;
|
||||
}
|
||||
/**
|
||||
* set the layer visibility
|
||||
* @param visibility_m the layer minimum visibility in meters.
|
||||
*/
|
||||
void setVisibility_m(float visibility_m)
|
||||
{
|
||||
_visibilityM = visibility_m;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* get the transition/boundary layer depth in meters. This
|
||||
* allows gradual entry/exit from the cloud layer via adjusting
|
||||
* visibility.
|
||||
*/
|
||||
float getTransition_m () const
|
||||
{
|
||||
return _transitionM;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the transition layer size in meters
|
||||
* @param transition_m the transition layer size in meters
|
||||
*/
|
||||
void setTransition_m (float transition_m)
|
||||
{
|
||||
_transitionM = transition_m;
|
||||
}
|
||||
|
||||
/** get coverage type */
|
||||
Coverage getCoverage () const
|
||||
{
|
||||
return _coverage;
|
||||
}
|
||||
|
||||
/**
|
||||
* set coverage type
|
||||
* @param coverage the coverage type
|
||||
*/
|
||||
void setCoverage (Coverage coverage)
|
||||
{
|
||||
_coverage = coverage;
|
||||
}
|
||||
|
||||
/** get coverage as string */
|
||||
const std::string & getCoverageString() const;
|
||||
|
||||
/** get coverage as string */
|
||||
static const std::string & getCoverageString( Coverage coverage );
|
||||
|
||||
/** get coverage type from string */
|
||||
static Coverage getCoverageType( const std::string & coverage );
|
||||
|
||||
/** set coverage as string */
|
||||
void setCoverageString( const std::string & coverage );
|
||||
|
||||
/**
|
||||
* set the cloud movement direction
|
||||
* @param dir the cloud movement direction
|
||||
*/
|
||||
inline void setDirection(float dir) {
|
||||
// cout << "cloud dir = " << dir << endl;
|
||||
direction = dir;
|
||||
}
|
||||
|
||||
/** get the cloud movement direction */
|
||||
inline float getDirection() { return direction; }
|
||||
|
||||
/**
|
||||
* set the cloud movement speed
|
||||
* @param sp the cloud movement speed
|
||||
*/
|
||||
inline void setSpeed(float sp) {
|
||||
// cout << "cloud speed = " << sp << endl;
|
||||
speed = sp;
|
||||
}
|
||||
|
||||
/** get the cloud movement speed */
|
||||
float getSpeed() { return speed; }
|
||||
|
||||
void setAlpha( float alpha );
|
||||
|
||||
void setMaxAlpha( float alpha )
|
||||
{
|
||||
_maxAlpha = alpha;
|
||||
}
|
||||
|
||||
float getMaxAlpha() const
|
||||
{
|
||||
return _maxAlpha;
|
||||
}
|
||||
|
||||
/** Enable/disable 3D clouds in this layer */
|
||||
void set_enable3dClouds(bool enable);
|
||||
private:
|
||||
float _spanM = 0.0f;
|
||||
float _elevationM = 0.0f;
|
||||
float _thicknessM = 0.0f;
|
||||
float _transitionM = 0.0f;
|
||||
float _visibilityM = 0.0f;
|
||||
Coverage _coverage;
|
||||
float scale = 0.0f;
|
||||
float speed = 0.0f;
|
||||
float direction = 0.0f;
|
||||
float _maxAlpha = 0.0f;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class SGSky
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
void add_cloud_layer (SGCloudLayer * layer);
|
||||
|
||||
const SGCloudLayer * get_cloud_layer (int i) const
|
||||
{
|
||||
return _cloudLayers.at(i);
|
||||
}
|
||||
|
||||
SGCloudLayer * get_cloud_layer (int i);
|
||||
|
||||
int get_cloud_layer_count () const;
|
||||
|
||||
|
||||
/** @return current effective visibility */
|
||||
float get_visibility() const
|
||||
{ return _visibility; }
|
||||
|
||||
/** Set desired clear air visibility.
|
||||
* @param v visibility in meters
|
||||
*/
|
||||
void set_visibility( float v )
|
||||
{ _visibility = v; }
|
||||
|
||||
/** Get 3D cloud density */
|
||||
double get_3dCloudDensity() const
|
||||
{
|
||||
return _3dcloudDensity;
|
||||
}
|
||||
|
||||
/** Set 3D cloud density
|
||||
* @param density 3D cloud density
|
||||
*/
|
||||
void set_3dCloudDensity(double density)
|
||||
{
|
||||
_3dcloudDensity = density;
|
||||
}
|
||||
|
||||
/** Get 3D cloud visibility range*/
|
||||
float get_3dCloudVisRange() const
|
||||
{
|
||||
return _3dcloudVisRange;
|
||||
}
|
||||
|
||||
/** Set 3D cloud visibility range
|
||||
*
|
||||
* @param vis 3D cloud visibility range
|
||||
*/
|
||||
void set_3dCloudVisRange(float vis)
|
||||
{
|
||||
_3dcloudVisRange = vis;
|
||||
}
|
||||
|
||||
/** Get 3D cloud impostor distance*/
|
||||
float get_3dCloudImpostorDistance() const
|
||||
{
|
||||
return _3dcloudImpostorDistance;
|
||||
}
|
||||
|
||||
/** Set 3D cloud impostor distance
|
||||
*
|
||||
* @param vis 3D cloud impostor distance
|
||||
*/
|
||||
void set_3dCloudImpostorDistance(float vis)
|
||||
{
|
||||
_3dcloudImpostorDistance = vis;
|
||||
}
|
||||
|
||||
/** Get 3D cloud LoD1 Range*/
|
||||
float get_3dCloudLoD1Range() const
|
||||
{
|
||||
return _3dcloudLoDRange1;
|
||||
}
|
||||
|
||||
/** Set 3D cloud LoD1 Range
|
||||
* @param vis LoD1 Range
|
||||
*/
|
||||
void set_3dCloudLoD1Range(float vis)
|
||||
{
|
||||
_3dcloudLoDRange1 = vis;
|
||||
}
|
||||
|
||||
/** Get 3D cloud LoD2 Range*/
|
||||
float get_3dCloudLoD2Range() const
|
||||
{
|
||||
return _3dcloudLoDRange2;
|
||||
}
|
||||
|
||||
/** Set 3D cloud LoD2 Range
|
||||
* @param vis LoD2 Range
|
||||
*/
|
||||
void set_3dCloudLoD2Range(float vis)
|
||||
{
|
||||
_3dcloudLoDRange2 = vis;
|
||||
}
|
||||
|
||||
/** Get 3D cloud impostor usage */
|
||||
bool get_3dCloudUseImpostors() const
|
||||
{
|
||||
return _3dcloudUSeImpostors;
|
||||
}
|
||||
|
||||
/** Set 3D cloud impostor usage
|
||||
*
|
||||
* @param imp whether use impostors for 3D clouds
|
||||
*/
|
||||
void set_3dCloudUseImpostors(bool imp)
|
||||
{
|
||||
_3dcloudUSeImpostors = imp;
|
||||
}
|
||||
|
||||
/** Get 3D cloud wrapping */
|
||||
bool get_3dCloudWrap() const
|
||||
{ return _3dcloudWrap; }
|
||||
|
||||
/** Set 3D cloud wrapping
|
||||
* @param wrap whether to wrap 3D clouds
|
||||
*/
|
||||
void set_3dCloudWrap(bool wrap)
|
||||
{ _3dcloudWrap = wrap; }
|
||||
|
||||
void set_clouds_enabled(bool enabled);
|
||||
|
||||
private:
|
||||
float _visibility = 0.0;
|
||||
bool _3dcloudsEnabled = false;
|
||||
bool _3dcloudWrap = false;
|
||||
bool _3dcloudUSeImpostors = false;
|
||||
float _3dcloudImpostorDistance = 0.0;
|
||||
float _3dcloudLoDRange1 = 0.0;
|
||||
float _3dcloudLoDRange2 = 0.0;
|
||||
float _3dcloudVisRange = 0.0;
|
||||
float _3dcloudDensity = 0.0;
|
||||
|
||||
std::vector<SGCloudLayer*> _cloudLayers;
|
||||
};
|
||||
|
||||
#endif
|
57
tests/fake_sound.cxx
Normal file
57
tests/fake_sound.cxx
Normal file
|
@ -0,0 +1,57 @@
|
|||
#include <simgear/sound/soundmgr.hxx>
|
||||
|
||||
class SGSoundMgr::SoundManagerPrivate
|
||||
{
|
||||
public:
|
||||
};
|
||||
|
||||
SGSoundMgr::SGSoundMgr()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SGSoundMgr::~SGSoundMgr()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SGSoundMgr::init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SGSoundMgr::stop()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void SGSoundMgr::suspend()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SGSoundMgr::resume()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SGSoundMgr::update(double dt)
|
||||
{
|
||||
}
|
||||
|
||||
void SGSoundMgr::reinit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool SGSoundMgr::load(const std::string &samplepath, void **data, int *format, size_t *size, int *freq, int *block)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<const char*> SGSoundMgr::get_available_devices()
|
||||
{
|
||||
std::vector<const char*> result;
|
||||
return result;
|
||||
}
|
77
tests/fgTestDriver.cxx
Normal file
77
tests/fgTestDriver.cxx
Normal file
|
@ -0,0 +1,77 @@
|
|||
#include <vector>
|
||||
|
||||
#include <simgear/props/condition.hxx>
|
||||
#include <simgear/props/props_io.hxx>
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
|
||||
class TestStep
|
||||
{
|
||||
public:
|
||||
virtual void run() = 0;
|
||||
// name for logging purposes
|
||||
};
|
||||
|
||||
typedef std::vector<TestStep*> TestStepSequence;
|
||||
|
||||
class SimulateStep : public TestStep
|
||||
{
|
||||
public:
|
||||
void run() override
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
double m_count;
|
||||
double m_dt;
|
||||
|
||||
SGGeod m_endPosition;
|
||||
double m_endHeadingTrueDeg;
|
||||
// other fake FDM data
|
||||
};
|
||||
|
||||
class CommandStep : public TestStep
|
||||
{
|
||||
public:
|
||||
void run() override
|
||||
{
|
||||
// build the command and run it
|
||||
}
|
||||
private:
|
||||
SGPropertyNode_ptr m_cmd;
|
||||
};
|
||||
|
||||
class CheckStep : public TestStep
|
||||
{
|
||||
public:
|
||||
void run() override
|
||||
{
|
||||
for (auto cond : m_conditions) {
|
||||
// eval
|
||||
|
||||
// if failed, boom
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<SGConditionRef> m_conditions;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// parse XML
|
||||
|
||||
// find test name
|
||||
|
||||
// wipe working dir
|
||||
|
||||
// create working dir
|
||||
|
||||
// build test stages
|
||||
|
||||
// read and create subsystems
|
||||
|
||||
// execute in turn
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
382
tests/testStubs.cxx
Normal file
382
tests/testStubs.cxx
Normal file
|
@ -0,0 +1,382 @@
|
|||
#include <string>
|
||||
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
|
||||
#include <Main/locale.hxx>
|
||||
#include <Main/options.hxx>
|
||||
#include <Scripting/NasalSys.hxx>
|
||||
#include <GUI/MessageBox.hxx>
|
||||
#include <ATC/trafficcontrol.hxx>
|
||||
#include <ATC/GroundController.hxx>
|
||||
#include <Scenery/scenery.hxx>
|
||||
|
||||
// declared extern in main.hxx
|
||||
std::string hostname;
|
||||
|
||||
string fgBasePackageVersion(const SGPath& base_path)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
void fgHiResDump()
|
||||
{
|
||||
}
|
||||
|
||||
void fgDumpSnapShot()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void fgCancelSnapShot()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void fgDumpSceneGraph()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void fgOSFullScreen()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void guiErrorMessage(const char *txt)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void guiErrorMessage(const char *txt, const sg_throwable &throwable)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void fgPrintVisibleSceneInfoCommand()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void openBrowser(const std::string& s)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void fgDumpTerrainBranch()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void fgOSExit(int code)
|
||||
{
|
||||
}
|
||||
|
||||
void postinitNasalGUI(naRef globals, naContext c)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void syncPausePopupState()
|
||||
{
|
||||
|
||||
}
|
||||
void
|
||||
SGSetTextureFilter( int max)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
SGGetTextureFilter()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FGScenery::get_elevation_m(const SGGeod& geod, double& alt,
|
||||
const simgear::BVHMaterial** material,
|
||||
const osg::Node* butNotFrom)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace flightgear
|
||||
{
|
||||
MessageBoxResult modalMessageBox(const std::string& caption,
|
||||
const std::string& msg,
|
||||
const std::string& moreText)
|
||||
{
|
||||
return MSG_BOX_OK;
|
||||
}
|
||||
|
||||
MessageBoxResult fatalMessageBox(const std::string& caption,
|
||||
const std::string& msg,
|
||||
const std::string& moreText)
|
||||
{
|
||||
return MSG_BOX_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
string_list
|
||||
FGLocale::getUserLanguage()
|
||||
{
|
||||
string_list result;
|
||||
const char* langEnv = ::getenv("LANG");
|
||||
if (langEnv) {
|
||||
result.push_back(langEnv);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
namespace flightgear
|
||||
{
|
||||
|
||||
SGPath Options::platformDefaultRoot() const
|
||||
{
|
||||
SGPath dataDir;
|
||||
dataDir.append("data");
|
||||
return dataDir;
|
||||
}
|
||||
|
||||
} // of namespace flightgear
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
FGATCController::FGATCController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
FGATCController::~FGATCController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
FGATCInstruction::FGATCInstruction()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////
|
||||
|
||||
|
||||
FGTowerController::FGTowerController(FGAirportDynamics*)
|
||||
{
|
||||
}
|
||||
|
||||
FGTowerController::~FGTowerController()
|
||||
{
|
||||
}
|
||||
|
||||
void FGTowerController::render(bool)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FGTowerController::signOff(int id)
|
||||
{
|
||||
}
|
||||
|
||||
std::string FGTowerController::getName()
|
||||
{
|
||||
return "tower";
|
||||
}
|
||||
|
||||
void FGTowerController::update(double dt)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FGTowerController::announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute, double lat, double lon, double hdg, double spd, double alt, double radius, int leg, FGAIAircraft *aircraft)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FGTowerController::updateAircraftInformation(int id, double lat, double lon, double heading, double speed, double alt, double dt)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool FGTowerController::hasInstruction(int id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
FGATCInstruction FGTowerController::getInstruction(int id)
|
||||
{
|
||||
return FGATCInstruction();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
/// \brief FGApproachController::FGApproachController
|
||||
///
|
||||
FGApproachController::FGApproachController(FGAirportDynamics*)
|
||||
{
|
||||
}
|
||||
|
||||
FGApproachController::~FGApproachController()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void FGApproachController::render(bool)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FGApproachController::signOff(int id)
|
||||
{
|
||||
}
|
||||
|
||||
std::string FGApproachController::getName()
|
||||
{
|
||||
return "approach";
|
||||
}
|
||||
|
||||
void FGApproachController::update(double dt)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FGApproachController::announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute, double lat, double lon, double hdg, double spd, double alt, double radius, int leg, FGAIAircraft *aircraft)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FGApproachController::updateAircraftInformation(int id, double lat, double lon, double heading, double speed, double alt, double dt)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool FGApproachController::hasInstruction(int id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
FGATCInstruction FGApproachController::getInstruction(int id)
|
||||
{
|
||||
return FGATCInstruction();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
FGStartupController::FGStartupController(FGAirportDynamics*)
|
||||
{
|
||||
}
|
||||
|
||||
FGStartupController::~FGStartupController()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void FGStartupController::render(bool)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FGStartupController::signOff(int id)
|
||||
{
|
||||
}
|
||||
|
||||
std::string FGStartupController::getName()
|
||||
{
|
||||
return "startup";
|
||||
}
|
||||
|
||||
void FGStartupController::update(double dt)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FGStartupController::announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute, double lat, double lon, double hdg, double spd, double alt, double radius, int leg, FGAIAircraft *aircraft)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FGStartupController::updateAircraftInformation(int id, double lat, double lon, double heading, double speed, double alt, double dt)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool FGStartupController::hasInstruction(int id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
FGATCInstruction FGStartupController::getInstruction(int id)
|
||||
{
|
||||
return FGATCInstruction();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
FGGroundController::FGGroundController()
|
||||
{
|
||||
}
|
||||
|
||||
FGGroundController::~FGGroundController()
|
||||
{
|
||||
}
|
||||
|
||||
void FGGroundController::init(FGAirportDynamics* pr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FGGroundController::render(bool)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FGGroundController::signOff(int id)
|
||||
{
|
||||
}
|
||||
|
||||
std::string FGGroundController::getName()
|
||||
{
|
||||
return "ground";
|
||||
}
|
||||
|
||||
void FGGroundController::update(double dt)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FGGroundController::announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute, double lat, double lon, double hdg, double spd, double alt, double radius, int leg, FGAIAircraft *aircraft)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FGGroundController::updateAircraftInformation(int id, double lat, double lon, double heading, double speed, double alt, double dt)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool FGGroundController::hasInstruction(int id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
FGATCInstruction FGGroundController::getInstruction(int id)
|
||||
{
|
||||
return FGATCInstruction();
|
||||
}
|
||||
|
||||
|
||||
#if defined(SG_WINDOWS)
|
||||
|
||||
#include <plib/sg.h>
|
||||
|
||||
// this stub is needed on Windows because sg.h decleares this function as extern
|
||||
void sgdMakeCoordMat4(sgdMat4 m, const SGDfloat x, const SGDfloat y, const SGDfloat z, const SGDfloat h, const SGDfloat p, const SGDfloat r)
|
||||
{
|
||||
}
|
||||
#endif
|
147
tests/test_flightplan.cxx
Normal file
147
tests/test_flightplan.cxx
Normal file
|
@ -0,0 +1,147 @@
|
|||
#include "config.h"
|
||||
|
||||
#include "unitTestHelpers.hxx"
|
||||
|
||||
#include <simgear/misc/test_macros.hxx>
|
||||
#include <simgear/misc/strutils.hxx>
|
||||
|
||||
#include <Navaids/FlightPlan.hxx>
|
||||
#include <Navaids/routePath.hxx>
|
||||
#include <Navaids/NavDataCache.hxx>
|
||||
#include <Navaids/waypoint.hxx>
|
||||
#include <Navaids/navlist.hxx>
|
||||
#include <Navaids/navrecord.hxx>
|
||||
|
||||
#include <Airports/airport.hxx>
|
||||
|
||||
using namespace flightgear;
|
||||
|
||||
FlightPlanRef makeTestFP(const std::string& depICAO, const std::string& depRunway,
|
||||
const std::string& destICAO, const std::string& destRunway,
|
||||
const std::string& waypoints)
|
||||
{
|
||||
FlightPlanRef f = new FlightPlan;
|
||||
|
||||
FGAirportRef depApt = FGAirport::getByIdent(depICAO);
|
||||
f->setDeparture(depApt->getRunwayByIdent(depRunway));
|
||||
|
||||
|
||||
FGAirportRef destApt = FGAirport::getByIdent(destICAO);
|
||||
f->setDestination(destApt->getRunwayByIdent(destRunway));
|
||||
|
||||
for (auto ws : simgear::strutils::split(waypoints)) {
|
||||
WayptRef wpt = f->waypointFromString(ws);
|
||||
f->insertWayptAtIndex(wpt, -1);
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
void testBasic()
|
||||
{
|
||||
FlightPlanRef fp1 = makeTestFP("EGCC", "23L", "EHAM", "24",
|
||||
"TNT CLN");
|
||||
fp1->setIdent("testplan");
|
||||
|
||||
SG_CHECK_EQUAL(fp1->ident(), "testplan");
|
||||
SG_CHECK_EQUAL(fp1->departureAirport()->ident(), "EGCC");
|
||||
SG_CHECK_EQUAL(fp1->departureRunway()->ident(), "23L");
|
||||
SG_CHECK_EQUAL(fp1->destinationAirport()->ident(), "EHAM");
|
||||
SG_CHECK_EQUAL(fp1->destinationRunway()->ident(), "24");
|
||||
|
||||
SG_CHECK_EQUAL(fp1->numLegs(), 2);
|
||||
|
||||
SG_CHECK_EQUAL(fp1->legAtIndex(0)->waypoint()->source()->ident(), "TNT");
|
||||
SG_CHECK_EQUAL(fp1->legAtIndex(0)->waypoint()->source()->name(), "TRENT VOR-DME");
|
||||
|
||||
SG_CHECK_EQUAL(fp1->legAtIndex(1)->waypoint()->source()->ident(), "CLN");
|
||||
SG_CHECK_EQUAL(fp1->legAtIndex(1)->waypoint()->source()->name(), "CLACTON VOR-DME");
|
||||
}
|
||||
|
||||
void testRoutePathBasic()
|
||||
{
|
||||
FlightPlanRef fp1 = makeTestFP("EGHI", "20", "EDDM", "08L",
|
||||
"SFD LYD BNE CIV ELLX LUX SAA KRH WLD");
|
||||
|
||||
|
||||
RoutePath rtepath(fp1);
|
||||
const unsigned int legCount = fp1->numLegs();
|
||||
for (int leg = 0; leg < legCount; ++leg) {
|
||||
rtepath.trackForIndex(leg);
|
||||
rtepath.pathForIndex(leg);
|
||||
rtepath.distanceForIndex(leg);
|
||||
}
|
||||
|
||||
rtepath.distanceBetweenIndices(2, 5);
|
||||
|
||||
// check some leg parameters
|
||||
|
||||
// BOLOUGNE SUR MER, near LFAY (AMIENS)
|
||||
FGNavRecordRef bne = FGNavList::findByFreq(113.8, FGAirport::getByIdent("LFAY")->geod());
|
||||
|
||||
// CHIEVRES
|
||||
FGNavRecordRef civ = FGNavList::findByFreq(113.2, FGAirport::getByIdent("EBCI")->geod());
|
||||
|
||||
double distM = SGGeodesy::distanceM(bne->geod(), civ->geod());
|
||||
double trackDeg = SGGeodesy::courseDeg(bne->geod(), civ->geod());
|
||||
|
||||
SG_CHECK_EQUAL_EP2(trackDeg, rtepath.trackForIndex(3), 0.5);
|
||||
SG_CHECK_EQUAL_EP2(distM, rtepath.distanceForIndex(3), 2000); // 2km precision, allow for turns
|
||||
|
||||
}
|
||||
|
||||
// https://sourceforge.net/p/flightgear/codetickets/1703/
|
||||
// https://sourceforge.net/p/flightgear/codetickets/1939/
|
||||
|
||||
void testRoutePathSkipped()
|
||||
{
|
||||
FlightPlanRef fp1 = makeTestFP("EHAM", "24", "EDDM", "08L",
|
||||
"EHEH KBO TAU FFM FFM/100/0.01 FFM/120/0.02 WUR WLD");
|
||||
|
||||
|
||||
RoutePath rtepath(fp1);
|
||||
|
||||
// skipped point uses inbound track
|
||||
SG_CHECK_EQUAL_EP(rtepath.trackForIndex(3), rtepath.trackForIndex(4));
|
||||
|
||||
SG_CHECK_EQUAL_EP(0.0, rtepath.distanceForIndex(4));
|
||||
SG_CHECK_EQUAL_EP(0.0, rtepath.distanceForIndex(5));
|
||||
|
||||
SG_CHECK_EQUAL_EP2(101000, rtepath.distanceForIndex(6), 1000);
|
||||
|
||||
|
||||
// this tests skipping two preceeding points works as it should
|
||||
SGGeodVec vec = rtepath.pathForIndex(6);
|
||||
SG_CHECK_EQUAL(vec.size(), 9);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void testRoutePathTrivialFlightPlan()
|
||||
{
|
||||
FlightPlanRef fp1 = makeTestFP("EGPH", "24", "EGPH", "06",
|
||||
"");
|
||||
|
||||
|
||||
RoutePath rtepath(fp1);
|
||||
const unsigned int legCount = fp1->numLegs();
|
||||
for (int leg = 0; leg < legCount; ++leg) {
|
||||
rtepath.trackForIndex(leg);
|
||||
rtepath.pathForIndex(leg);
|
||||
rtepath.distanceForIndex(leg);
|
||||
}
|
||||
|
||||
SG_CHECK_EQUAL_EP(0.0, fp1->totalDistanceNm());
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
fgtest::initTestGlobals("flightplan");
|
||||
|
||||
testBasic();
|
||||
testRoutePathBasic();
|
||||
testRoutePathSkipped();
|
||||
testRoutePathTrivialFlightPlan();
|
||||
|
||||
fgtest::shutdownTestGlobals();
|
||||
}
|
29
tests/test_navaids2.cxx
Normal file
29
tests/test_navaids2.cxx
Normal file
|
@ -0,0 +1,29 @@
|
|||
#include "unitTestHelpers.hxx"
|
||||
|
||||
#include <simgear/misc/test_macros.hxx>
|
||||
|
||||
#include <Navaids/NavDataCache.hxx>
|
||||
#include <Navaids/navrecord.hxx>
|
||||
#include <Navaids/navlist.hxx>
|
||||
|
||||
void testBasic()
|
||||
{
|
||||
SGGeod egccPos = SGGeod::fromDeg(-2.27, 53.35);
|
||||
FGNavRecordRef tla = FGNavList::findByFreq(115.7, egccPos);
|
||||
|
||||
SG_CHECK_EQUAL(strcmp(tla->get_ident(), "TNT"), 0);
|
||||
SG_CHECK_EQUAL(tla->ident(), "TNT");
|
||||
SG_CHECK_EQUAL(tla->name(), "TRENT VOR-DME");
|
||||
SG_CHECK_EQUAL(tla->get_freq(), 11570);
|
||||
SG_CHECK_EQUAL(tla->get_range(), 130);
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
fgtest::initTestGlobals("navaids2");
|
||||
|
||||
testBasic();
|
||||
|
||||
fgtest::shutdownTestGlobals();
|
||||
}
|
88
tests/unitTestHelpers.cxx
Normal file
88
tests/unitTestHelpers.cxx
Normal file
|
@ -0,0 +1,88 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include "unitTestHelpers.hxx"
|
||||
|
||||
#include <Main/globals.hxx>
|
||||
#include <Navaids/NavDataCache.hxx>
|
||||
#include <Time/TimeManager.hxx>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/sg_dir.hxx>
|
||||
#include <simgear/timing/timestamp.hxx>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace fgtest
|
||||
{
|
||||
|
||||
bool looksLikeFGData(const SGPath& path)
|
||||
{
|
||||
return (path / "defaults.xml").exists();
|
||||
}
|
||||
|
||||
void initTestGlobals(const std::string& testName)
|
||||
{
|
||||
sglog().setLogLevels( SG_ALL, SG_WARN );
|
||||
sglog().setDeveloperMode(true);
|
||||
|
||||
globals = new FGGlobals;
|
||||
|
||||
bool foundRoot = false;
|
||||
if (std::getenv("FG_ROOT")) {
|
||||
SGPath fg_root = SGPath::fromEnv("FG_ROOT");
|
||||
if (looksLikeFGData(fg_root)) {
|
||||
globals->set_fg_root(fg_root);
|
||||
foundRoot = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundRoot) {
|
||||
SGPath pkgLibDir = SGPath::fromUtf8(PKGLIBDIR);
|
||||
if (looksLikeFGData(pkgLibDir)) {
|
||||
globals->set_fg_root(pkgLibDir);
|
||||
foundRoot = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundRoot) {
|
||||
SGPath dataDir = SGPath::fromUtf8(FGSRCDIR) / ".." / "fgdata";
|
||||
if (looksLikeFGData(dataDir)) {
|
||||
globals->set_fg_root(dataDir);
|
||||
foundRoot = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundRoot) {
|
||||
std::cerr << "FGData not found" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
// current dir
|
||||
SGPath homePath = simgear::Dir::current().path() / "test_home";
|
||||
if (!homePath.exists()) {
|
||||
(homePath / "dummyFile").create_dir(0755);
|
||||
}
|
||||
|
||||
globals->set_fg_home(homePath);
|
||||
|
||||
flightgear::NavDataCache* cache = flightgear::NavDataCache::createInstance();
|
||||
if (cache->isRebuildRequired()) {
|
||||
std::cerr << "Navcache rebuild for testing" << std::flush;
|
||||
|
||||
while (cache->rebuild() != flightgear::NavDataCache::REBUILD_DONE) {
|
||||
SGTimeStamp::sleepForMSec(1000);
|
||||
std::cerr << "." << std::flush;
|
||||
}
|
||||
}
|
||||
|
||||
TimeManager* t = new TimeManager;
|
||||
t->init(); // establish mag-var data
|
||||
}
|
||||
|
||||
void shutdownTestGlobals()
|
||||
{
|
||||
delete globals;
|
||||
}
|
||||
} // of namespace fgtest
|
15
tests/unitTestHelpers.hxx
Normal file
15
tests/unitTestHelpers.hxx
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef FG_TEST_HELPERS_HXX
|
||||
#define FG_TEST_HELPERS_HXX
|
||||
|
||||
#include <string>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
namespace fgtest
|
||||
{
|
||||
|
||||
void initTestGlobals(const std::string& testName);
|
||||
|
||||
void shutdownTestGlobals();
|
||||
}
|
||||
|
||||
#endif // of FG_TEST_HELPERS_HXX
|
Loading…
Reference in a new issue