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:
parent
b6d70d2c71
commit
991beb0b5e
4 changed files with 112 additions and 71 deletions
|
@ -25,12 +25,14 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <simgear/constants.h>
|
#include <simgear/constants.h>
|
||||||
|
#include <simgear/structure/exception.hxx>
|
||||||
|
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
#include <Network/native_ctrls.hxx>
|
#include <Network/native_ctrls.hxx>
|
||||||
#include <Network/native_fdm.hxx>
|
#include <Network/native_fdm.hxx>
|
||||||
#include <Network/net_ctrls.hxx>
|
#include <Network/net_ctrls.hxx>
|
||||||
#include <Network/net_fdm.hxx>
|
#include <Network/net_fdm.hxx>
|
||||||
|
#include <FDM/fdm_shell.hxx>
|
||||||
|
|
||||||
#include "replay.hxx"
|
#include "replay.hxx"
|
||||||
|
|
||||||
|
@ -46,7 +48,9 @@ const double FGReplay::lt_dt = 5.0; // long term sample rate (sec)
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
FGReplay::FGReplay() {
|
FGReplay::FGReplay() :
|
||||||
|
last_replay_state(0)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,35 +58,44 @@ FGReplay::FGReplay() {
|
||||||
* Destructor
|
* Destructor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
FGReplay::~FGReplay() {
|
FGReplay::~FGReplay()
|
||||||
while ( !short_term.empty() ) {
|
{
|
||||||
//cerr << "Deleting Short term" <<endl;
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all internal buffers.
|
||||||
|
*/
|
||||||
|
void FGReplay::clear()
|
||||||
|
{
|
||||||
|
while ( !short_term.empty() )
|
||||||
|
{
|
||||||
delete short_term.front();
|
delete short_term.front();
|
||||||
short_term.pop_front();
|
short_term.pop_front();
|
||||||
}
|
}
|
||||||
while ( !medium_term.empty() ) {
|
while ( !medium_term.empty() )
|
||||||
//cerr << "Deleting Medium term" <<endl;
|
{
|
||||||
delete medium_term.front();
|
delete medium_term.front();
|
||||||
medium_term.pop_front();
|
medium_term.pop_front();
|
||||||
}
|
}
|
||||||
while ( !long_term.empty() ) {
|
while ( !long_term.empty() )
|
||||||
//cerr << "Deleting Long term" <<endl;
|
{
|
||||||
delete long_term.front();
|
delete long_term.front();
|
||||||
long_term.pop_front();
|
long_term.pop_front();
|
||||||
}
|
}
|
||||||
while ( !recycler.empty() ) {
|
while ( !recycler.empty() )
|
||||||
//cerr << "Deleting Recycler" <<endl;
|
{
|
||||||
delete recycler.front();
|
delete recycler.front();
|
||||||
recycler.pop_front();
|
recycler.pop_front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the data structures
|
* Initialize the data structures
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void FGReplay::init() {
|
void FGReplay::init()
|
||||||
|
{
|
||||||
reinit();
|
reinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,33 +103,21 @@ void FGReplay::init() {
|
||||||
* Reset replay queues.
|
* Reset replay queues.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void FGReplay::reinit() {
|
void FGReplay::reinit()
|
||||||
|
{
|
||||||
sim_time = 0.0;
|
sim_time = 0.0;
|
||||||
last_mt_time = 0.0;
|
last_mt_time = 0.0;
|
||||||
last_lt_time = 0.0;
|
last_lt_time = 0.0;
|
||||||
|
|
||||||
// Make sure all queues are flushed
|
// Make sure all queues are flushed
|
||||||
while ( !short_term.empty() ) {
|
clear();
|
||||||
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();
|
|
||||||
}
|
|
||||||
// Create an estimated nr of required ReplayData objects
|
// Create an estimated nr of required ReplayData objects
|
||||||
// 120 is an estimated maximum frame rate.
|
// 120 is an estimated maximum frame rate.
|
||||||
int estNrObjects = (int) ((st_list_time*120) + (mt_list_time*mt_dt) +
|
int estNrObjects = (int) ((st_list_time*120) + (mt_list_time*mt_dt) +
|
||||||
(lt_list_time*lt_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);
|
recycler.push_back(new FGReplayData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,9 +126,11 @@ void FGReplay::reinit() {
|
||||||
* Bind to the property tree
|
* Bind to the property tree
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void FGReplay::bind() {
|
void FGReplay::bind()
|
||||||
|
{
|
||||||
disable_replay = fgGetNode( "/sim/replay/disable", true );
|
disable_replay = fgGetNode( "/sim/replay/disable", true );
|
||||||
replay_master = fgGetNode( "/sim/freeze/replay-state", 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
|
* Unbind from the property tree
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void FGReplay::unbind() {
|
void FGReplay::unbind()
|
||||||
|
{
|
||||||
// nothing to unbind
|
// nothing to unbind
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,22 +148,60 @@ void FGReplay::unbind() {
|
||||||
* Update the saved data
|
* Update the saved data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void FGReplay::update( double dt ) {
|
void FGReplay::update( double dt )
|
||||||
|
{
|
||||||
timingInfo.clear();
|
timingInfo.clear();
|
||||||
stamp("begin");
|
stamp("begin");
|
||||||
|
|
||||||
if( disable_replay->getBoolValue() ) {
|
if (( sim_time != 0.0 )&&
|
||||||
if ( sim_time != 0.0 ) {
|
( disable_replay->getBoolValue() ))
|
||||||
|
{
|
||||||
// we were recording data
|
// we were recording data
|
||||||
init();
|
reinit();
|
||||||
}
|
}
|
||||||
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();
|
||||||
}
|
}
|
||||||
//stamp("point_01");
|
else
|
||||||
if ( replay_master->getIntValue() > 0 ) {
|
if ((replay_state == 0)&&
|
||||||
// don't record the replay session
|
(last_replay_state > 0))
|
||||||
return;
|
{
|
||||||
|
// 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;
|
//cerr << "Recording replay" << endl;
|
||||||
sim_time += dt;
|
sim_time += dt;
|
||||||
|
|
||||||
|
@ -186,6 +228,7 @@ void FGReplay::update( double dt ) {
|
||||||
recycler.pop_front();
|
recycler.pop_front();
|
||||||
//stamp("point_04be");
|
//stamp("point_04be");
|
||||||
}
|
}
|
||||||
|
|
||||||
r->sim_time = sim_time;
|
r->sim_time = sim_time;
|
||||||
//r->ctrls = c;
|
//r->ctrls = c;
|
||||||
//stamp("point_04e");
|
//stamp("point_04e");
|
||||||
|
|
|
@ -79,6 +79,7 @@ public:
|
||||||
double get_end_time();
|
double get_end_time();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void clear();
|
||||||
|
|
||||||
static const double st_list_time; // 60 secs of high res data
|
static const double st_list_time; // 60 secs of high res data
|
||||||
static const double mt_list_time; // 10 mins of 1 fps data
|
static const double mt_list_time; // 10 mins of 1 fps data
|
||||||
|
@ -91,6 +92,7 @@ private:
|
||||||
double sim_time;
|
double sim_time;
|
||||||
double last_mt_time;
|
double last_mt_time;
|
||||||
double last_lt_time;
|
double last_lt_time;
|
||||||
|
int last_replay_state;
|
||||||
|
|
||||||
replay_list_type short_term;
|
replay_list_type short_term;
|
||||||
replay_list_type medium_term;
|
replay_list_type medium_term;
|
||||||
|
@ -98,6 +100,7 @@ private:
|
||||||
replay_list_type recycler;
|
replay_list_type recycler;
|
||||||
SGPropertyNode_ptr disable_replay;
|
SGPropertyNode_ptr disable_replay;
|
||||||
SGPropertyNode_ptr replay_master;
|
SGPropertyNode_ptr replay_master;
|
||||||
|
SGPropertyNode_ptr replay_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -160,24 +160,8 @@ void FDMShell::update(double dt)
|
||||||
_impl->ToggleDataLogging(doLog);
|
_impl->ToggleDataLogging(doLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME - replay manager should handle most of this
|
if (!_impl->is_suspended())
|
||||||
int replayState = fgGetInt("/sim/freeze/replay-state", 0);
|
_impl->update(dt);
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FDMShell::createImplementation()
|
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,6 +50,7 @@ public:
|
||||||
virtual void unbind();
|
virtual void unbind();
|
||||||
|
|
||||||
virtual void update(double dt);
|
virtual void update(double dt);
|
||||||
|
SGSubsystem* getFDM();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue