1
0
Fork 0

replay/FDM shell subsystem refactoring

Move final bits of replay code to where it belongs.
Use subsystem suspend/resume for FDM shell during instant replay.
This commit is contained in:
ThorstenB 2011-03-21 23:07:05 +01:00
parent b6d70d2c71
commit 991beb0b5e
4 changed files with 112 additions and 71 deletions

View file

@ -25,12 +25,14 @@
#endif
#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 +48,9 @@ const double FGReplay::lt_dt = 5.0; // long term sample rate (sec)
* Constructor
*/
FGReplay::FGReplay() {
FGReplay::FGReplay() :
last_replay_state(0)
{
}
@ -54,35 +58,44 @@ 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()
{
reinit();
}
@ -90,33 +103,21 @@ void FGReplay::init() {
* Reset replay queues.
*/
void FGReplay::reinit() {
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);
}
}
@ -125,9 +126,11 @@ void FGReplay::reinit() {
* Bind to the property tree
*/
void FGReplay::bind() {
void FGReplay::bind()
{
disable_replay = fgGetNode( "/sim/replay/disable", true );
replay_master = fgGetNode( "/sim/freeze/replay-state", true );
replay_time = fgGetNode( "/sim/replay/time", true);
}
@ -135,7 +138,8 @@ void FGReplay::bind() {
* Unbind from the property tree
*/
void FGReplay::unbind() {
void FGReplay::unbind()
{
// nothing to unbind
}
@ -144,22 +148,60 @@ void FGReplay::unbind() {
* Update the saved data
*/
void FGReplay::update( double dt ) {
void FGReplay::update( double dt )
{
timingInfo.clear();
stamp("begin");
if( disable_replay->getBoolValue() ) {
if ( sim_time != 0.0 ) {
// we were recording data
init();
}
return;
if (( sim_time != 0.0 )&&
( disable_replay->getBoolValue() ))
{
// we were recording data
reinit();
}
//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 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;
@ -180,12 +222,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");

View file

@ -79,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
@ -91,6 +92,7 @@ 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;
@ -98,6 +100,7 @@ private:
replay_list_type recycler;
SGPropertyNode_ptr disable_replay;
SGPropertyNode_ptr replay_master;
SGPropertyNode_ptr replay_time;
};

View file

@ -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;
}

View file

@ -50,7 +50,8 @@ public:
virtual void unbind();
virtual void update(double dt);
SGSubsystem* getFDM();
private:
void createImplementation();