]> git.mxchange.org Git - simgear.git/blobdiff - simgear/structure/subsystem_mgr.cxx
two warning fixes
[simgear.git] / simgear / structure / subsystem_mgr.cxx
index ee9c15d1750dab1ab90d5e02b1612f1a4712fa1d..9488faea51a06c1b2c58d624adc4f11f6a5c60c7 100644 (file)
@@ -8,7 +8,7 @@
 #include <simgear/math/SGMath.hxx>
 
 
-\f
+const int SG_MAX_SUBSYSTEM_EXCEPTIONS = 4;\f
 ////////////////////////////////////////////////////////////////////////
 // Implementation of SGSubsystem
 ////////////////////////////////////////////////////////////////////////
@@ -104,7 +104,9 @@ void SGSubsystem::stamp(const string& name)
 // Implementation of SGSubsystemGroup.
 ////////////////////////////////////////////////////////////////////////
 
-SGSubsystemGroup::SGSubsystemGroup ()
+SGSubsystemGroup::SGSubsystemGroup () :
+  _fixedUpdateTime(-1.0),
+  _updateTimeRemainder(0.0)
 {
 }
 
@@ -157,18 +159,31 @@ SGSubsystemGroup::unbind ()
 void
 SGSubsystemGroup::update (double delta_time_sec)
 {
-    for (unsigned int i = 0; i < _members.size(); i++)
-    {
-         SGTimeStamp timeStamp = SGTimeStamp::now();
-         _members[i]->update(delta_time_sec); // indirect call
-         timeStamp = timeStamp - SGTimeStamp::now();
-         double b = timeStamp.toUSecs();
-         _members[i]->updateExecutionTime(b);
-         double threshold = _members[i]->getTimeWarningThreshold();
-         if (( b > threshold ) && (b > 10000)) {
-             _members[i]->printTimingInformation(b);
-         }
+    int loopCount = 1;
+    // if dt == 0.0, we are paused, so we need to run one iteration
+    // of our members; if we have a fixed update time, we compute a
+    // loop count, and locally adjust dt
+    if ((delta_time_sec > 0.0) && (_fixedUpdateTime > 0.0)) {
+      double localDelta = delta_time_sec + _updateTimeRemainder;
+      loopCount = SGMiscd::roundToInt(localDelta / _fixedUpdateTime);
+      _updateTimeRemainder = delta_time_sec - (loopCount * _fixedUpdateTime);
+      delta_time_sec = _fixedUpdateTime;
     }
+
+    while (loopCount-- > 0) {
+      for (unsigned int i = 0; i < _members.size(); i++)
+      {
+           SGTimeStamp timeStamp = SGTimeStamp::now();
+           _members[i]->update(delta_time_sec); // indirect call
+           timeStamp = timeStamp - SGTimeStamp::now();
+           double b = timeStamp.toUSecs();
+           _members[i]->updateExecutionTime(b);
+           double threshold = _members[i]->getTimeWarningThreshold();
+           if (( b > threshold ) && (b > 10000)) {
+               _members[i]->printTimingInformation(b);
+           }
+      }
+    } // of multiple update loop
 }
 
 void 
@@ -233,6 +248,12 @@ SGSubsystemGroup::remove_subsystem (const string &name)
     }
 }
 
+void
+SGSubsystemGroup::set_fixed_update_time(double dt)
+{
+  _fixedUpdateTime = dt;
+}
+
 void
 SGSubsystemGroup::Member::printTimingStatistics ()
 {
@@ -287,7 +308,8 @@ SGSubsystemGroup::Member::Member ()
       subsystem(0),
       min_step_sec(0),
       elapsed_sec(0),
-      collectTimeStats(false)
+      collectTimeStats(false),
+      exceptionCount(0)
 {
 }
 
@@ -305,11 +327,26 @@ void
 SGSubsystemGroup::Member::update (double delta_time_sec)
 {
     elapsed_sec += delta_time_sec;
-    if (elapsed_sec >= min_step_sec) {
-        if (!subsystem->is_suspended()) {
-            subsystem->update(elapsed_sec);
-            elapsed_sec = 0;
-        }
+    if (elapsed_sec < min_step_sec) {
+        return;
+    }
+    
+    if (subsystem->is_suspended()) {
+        return;
+    }
+    
+    try {
+      subsystem->update(elapsed_sec);
+      elapsed_sec = 0;
+    } catch (sg_exception& e) {
+      SG_LOG(SG_GENERAL, SG_ALERT, "caught exception processing subsystem:" << name
+        << "\nmessage:" << e.getMessage());
+      
+      if (++exceptionCount > SG_MAX_SUBSYSTEM_EXCEPTIONS) {
+        SG_LOG(SG_GENERAL, SG_ALERT, "(exceptionCount=" << exceptionCount <<
+          ", suspending)");
+        subsystem->suspend();
+      }
     }
 }