]> git.mxchange.org Git - simgear.git/commitdiff
Support for incremental init of subsystems.
authorJames Turner <zakalawe@mac.com>
Tue, 18 Sep 2012 19:26:28 +0000 (20:26 +0100)
committerJames Turner <zakalawe@mac.com>
Tue, 18 Sep 2012 19:26:28 +0000 (20:26 +0100)
Allow subsystem init to be incremental, i.e requiring repeated init calls until a 'done' code is returned. Use this to support incremental init in groups and the manager. (It would also be possible to support it in an individual subsystem).

Note that if you use the existing init() calls, behaviour is unchanged.

simgear/structure/subsystem_mgr.cxx
simgear/structure/subsystem_mgr.hxx

index 4df51a6eee0cf88201b10101e3392a40049c0f30..8a3d6a7081f315296e358889a85eb333695ffd7d 100644 (file)
@@ -56,6 +56,13 @@ SGSubsystem::init ()
 {
 }
 
+SGSubsystem::InitStatus
+SGSubsystem::incrementalInit ()
+{
+  init();
+  return INIT_DONE;
+}
+
 void
 SGSubsystem::postinit ()
 {
@@ -135,13 +142,15 @@ public:
     double elapsed_sec;
     bool collectTimeStats;
     int exceptionCount;
+    int initTime;
 };
 
 
 
 SGSubsystemGroup::SGSubsystemGroup () :
   _fixedUpdateTime(-1.0),
-  _updateTimeRemainder(0.0)
+  _updateTimeRemainder(0.0),
+  _initPosition(-1)
 {
 }
 
@@ -161,6 +170,26 @@ SGSubsystemGroup::init ()
         _members[i]->subsystem->init();
 }
 
+SGSubsystem::InitStatus
+SGSubsystemGroup::incrementalInit()
+{
+  if (_initPosition < 0)
+    _initPosition = 0;
+  
+  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 ()
 {
@@ -181,6 +210,7 @@ SGSubsystemGroup::shutdown ()
     // reverse order to prevent order dependency problems
     for (unsigned int i = _members.size(); i > 0; i--)
         _members[i-1]->subsystem->shutdown();
+  _initPosition = -1;
 }
 
 void
@@ -333,7 +363,8 @@ SGSubsystemGroup::Member::Member ()
       subsystem(0),
       min_step_sec(0),
       elapsed_sec(0),
-      exceptionCount(0)
+      exceptionCount(0),
+      initTime(0)
 {
 }
 
@@ -380,7 +411,8 @@ SGSubsystemGroup::Member::update (double delta_time_sec)
 ////////////////////////////////////////////////////////////////////////
 
 
-SGSubsystemMgr::SGSubsystemMgr ()
+SGSubsystemMgr::SGSubsystemMgr () :
+  _initPosition(-1)
 {
   for (int i = 0; i < MAX_GROUPS; i++) {
     _groups[i] = new SGSubsystemGroup;
@@ -405,6 +437,22 @@ SGSubsystemMgr::init ()
             _groups[i]->init();
 }
 
+SGSubsystem::InitStatus
+SGSubsystemMgr::incrementalInit()
+{
+  if (_initPosition < 0)
+    _initPosition = 0;
+  
+  if (_initPosition >= MAX_GROUPS)
+    return INIT_DONE;
+  
+  InitStatus memberStatus = _groups[_initPosition]->incrementalInit();  
+  if (memberStatus == INIT_DONE)
+    ++_initPosition;
+  
+  return INIT_CONTINUE;
+}
+
 void
 SGSubsystemMgr::postinit ()
 {
@@ -425,6 +473,8 @@ SGSubsystemMgr::shutdown ()
     // reverse order to prevent order dependency problems
     for (int i = MAX_GROUPS-1; i >= 0; i--)
         _groups[i]->shutdown();
+  
+    _initPosition = -1;
 }
 
 
index a0e76809c8a3522ddff53b49927248442ab21eff..186849192df1f9901cf71fe3170e568137fc0ee9 100644 (file)
@@ -150,6 +150,13 @@ public:
    */
   virtual void init ();
 
+  typedef enum
+  {
+    INIT_DONE,      ///< subsystem is fully initialised
+    INIT_CONTINUE   ///< init should be called again
+  } InitStatus;
+  
+  virtual InitStatus incrementalInit ();
 
   /**
    * Initialize parts that depend on other subsystems having been initialized.
@@ -289,7 +296,8 @@ public:
     SGSubsystemGroup ();
     virtual ~SGSubsystemGroup ();
 
-    virtual void init ();
+    virtual void init();
+    virtual InitStatus incrementalInit ();
     virtual void postinit ();
     virtual void reinit ();
     virtual void shutdown ();
@@ -322,6 +330,9 @@ private:
     
     double _fixedUpdateTime;
     double _updateTimeRemainder;
+    
+  /// index of the member we are currently init-ing
+    int _initPosition;
 };
 
 
@@ -364,6 +375,7 @@ public:
     virtual ~SGSubsystemMgr ();
 
     virtual void init ();
+    virtual InitStatus incrementalInit ();
     virtual void postinit ();
     virtual void reinit ();
     virtual void shutdown ();
@@ -394,7 +406,8 @@ public:
 
 private:
     SGSubsystemGroup* _groups[MAX_GROUPS];
-
+    int _initPosition;
+  
     typedef std::map<std::string, SGSubsystem*> SubsystemDict;
     SubsystemDict _subsystem_map;
 };