Merge branch 'next' of http://git.gitorious.org/fg/flightgear into next
This commit is contained in:
commit
4a63946e94
27 changed files with 637 additions and 417 deletions
|
@ -20,7 +20,7 @@
|
|||
; C:\> subst X: /d
|
||||
;
|
||||
|
||||
#define FGVER "v20110228"
|
||||
#define FGVER "v20110324"
|
||||
|
||||
[Setup]
|
||||
AppId=FlightGear {#FGVER}
|
||||
|
@ -52,7 +52,7 @@ Name: "insoal"; Description: "Install OpenAL (the sound engine)"
|
|||
; NOTE: run subst X: F:\ (or whatever path the expanded tree resides at)
|
||||
Source: "X:\*.txt"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "X:\bin\Win32\*.*"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion recursesubdirs
|
||||
Source: "X:\bin\vcredist_x86.exe"; DestDir: "{app}\bin"; Flags: ignoreversion
|
||||
;;; Source: "X:\bin\vcredist_x86.exe"; DestDir: "{app}\bin"; Flags: ignoreversion
|
||||
Source: "X:\bin\oalinst.exe"; DestDir: "{app}\bin"; Flags: ignoreversion
|
||||
Source: "X:\data\*.*"; DestDir: "{app}\data"; Flags: ignoreversion recursesubdirs
|
||||
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||
|
@ -88,7 +88,7 @@ Name: "{group}\Tools\Explore Documentation Folder"; Filename: "{app}\data\Docs"
|
|||
; Name: "{userdesktop}\FlightGear {#FGVER}"; Filename: "{app}\bin\Win32\fgfs.exe"; Parameters: "--fg-root=."; WorkingDir: "{app}"; Tasks: desktopicon
|
||||
|
||||
[Run]
|
||||
Filename: "{app}\bin\vcredist_x86.exe"; WorkingDir: "{app}"; Parameters: "/qb!"; Description: "Installing Flightgear prerequisites"
|
||||
;;; Filename: "{app}\bin\vcredist_x86.exe"; WorkingDir: "{app}"; Parameters: "/qb!"; Description: "Installing Flightgear prerequisites"
|
||||
|
||||
; Put installation directory into the fgrun.prefs
|
||||
filename: "{app}\bin\Win32\fgrun.exe"; WorkingDir: "{app}\bin\Win32"; Parameters: "--silent ""--fg-exe={app}\bin\Win32\fgfs.exe"" ""--ts-exe={app}\bin\Win32\terrasync.exe"" ""--fg-root={app}\data"" ""--fg-scenery={app}\data\Scenery;{app}\scenery;{code:TerrasyncDir}"" --ts-dir=3"
|
||||
|
|
|
@ -24,13 +24,16 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <float.h>
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <Network/native_ctrls.hxx>
|
||||
#include <Network/native_fdm.hxx>
|
||||
#include <Network/net_ctrls.hxx>
|
||||
#include <Network/net_fdm.hxx>
|
||||
#include <FDM/fdm_shell.hxx>
|
||||
|
||||
#include "replay.hxx"
|
||||
|
||||
|
@ -46,7 +49,9 @@ const double FGReplay::lt_dt = 5.0; // long term sample rate (sec)
|
|||
* Constructor
|
||||
*/
|
||||
|
||||
FGReplay::FGReplay() {
|
||||
FGReplay::FGReplay() :
|
||||
last_replay_state(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
@ -54,73 +59,82 @@ FGReplay::FGReplay() {
|
|||
* Destructor
|
||||
*/
|
||||
|
||||
FGReplay::~FGReplay() {
|
||||
while ( !short_term.empty() ) {
|
||||
//cerr << "Deleting Short term" <<endl;
|
||||
FGReplay::~FGReplay()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all internal buffers.
|
||||
*/
|
||||
void FGReplay::clear()
|
||||
{
|
||||
while ( !short_term.empty() )
|
||||
{
|
||||
delete short_term.front();
|
||||
short_term.pop_front();
|
||||
}
|
||||
while ( !medium_term.empty() ) {
|
||||
//cerr << "Deleting Medium term" <<endl;
|
||||
delete medium_term.front();
|
||||
while ( !medium_term.empty() )
|
||||
{
|
||||
delete medium_term.front();
|
||||
medium_term.pop_front();
|
||||
}
|
||||
while ( !long_term.empty() ) {
|
||||
//cerr << "Deleting Long term" <<endl;
|
||||
delete long_term.front();
|
||||
while ( !long_term.empty() )
|
||||
{
|
||||
delete long_term.front();
|
||||
long_term.pop_front();
|
||||
}
|
||||
while ( !recycler.empty() ) {
|
||||
//cerr << "Deleting Recycler" <<endl;
|
||||
delete recycler.front();
|
||||
while ( !recycler.empty() )
|
||||
{
|
||||
delete recycler.front();
|
||||
recycler.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the data structures
|
||||
*/
|
||||
|
||||
void FGReplay::init() {
|
||||
void FGReplay::init()
|
||||
{
|
||||
disable_replay = fgGetNode( "/sim/replay/disable", true );
|
||||
replay_master = fgGetNode( "/sim/freeze/replay-state", true );
|
||||
replay_time = fgGetNode( "/sim/replay/time", true);
|
||||
reinit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset replay queues.
|
||||
*/
|
||||
|
||||
void FGReplay::reinit()
|
||||
{
|
||||
sim_time = 0.0;
|
||||
last_mt_time = 0.0;
|
||||
last_lt_time = 0.0;
|
||||
|
||||
// Make sure all queues are flushed
|
||||
while ( !short_term.empty() ) {
|
||||
delete short_term.front();
|
||||
short_term.pop_front();
|
||||
}
|
||||
while ( !medium_term.empty() ) {
|
||||
delete medium_term.front();
|
||||
medium_term.pop_front();
|
||||
}
|
||||
while ( !long_term.empty() ) {
|
||||
delete long_term.front();
|
||||
long_term.pop_front();
|
||||
}
|
||||
while ( !recycler.empty() ) {
|
||||
delete recycler.front();
|
||||
recycler.pop_front();
|
||||
}
|
||||
clear();
|
||||
|
||||
// Create an estimated nr of required ReplayData objects
|
||||
// 120 is an estimated maximum frame rate.
|
||||
int estNrObjects = (int) ((st_list_time*120) + (mt_list_time*mt_dt) +
|
||||
(lt_list_time*lt_dt));
|
||||
for (int i = 0; i < estNrObjects; i++) {
|
||||
for (int i = 0; i < estNrObjects; i++)
|
||||
{
|
||||
recycler.push_back(new FGReplayData);
|
||||
|
||||
}
|
||||
replay_master->setIntValue(0);
|
||||
disable_replay->setBoolValue(0);
|
||||
replay_time->setDoubleValue(0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Bind to the property tree
|
||||
*/
|
||||
|
||||
void FGReplay::bind() {
|
||||
disable_replay = fgGetNode( "/sim/replay/disable", true );
|
||||
void FGReplay::bind()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
@ -128,7 +142,8 @@ void FGReplay::bind() {
|
|||
* Unbind from the property tree
|
||||
*/
|
||||
|
||||
void FGReplay::unbind() {
|
||||
void FGReplay::unbind()
|
||||
{
|
||||
// nothing to unbind
|
||||
}
|
||||
|
||||
|
@ -137,24 +152,62 @@ void FGReplay::unbind() {
|
|||
* Update the saved data
|
||||
*/
|
||||
|
||||
void FGReplay::update( double dt ) {
|
||||
void FGReplay::update( double dt )
|
||||
{
|
||||
timingInfo.clear();
|
||||
stamp("begin");
|
||||
static SGPropertyNode *replay_master
|
||||
= fgGetNode( "/sim/freeze/replay-state", true );
|
||||
|
||||
if( disable_replay->getBoolValue() ) {
|
||||
if ( sim_time != 0.0 ) {
|
||||
// we were recording data
|
||||
init();
|
||||
}
|
||||
return;
|
||||
if ( disable_replay->getBoolValue() )
|
||||
{
|
||||
replay_master->setIntValue(0);
|
||||
replay_time->setDoubleValue(0);
|
||||
disable_replay->setBoolValue(0);
|
||||
}
|
||||
//stamp("point_01");
|
||||
if ( replay_master->getIntValue() > 0 ) {
|
||||
// don't record the replay session
|
||||
return;
|
||||
|
||||
int replay_state = replay_master->getIntValue();
|
||||
|
||||
if ((replay_state > 0)&&
|
||||
(last_replay_state == 0))
|
||||
{
|
||||
// replay is starting, suspend FDM
|
||||
/* FIXME we need to suspend/resume the FDM - not the entire FDM shell.
|
||||
* FDM isn't available via the global subsystem manager yet, so need a
|
||||
* method at the FDMshell for now */
|
||||
((FDMShell*) globals->get_subsystem("flight"))->getFDM()->suspend();
|
||||
}
|
||||
else
|
||||
if ((replay_state == 0)&&
|
||||
(last_replay_state > 0))
|
||||
{
|
||||
// replay was active, restore most recent frame
|
||||
replay(DBL_MAX);
|
||||
// replay is finished, resume FDM
|
||||
((FDMShell*) globals->get_subsystem("flight"))->getFDM()->resume();
|
||||
}
|
||||
|
||||
// remember recent state
|
||||
last_replay_state = replay_state;
|
||||
|
||||
switch(replay_state)
|
||||
{
|
||||
case 0:
|
||||
// replay inactive, keep recording
|
||||
break;
|
||||
case 1:
|
||||
// replay active
|
||||
replay( replay_time->getDoubleValue() );
|
||||
replay_time->setDoubleValue( replay_time->getDoubleValue()
|
||||
+ ( dt * fgGetInt("/sim/speed-up") ) );
|
||||
return; // don't record the replay session
|
||||
case 2:
|
||||
// replay paused, no-op
|
||||
return; // don't record the replay session
|
||||
default:
|
||||
throw sg_range_exception("unknown FGReplay state");
|
||||
}
|
||||
|
||||
// flight recording
|
||||
|
||||
//cerr << "Recording replay" << endl;
|
||||
sim_time += dt;
|
||||
|
||||
|
@ -175,12 +228,13 @@ void FGReplay::update( double dt ) {
|
|||
if (!recycler.size()) {
|
||||
stamp("Replay_01");
|
||||
r = new FGReplayData;
|
||||
stamp("Replay_02");
|
||||
stamp("Replay_02");
|
||||
} else {
|
||||
r = recycler.front();
|
||||
recycler.pop_front();
|
||||
//stamp("point_04be");
|
||||
r = recycler.front();
|
||||
recycler.pop_front();
|
||||
//stamp("point_04be");
|
||||
}
|
||||
|
||||
r->sim_time = sim_time;
|
||||
//r->ctrls = c;
|
||||
//stamp("point_04e");
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
virtual ~FGReplay();
|
||||
|
||||
virtual void init();
|
||||
virtual void reinit();
|
||||
virtual void bind();
|
||||
virtual void unbind();
|
||||
virtual void update( double dt );
|
||||
|
@ -78,6 +79,7 @@ public:
|
|||
double get_end_time();
|
||||
|
||||
private:
|
||||
void clear();
|
||||
|
||||
static const double st_list_time; // 60 secs of high res data
|
||||
static const double mt_list_time; // 10 mins of 1 fps data
|
||||
|
@ -90,12 +92,15 @@ private:
|
|||
double sim_time;
|
||||
double last_mt_time;
|
||||
double last_lt_time;
|
||||
int last_replay_state;
|
||||
|
||||
replay_list_type short_term;
|
||||
replay_list_type medium_term;
|
||||
replay_list_type long_term;
|
||||
replay_list_type recycler;
|
||||
SGPropertyNode_ptr disable_replay;
|
||||
SGPropertyNode_ptr replay_master;
|
||||
SGPropertyNode_ptr replay_time;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -76,12 +76,8 @@ FGEnvironmentMgr::~FGEnvironmentMgr ()
|
|||
remove_subsystem("precipitation");
|
||||
delete subsys;
|
||||
|
||||
subsys = get_subsystem("metarfetcher");
|
||||
remove_subsystem("metarfetcher");
|
||||
delete subsys;
|
||||
|
||||
subsys = get_subsystem("metarcontroller");
|
||||
remove_subsystem("metarcontroller");
|
||||
subsys = get_subsystem("realwx");
|
||||
remove_subsystem("realwx");
|
||||
delete subsys;
|
||||
|
||||
subsys = get_subsystem("controller");
|
||||
|
@ -346,9 +342,6 @@ FGEnvironmentMgr::set_cloud_layer_maxalpha (int index, double maxalpha)
|
|||
thesky->get_cloud_layer(index)->setMaxAlpha(maxalpha);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
FGEnvironmentMgr::set_cloud_layer_coverage_type (int index, int type )
|
||||
{
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <simgear/threads/SGQueue.hxx>
|
||||
#endif
|
||||
|
||||
using simgear::PropertyList;
|
||||
|
||||
namespace Environment {
|
||||
|
||||
|
|
|
@ -570,6 +570,22 @@ void FGJSBsim::update( double dt )
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
void FGJSBsim::suspend()
|
||||
{
|
||||
fdmex->Hold();
|
||||
SGSubsystem::suspend();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void FGJSBsim::resume()
|
||||
{
|
||||
fdmex->Resume();
|
||||
SGSubsystem::resume();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// Convert from the FGInterface struct to the JSBsim generic_ struct
|
||||
|
||||
bool FGJSBsim::copy_to_JSBsim()
|
||||
|
@ -1011,7 +1027,9 @@ void FGJSBsim::set_Latitude(double lat)
|
|||
_set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET );
|
||||
fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET );
|
||||
fgic->SetLatitudeRadIC( lat_geoc );
|
||||
needTrim=true;
|
||||
|
||||
if (!fdmex->Holding())
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1024,7 +1042,9 @@ void FGJSBsim::set_Longitude(double lon)
|
|||
|
||||
update_ic();
|
||||
fgic->SetLongitudeRadIC( lon );
|
||||
needTrim=true;
|
||||
|
||||
if (!fdmex->Holding())
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
// Sets the altitude above sea level.
|
||||
|
@ -1049,7 +1069,9 @@ void FGJSBsim::set_Altitude(double alt)
|
|||
"Terrain elevation: " << FGInterface::get_Runway_altitude() * SG_METER_TO_FEET );
|
||||
fgic->SetLatitudeRadIC( lat_geoc );
|
||||
fgic->SetAltitudeASLFtIC(alt);
|
||||
needTrim=true;
|
||||
|
||||
if (!fdmex->Holding())
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
void FGJSBsim::set_V_calibrated_kts(double vc)
|
||||
|
@ -1061,7 +1083,9 @@ void FGJSBsim::set_V_calibrated_kts(double vc)
|
|||
|
||||
update_ic();
|
||||
fgic->SetVcalibratedKtsIC(vc);
|
||||
needTrim=true;
|
||||
|
||||
if (!fdmex->Holding())
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
void FGJSBsim::set_Mach_number(double mach)
|
||||
|
@ -1073,7 +1097,9 @@ void FGJSBsim::set_Mach_number(double mach)
|
|||
|
||||
update_ic();
|
||||
fgic->SetMachIC(mach);
|
||||
needTrim=true;
|
||||
|
||||
if (!fdmex->Holding())
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
void FGJSBsim::set_Velocities_Local( double north, double east, double down )
|
||||
|
@ -1088,7 +1114,9 @@ void FGJSBsim::set_Velocities_Local( double north, double east, double down )
|
|||
fgic->SetVNorthFpsIC(north);
|
||||
fgic->SetVEastFpsIC(east);
|
||||
fgic->SetVDownFpsIC(down);
|
||||
needTrim=true;
|
||||
|
||||
if (!fdmex->Holding())
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
void FGJSBsim::set_Velocities_Wind_Body( double u, double v, double w)
|
||||
|
@ -1103,7 +1131,9 @@ void FGJSBsim::set_Velocities_Wind_Body( double u, double v, double w)
|
|||
fgic->SetUBodyFpsIC(u);
|
||||
fgic->SetVBodyFpsIC(v);
|
||||
fgic->SetWBodyFpsIC(w);
|
||||
needTrim=true;
|
||||
|
||||
if (!fdmex->Holding())
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
//Euler angles
|
||||
|
@ -1119,7 +1149,9 @@ void FGJSBsim::set_Euler_Angles( double phi, double theta, double psi )
|
|||
fgic->SetThetaRadIC(theta);
|
||||
fgic->SetPhiRadIC(phi);
|
||||
fgic->SetPsiRadIC(psi);
|
||||
needTrim=true;
|
||||
|
||||
if (!fdmex->Holding())
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
//Flight Path
|
||||
|
@ -1137,7 +1169,9 @@ void FGJSBsim::set_Climb_Rate( double roc)
|
|||
if( !(fabs(roc) > 1 && fabs(fgic->GetFlightPathAngleRadIC()) < 0.01) ) {
|
||||
fgic->SetClimbRateFpsIC(roc);
|
||||
}
|
||||
needTrim=true;
|
||||
|
||||
if (!fdmex->Holding())
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
void FGJSBsim::set_Gamma_vert_rad( double gamma)
|
||||
|
@ -1148,7 +1182,9 @@ void FGJSBsim::set_Gamma_vert_rad( double gamma)
|
|||
if( !(fabs(gamma) < 0.01 && fabs(fgic->GetClimbRateFpsIC()) > 1) ) {
|
||||
fgic->SetFlightPathAngleRadIC(gamma);
|
||||
}
|
||||
needTrim=true;
|
||||
|
||||
if (!fdmex->Holding())
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
void FGJSBsim::init_gear(void )
|
||||
|
|
|
@ -113,6 +113,12 @@ public:
|
|||
/// Unbind properties
|
||||
void unbind();
|
||||
|
||||
/// Suspend integration
|
||||
void suspend();
|
||||
|
||||
/// Resume integration
|
||||
void resume();
|
||||
|
||||
/// @name Position Parameter Set
|
||||
//@{
|
||||
/** Set geocentric latitude
|
||||
|
|
|
@ -236,12 +236,6 @@ TankPropertiesList::TankPropertiesList( SGPropertyNode_ptr rootNode )
|
|||
}
|
||||
|
||||
_tiedProperties.setRoot( rootNode );
|
||||
_tiedProperties.Tie("total-fuel-kg", this, &TankPropertiesList::getTotalContent_kg );
|
||||
_tiedProperties.Tie("total-fuel-lbs", this, &TankPropertiesList::getTotalContent_lbs );
|
||||
_tiedProperties.Tie("total-fuel-gal_us", this, &TankPropertiesList::getTotalContent_gal_us );
|
||||
_tiedProperties.Tie("total-fuel-gals", this, &TankPropertiesList::getTotalContent_gal_us );
|
||||
_tiedProperties.Tie("total-fuel-gal_imp", this, &TankPropertiesList::getTotalContent_gal_imp );
|
||||
_tiedProperties.Tie("total-fuel-norm", this, &TankPropertiesList::getTotalContent_norm );
|
||||
}
|
||||
|
||||
double TankPropertiesList::getTotalContent_lbs() const
|
||||
|
@ -297,6 +291,12 @@ double TankPropertiesList::getTotalContent_norm() const
|
|||
|
||||
void TankPropertiesList::bind()
|
||||
{
|
||||
_tiedProperties.Tie("total-fuel-kg", this, &TankPropertiesList::getTotalContent_kg );
|
||||
_tiedProperties.Tie("total-fuel-lbs", this, &TankPropertiesList::getTotalContent_lbs );
|
||||
_tiedProperties.Tie("total-fuel-gal_us", this, &TankPropertiesList::getTotalContent_gal_us );
|
||||
_tiedProperties.Tie("total-fuel-gals", this, &TankPropertiesList::getTotalContent_gal_us );
|
||||
_tiedProperties.Tie("total-fuel-gal_imp", this, &TankPropertiesList::getTotalContent_gal_imp );
|
||||
_tiedProperties.Tie("total-fuel-norm", this, &TankPropertiesList::getTotalContent_norm );
|
||||
for( const_iterator it = begin(); it != end(); ++it ) {
|
||||
(*it)->bind();
|
||||
}
|
||||
|
|
|
@ -90,11 +90,11 @@ void FDMShell::reinit()
|
|||
|
||||
void FDMShell::bind()
|
||||
{
|
||||
_tankProperties.bind();
|
||||
if (_impl && _impl->get_inited()) {
|
||||
if (_impl->get_bound()) {
|
||||
throw sg_exception("FDMShell::bind of bound FGInterface impl");
|
||||
}
|
||||
_tankProperties.bind();
|
||||
_impl->bind();
|
||||
}
|
||||
}
|
||||
|
@ -139,8 +139,8 @@ void FDMShell::update(double dt)
|
|||
// pull environmental data in, since the FDMs are lazy
|
||||
_impl->set_Velocities_Local_Airmass(
|
||||
_props->getDoubleValue("environment/wind-from-north-fps", 0.0),
|
||||
_props->getDoubleValue("environment/wind-from-east-fps", 0.0),
|
||||
_props->getDoubleValue("environment/wind-from-down-fps", 0.0));
|
||||
_props->getDoubleValue("environment/wind-from-east-fps", 0.0),
|
||||
_props->getDoubleValue("environment/wind-from-down-fps", 0.0));
|
||||
|
||||
if (_props->getBoolValue("environment/params/control-fdm-atmosphere")) {
|
||||
// convert from Rankine to Celsius
|
||||
|
@ -160,24 +160,8 @@ void FDMShell::update(double dt)
|
|||
_impl->ToggleDataLogging(doLog);
|
||||
}
|
||||
|
||||
// FIXME - replay manager should handle most of this
|
||||
int replayState = fgGetInt("/sim/freeze/replay-state", 0);
|
||||
if (replayState == 0) {
|
||||
_impl->update(dt); // normal code path
|
||||
} else if (replayState == 1) {
|
||||
// should be inside FGReplay!
|
||||
SGPropertyNode* replay_time = fgGetNode("/sim/replay/time", true);
|
||||
FGReplay *r = (FGReplay *)(globals->get_subsystem( "replay" ));
|
||||
r->replay( replay_time->getDoubleValue() );
|
||||
replay_time->setDoubleValue( replay_time->getDoubleValue()
|
||||
+ ( dt
|
||||
* fgGetInt("/sim/speed-up") ) );
|
||||
|
||||
} else if (replayState == 2) {
|
||||
// paused replay, no-op
|
||||
} else {
|
||||
throw sg_range_exception("unknown FGReplay state");
|
||||
}
|
||||
if (!_impl->is_suspended())
|
||||
_impl->update(dt);
|
||||
}
|
||||
|
||||
void FDMShell::createImplementation()
|
||||
|
@ -268,3 +252,13 @@ void FDMShell::createImplementation()
|
|||
|
||||
}
|
||||
|
||||
/*
|
||||
* Return FDM subsystem.
|
||||
*/
|
||||
|
||||
SGSubsystem* FDMShell::getFDM()
|
||||
{
|
||||
/* FIXME we could drop/replace this method, when _impl was a added
|
||||
* to the global subsystem manager - like other proper subsystems... */
|
||||
return _impl;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,8 @@ public:
|
|||
virtual void unbind();
|
||||
|
||||
virtual void update(double dt);
|
||||
|
||||
SGSubsystem* getFDM();
|
||||
|
||||
private:
|
||||
|
||||
void createImplementation();
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -221,7 +221,7 @@ do_exit (const SGPropertyNode * arg)
|
|||
static bool
|
||||
do_reset (const SGPropertyNode * arg)
|
||||
{
|
||||
doSimulatorReset();
|
||||
fgReInitSubsystems();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1243,8 +1243,10 @@ do_log_level (const SGPropertyNode * arg)
|
|||
static bool
|
||||
do_replay (const SGPropertyNode * arg)
|
||||
{
|
||||
// freeze the master fdm
|
||||
// freeze the fdm, resume from sim pause
|
||||
fgSetInt( "/sim/freeze/replay-state", 1 );
|
||||
fgSetBool("/sim/freeze/master", 0 );
|
||||
fgSetBool("/sim/freeze/clock", 0 );
|
||||
|
||||
FGReplay *r = (FGReplay *)(globals->get_subsystem( "replay" ));
|
||||
|
||||
|
|
|
@ -1517,7 +1517,7 @@ bool fgInitSubsystems() {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Reset: this is what the 'reset' command (and hence, GUI) is attached to
|
||||
void fgReInitSubsystems()
|
||||
{
|
||||
static const SGPropertyNode *master_freeze
|
||||
|
@ -1553,11 +1553,17 @@ void fgReInitSubsystems()
|
|||
// Initialize the FDM
|
||||
globals->get_subsystem("flight")->reinit();
|
||||
|
||||
// reset replay buffers
|
||||
globals->get_subsystem("replay")->reinit();
|
||||
|
||||
// reload offsets from config defaults
|
||||
globals->get_viewmgr()->reinit();
|
||||
|
||||
globals->get_subsystem("time")->reinit();
|
||||
|
||||
// need to bind FDMshell again, since we manually unbound it above...
|
||||
globals->get_subsystem("flight")->bind();
|
||||
|
||||
// setup state to end re-init
|
||||
fgSetBool("/sim/signals/reinit", false);
|
||||
if ( !freeze ) {
|
||||
|
@ -1567,13 +1573,6 @@ void fgReInitSubsystems()
|
|||
}
|
||||
|
||||
|
||||
void doSimulatorReset(void) // from gui_local.cxx -- TODO merge with fgReInitSubsystems()
|
||||
{
|
||||
|
||||
|
||||
fgReInitSubsystems();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// helper object to implement the --show-aircraft command.
|
||||
// resides here so we can share the fgFindAircraftInDir template above,
|
||||
|
|
|
@ -62,16 +62,10 @@ bool fgInitGeneral ();
|
|||
// gear, its initialization call should located in this routine.
|
||||
bool fgInitSubsystems();
|
||||
|
||||
|
||||
// Reset
|
||||
|
||||
// Reset: this is what the 'reset' command (and hence, GUI) is attached to
|
||||
void fgReInitSubsystems();
|
||||
|
||||
/**
|
||||
* this is what the 'reset' command (and hence, GUI) is attached too
|
||||
* it overlaps with fgReInitSubsystems quite substantially
|
||||
*/
|
||||
void doSimulatorReset(void);
|
||||
|
||||
// Set the initial position based on presets (or defaults)
|
||||
bool fgInitPosition();
|
||||
|
||||
|
|
|
@ -204,7 +204,7 @@ fgviewerMain(int argc, char** argv)
|
|||
}
|
||||
|
||||
globals->set_matlib( new SGMaterialLib );
|
||||
simgear::SGModelLib::init(globals->get_fg_root());
|
||||
simgear::SGModelLib::init(globals->get_fg_root(), globals->get_props());
|
||||
|
||||
// Initialize the material property subsystem.
|
||||
|
||||
|
|
|
@ -121,6 +121,15 @@ static void fgMainLoop( void ) {
|
|||
static SGPropertyNode_ptr frame_signal
|
||||
= fgGetNode("/sim/signals/frame", true);
|
||||
|
||||
static SGPropertyNode_ptr _statisticsFlag
|
||||
= fgGetNode("/sim/timing-statistics/enabled", true);
|
||||
static SGPropertyNode_ptr _statisticsInterval
|
||||
= fgGetNode("/sim/timing-statistics/interval-s", true);
|
||||
static SGPropertyNode_ptr _statiticsMinJitter
|
||||
= fgGetNode("/sim/timing-statistics/min-jitter-ms", true);
|
||||
static SGPropertyNode_ptr _statiticsMinTime
|
||||
= fgGetNode("/sim/timing-statistics/min-time-ms", true);
|
||||
|
||||
frame_signal->fireValueChanged();
|
||||
SGCloudLayer::enable_bump_mapping = fgGetBool("/sim/rendering/bump-mapping");
|
||||
|
||||
|
@ -206,6 +215,28 @@ static void fgMainLoop( void ) {
|
|||
simgear::sleepForMSec(500);
|
||||
}
|
||||
}
|
||||
|
||||
// print timing statistics
|
||||
static bool _lastStatisticsFlag = false;
|
||||
if (_lastStatisticsFlag != _statisticsFlag->getBoolValue())
|
||||
{
|
||||
// flag has changed, update subsystem manager
|
||||
_lastStatisticsFlag = _statisticsFlag->getBoolValue();
|
||||
globals->get_subsystem_mgr()->collectDebugTiming(_lastStatisticsFlag);
|
||||
}
|
||||
if (_lastStatisticsFlag)
|
||||
{
|
||||
static double elapsed = 0;
|
||||
elapsed += real_dt;
|
||||
if (elapsed >= _statisticsInterval->getDoubleValue())
|
||||
{
|
||||
// print and reset timing statistics
|
||||
globals->get_subsystem_mgr()->printTimingStatistics(_statiticsMinTime->getDoubleValue(),
|
||||
_statiticsMinJitter->getDoubleValue());
|
||||
elapsed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
simgear::AtomicChangeListener::fireChangeListeners();
|
||||
|
||||
SG_LOG( SG_ALL, SG_DEBUG, "" );
|
||||
|
@ -359,8 +390,7 @@ static void fgIdleFunction ( void ) {
|
|||
// Initialize the material manager
|
||||
////////////////////////////////////////////////////////////////////
|
||||
globals->set_matlib( new SGMaterialLib );
|
||||
simgear::SGModelLib::init(globals->get_fg_root());
|
||||
simgear::SGModelLib::setPropRoot(globals->get_props());
|
||||
simgear::SGModelLib::init(globals->get_fg_root(), globals->get_props());
|
||||
simgear::SGModelLib::setPanelFunc(load_panel);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// model.cxx - manage a 3D aircraft model.
|
||||
// acmodel.cxx - manage a 3D aircraft model.
|
||||
// Written by David Megginson, started 2002.
|
||||
//
|
||||
// This file is in the Public Domain, and comes with no warranty.
|
||||
|
@ -84,6 +84,7 @@ void
|
|||
FGAircraftModel::reinit()
|
||||
{
|
||||
deinit();
|
||||
_fx->reinit();
|
||||
init();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// model.hxx - manage a 3D aircraft model.
|
||||
// acmodel.hxx - manage a 3D aircraft model.
|
||||
// Written by David Megginson, started 2002.
|
||||
//
|
||||
// This file is in the Public Domain, and comes with no warranty.
|
||||
|
|
|
@ -541,9 +541,9 @@ FGGeneric::reinit()
|
|||
SGPropertyNode root;
|
||||
try {
|
||||
readProperties(path.str(), &root);
|
||||
} catch (const sg_exception &) {
|
||||
} catch (const sg_exception & ex) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"Unable to load the protocol configuration file");
|
||||
"Unable to load the protocol configuration file: " << ex.getFormattedMessage() );
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,31 @@
|
|||
|
||||
static FGNasalSys* nasalSys = 0;
|
||||
|
||||
// Listener class for loading Nasal modules on demand
|
||||
class FGNasalModuleListener : public SGPropertyChangeListener
|
||||
{
|
||||
public:
|
||||
FGNasalModuleListener(SGPropertyNode* node);
|
||||
|
||||
virtual void valueChanged(SGPropertyNode* node);
|
||||
|
||||
private:
|
||||
SGPropertyNode_ptr _node;
|
||||
};
|
||||
|
||||
FGNasalModuleListener::FGNasalModuleListener(SGPropertyNode* node) : _node(node)
|
||||
{
|
||||
}
|
||||
|
||||
void FGNasalModuleListener::valueChanged(SGPropertyNode*)
|
||||
{
|
||||
if (_node->getBoolValue("enabled",false)&&
|
||||
!_node->getBoolValue("loaded",true))
|
||||
{
|
||||
nasalSys->loadPropertyScripts(_node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Read and return file contents in a single buffer. Note use of
|
||||
// stat() to get the file size. This is a win32 function, believe it
|
||||
|
@ -737,12 +762,15 @@ void FGNasalSys::init()
|
|||
|
||||
// Now load the various source files in the Nasal directory
|
||||
simgear::Dir nasalDir(SGPath(globals->get_fg_root(), "Nasal"));
|
||||
simgear::PathList scripts = nasalDir.children(simgear::Dir::TYPE_FILE, ".nas");
|
||||
|
||||
for (unsigned int i=0; i<scripts.size(); ++i) {
|
||||
SGPath fullpath(scripts[i]);
|
||||
SGPath file = fullpath.file();
|
||||
loadModule(fullpath, file.base().c_str());
|
||||
loadScriptDirectory(nasalDir);
|
||||
|
||||
// Add modules in Nasal subdirectories to property tree
|
||||
simgear::PathList directories = nasalDir.children(simgear::Dir::TYPE_DIR+
|
||||
simgear::Dir::NO_DOT_OR_DOTDOT, "");
|
||||
for (unsigned int i=0; i<directories.size(); ++i) {
|
||||
simgear::Dir dir(directories[i]);
|
||||
simgear::PathList scripts = dir.children(simgear::Dir::TYPE_FILE, ".nas");
|
||||
addModule(directories[i].file(), scripts);
|
||||
}
|
||||
|
||||
// set signal and remove node to avoid restoring at reinit
|
||||
|
@ -777,29 +805,75 @@ void FGNasalSys::update(double)
|
|||
_context = naNewContext();
|
||||
}
|
||||
|
||||
// Loads all scripts in given directory
|
||||
void FGNasalSys::loadScriptDirectory(simgear::Dir nasalDir)
|
||||
{
|
||||
simgear::PathList scripts = nasalDir.children(simgear::Dir::TYPE_FILE, ".nas");
|
||||
for (unsigned int i=0; i<scripts.size(); ++i) {
|
||||
SGPath fullpath(scripts[i]);
|
||||
SGPath file = fullpath.file();
|
||||
loadModule(fullpath, file.base().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Create module with list of scripts
|
||||
void FGNasalSys::addModule(string moduleName, simgear::PathList scripts)
|
||||
{
|
||||
if (scripts.size()>0)
|
||||
{
|
||||
SGPropertyNode* nasal = globals->get_props()->getNode("nasal");
|
||||
SGPropertyNode* module_node = nasal->getChild(moduleName,0,true);
|
||||
for (unsigned int i=0; i<scripts.size(); ++i) {
|
||||
SGPropertyNode* pFileNode = module_node->getChild("file",i,true);
|
||||
pFileNode->setStringValue(scripts[i].c_str());
|
||||
}
|
||||
if (!module_node->hasChild("enabled",0))
|
||||
{
|
||||
SGPropertyNode* node = module_node->getChild("enabled",0,true);
|
||||
node->setBoolValue(true);
|
||||
node->setAttribute(SGPropertyNode::USERARCHIVE,true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loads the scripts found under /nasal in the global tree
|
||||
void FGNasalSys::loadPropertyScripts()
|
||||
{
|
||||
SGPropertyNode* nasal = globals->get_props()->getNode("nasal");
|
||||
if(!nasal) return;
|
||||
|
||||
for(int i=0; i<nasal->nChildren(); i++) {
|
||||
for(int i=0; i<nasal->nChildren(); i++)
|
||||
{
|
||||
SGPropertyNode* n = nasal->getChild(i);
|
||||
loadPropertyScripts(n);
|
||||
}
|
||||
}
|
||||
|
||||
const char* module = n->getName();
|
||||
if(n->hasChild("module"))
|
||||
module = n->getStringValue("module");
|
||||
// Loads the scripts found under /nasal in the global tree
|
||||
void FGNasalSys::loadPropertyScripts(SGPropertyNode* n)
|
||||
{
|
||||
bool is_loaded = false;
|
||||
|
||||
const char* module = n->getName();
|
||||
if(n->hasChild("module"))
|
||||
module = n->getStringValue("module");
|
||||
if (n->getBoolValue("enabled",true))
|
||||
{
|
||||
// allow multiple files to be specified within a single
|
||||
// Nasal module tag
|
||||
int j = 0;
|
||||
SGPropertyNode *fn;
|
||||
bool file_specified = false;
|
||||
bool ok=true;
|
||||
while((fn = n->getChild("file", j)) != NULL) {
|
||||
file_specified = true;
|
||||
const char* file = fn->getStringValue();
|
||||
SGPath p = globals->resolve_maybe_aircraft_path(file);
|
||||
loadModule(p, module);
|
||||
SGPath p(file);
|
||||
if (!p.isAbsolute() || !p.exists())
|
||||
{
|
||||
p = globals->resolve_maybe_aircraft_path(file);
|
||||
}
|
||||
ok &= loadModule(p, module);
|
||||
j++;
|
||||
}
|
||||
|
||||
|
@ -809,10 +883,30 @@ void FGNasalSys::loadPropertyScripts()
|
|||
createModule(module, n->getPath().c_str(), src, strlen(src));
|
||||
|
||||
if(!file_specified && !src)
|
||||
{
|
||||
// module no longer exists - clear the archived "enable" flag
|
||||
n->setAttribute(SGPropertyNode::USERARCHIVE,false);
|
||||
SGPropertyNode* node = n->getChild("enabled",0,false);
|
||||
if (node)
|
||||
node->setAttribute(SGPropertyNode::USERARCHIVE,false);
|
||||
|
||||
SG_LOG(SG_NASAL, SG_ALERT, "Nasal error: " <<
|
||||
"no <file> or <script> defined in " <<
|
||||
"/nasal/" << module);
|
||||
"no <file> or <script> defined in " <<
|
||||
"/nasal/" << module);
|
||||
}
|
||||
else
|
||||
is_loaded = ok;
|
||||
}
|
||||
else
|
||||
{
|
||||
SGPropertyNode* enable = n->getChild("enabled");
|
||||
if (enable)
|
||||
{
|
||||
FGNasalModuleListener* listener = new FGNasalModuleListener(n);
|
||||
enable->addChangeListener(listener, false);
|
||||
}
|
||||
}
|
||||
n->setBoolValue("loaded",is_loaded);
|
||||
}
|
||||
|
||||
// Logs a runtime error, with stack trace, to the FlightGear log stream
|
||||
|
@ -832,7 +926,7 @@ void FGNasalSys::logError(naContext context)
|
|||
// Reads a script file, executes it, and places the resulting
|
||||
// namespace into the global namespace under the specified module
|
||||
// name.
|
||||
void FGNasalSys::loadModule(SGPath file, const char* module)
|
||||
bool FGNasalSys::loadModule(SGPath file, const char* module)
|
||||
{
|
||||
int len = 0;
|
||||
char* buf = readfile(file.c_str(), &len);
|
||||
|
@ -840,25 +934,26 @@ void FGNasalSys::loadModule(SGPath file, const char* module)
|
|||
SG_LOG(SG_NASAL, SG_ALERT,
|
||||
"Nasal error: could not read script file " << file.c_str()
|
||||
<< " into module " << module);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
createModule(module, file.c_str(), buf, len);
|
||||
bool ok = createModule(module, file.c_str(), buf, len);
|
||||
delete[] buf;
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Parse and run. Save the local variables namespace, as it will
|
||||
// become a sub-object of globals. The optional "arg" argument can be
|
||||
// used to pass an associated property node to the module, which can then
|
||||
// be accessed via cmdarg(). (This is, for example, used by XML dialogs.)
|
||||
void FGNasalSys::createModule(const char* moduleName, const char* fileName,
|
||||
bool FGNasalSys::createModule(const char* moduleName, const char* fileName,
|
||||
const char* src, int len,
|
||||
const SGPropertyNode* cmdarg,
|
||||
int argc, naRef* args)
|
||||
{
|
||||
naRef code = parse(fileName, src, len);
|
||||
if(naIsNil(code))
|
||||
return;
|
||||
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
|
||||
|
@ -873,6 +968,7 @@ void FGNasalSys::createModule(const char* moduleName, const char* fileName,
|
|||
|
||||
call(code, argc, args, locals);
|
||||
hashset(_globals, moduleName, locals);
|
||||
return true;
|
||||
}
|
||||
|
||||
void FGNasalSys::deleteModule(const char* moduleName)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/structure/subsystem_mgr.hxx>
|
||||
#include <simgear/misc/sg_dir.hxx>
|
||||
#include <simgear/nasal/nasal.h>
|
||||
#include <simgear/scene/model/modellib.hxx>
|
||||
#include <simgear/xml/easyxml.hxx>
|
||||
|
@ -24,7 +25,7 @@ public:
|
|||
|
||||
// Loads a nasal script from an external file and inserts it as a
|
||||
// global module of the specified name.
|
||||
void loadModule(SGPath file, const char* moduleName);
|
||||
bool loadModule(SGPath file, const char* moduleName);
|
||||
|
||||
// Simple hook to run arbitrary source code. Returns a bool to
|
||||
// indicate successful execution. Does *not* return any Nasal
|
||||
|
@ -53,7 +54,7 @@ public:
|
|||
// Callbacks for command and timer bindings
|
||||
virtual bool handleCommand(const SGPropertyNode* arg);
|
||||
|
||||
void createModule(const char* moduleName, const char* fileName,
|
||||
bool createModule(const char* moduleName, const char* fileName,
|
||||
const char* src, int len, const SGPropertyNode* cmdarg=0,
|
||||
int argc=0, naRef*args=0);
|
||||
|
||||
|
@ -65,6 +66,7 @@ public:
|
|||
private:
|
||||
friend class FGNasalScript;
|
||||
friend class FGNasalListener;
|
||||
friend class FGNasalModuleListener;
|
||||
|
||||
//
|
||||
// FGTimer subclass for handling Nasal timer callbacks.
|
||||
|
@ -85,6 +87,9 @@ private:
|
|||
static int _listenerId;
|
||||
|
||||
void loadPropertyScripts();
|
||||
void loadPropertyScripts(SGPropertyNode* n);
|
||||
void loadScriptDirectory(simgear::Dir nasalDir);
|
||||
void addModule(string moduleName, simgear::PathList scripts);
|
||||
void hashset(naRef hash, const char* key, naRef val);
|
||||
void logError(naContext);
|
||||
naRef parse(const char* filename, const char* buf, int len);
|
||||
|
|
|
@ -8,4 +8,4 @@ libSound_a_SOURCES = \
|
|||
sample_queue.cxx sample_queue.hxx \
|
||||
voiceplayer.cxx voiceplayer.hxx
|
||||
|
||||
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
|
||||
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_builddir) -I$(top_builddir)/src
|
||||
|
|
|
@ -109,6 +109,9 @@ FGFX::init()
|
|||
void
|
||||
FGFX::reinit()
|
||||
{
|
||||
for ( unsigned int i = 0; i < _sound.size(); i++ ) {
|
||||
delete _sound[i];
|
||||
}
|
||||
_sound.clear();
|
||||
init();
|
||||
};
|
||||
|
|
|
@ -42,12 +42,6 @@
|
|||
|
||||
using std::string;
|
||||
|
||||
#if defined( HAVE_VERSION_H ) && HAVE_VERSION_H
|
||||
# include <Include/version.h>
|
||||
#else
|
||||
# include <Include/no_version.h>
|
||||
#endif
|
||||
|
||||
#include "voiceplayer.hxx"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -135,6 +135,7 @@ public:
|
|||
public:
|
||||
bool silence;
|
||||
|
||||
virtual ~Element() {}
|
||||
virtual inline void play (float volume) {}
|
||||
virtual inline void stop () {}
|
||||
virtual bool is_playing () = 0;
|
||||
|
@ -186,7 +187,7 @@ public:
|
|||
inline Voice (FGVoicePlayer *_player)
|
||||
: element(NULL), player(_player), volume(1.0) {}
|
||||
|
||||
~Voice ();
|
||||
virtual ~Voice ();
|
||||
|
||||
inline void append (Element *_element) { elements.push_back(_element); }
|
||||
|
||||
|
@ -229,7 +230,7 @@ public:
|
|||
dev_name(_dev_name), dir_prefix(""),
|
||||
speaker(this,properties_handler) {}
|
||||
|
||||
~FGVoicePlayer ();
|
||||
virtual ~FGVoicePlayer ();
|
||||
|
||||
void init ();
|
||||
void pause();
|
||||
|
|
|
@ -88,9 +88,11 @@ void TimeManager::init()
|
|||
_warp->getIntValue());
|
||||
globals->set_time_params(_impl);
|
||||
|
||||
// frame/update-rate counters
|
||||
// frame-rate / worst-case latency / update-rate counters
|
||||
_frameRate = fgGetNode("/sim/frame-rate", true);
|
||||
_frameLatency = fgGetNode("/sim/frame-latency-max-ms", true);
|
||||
_lastFrameTime = 0;
|
||||
_frameLatencyMax = 0.0;
|
||||
_frameCount = 0;
|
||||
}
|
||||
|
||||
|
@ -160,7 +162,9 @@ void TimeManager::computeTimeDeltas(double& simDt, double& realDt)
|
|||
SGTimeStamp currentStamp;
|
||||
currentStamp.stamp();
|
||||
double dt = (currentStamp - _lastStamp).toSecs();
|
||||
|
||||
if (dt > _frameLatencyMax)
|
||||
_frameLatencyMax = dt;
|
||||
|
||||
// Limit the time we need to spend in simulation loops
|
||||
// That means, if the /sim/max-simtime-per-frame value is strictly positive
|
||||
// you can limit the maximum amount of time you will do simulations for
|
||||
|
@ -251,7 +255,9 @@ void TimeManager::computeFrameRate()
|
|||
// Calculate frame rate average
|
||||
if ((_impl->get_cur_time() != _lastFrameTime)) {
|
||||
_frameRate->setIntValue(_frameCount);
|
||||
_frameLatency->setDoubleValue(_frameLatencyMax*1000);
|
||||
_frameCount = 0;
|
||||
_frameLatencyMax = 0.0;
|
||||
}
|
||||
|
||||
_lastFrameTime = _impl->get_cur_time();
|
||||
|
|
|
@ -78,9 +78,11 @@ private:
|
|||
SGPropertyNode_ptr _longitudeDeg;
|
||||
SGPropertyNode_ptr _latitudeDeg;
|
||||
|
||||
// frame-rate / update-rate counters
|
||||
// frame-rate / worst-case latency / update-rate counters
|
||||
SGPropertyNode_ptr _frameRate;
|
||||
SGPropertyNode_ptr _frameLatency;
|
||||
time_t _lastFrameTime;
|
||||
double _frameLatencyMax;
|
||||
int _frameCount;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue