From d6e18c8a3522785f0068945bb0e4d517785df5e5 Mon Sep 17 00:00:00 2001 From: James Turner Date: Tue, 18 Sep 2012 20:26:28 +0100 Subject: [PATCH] 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. --- simgear/structure/subsystem_mgr.cxx | 56 +++++++++++++++++++++++++++-- simgear/structure/subsystem_mgr.hxx | 17 +++++++-- 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/simgear/structure/subsystem_mgr.cxx b/simgear/structure/subsystem_mgr.cxx index 4df51a6e..8a3d6a70 100644 --- a/simgear/structure/subsystem_mgr.cxx +++ b/simgear/structure/subsystem_mgr.cxx @@ -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; } diff --git a/simgear/structure/subsystem_mgr.hxx b/simgear/structure/subsystem_mgr.hxx index a0e76809..18684919 100644 --- a/simgear/structure/subsystem_mgr.hxx +++ b/simgear/structure/subsystem_mgr.hxx @@ -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 SubsystemDict; SubsystemDict _subsystem_map; }; -- 2.39.5