Support for incremental init of subsystems.

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.
This commit is contained in:
James Turner
2012-09-18 20:26:28 +01:00
parent 4993a5c6c0
commit d6e18c8a35
2 changed files with 68 additions and 5 deletions

View 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;
}

View 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;
};