]> git.mxchange.org Git - simgear.git/blobdiff - simgear/structure/subsystem_mgr.cxx
Some Linux platforms need <cstdio> for snprintf.
[simgear.git] / simgear / structure / subsystem_mgr.cxx
index df2c0ef38349bcc60f124a6b9869ae3da07e9574..f9eb752b8742ba0f7af2e0334052964f61e01fd6 100644 (file)
@@ -33,6 +33,8 @@
 
 const int SG_MAX_SUBSYSTEM_EXCEPTIONS = 4;
 
+using std::string;
+
 ////////////////////////////////////////////////////////////////////////
 // Implementation of SGSubsystem
 ////////////////////////////////////////////////////////////////////////
@@ -54,6 +56,13 @@ SGSubsystem::init ()
 {
 }
 
+SGSubsystem::InitStatus
+SGSubsystem::incrementalInit ()
+{
+  init();
+  return INIT_DONE;
+}
+
 void
 SGSubsystem::postinit ()
 {
@@ -108,7 +117,6 @@ void SGSubsystem::stamp(const string& name)
     timingInfo.push_back(TimingInfo(name, SGTimeStamp::now()));
 }
 
-\f
 ////////////////////////////////////////////////////////////////////////
 // Implementation of SGSubsystemGroup.
 ////////////////////////////////////////////////////////////////////////
@@ -128,25 +136,27 @@ public:
 
     SampleStatistic timeStat;
     std::string name;
-    SGSubsystem * subsystem;
+    SGSharedPtr<SGSubsystem> subsystem;
     double min_step_sec;
     double elapsed_sec;
     bool collectTimeStats;
     int exceptionCount;
+    int initTime;
 };
 
 
 
 SGSubsystemGroup::SGSubsystemGroup () :
   _fixedUpdateTime(-1.0),
