]> git.mxchange.org Git - flightgear.git/commitdiff
replay/FDM shell subsystem refactoring
authorThorstenB <brehmt@gmail.com>
Mon, 21 Mar 2011 22:07:05 +0000 (23:07 +0100)
committerThorstenB <brehmt@gmail.com>
Mon, 21 Mar 2011 22:07:05 +0000 (23:07 +0100)
Move final bits of replay code to where it belongs.
Use subsystem suspend/resume for FDM shell during instant replay.

src/Aircraft/replay.cxx
src/Aircraft/replay.hxx
src/FDM/fdm_shell.cxx
src/FDM/fdm_shell.hxx

index 6c5c410d82793c44043ab27a4ff0268d743fe6ff..9ecc353d8f6b54b8d38c2a6126b369226fb72048 100644 (file)
 #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");
index bad1ce8b1d18980102ac01e68256dad2b67ecf80..3ad3aed0c69bdf3c69e72317c50fb2bf394cd8ba 100644 (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;
 };
 
 
index 7d936e3d15ca77b66487c4e9fef7e21722eac158..401483e4b5ce26b26f881af1e77b30bc8bd7e391 100644 (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;
+}
index 759be1c9e79d1f2fd6d122ee8a6aef6da3f59ae5..04bbf1b722a1c409f3e8a5a25ae973d8304906f1 100644 (file)
@@ -50,7 +50,8 @@ public:
   virtual void unbind();
   
   virtual void update(double dt);
-  
+  SGSubsystem* getFDM();
+
 private:
 
   void createImplementation();