// Initialize the logger.
////////////////////////////////////////////////////////////////////
- globals->set_logger(new FGLogger);
- globals->get_logger()->init();
- globals->get_logger()->bind();
+ globals->get_subsystem_mgr()->add(FGSubsystemMgr::GENERAL,
+ "logger",
+ new FGLogger);
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Initialize the sound-effects subsystem.
////////////////////////////////////////////////////////////////////
- globals->set_fx(new FGFX);
- globals->get_fx()->init();
- globals->get_fx()->bind();
-#endif
+ globals->get_subsystem_mgr()->add(FGSubsystemMgr::GENERAL,
+ "fx",
+ new FGFX);
+
- ////////////////////////////////////////////////////////////////////
- // Initialize the aircraft systems.
- ////////////////////////////////////////////////////////////////////
- globals->get_systemmgr()->init();
- globals->get_systemmgr()->bind();
+#endif
- ////////////////////////////////////////////////////////////////////
- // Initialize the instrumentation.
- ////////////////////////////////////////////////////////////////////
- globals->get_instrumentmgr()->init();
- globals->get_instrumentmgr()->bind();
+ globals->get_subsystem_mgr()->add(FGSubsystemMgr::GENERAL,
+ "instrumentation",
+ new FGInstrumentMgr);
+ globals->get_subsystem_mgr()->add(FGSubsystemMgr::GENERAL,
+ "systems",
+ new FGSystemMgr);
////////////////////////////////////////////////////////////////////
// Initialize the radio stack subsystem.
current_input.bind();
+ ////////////////////////////////////////////////////////////////////
+ // Bind and initialize subsystems.
+ ////////////////////////////////////////////////////////////////////
+
+ globals->get_subsystem_mgr()->bind();
+ globals->get_subsystem_mgr()->init();
+
+
////////////////////////////////////////////////////////////////////////
// End of subsystem initialization.
////////////////////////////////////////////////////////////////////
return _suspended || _freeze_master_node->getBoolValue();
}
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGSubsystemGroup.
+////////////////////////////////////////////////////////////////////////
+
+FGSubsystemGroup::FGSubsystemGroup ()
+{
+}
+
+FGSubsystemGroup::~FGSubsystemGroup ()
+{
+ for (int i = 0; i < _members.size(); i++)
+ delete _members[i];
+}
+
+void
+FGSubsystemGroup::init ()
+{
+ for (int i = 0; i < _members.size(); i++)
+ _members[i]->subsystem->init();
+}
+
+void
+FGSubsystemGroup::bind ()
+{
+ for (int i = 0; i < _members.size(); i++)
+ _members[i]->subsystem->bind();
+}
+
+void
+FGSubsystemGroup::unbind ()
+{
+ for (int i = 0; i < _members.size(); i++)
+ _members[i]->subsystem->unbind();
+}
+
+void
+FGSubsystemGroup::update (double delta_time_sec)
+{
+ if (!is_suspended()) {
+ for (int i = 0; i < _members.size(); i++)
+ _members[i]->update(delta_time_sec); // indirect call
+ }
+}
+
+void
+FGSubsystemGroup::set_subsystem (const string &name, FGSubsystem * subsystem,
+ double min_step_sec)
+{
+ Member * member = get_member(name, true);
+ if (member->subsystem != 0)
+ delete member->subsystem;
+ member->name = name;
+ member->subsystem = subsystem;
+ member->min_step_sec = min_step_sec;
+}
+
+FGSubsystem *
+FGSubsystemGroup::get_subsystem (const string &name)
+{
+ Member * member = get_member(name);
+ if (member != 0)
+ return member->subsystem;
+ else
+ return 0;
+}
+
+void
+FGSubsystemGroup::remove_subsystem (const string &name)
+{
+ for (int i = 0; i < _members.size(); i++) {
+ if (name == _members[i]->name) {
+ _members.erase(_members.begin() + i);
+ return;
+ }
+ }
+}
+
+bool
+FGSubsystemGroup::has_subsystem (const string &name) const
+{
+ return (((FGSubsystemGroup *)this)->get_member(name) != 0);
+}
+
+FGSubsystemGroup::Member *
+FGSubsystemGroup::get_member (const string &name, bool create)
+{
+ for (int i = 0; i < _members.size(); i++) {
+ if (_members[i]->name == name)
+ return _members[i];
+ }
+ if (create) {
+ Member * member = new Member;
+ _members.push_back(member);
+ return member;
+ } else {
+ return 0;
+ }
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGSubsystemGroup::Member
+////////////////////////////////////////////////////////////////////////
+
+
+FGSubsystemGroup::Member::Member ()
+ : name(""),
+ subsystem(0),
+ min_step_sec(0),
+ elapsed_sec(0)
+{
+}
+
+FGSubsystemGroup::Member::Member (const Member &)
+{
+ Member();
+}
+
+FGSubsystemGroup::Member::~Member ()
+{
+ // FIXME: causes a crash
+// delete subsystem;
+}
+
+void
+FGSubsystemGroup::Member::update (double delta_time_sec)
+{
+ elapsed_sec += delta_time_sec;
+ if (elapsed_sec >= min_step_sec) {
+ subsystem->update(delta_time_sec);
+ elapsed_sec -= min_step_sec;
+ }
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGSubsystemMgr.
+////////////////////////////////////////////////////////////////////////
+
+
+FGSubsystemMgr::FGSubsystemMgr ()
+{
+}
+
+FGSubsystemMgr::~FGSubsystemMgr ()
+{
+}
+
+void
+FGSubsystemMgr::init ()
+{
+ for (int i = 0; i < MAX_GROUPS; i++)
+ _groups[i].init();
+}
+
+void
+FGSubsystemMgr::bind ()
+{
+ for (int i = 0; i < MAX_GROUPS; i++)
+ _groups[i].bind();
+}
+
+void
+FGSubsystemMgr::unbind ()
+{
+ for (int i = 0; i < MAX_GROUPS; i++)
+ _groups[i].unbind();
+}
+
+void
+FGSubsystemMgr::update (double delta_time_sec)
+{
+ if (!is_suspended()) {
+ for (int i = 0; i < MAX_GROUPS; i++)
+ _groups[i].update(delta_time_sec);
+ }
+}
+
+void
+FGSubsystemMgr::add (GroupType group, const string &name,
+ FGSubsystem * subsystem, double min_time_sec)
+{
+ SG_LOG(SG_GENERAL, SG_INFO, "Adding subsystem " << name);
+ get_group(group)->set_subsystem(name, subsystem, min_time_sec);
+}
+
+FGSubsystemGroup *
+FGSubsystemMgr::get_group (GroupType group)
+{
+ return &(_groups[group]);
+}
+
// end of fgfs.cxx
# include <config.h>
#endif
-#ifdef SG_MATH_EXCEPTION_CLASH
-# include <math.h>
-#endif
+#include <simgear/compiler.h>
+
+// #ifdef SG_MATH_EXCEPTION_CLASH
+// # include <math.h>
+// #endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
# include <float.h>
#endif
+#include STL_STRING
+SG_USING_STD(string);
+
+#include <vector>
+SG_USING_STD(vector);
+
+#include <map>
+SG_USING_STD(map);
+
#include <simgear/misc/props.hxx>
};
+\f
+/**
+ * A group of FlightGear subsystems.
+ */
+class FGSubsystemGroup : public FGSubsystem
+{
+public:
+
+ FGSubsystemGroup ();
+ virtual ~FGSubsystemGroup ();
+
+ virtual void init ();
+ virtual void bind ();
+ virtual void unbind ();
+ virtual void update (double delta_time_sec);
+
+ virtual void set_subsystem (const string &name,
+ FGSubsystem * subsystem,
+ double min_step_sec = 0);
+ virtual FGSubsystem * get_subsystem (const string &name);
+ virtual void remove_subsystem (const string &name);
+ virtual bool has_subsystem (const string &name) const;
+
+private:
+
+ struct Member {
+
+ Member ();
+ Member (const Member &member);
+ virtual ~Member ();
+
+ virtual void update (double delta_time_sec);
+
+ string name;
+ FGSubsystem * subsystem;
+ double min_step_sec;
+ double elapsed_sec;
+ };
+
+ Member * get_member (const string &name, bool create = false);
+
+ vector<Member *> _members;
+};
+
+
+\f
+/**
+ * Manage subsystems for the application.
+ */
+class FGSubsystemMgr : public FGSubsystem
+{
+public:
+
+ enum GroupType {
+ INIT = 0,
+ GENERAL,
+ MAX_GROUPS
+ };
+
+ FGSubsystemMgr ();
+ virtual ~FGSubsystemMgr ();
+
+ virtual void init ();
+ virtual void bind ();
+ virtual void unbind ();
+ virtual void update (double delta_time_sec);
+
+ virtual void add (GroupType group, const string &name,
+ FGSubsystem * subsystem,
+ double min_time_sec = 0);
+
+ virtual FGSubsystemGroup * get_group (GroupType group);
+
+private:
+
+ FGSubsystemGroup _groups[MAX_GROUPS];
+
+};
+
+
+
#endif // __FGFS_HXX
// end of fgfs.hxx
#include <simgear/misc/commands.hxx>
#include <Environment/environment_mgr.hxx>
-#include <Instrumentation/instrument_mgr.hxx>
-#include <Systems/system_mgr.hxx>
#include "globals.hxx"
#include "viewmgr.hxx"
// Constructor
FGGlobals::FGGlobals() :
+ subsystem_mgr(new FGSubsystemMgr),
sim_time_sec(0.0),
#if defined(FX) && defined(XMESA)
fullscreen( true ),
#endif
warp( 0 ),
warp_delta( 0 ),
- logger(0),
- systemmgr(new FGSystemMgr),
- instrumentmgr(new FGInstrumentMgr),
props(new SGPropertyNode),
initial_state(0),
commands(new SGCommandMgr),
// Destructor
FGGlobals::~FGGlobals()
{
+ delete subsystem_mgr;
delete initial_state;
delete props;
delete commands;
class SGPropertyNode;
class SGCommandMgr;
-class FGLogger;
+class FGSubsystemMgr;
class FGEnvironmentMgr;
class FGEnvironment;
class FGControls;
class FGSteam;
class FGSoundMgr;
-class FGSystemMgr;
-class FGInstrumentMgr;
class FGAutopilot;
-class FGFX;
class FGViewMgr;
class FGViewer;
class FGATCMgr;
private:
+ FGSubsystemMgr * subsystem_mgr;
+
// Number of milliseconds elapsed since the start of the program.
double sim_time_sec;
// to make time progress faster than normal (or even run in reverse.)
long int warp_delta;
- // Logger
- FGLogger *logger;
-
// Time structure
SGTime *time_params;
// sound manager
FGSoundMgr *soundmgr;
- // sound-effects manager
- FGFX *fx;
-
- // aircraft system manager
- FGSystemMgr * systemmgr;
-
- // aircraft instrument manager
- FGInstrumentMgr * instrumentmgr;
-
// environment information
FGEnvironmentMgr * environment_mgr;
FGGlobals();
~FGGlobals();
+ inline FGSubsystemMgr * get_subsystem_mgr () const {
+ return subsystem_mgr;
+ }
+
inline double get_sim_time_sec () const { return sim_time_sec; }
inline void inc_sim_time_sec (double dt) { sim_time_sec += dt; }
inline void set_sim_time_sec (double t) { sim_time_sec = t; }
inline void set_warp_delta( long int d ) { warp_delta = d; }
inline void inc_warp_delta( long int d ) { warp_delta += d; }
- inline FGLogger * get_logger () { return logger; }
- inline void set_logger (FGLogger * l) { logger = l; }
-
inline SGTime *get_time_params() const { return time_params; }
inline void set_time_params( SGTime *t ) { time_params = t; }
inline FGSoundMgr *get_soundmgr() const { return soundmgr; }
inline void set_soundmgr( FGSoundMgr *sm ) { soundmgr = sm; }
- inline FGSystemMgr *get_systemmgr() const { return systemmgr; }
-
- inline FGInstrumentMgr *get_instrumentmgr() const { return instrumentmgr; }
-
- inline FGFX *get_fx() const { return fx; }
- inline void set_fx( FGFX *x ) { fx = x; }
-
inline FGControls *get_controls() const { return controls; }
inline void set_controls( FGControls *c ) { controls = c; }
glEnable( GL_DEPTH_TEST );
glEnable( GL_FOG );
- globals->get_logger()->update(delta_time_sec);
+// globals->get_logger()->update(delta_time_sec);
}
glutSwapBuffers();
#ifdef ENABLE_AUDIO_SUPPORT
if ( fgGetBool("/sim/sound/audible")
&& globals->get_soundmgr()->is_working() ) {
- globals->get_fx()->update( delta_time_sec );
+// globals->get_fx()->update( delta_time_sec );
globals->get_soundmgr()->update( delta_time_sec );
}
#endif
- globals->get_systemmgr()->update( delta_time_sec );
- globals->get_instrumentmgr()->update( delta_time_sec );
+// globals->get_systemmgr()->update( delta_time_sec );
+// globals->get_instrumentmgr()->update( delta_time_sec );
+ globals->get_subsystem_mgr()->update(delta_time_sec);
//
// Tile Manager updates - see if we need to load any new scenery tiles.