-  _updateTimeRemainder(0.0)
+  _updateTimeRemainder(0.0),
+  _initPosition(0)
 {
 }
 
 SGSubsystemGroup::~SGSubsystemGroup ()
 {
     // reverse order to prevent order dependency problems
-    for (unsigned int i = _members.size(); i > 0; i--)
+    for( size_t i = _members.size(); i > 0; i-- )
     {
         delete _members[i-1];
     }
@@ -155,21 +165,38 @@ SGSubsystemGroup::~SGSubsystemGroup ()
 void
 SGSubsystemGroup::init ()
 {
-    for (unsigned int i = 0; i < _members.size(); i++)
+    for( size_t i = 0; i < _members.size(); i++ )
         _members[i]->subsystem->init();
 }
 
+SGSubsystem::InitStatus
+SGSubsystemGroup::incrementalInit()
+{
+  if (_initPosition >= _members.size())
+    return INIT_DONE;
+  
+  SGTimeStamp st;
+  st.stamp();
+  InitStatus memberStatus = _members[_initPosition]->subsystem->incrementalInit();
+  _members[_initPosition]->initTime += st.elapsedMSec();
+  
+  if (memberStatus == INIT_DONE)
+    ++_initPosition;
+  
+  return INIT_CONTINUE;
+}
+
 void
 SGSubsystemGroup::postinit ()
 {
-    for (unsigned int i = 0; i < _members.size(); i++)
+    for( size_t i = 0; i < _members.size(); i++ )
         _members[i]->subsystem->postinit();
 }
 
 void
 SGSubsystemGroup::reinit ()
 {
-    for (unsigned int i = 0; i < _members.size(); i++)
+    for( size_t i = 0; i < _members.size(); i++ )
         _members[i]->subsystem->reinit();
 }
 
@@ -177,14 +204,15 @@ void
 SGSubsystemGroup::shutdown ()
 {
     // reverse order to prevent order dependency problems
-    for (unsigned int i = _members.size(); i > 0; i--)
+    for( size_t i = _members.size(); i > 0; i-- )
         _members[i-1]->subsystem->shutdown();
+  _initPosition = 0;
 }
 
 void
 SGSubsystemGroup::bind ()
 {
-    for (unsigned int i = 0; i < _members.size(); i++)
+    for( size_t i = 0; i < _members.size(); i++ )
         _members[i]->subsystem->bind();
 }
 
@@ -192,7 +220,7 @@ void
 SGSubsystemGroup::unbind ()
 {
     // reverse order to prevent order dependency problems
-    for (unsigned int i = _members.size(); i > 0; i--)
+    for( size_t i = _members.size(); i > 0; i-- )
        _members[i-1]->subsystem->unbind();
 }
 
@@ -213,7 +241,7 @@ SGSubsystemGroup::update (double delta_time_sec)
     bool recordTime = (reportTimingCb != NULL);
     SGTimeStamp timeStamp;
     while (loopCount-- > 0) {
-      for (unsigned int i = 0; i < _members.size(); i++)
+      for( size_t i = 0; i < _members.size(); i++ )
       {
           if (recordTime)
               timeStamp = SGTimeStamp::now();
@@ -232,7 +260,7 @@ SGSubsystemGroup::update (double delta_time_sec)
 void
 SGSubsystemGroup::reportTiming(void)
 {
-    for (unsigned int i = _members.size(); i > 0; i--)
+    for( size_t i = _members.size(); i > 0; i-- )
     {
         _members[i-1]->reportTiming();
     }
@@ -241,17 +269,27 @@ SGSubsystemGroup::reportTiming(void)
 void
 SGSubsystemGroup::suspend ()
 {
-    for (unsigned int i = 0; i < _members.size(); i++)
+    for( size_t i = 0; i < _members.size(); i++ )
         _members[i]->subsystem->suspend();
 }
 
 void
 SGSubsystemGroup::resume ()
 {
-    for (unsigned int i = 0; i < _members.size(); i++)
+    for( size_t i = 0; i < _members.size(); i++ )
         _members[i]->subsystem->resume();
 }
 
+string_list
+SGSubsystemGroup::member_names() const
+{
+       string_list result;
+       for( size_t i = 0; i < _members.size(); i++ )
+               result.push_back( _members[i]->name );
+       
+       return result;
+}
+
 bool
 SGSubsystemGroup::is_suspended () const
 {
@@ -283,12 +321,26 @@ SGSubsystemGroup::get_subsystem (const string &name)
 void
 SGSubsystemGroup::remove_subsystem (const string &name)
 {
-    for (unsigned int i = 0; i < _members.size(); i++) {
-        if (name == _members[i]->name) {
-            _members.erase(_members.begin() + i);
+    MemberVec::iterator it = _members.begin();
+    for (; it != _members.end(); ++it) {
+        if (name == (*it)->name) {
+            delete *it;
+            _members.erase(it);
             return;
         }
     }
+    
+    SG_LOG(SG_GENERAL, SG_WARN, "remove_subsystem: missing:" << name);
+}
+
+//------------------------------------------------------------------------------
+void SGSubsystemGroup::clearSubsystems()
+{
+  for( MemberVec::iterator it = _members.begin();
+                           it != _members.end();
+                         ++it )
+    delete *it;
+  _members.clear();
 }
 
 void
@@ -306,7 +358,7 @@ SGSubsystemGroup::has_subsystem (const string &name) const
 SGSubsystemGroup::Member *
 SGSubsystemGroup::get_member (const string &name, bool create)
 {
-    for (unsigned int i = 0; i < _members.size(); i++) {
+    for( size_t i = 0; i < _members.size(); i++ ) {
         if (_members[i]->name == name)
             return _members[i];
     }
@@ -320,7 +372,6 @@ SGSubsystemGroup::get_member (const string &name, bool create)
 }
 
 
-\f
 ////////////////////////////////////////////////////////////////////////
 // Implementation of SGSubsystemGroup::Member
 ////////////////////////////////////////////////////////////////////////
@@ -331,7 +382,8 @@ SGSubsystemGroup::Member::Member ()
       subsystem(0),
       min_step_sec(0),
       elapsed_sec(0),
-      exceptionCount(0)
+      exceptionCount(0),
+      initTime(0)
 {
 }
 
@@ -342,7 +394,6 @@ SGSubsystemGroup::Member::Member (const Member &)
 
 SGSubsystemGroup::Member::~Member ()
 {
-    delete subsystem;
 }
 
 void
@@ -378,7 +429,8 @@ SGSubsystemGroup::Member::update (double delta_time_sec)
 ////////////////////////////////////////////////////////////////////////
 
 
-SGSubsystemMgr::SGSubsystemMgr ()
+SGSubsystemMgr::SGSubsystemMgr () :
+  _initPosition(0)
 {
   for (int i = 0; i < MAX_GROUPS; i++) {
     _groups[i] = new SGSubsystemGroup;
@@ -403,6 +455,19 @@ SGSubsystemMgr::init ()
             _groups[i]->init();
 }
 
+SGSubsystem::InitStatus
+SGSubsystemMgr::incrementalInit()
+{
+  if (_initPosition >= MAX_GROUPS)
+    return INIT_DONE;
+  
+  InitStatus memberStatus = _groups[_initPosition]->incrementalInit();  
+  if (memberStatus == INIT_DONE)
+    ++_initPosition;
+  
+  return INIT_CONTINUE;
+}
+
 void
 SGSubsystemMgr::postinit ()
 {
@@ -423,6 +488,8 @@ SGSubsystemMgr::shutdown ()
     // reverse order to prevent order dependency problems
     for (int i = MAX_GROUPS-1; i >= 0; i--)
         _groups[i]->shutdown();
+  
+    _initPosition = 0;
 }
 
 
@@ -473,36 +540,33 @@ void
 SGSubsystemMgr::add (const char * name, SGSubsystem * subsystem,
                      GroupType group, double min_time_sec)
 {
-    SG_LOG(SG_GENERAL, SG_INFO, "Adding subsystem " << name);
+    SG_LOG(SG_GENERAL, SG_DEBUG, "Adding subsystem " << name);
     get_group(group)->set_subsystem(name, subsystem, min_time_sec);
 
     if (_subsystem_map.find(name) != _subsystem_map.end()) {
         SG_LOG(SG_GENERAL, SG_ALERT, "Adding duplicate subsystem " << name);
-        throw sg_exception("duplicate subsystem");
+        throw sg_exception("duplicate subsystem:" + std::string(name));
     }
     _subsystem_map[name] = subsystem;
 }
 
-SGSubsystem* 
+void
 SGSubsystemMgr::remove(const char* name)
 {
   SubsystemDict::iterator s =_subsystem_map.find(name);
   if (s == _subsystem_map.end()) {
-    return NULL;
+    return;
   }
   
-  SGSubsystem* sub = s->second;
   _subsystem_map.erase(s);
   
 // tedious part - we don't know which group the subsystem belongs too
   for (int i = 0; i < MAX_GROUPS; i++) {
-    if (_groups[i]->get_subsystem(name) == sub) {
+    if (_groups[i]->get_subsystem(name) != NULL) {
       _groups[i]->remove_subsystem(name);
       break;
     }
   } // of groups iteration
-  
-  return sub;
 }