]> git.mxchange.org Git - simgear.git/commitdiff
Move FGEventMgr and FGSubsystemMgr over to SimGear, add SGEventMgr to FlightGear...
authorehofman <ehofman>
Wed, 24 Sep 2003 17:19:22 +0000 (17:19 +0000)
committerehofman <ehofman>
Wed, 24 Sep 2003 17:19:22 +0000 (17:19 +0000)
22 files changed:
configure.ac
simgear/Makefile.am
simgear/misc/Makefile.am
simgear/misc/commands.cxx [deleted file]
simgear/misc/commands.hxx [deleted file]
simgear/misc/exception.cxx [deleted file]
simgear/misc/exception.hxx [deleted file]
simgear/props/condition.cxx
simgear/scene/material/matlib.cxx
simgear/scene/model/model.cxx
simgear/structure/.cvsignore [new file with mode: 0644]
simgear/structure/Makefile.am [new file with mode: 0644]
simgear/structure/callback.hxx [new file with mode: 0644]
simgear/structure/commands.cxx [new file with mode: 0644]
simgear/structure/commands.hxx [new file with mode: 0644]
simgear/structure/event_mgr.cxx [new file with mode: 0644]
simgear/structure/event_mgr.hxx [new file with mode: 0644]
simgear/structure/exception.cxx [new file with mode: 0644]
simgear/structure/exception.hxx [new file with mode: 0644]
simgear/structure/subsystem_mgr.cxx [new file with mode: 0644]
simgear/structure/subsystem_mgr.hxx [new file with mode: 0644]
simgear/xml/easyxml.hxx

index d3f68ffd228f091a48de17f46cc4e710f1b43fc6..eac3f371c422ca04d5d69ed7c3544f3a96396eda 100644 (file)
@@ -367,6 +367,7 @@ AC_CONFIG_FILES([ \
        simgear/screen/Makefile \
        simgear/serial/Makefile \
        simgear/sound/Makefile \
+       simgear/structure/Makefile \
        simgear/threads/Makefile \
        simgear/timing/Makefile \
        simgear/xgl/Makefile \
index 9422b2eb8e8ddba6d0ed3eda14eb95b22e8f2039..24681e0dc071e08201b04cd6d7b2c5d68eb806a4 100644 (file)
@@ -30,6 +30,7 @@ SUBDIRS = \
        serial \
        sound \
        $(SGTHREAD_DIR) \
+       structure \
        timing \
        xgl
 
index 1d0ac77b32784a752e1bf64f1d091fc2d6d704a0..d8a4555f17b98d019f79ffee52b1ed7a7524d541 100644 (file)
@@ -3,8 +3,6 @@ includedir = @includedir@/misc
 lib_LIBRARIES = libsgmisc.a
 
 include_HEADERS = \
-       commands.hxx \
-       exception.hxx \
        sg_path.hxx \
        sgstream.hxx \
        stopwatch.hxx \
@@ -14,8 +12,6 @@ include_HEADERS = \
        zfstream.hxx
 
 libsgmisc_a_SOURCES = \
-       commands.cxx \
-       exception.cxx \
        sg_path.cxx \
        sgstream.cxx \
        strutils.cxx \
diff --git a/simgear/misc/commands.cxx b/simgear/misc/commands.cxx
deleted file mode 100644 (file)
index 2e2c592..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-// commands.cxx - encapsulated commands.
-// Started Spring 2001 by David Megginson, david@megginson.com
-// This code is released into the Public Domain.
-//
-// $Id$
-
-#include <simgear/props/props_io.hxx>
-
-#include "commands.hxx"
-
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Implementation of SGCommandMgr class.
-////////////////////////////////////////////////////////////////////////
-
-
-SGCommandMgr::SGCommandMgr ()
-{
-  // no-op
-}
-
-SGCommandMgr::~SGCommandMgr ()
-{
-  // no-op
-}
-
-void
-SGCommandMgr::addCommand (const string &name, command_t command)
-{
-  _commands[name] = command;
-}
-
-SGCommandMgr::command_t
-SGCommandMgr::getCommand (const string &name) const
-{
-  const command_map::const_iterator it = _commands.find(name);
-  return (it != _commands.end() ? it->second : 0);
-}
-
-vector<string>
-SGCommandMgr::getCommandNames () const
-{
-  vector<string> names;
-  command_map::const_iterator it = _commands.begin();
-  command_map::const_iterator last = _commands.end();
-  while (it != last) {
-    names.push_back(it->first);
-    it++;
-  }
-  return names;
-}
-
-bool
-SGCommandMgr::execute (const string &name, const SGPropertyNode * arg) const
-{
-  command_t command = getCommand(name);
-  if (command == 0)
-    return false;
-  else
-    return (*command)(arg);
-}
-
-// end of commands.cxx
diff --git a/simgear/misc/commands.hxx b/simgear/misc/commands.hxx
deleted file mode 100644 (file)
index 4ab28a0..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * \file commands.hxx
- * Interface definition for encapsulated commands.
- * Started Spring 2001 by David Megginson, david@megginson.com
- * This code is released into the Public Domain.
- *
- * $Id$
- */
-
-#ifndef __COMMANDS_HXX
-#define __COMMANDS_HXX
-
-
-#include <simgear/compiler.h>
-
-#include STL_STRING
-#include <map>
-#include <vector>
-
-#include <simgear/props/props.hxx>
-
-SG_USING_STD(string);
-SG_USING_STD(map);
-SG_USING_STD(vector);
-
-
-/**
- * Manage commands.
- *
- * <p>This class allows the application to register and unregister
- * commands, and provides shortcuts for executing them.  Commands are
- * simple functions that take a const pointer to an SGPropertyNode:
- * the function may use the nodes children as parameters.</p>
- *
- * @author David Megginson, david@megginson.com
- */
-class SGCommandMgr
-{
-public:
-
-  /**
-   * Type for a command function.
-   */
-  typedef bool (*command_t) (const SGPropertyNode * arg);
-
-
-  /**
-   * Default constructor.
-   */
-  SGCommandMgr ();
-
-
-  /**
-   * Destructor.
-   */
-  virtual ~SGCommandMgr ();
-
-
-  /**
-   * Register a new command with the manager.
-   *
-   * @param name The command name.  Any existing command with
-   * the same name will silently be overwritten.
-   * @param command A pointer to a one-arg function returning
-   * a bool result.  The argument is always a const pointer to
-   * an SGPropertyNode (which may contain multiple values).
-   */
-  virtual void addCommand (const string &name, command_t command);
-
-
-  /**
-   * Look up an existing command.
-   *
-   * @param name The command name.
-   * @return A pointer to the command, or 0 if there is no registered
-   * command with the name specified.
-   */
-  virtual command_t getCommand (const string &name) const;
-
-
-  /**
-   * Get a list of all existing command names.
-   *
-   * @return A (possibly empty) vector of the names of all registered
-   * commands.
-   */
-  virtual vector<string> getCommandNames () const;
-
-
-  /**
-   * Execute a command.
-   *
-   * @param name The name of the command.
-   * @param arg A const pointer to an SGPropertyNode.  The node
-   * may have a value and/or children, etc., so that it is possible
-   * to pass an arbitrarily complex data structure to a command.
-   * @return true if the command is present and executes successfully,
-   * false otherwise.
-   */
-  virtual bool execute (const string &name, const SGPropertyNode * arg) const;
-
-private:
-
-  typedef map<string,command_t> command_map;
-  command_map _commands;
-
-};
-
-#endif // __COMMANDS_HXX
-
-// end of commands.hxx
diff --git a/simgear/misc/exception.cxx b/simgear/misc/exception.cxx
deleted file mode 100644 (file)
index 75f4cf5..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-// exception.cxx - implementation of SimGear base exceptions.
-// Started Summer 2001 by David Megginson, david@megginson.com
-// This code is released into the Public Domain.
-//
-// $Id$
-
-
-#include "exception.hxx"
-#include <stdio.h>
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Implementation of sg_location class.
-////////////////////////////////////////////////////////////////////////
-
-sg_location::sg_location ()
-  : _path(""),
-    _line(-1),
-    _column(-1),
-    _byte(-1)
-{
-}
-
-sg_location::sg_location (const string &path, int line, int column)
-  : _path(path),
-    _line(line),
-    _column(column),
-    _byte(-1)
-{
-}
-
-sg_location::~sg_location ()
-{
-}
-
-const string &
-sg_location::getPath () const
-{
-  return _path;
-}
-
-void
-sg_location::setPath (const string &path)
-{
-  _path = path;
-}
-
-int
-sg_location::getLine () const
-{
-  return _line;
-}
-
-void
-sg_location::setLine (int line)
-{
-  _line = line;
-}
-
-int
-sg_location::getColumn () const
-{
-  return _column;
-}
-
-void
-sg_location::setColumn (int column)
-{
-  _column = column;
-}
-
-int
-sg_location::getByte () const
-{
-  return _byte;
-}
-
-void
-sg_location::setByte (int byte)
-{
-  _byte = byte;
-}
-
-string
-sg_location::asString () const
-{
-  char buf[128];
-  string out = "";
-  if (_path != (string)"") {
-    out += _path;
-    if (_line != -1 || _column != -1)
-      out += ",\n";
-  }
-  if (_line != -1) {
-    sprintf(buf, "line %d", _line);
-    out += buf;
-    if (_column != -1)
-      out += ", ";
-  }
-  if (_column != -1) {
-    sprintf(buf, "column %d", _column);
-    out += buf;
-  }
-  return out;
-    
-}
-
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Implementation of sg_throwable class.
-////////////////////////////////////////////////////////////////////////
-
-sg_throwable::sg_throwable ()
-  : _message(""),
-    _origin("")
-{
-}
-
-sg_throwable::sg_throwable (const string &message, const string &origin)
-  : _message(message),
-    _origin(origin)
-{
-}
-
-sg_throwable::~sg_throwable ()
-{
-}
-
-const string &
-sg_throwable::getMessage () const
-{
-  return _message;
-}
-
-const string
-sg_throwable::getFormattedMessage () const
-{
-  return getMessage();
-}
-
-void
-sg_throwable::setMessage (const string &message)
-{
-  _message = message;
-}
-
-const string &
-sg_throwable::getOrigin () const
-{
-  return _origin;
-}
-
-void
-sg_throwable::setOrigin (const string &origin)
-{
-  _origin = origin;
-}
-
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Implementation of sg_error class.
-////////////////////////////////////////////////////////////////////////
-
-sg_error::sg_error ()
-  : sg_throwable ()
-{
-}
-
-sg_error::sg_error (const string &message, const string &origin)
-  : sg_throwable(message, origin)
-{
-}
-
-sg_error::~sg_error ()
-{
-}
-
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Implementation of sg_exception class.
-////////////////////////////////////////////////////////////////////////
-
-sg_exception::sg_exception ()
-  : sg_throwable ()
-{
-}
-
-sg_exception::sg_exception (const string &message, const string &origin)
-  : sg_throwable(message, origin)
-{
-}
-
-sg_exception::~sg_exception ()
-{
-}
-
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Implementation of sg_io_exception.
-////////////////////////////////////////////////////////////////////////
-
-sg_io_exception::sg_io_exception ()
-  : sg_exception()
-{
-}
-
-sg_io_exception::sg_io_exception (const string &message, const string &origin)
-  : sg_exception(message, origin)
-{
-}
-
-sg_io_exception::sg_io_exception (const string &message,
-                                 const sg_location &location,
-                                 const string &origin)
-  : sg_exception(message, origin),
-    _location(location)
-{
-}
-
-sg_io_exception::~sg_io_exception ()
-{
-}
-
-const string
-sg_io_exception::getFormattedMessage () const
-{
-  string ret = getMessage();
-  ret += "\n at ";
-  ret += getLocation().asString();
-  return ret;
-}
-
-const sg_location &
-sg_io_exception::getLocation () const
-{
-  return _location;
-}
-
-void
-sg_io_exception::setLocation (const sg_location &location)
-{
-  _location = location;
-}
-
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Implementation of sg_format_exception.
-////////////////////////////////////////////////////////////////////////
-
-sg_format_exception::sg_format_exception ()
-  : sg_exception(),
-    _text("")
-{
-}
-
-sg_format_exception::sg_format_exception (const string &message,
-                                         const string &text,
-                                         const string &origin)
-  : sg_exception(message, origin),
-    _text(text)
-{
-}
-
-sg_format_exception::~sg_format_exception ()
-{
-}
-
-const string &
-sg_format_exception::getText () const
-{
-  return _text;
-}
-
-void
-sg_format_exception::setText (const string &text)
-{
-  _text = text;
-}
-
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Implementation of sg_range_exception.
-////////////////////////////////////////////////////////////////////////
-
-sg_range_exception::sg_range_exception ()
-  : sg_exception()
-{
-}
-
-sg_range_exception::sg_range_exception (const string &message,
-                                       const string &origin)
-  : sg_exception(message, origin)
-{
-}
-
-sg_range_exception::~sg_range_exception ()
-{
-}
-
-
-// end of exception.cxx
diff --git a/simgear/misc/exception.hxx b/simgear/misc/exception.hxx
deleted file mode 100644 (file)
index 9de8ea8..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/**
- * \file exception.hxx
- * Interface definition for SimGear base exceptions.
- * Started Spring 2001 by David Megginson, david@megginson.com
- * This code is released into the Public Domain.
- *
- * $Id$
- */
-
-#ifndef __SIMGEAR_MISC_EXCEPTION_HXX
-#define __SIMGEAR_MISC_EXCEPTION_HXX 1
-
-#include <simgear/compiler.h>
-#include STL_STRING
-
-SG_USING_STD(string);
-
-
-/**
- * Information encapsulating a single location in an external resource
- *
- * A position in the resource my optionally be provided, either by
- * line number, line number and column number, or byte offset from the
- * beginning of the resource.
- */
-class sg_location
-{
-public:
-  sg_location ();
-  sg_location (const string &path, int line = -1, int column = -1);
-  virtual ~sg_location ();
-  virtual const string &getPath () const;
-  virtual void setPath (const string &path);
-  virtual int getLine () const;
-  virtual void setLine (int line);
-  virtual int getColumn () const;
-  virtual void setColumn (int column);
-  virtual int getByte () const;
-  virtual void setByte (int byte);
-  virtual string asString () const;
-private:
-  string _path;
-  int _line;
-  int _column;
-  int _byte;
-};
-
-
-/**
- * Abstract base class for all throwables.
- */
-class sg_throwable
-{
-public:
-  sg_throwable ();
-  sg_throwable (const string &message, const string &origin = "");
-  virtual ~sg_throwable ();
-  virtual const string &getMessage () const;
-  virtual const string getFormattedMessage () const;
-  virtual void setMessage (const string &message);
-  virtual const string &getOrigin () const;
-  virtual void setOrigin (const string &origin);
-private:
-  string _message;
-  string _origin;
-};
-
-
-
-/**
- * An unexpected fatal error.
- *
- * Methods and functions show throw this exception when something
- * very bad has happened (such as memory corruption or
- * a totally unexpected internal value).  Applications should catch
- * this exception only at the top level if at all, and should
- * normally terminate execution soon afterwards.
- */
-class sg_error : public sg_throwable
-{
-public:
-  sg_error ();
-  sg_error (const string &message, const string &origin = "");
-  virtual ~sg_error ();
-};
-
-
-/**
- * Base class for all SimGear exceptions.
- *
- * SimGear-based code should throw this exception only when no
- * more specific exception applies.  It may not be caught until
- * higher up in the application, where it is not possible to
- * resume normal operations if desired.
- *
- * A caller can catch sg_exception by default to ensure that
- * all exceptions are caught.  Every SimGear exception can contain
- * a human-readable error message and a human-readable string
- * indicating the part of the application causing the exception
- * (as an aid to debugging, only).
- */
-class sg_exception : public sg_throwable
-{
-public:
-  sg_exception ();
-  sg_exception (const string &message, const string &origin = "");
-  virtual ~sg_exception ();
-};
-
-
-/**
- * An I/O-related SimGear exception.
- *
- * SimGear-based code should throw this exception when it fails
- * to read from or write to an external resource, such as a file,
- * socket, URL, or database.
- *
- * In addition to the functionality of sg_exception, an
- * sg_io_exception may contain location information, such as the name
- * of a file or URL, and possible also a location in that file or URL.
- */
-class sg_io_exception : public sg_exception
-{
-public:
-  sg_io_exception ();
-  sg_io_exception (const string &message, const string &origin = "");
-  sg_io_exception (const string &message, const sg_location &location,
-                  const string &origin = "");
-  virtual ~sg_io_exception ();
-  virtual const string getFormattedMessage () const;
-  virtual const sg_location &getLocation () const;
-  virtual void setLocation (const sg_location &location);
-private:
-  sg_location _location;
-};
-
-
-/**
- * A format-related SimGear exception.
- *
- * SimGear-based code should throw this exception when a string
- * does not appear in the expected format (for example, a date
- * string does not conform to ISO 8601).
- *
- * In addition to the functionality of sg_exception, an
- * sg_format_exception can contain a copy of the original malformated
- * text.
- */
-class sg_format_exception : public sg_exception
-{
-public:
-  sg_format_exception ();
-  sg_format_exception (const string &message, const string &text,
-                      const string &origin = "");
-  virtual ~sg_format_exception ();
-  virtual const string &getText () const;
-  virtual void setText (const string &text);
-private:
-  string _text;
-};
-
-
-/**
- * A range-related SimGear exception.
- *
- * SimGear-based code should throw this exception when a value falls
- * outside the range where it can reasonably be handled; examples
- * include longitude outside the range -180:180, unrealistically high
- * forces or velocities, an illegal airport code, etc.  A range
- * exception usually means that something has gone wrong internally.
- */
-class sg_range_exception : public sg_exception
-{
-public:
-  sg_range_exception ();
-  sg_range_exception (const string &message, const string &origin = "");
-  virtual ~sg_range_exception ();
-};
-
-#endif
-
-// end of exception.hxx
index b1314af421c7c0bab77fa357ce71e6a442e98c69..014aff4596639790268236db06871d7e7f5cae8b 100644 (file)
 
 // #include STL_IOSTREAM
 
-#include <simgear/misc/exception.hxx>
+#include <simgear/structure/exception.hxx>
 
 #include "props.hxx"
-
 #include "condition.hxx"
 
 SG_USING_STD(istream);
index d6ba03823d97329626b35f9b700c5145ee5ed803..9d0ee86dbf8ababe49f0683a32ee9cd4c46047b3 100644 (file)
@@ -37,7 +37,7 @@
 
 #include <simgear/compiler.h>
 #include <simgear/constants.h>
-#include <simgear/misc/exception.hxx>
+#include <simgear/structure/exception.hxx>
 
 #include <string.h>
 #include STL_STRING
index 311ee707a5fced443e92a619857e0d8f74edfefe..9d387ae286faed145f74a52938e447b184232665 100644 (file)
 #include <plib/ssg.h>
 #include <plib/ul.h>
 
-#include <simgear/misc/exception.hxx>
+#include <simgear/structure/exception.hxx>
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/props/props.hxx>
 #include <simgear/props/props_io.hxx>
 
 #include "animation.hxx"
-
 #include "model.hxx"
 
 SG_USING_STD(vector);
diff --git a/simgear/structure/.cvsignore b/simgear/structure/.cvsignore
new file mode 100644 (file)
index 0000000..e995588
--- /dev/null
@@ -0,0 +1,3 @@
+.deps
+Makefile
+Makefile.in
diff --git a/simgear/structure/Makefile.am b/simgear/structure/Makefile.am
new file mode 100644 (file)
index 0000000..386c9d9
--- /dev/null
@@ -0,0 +1,20 @@
+includedir = @includedir@/structure
+
+lib_LIBRARIES = libsgstructure.a
+
+include_HEADERS = \
+       callback.hxx \
+       commands.hxx \
+       exception.hxx \
+       event_mgr.hxx \
+       subsystem_mgr.hxx
+
+libsgstructure_a_SOURCES = \
+       commands.cxx \
+       exception.cxx \
+       event_mgr.cxx\
+       subsystem_mgr.cxx
+
+
+INCLUDES = -I$(top_srcdir)
+
diff --git a/simgear/structure/callback.hxx b/simgear/structure/callback.hxx
new file mode 100644 (file)
index 0000000..a5fab15
--- /dev/null
@@ -0,0 +1,148 @@
+/**************************************************************************
+ * callback.hxx -- Wrapper classes to treat function and method pointers
+ * as objects.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ **************************************************************************/
+
+#ifndef _SG_CALLBACK_HXX
+#define _SG_CALLBACK_HXX
+
+/**
+ * Abstract base class for all callbacks.
+ */
+class SGCallback
+{
+public:
+
+    /**
+     * 
+     */
+    virtual ~SGCallback() {}
+
+    /**
+     * 
+     */
+    virtual SGCallback* clone() const = 0;
+
+    /**
+     * Execute the callback function.
+     */
+    virtual void operator()() = 0;
+
+protected:
+    /**
+     * 
+     */
+    SGCallback() {}
+
+private:
+    // Not implemented.
+    void operator=( const SGCallback& );
+};
+
+/**
+ * Callback for invoking a file scope function.
+ */
+template< typename Fun >
+class SGFunctionCallback : public SGCallback
+{
+public:
+    /**
+     * 
+     */
+    SGFunctionCallback( const Fun& fun )
+       : SGCallback(), f_(fun) {}
+
+    SGCallback* clone() const
+    {
+       return new SGFunctionCallback( *this );
+    }
+
+    void operator()() { f_(); }
+
+private:
+    // Not defined.
+    SGFunctionCallback();
+
+private:
+    Fun f_;
+};
+
+/**
+ * Callback for invoking a member function.
+ */
+template< class ObjPtr, typename MemFn >
+class SGMethodCallback : public SGCallback
+{
+public:
+
+    /**
+     * 
+     */
+    SGMethodCallback( const ObjPtr& pObj, MemFn pMemFn )
+       : SGCallback(),
+         pObj_(pObj),
+         pMemFn_(pMemFn)
+    {
+    }
+
+    /**
+     * 
+     */
+    SGCallback* clone() const
+    {
+       return new SGMethodCallback( *this );
+    }
+
+    /**
+     * 
+     */
+    void operator()()
+    {
+       ((*pObj_).*pMemFn_)();
+    }
+
+private:
+    // Not defined.
+    SGMethodCallback();
+
+private:
+    ObjPtr pObj_;
+    MemFn pMemFn_;
+};
+
+/**
+ * Helper template functions.
+ */
+
+template< typename Fun >
+SGCallback*
+make_callback( const Fun& fun )
+{
+    return new SGFunctionCallback<Fun>(fun);
+}
+
+template< class ObjPtr, typename MemFn >
+SGCallback*
+make_callback( const ObjPtr& pObj, MemFn pMemFn )
+{
+    return new SGMethodCallback<ObjPtr,MemFn>(pObj, pMemFn );
+}
+
+#endif // _SG_CALLBACK_HXX
+
diff --git a/simgear/structure/commands.cxx b/simgear/structure/commands.cxx
new file mode 100644 (file)
index 0000000..2e2c592
--- /dev/null
@@ -0,0 +1,64 @@
+// commands.cxx - encapsulated commands.
+// Started Spring 2001 by David Megginson, david@megginson.com
+// This code is released into the Public Domain.
+//
+// $Id$
+
+#include <simgear/props/props_io.hxx>
+
+#include "commands.hxx"
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of SGCommandMgr class.
+////////////////////////////////////////////////////////////////////////
+
+
+SGCommandMgr::SGCommandMgr ()
+{
+  // no-op
+}
+
+SGCommandMgr::~SGCommandMgr ()
+{
+  // no-op
+}
+
+void
+SGCommandMgr::addCommand (const string &name, command_t command)
+{
+  _commands[name] = command;
+}
+
+SGCommandMgr::command_t
+SGCommandMgr::getCommand (const string &name) const
+{
+  const command_map::const_iterator it = _commands.find(name);
+  return (it != _commands.end() ? it->second : 0);
+}
+
+vector<string>
+SGCommandMgr::getCommandNames () const
+{
+  vector<string> names;
+  command_map::const_iterator it = _commands.begin();
+  command_map::const_iterator last = _commands.end();
+  while (it != last) {
+    names.push_back(it->first);
+    it++;
+  }
+  return names;
+}
+
+bool
+SGCommandMgr::execute (const string &name, const SGPropertyNode * arg) const
+{
+  command_t command = getCommand(name);
+  if (command == 0)
+    return false;
+  else
+    return (*command)(arg);
+}
+
+// end of commands.cxx
diff --git a/simgear/structure/commands.hxx b/simgear/structure/commands.hxx
new file mode 100644 (file)
index 0000000..4ab28a0
--- /dev/null
@@ -0,0 +1,111 @@
+/**
+ * \file commands.hxx
+ * Interface definition for encapsulated commands.
+ * Started Spring 2001 by David Megginson, david@megginson.com
+ * This code is released into the Public Domain.
+ *
+ * $Id$
+ */
+
+#ifndef __COMMANDS_HXX
+#define __COMMANDS_HXX
+
+
+#include <simgear/compiler.h>
+
+#include STL_STRING
+#include <map>
+#include <vector>
+
+#include <simgear/props/props.hxx>
+
+SG_USING_STD(string);
+SG_USING_STD(map);
+SG_USING_STD(vector);
+
+
+/**
+ * Manage commands.
+ *
+ * <p>This class allows the application to register and unregister
+ * commands, and provides shortcuts for executing them.  Commands are
+ * simple functions that take a const pointer to an SGPropertyNode:
+ * the function may use the nodes children as parameters.</p>
+ *
+ * @author David Megginson, david@megginson.com
+ */
+class SGCommandMgr
+{
+public:
+
+  /**
+   * Type for a command function.
+   */
+  typedef bool (*command_t) (const SGPropertyNode * arg);
+
+
+  /**
+   * Default constructor.
+   */
+  SGCommandMgr ();
+
+
+  /**
+   * Destructor.
+   */
+  virtual ~SGCommandMgr ();
+
+
+  /**
+   * Register a new command with the manager.
+   *
+   * @param name The command name.  Any existing command with
+   * the same name will silently be overwritten.
+   * @param command A pointer to a one-arg function returning
+   * a bool result.  The argument is always a const pointer to
+   * an SGPropertyNode (which may contain multiple values).
+   */
+  virtual void addCommand (const string &name, command_t command);
+
+
+  /**
+   * Look up an existing command.
+   *
+   * @param name The command name.
+   * @return A pointer to the command, or 0 if there is no registered
+   * command with the name specified.
+   */
+  virtual command_t getCommand (const string &name) const;
+
+
+  /**
+   * Get a list of all existing command names.
+   *
+   * @return A (possibly empty) vector of the names of all registered
+   * commands.
+   */
+  virtual vector<string> getCommandNames () const;
+
+
+  /**
+   * Execute a command.
+   *
+   * @param name The name of the command.
+   * @param arg A const pointer to an SGPropertyNode.  The node
+   * may have a value and/or children, etc., so that it is possible
+   * to pass an arbitrarily complex data structure to a command.
+   * @return true if the command is present and executes successfully,
+   * false otherwise.
+   */
+  virtual bool execute (const string &name, const SGPropertyNode * arg) const;
+
+private:
+
+  typedef map<string,command_t> command_map;
+  command_map _commands;
+
+};
+
+#endif // __COMMANDS_HXX
+
+// end of commands.hxx
diff --git a/simgear/structure/event_mgr.cxx b/simgear/structure/event_mgr.cxx
new file mode 100644 (file)
index 0000000..979420d
--- /dev/null
@@ -0,0 +1,258 @@
+//
+// SGEventMgr.cxx -- Event Manager
+//
+// Written by Bernie Bright, started April 2002.
+//
+// Copyright (C) 2002  Curtis L. Olson  - curt@me.umn.edu
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+
+#ifdef HAVE_CONFIG_H
+#  include <simgear_config.h>
+#endif
+
+#include <simgear/compiler.h>
+
+#include <simgear/debug/logstream.hxx>
+
+#include "event_mgr.hxx"
+
+SGEvent::SGEvent()
+    : _name(""),
+      _callback(0),
+      _subsystem(0),
+      _repeat_value(0),
+      _initial_value(0),
+      _ms_to_go(0),
+      _cum_time(0),
+      _min_time(100000),
+      _max_time(0),
+      _count(0)
+{
+}
+
+SGEvent::SGEvent( const char* name,
+                  SGCallback* cb,
+                  interval_type repeat_value,
+                  interval_type initial_value )
+    : _name(name),
+      _callback(cb),
+      _subsystem(NULL),
+      _repeat_value(repeat_value),
+      _initial_value(initial_value),
+      _cum_time(0),
+      _min_time(100000),
+      _max_time(0),
+      _count(0)
+{
+    if (_initial_value < 0)
+    {
+        this->run();
+        _ms_to_go = _repeat_value;
+    }
+    else
+    {
+        _ms_to_go = _initial_value;
+    }
+}
+
+SGEvent::SGEvent( const char* name,
+                  const SGSubsystem* subsystem,
+                  interval_type repeat_value,
+                  interval_type initial_value )
+    : _name(name),
+      _callback(NULL),
+      _subsystem((SGSubsystem*)&subsystem),
+      _repeat_value(repeat_value),
+      _initial_value(initial_value),
+      _cum_time(0),
+      _min_time(100000),
+      _max_time(0),
+      _count(0)
+{
+    if (_initial_value < 0)
+    {
+        this->run();
+        _ms_to_go = _repeat_value;
+    }
+    else
+    {
+        _ms_to_go = _initial_value;
+    }
+}
+
+
+SGEvent::~SGEvent()
+{
+    //delete callback_;
+}
+
+void
+SGEvent::run()
+{
+    SGTimeStamp start_time;
+    SGTimeStamp finish_time;
+
+    start_time.stamp();
+
+    // run the event
+    if (_callback)
+    {
+        (*_callback)();
+    } else if (_subsystem)
+    {
+        _subsystem->update(_repeat_value);
+    }
+
+    finish_time.stamp();
+
+    ++_count;
+
+    unsigned long duration = finish_time - start_time;
+
+    _cum_time += duration;
+
+    if ( duration < _min_time ) {
+        _min_time = duration;
+    }
+
+    if ( duration > _max_time ) {
+        _max_time = duration;
+    }
+}
+
+void
+SGEvent::print_stats() const
+{
+    SG_LOG( SG_EVENT, SG_INFO, 
+            "  " << _name
+            << " int=" << _repeat_value / 1000.0
+            << " cum=" << _cum_time
+            << " min=" << _min_time
+            << " max=" <<  _max_time
+            << " count=" << _count
+            << " ave=" << _cum_time / (double)_count );
+}
+
+
+
+SGEventMgr::SGEventMgr()
+{
+}
+
+SGEventMgr::~SGEventMgr()
+{
+}
+
+void
+SGEventMgr::init()
+{
+    SG_LOG( SG_EVENT, SG_INFO, "Initializing event manager" );
+
+    event_table.clear();
+}
+
+void
+SGEventMgr::reinit()
+{
+}
+
+
+void
+SGEventMgr::bind()
+{
+}
+
+void
+SGEventMgr::unbind()
+{
+}
+
+void
+SGEventMgr::update( double dt )
+{
+    int dt_ms = int(dt * 1000);
+
+    if (dt_ms < 0)
+    {
+        SG_LOG( SG_GENERAL, SG_ALERT,
+                "SGEventMgr::update() called with negative delta T" );
+        return;
+    }
+
+    int min_value = 0;
+    event_container_type::iterator first = event_table.begin();
+    event_container_type::iterator last = event_table.end();
+    event_container_type::iterator event = event_table.end();
+
+    // Scan all events.  Run one whose interval has expired.
+    while (first != last)
+    {
+        if (first->update( dt_ms ))
+        {
+            if (first->value() < min_value)
+            {
+                // Select event with largest negative value.
+                // Its been waiting longest.
+                min_value = first->value();
+                event = first;
+            }
+        }
+        ++first;
+    }
+
+    if (event != last)
+    {
+        event->run();
+
+        if (event->repeat_value() > 0)
+        {
+            event->reset();
+        }
+        else
+        {
+            SG_LOG( SG_GENERAL, SG_DEBUG, "Deleting event " << event->name() );
+            event_table.erase( event );
+        }
+    }
+}
+
+void
+SGEventMgr::add( const SGEvent& event )
+{
+    event_table.push_back( event );
+
+    SG_LOG( SG_EVENT, SG_INFO, "registered event " << event.name()
+            << " to run every " << event.repeat_value() << "ms" );
+}
+
+void
+SGEventMgr::print_stats() const
+{
+    SG_LOG( SG_EVENT, SG_INFO, "" );
+    SG_LOG( SG_EVENT, SG_INFO, "Event Stats" );
+    SG_LOG( SG_EVENT, SG_INFO, "-----------" );
+
+    event_container_type::const_iterator first = event_table.begin();
+    event_container_type::const_iterator last = event_table.end();
+    for (; first != last; ++first)
+    {
+        first->print_stats();
+    }
+
+    SG_LOG( SG_EVENT, SG_INFO, "" );
+}
diff --git a/simgear/structure/event_mgr.hxx b/simgear/structure/event_mgr.hxx
new file mode 100644 (file)
index 0000000..bcfd2d2
--- /dev/null
@@ -0,0 +1,209 @@
+// eventmMgr.hxx -- periodic event scheduler
+//
+// Written by Curtis Olson, started December 1997.
+// Modified by Bernie Bright, April 2002.
+//
+// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+
+#ifndef SG_EVENT_MGR_HXX
+#define SG_EVENT_MGR_HXX 1
+
+#include <simgear/compiler.h>
+
+#include <simgear/structure/callback.hxx>
+#include <simgear/structure/subsystem_mgr.hxx>
+#include <simgear/timing/timestamp.hxx>
+
+#include <vector>
+#include <string>
+
+SG_USING_STD(vector);
+SG_USING_STD(string);
+
+
+class SGEvent
+{
+
+public:
+
+    typedef int interval_type;
+
+private:
+
+    string _name;
+    SGCallback* _callback;
+    SGSubsystem* _subsystem;
+    interval_type _repeat_value;
+    interval_type _initial_value;
+    int _ms_to_go;
+
+    unsigned long _cum_time;    // cumulative processor time of this event
+    unsigned long _min_time;    // time of quickest execution
+    unsigned long _max_time;    // time of slowest execution
+    unsigned long _count;       // number of times executed
+
+public:
+
+    /**
+     * 
+     */
+    SGEvent();
+
+    SGEvent( const char* desc,
+             SGCallback* cb,
+             interval_type repeat_value,
+             interval_type initial_value );
+
+    SGEvent( const char* desc,
+             const SGSubsystem* subsystem,
+             interval_type repeat_value,
+             interval_type initial_value );
+
+    /**
+     * 
+     */
+    ~SGEvent();
+
+    /**
+     * 
+     */
+    inline void reset()
+    {
+        _ms_to_go = _repeat_value;
+    }
+
+    /**
+     * Execute this event's callback.
+     */
+    void run();
+
+    inline string name() const { return _name; }
+    inline interval_type repeat_value() const { return _repeat_value; }
+    inline int value() const { return _ms_to_go; }
+
+    /**
+     * Display event statistics.
+     */
+    void print_stats() const;
+
+    /**
+     * Update the elapsed time for this event.
+     * @param dt_ms elapsed time in milliseconds.
+     * @return true if elapsed time has expired.
+     */
+    inline bool update( int dt_ms )
+    {
+        return (_ms_to_go -= dt_ms) <= 0;
+    }
+};
+
+
+class SGEventMgr : public SGSubsystem
+{
+private:
+
+    typedef SGEvent::interval_type interval_type;
+    typedef vector< SGEvent > event_container_type;
+
+    void add( const SGEvent& event );
+
+    // registered events.
+    event_container_type event_table;
+
+
+public:
+    SGEventMgr();
+    ~SGEventMgr();
+
+    /**
+     * Initialize the scheduling subsystem.
+     */
+    void init();
+    void reinit();
+    void bind();
+    void unbind();
+
+    /*
+     * Update the elapsed time for all events.
+     * @param dt elapsed time in seconds.
+     */
+    void update( double dt );
+
+    /**
+     * register a free standing function to be executed some time in the future.
+     * @param desc A brief description of this callback for logging.
+     * @param cb The callback function to be executed.
+     * @param repeat_value repetition rate in milliseconds.
+     * @param initial_value initial delay value in milliseconds.  A value of
+     * -1 means run immediately.
+     */
+    template< typename Fun >
+    inline void add( const char* name,
+                     const Fun& f,
+                     interval_type repeat_value,
+                     interval_type initial_value = -1 )
+    {
+        this->add( SGEvent( name,
+                            make_callback(f),
+                            repeat_value,
+                            initial_value ) );
+    }
+
+    /**
+     * register a subsystem of which the update function will be executed some
+     * time in the future.
+     * @param desc A brief description of this callback for logging.
+     * @param subsystem The subsystem of which the update function will be
+     * executed.
+     * @param repeat_value repetition rate in milliseconds.
+     * @param initial_value initial delay value in milliseconds.  A value of
+     * -1 means run immediately.
+     */
+    inline void add( const char* name,
+                     const SGSubsystem* subsystem,
+                     interval_type repeat_value,
+                     interval_type initial_value = -1 )
+    {
+        this->add( SGEvent( name,
+                            subsystem,
+                            repeat_value,
+                            initial_value ) );
+    }
+
+    template< class ObjPtr, typename MemFn >
+    inline void add( const char* name,
+                     const ObjPtr& p,
+                     MemFn pmf,
+                     interval_type repeat_value,
+                     interval_type initial_value = -1 )
+    {
+        this->add( SGEvent( name,
+                            make_callback(p,pmf),
+                            repeat_value,
+                            initial_value ) );
+    }
+
+    /**
+     * Display statistics for all registered events.
+     */
+    void print_stats() const;
+};
+
+
+#endif //SG_EVENT_MGR_HXX
diff --git a/simgear/structure/exception.cxx b/simgear/structure/exception.cxx
new file mode 100644 (file)
index 0000000..75f4cf5
--- /dev/null
@@ -0,0 +1,307 @@
+// exception.cxx - implementation of SimGear base exceptions.
+// Started Summer 2001 by David Megginson, david@megginson.com
+// This code is released into the Public Domain.
+//
+// $Id$
+
+
+#include "exception.hxx"
+#include <stdio.h>
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of sg_location class.
+////////////////////////////////////////////////////////////////////////
+
+sg_location::sg_location ()
+  : _path(""),
+    _line(-1),
+    _column(-1),
+    _byte(-1)
+{
+}
+
+sg_location::sg_location (const string &path, int line, int column)
+  : _path(path),
+    _line(line),
+    _column(column),
+    _byte(-1)
+{
+}
+
+sg_location::~sg_location ()
+{
+}
+
+const string &
+sg_location::getPath () const
+{
+  return _path;
+}
+
+void
+sg_location::setPath (const string &path)
+{
+  _path = path;
+}
+
+int
+sg_location::getLine () const
+{
+  return _line;
+}
+
+void
+sg_location::setLine (int line)
+{
+  _line = line;
+}
+
+int
+sg_location::getColumn () const
+{
+  return _column;
+}
+
+void
+sg_location::setColumn (int column)
+{
+  _column = column;
+}
+
+int
+sg_location::getByte () const
+{
+  return _byte;
+}
+
+void
+sg_location::setByte (int byte)
+{
+  _byte = byte;
+}
+
+string
+sg_location::asString () const
+{
+  char buf[128];
+  string out = "";
+  if (_path != (string)"") {
+    out += _path;
+    if (_line != -1 || _column != -1)
+      out += ",\n";
+  }
+  if (_line != -1) {
+    sprintf(buf, "line %d", _line);
+    out += buf;
+    if (_column != -1)
+      out += ", ";
+  }
+  if (_column != -1) {
+    sprintf(buf, "column %d", _column);
+    out += buf;
+  }
+  return out;
+    
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of sg_throwable class.
+////////////////////////////////////////////////////////////////////////
+
+sg_throwable::sg_throwable ()
+  : _message(""),
+    _origin("")
+{
+}
+
+sg_throwable::sg_throwable (const string &message, const string &origin)
+  : _message(message),
+    _origin(origin)
+{
+}
+
+sg_throwable::~sg_throwable ()
+{
+}
+
+const string &
+sg_throwable::getMessage () const
+{
+  return _message;
+}
+
+const string
+sg_throwable::getFormattedMessage () const
+{
+  return getMessage();
+}
+
+void
+sg_throwable::setMessage (const string &message)
+{
+  _message = message;
+}
+
+const string &
+sg_throwable::getOrigin () const
+{
+  return _origin;
+}
+
+void
+sg_throwable::setOrigin (const string &origin)
+{
+  _origin = origin;
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of sg_error class.
+////////////////////////////////////////////////////////////////////////
+
+sg_error::sg_error ()
+  : sg_throwable ()
+{
+}
+
+sg_error::sg_error (const string &message, const string &origin)
+  : sg_throwable(message, origin)
+{
+}
+
+sg_error::~sg_error ()
+{
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of sg_exception class.
+////////////////////////////////////////////////////////////////////////
+
+sg_exception::sg_exception ()
+  : sg_throwable ()
+{
+}
+
+sg_exception::sg_exception (const string &message, const string &origin)
+  : sg_throwable(message, origin)
+{
+}
+
+sg_exception::~sg_exception ()
+{
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of sg_io_exception.
+////////////////////////////////////////////////////////////////////////
+
+sg_io_exception::sg_io_exception ()
+  : sg_exception()
+{
+}
+
+sg_io_exception::sg_io_exception (const string &message, const string &origin)
+  : sg_exception(message, origin)
+{
+}
+
+sg_io_exception::sg_io_exception (const string &message,
+                                 const sg_location &location,
+                                 const string &origin)
+  : sg_exception(message, origin),
+    _location(location)
+{
+}
+
+sg_io_exception::~sg_io_exception ()
+{
+}
+
+const string
+sg_io_exception::getFormattedMessage () const
+{
+  string ret = getMessage();
+  ret += "\n at ";
+  ret += getLocation().asString();
+  return ret;
+}
+
+const sg_location &
+sg_io_exception::getLocation () const
+{
+  return _location;
+}
+
+void
+sg_io_exception::setLocation (const sg_location &location)
+{
+  _location = location;
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of sg_format_exception.
+////////////////////////////////////////////////////////////////////////
+
+sg_format_exception::sg_format_exception ()
+  : sg_exception(),
+    _text("")
+{
+}
+
+sg_format_exception::sg_format_exception (const string &message,
+                                         const string &text,
+                                         const string &origin)
+  : sg_exception(message, origin),
+    _text(text)
+{
+}
+
+sg_format_exception::~sg_format_exception ()
+{
+}
+
+const string &
+sg_format_exception::getText () const
+{
+  return _text;
+}
+
+void
+sg_format_exception::setText (const string &text)
+{
+  _text = text;
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of sg_range_exception.
+////////////////////////////////////////////////////////////////////////
+
+sg_range_exception::sg_range_exception ()
+  : sg_exception()
+{
+}
+
+sg_range_exception::sg_range_exception (const string &message,
+                                       const string &origin)
+  : sg_exception(message, origin)
+{
+}
+
+sg_range_exception::~sg_range_exception ()
+{
+}
+
+
+// end of exception.cxx
diff --git a/simgear/structure/exception.hxx b/simgear/structure/exception.hxx
new file mode 100644 (file)
index 0000000..9de8ea8
--- /dev/null
@@ -0,0 +1,182 @@
+/**
+ * \file exception.hxx
+ * Interface definition for SimGear base exceptions.
+ * Started Spring 2001 by David Megginson, david@megginson.com
+ * This code is released into the Public Domain.
+ *
+ * $Id$
+ */
+
+#ifndef __SIMGEAR_MISC_EXCEPTION_HXX
+#define __SIMGEAR_MISC_EXCEPTION_HXX 1
+
+#include <simgear/compiler.h>
+#include STL_STRING
+
+SG_USING_STD(string);
+
+
+/**
+ * Information encapsulating a single location in an external resource
+ *
+ * A position in the resource my optionally be provided, either by
+ * line number, line number and column number, or byte offset from the
+ * beginning of the resource.
+ */
+class sg_location
+{
+public:
+  sg_location ();
+  sg_location (const string &path, int line = -1, int column = -1);
+  virtual ~sg_location ();
+  virtual const string &getPath () const;
+  virtual void setPath (const string &path);
+  virtual int getLine () const;
+  virtual void setLine (int line);
+  virtual int getColumn () const;
+  virtual void setColumn (int column);
+  virtual int getByte () const;
+  virtual void setByte (int byte);
+  virtual string asString () const;
+private:
+  string _path;
+  int _line;
+  int _column;
+  int _byte;
+};
+
+
+/**
+ * Abstract base class for all throwables.
+ */
+class sg_throwable
+{
+public:
+  sg_throwable ();
+  sg_throwable (const string &message, const string &origin = "");
+  virtual ~sg_throwable ();
+  virtual const string &getMessage () const;
+  virtual const string getFormattedMessage () const;
+  virtual void setMessage (const string &message);
+  virtual const string &getOrigin () const;
+  virtual void setOrigin (const string &origin);
+private:
+  string _message;
+  string _origin;
+};
+
+
+
+/**
+ * An unexpected fatal error.
+ *
+ * Methods and functions show throw this exception when something
+ * very bad has happened (such as memory corruption or
+ * a totally unexpected internal value).  Applications should catch
+ * this exception only at the top level if at all, and should
+ * normally terminate execution soon afterwards.
+ */
+class sg_error : public sg_throwable
+{
+public:
+  sg_error ();
+  sg_error (const string &message, const string &origin = "");
+  virtual ~sg_error ();
+};
+
+
+/**
+ * Base class for all SimGear exceptions.
+ *
+ * SimGear-based code should throw this exception only when no
+ * more specific exception applies.  It may not be caught until
+ * higher up in the application, where it is not possible to
+ * resume normal operations if desired.
+ *
+ * A caller can catch sg_exception by default to ensure that
+ * all exceptions are caught.  Every SimGear exception can contain
+ * a human-readable error message and a human-readable string
+ * indicating the part of the application causing the exception
+ * (as an aid to debugging, only).
+ */
+class sg_exception : public sg_throwable
+{
+public:
+  sg_exception ();
+  sg_exception (const string &message, const string &origin = "");
+  virtual ~sg_exception ();
+};
+
+
+/**
+ * An I/O-related SimGear exception.
+ *
+ * SimGear-based code should throw this exception when it fails
+ * to read from or write to an external resource, such as a file,
+ * socket, URL, or database.
+ *
+ * In addition to the functionality of sg_exception, an
+ * sg_io_exception may contain location information, such as the name
+ * of a file or URL, and possible also a location in that file or URL.
+ */
+class sg_io_exception : public sg_exception
+{
+public:
+  sg_io_exception ();
+  sg_io_exception (const string &message, const string &origin = "");
+  sg_io_exception (const string &message, const sg_location &location,
+                  const string &origin = "");
+  virtual ~sg_io_exception ();
+  virtual const string getFormattedMessage () const;
+  virtual const sg_location &getLocation () const;
+  virtual void setLocation (const sg_location &location);
+private:
+  sg_location _location;
+};
+
+
+/**
+ * A format-related SimGear exception.
+ *
+ * SimGear-based code should throw this exception when a string
+ * does not appear in the expected format (for example, a date
+ * string does not conform to ISO 8601).
+ *
+ * In addition to the functionality of sg_exception, an
+ * sg_format_exception can contain a copy of the original malformated
+ * text.
+ */
+class sg_format_exception : public sg_exception
+{
+public:
+  sg_format_exception ();
+  sg_format_exception (const string &message, const string &text,
+                      const string &origin = "");
+  virtual ~sg_format_exception ();
+  virtual const string &getText () const;
+  virtual void setText (const string &text);
+private:
+  string _text;
+};
+
+
+/**
+ * A range-related SimGear exception.
+ *
+ * SimGear-based code should throw this exception when a value falls
+ * outside the range where it can reasonably be handled; examples
+ * include longitude outside the range -180:180, unrealistically high
+ * forces or velocities, an illegal airport code, etc.  A range
+ * exception usually means that something has gone wrong internally.
+ */
+class sg_range_exception : public sg_exception
+{
+public:
+  sg_range_exception ();
+  sg_range_exception (const string &message, const string &origin = "");
+  virtual ~sg_range_exception ();
+};
+
+#endif
+
+// end of exception.hxx
diff --git a/simgear/structure/subsystem_mgr.cxx b/simgear/structure/subsystem_mgr.cxx
new file mode 100644 (file)
index 0000000..8b1d5ea
--- /dev/null
@@ -0,0 +1,333 @@
+
+#include <simgear/debug/logstream.hxx>
+
+#include "exception.hxx"
+#include "subsystem_mgr.hxx"
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of SGSubsystem
+////////////////////////////////////////////////////////////////////////
+
+
+SGSubsystem::SGSubsystem ()
+  : _suspended(false)
+{
+}
+
+SGSubsystem::~SGSubsystem ()
+{
+}
+
+void
+SGSubsystem::init ()
+{
+}
+
+void
+SGSubsystem::reinit ()
+{
+}
+
+void
+SGSubsystem::bind ()
+{
+}
+
+void
+SGSubsystem::unbind ()
+{
+}
+
+void
+SGSubsystem::suspend ()
+{
+  _suspended = true;
+}
+
+void
+SGSubsystem::suspend (bool suspended)
+{
+  _suspended = suspended;
+}
+
+void
+SGSubsystem::resume ()
+{
+  _suspended = false;
+}
+
+bool
+SGSubsystem::is_suspended () const
+{
+  return _suspended;
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of SGSubsystemGroup.
+////////////////////////////////////////////////////////////////////////
+
+SGSubsystemGroup::SGSubsystemGroup ()
+{
+}
+
+SGSubsystemGroup::~SGSubsystemGroup ()
+{
+    for (unsigned int i = 0; i < _members.size(); i++)
+        delete _members[i];
+}
+
+void
+SGSubsystemGroup::init ()
+{
+    for (unsigned int i = 0; i < _members.size(); i++)
+        _members[i]->subsystem->init();
+}
+
+void
+SGSubsystemGroup::reinit ()
+{
+    for (unsigned int i = 0; i < _members.size(); i++)
+        _members[i]->subsystem->reinit();
+}
+
+void
+SGSubsystemGroup::bind ()
+{
+    for (unsigned int i = 0; i < _members.size(); i++)
+        _members[i]->subsystem->bind();
+}
+
+void
+SGSubsystemGroup::unbind ()
+{
+    for (unsigned int i = 0; i < _members.size(); i++)
+        _members[i]->subsystem->unbind();
+}
+
+void
+SGSubsystemGroup::update (double delta_time_sec)
+{
+    for (unsigned int i = 0; i < _members.size(); i++)
+        _members[i]->update(delta_time_sec); // indirect call
+}
+
+void
+SGSubsystemGroup::suspend ()
+{
+    for (unsigned int i = 0; i < _members.size(); i++)
+        _members[i]->subsystem->suspend();
+}
+
+void
+SGSubsystemGroup::resume ()
+{
+    for (unsigned int i = 0; i < _members.size(); i++)
+        _members[i]->subsystem->resume();
+}
+
+bool
+SGSubsystemGroup::is_suspended () const
+{
+    return false;
+}
+
+void
+SGSubsystemGroup::set_subsystem (const string &name, SGSubsystem * 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;
+}
+
+SGSubsystem *
+SGSubsystemGroup::get_subsystem (const string &name)
+{
+    Member * member = get_member(name);
+    if (member != 0)
+        return member->subsystem;
+    else
+        return 0;
+}
+
+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);
+            return;
+        }
+    }
+}
+
+bool
+SGSubsystemGroup::has_subsystem (const string &name) const
+{
+    return (((SGSubsystemGroup *)this)->get_member(name) != 0);
+}
+
+SGSubsystemGroup::Member *
+SGSubsystemGroup::get_member (const string &name, bool create)
+{
+    for (unsigned 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 SGSubsystemGroup::Member
+////////////////////////////////////////////////////////////////////////
+
+
+SGSubsystemGroup::Member::Member ()
+    : name(""),
+      subsystem(0),
+      min_step_sec(0),
+      elapsed_sec(0)
+{
+}
+
+SGSubsystemGroup::Member::Member (const Member &)
+{
+    Member();
+}
+
+SGSubsystemGroup::Member::~Member ()
+{
+                                // FIXME: causes a crash
+//     delete subsystem;
+}
+
+void
+SGSubsystemGroup::Member::update (double delta_time_sec)
+{
+    elapsed_sec += delta_time_sec;
+    if (elapsed_sec >= min_step_sec) {
+        if (!subsystem->is_suspended()) {
+            subsystem->update(elapsed_sec);
+            elapsed_sec = 0;
+        }
+    }
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of SGSubsystemMgr.
+////////////////////////////////////////////////////////////////////////
+
+
+SGSubsystemMgr::SGSubsystemMgr ()
+{
+}
+
+SGSubsystemMgr::~SGSubsystemMgr ()
+{
+}
+
+void
+SGSubsystemMgr::init ()
+{
+    for (int i = 0; i < MAX_GROUPS; i++)
+            _groups[i].init();
+}
+
+void
+SGSubsystemMgr::reinit ()
+{
+    for (int i = 0; i < MAX_GROUPS; i++)
+            _groups[i].reinit();
+}
+
+void
+SGSubsystemMgr::bind ()
+{
+    for (int i = 0; i < MAX_GROUPS; i++)
+        _groups[i].bind();
+}
+
+void
+SGSubsystemMgr::unbind ()
+{
+    for (int i = 0; i < MAX_GROUPS; i++)
+        _groups[i].unbind();
+}
+
+void
+SGSubsystemMgr::update (double delta_time_sec)
+{
+    for (int i = 0; i < MAX_GROUPS; i++) {
+        _groups[i].update(delta_time_sec);
+    }
+}
+
+void
+SGSubsystemMgr::suspend ()
+{
+    for (int i = 0; i < MAX_GROUPS; i++)
+        _groups[i].suspend();
+}
+
+void
+SGSubsystemMgr::resume ()
+{
+    for (int i = 0; i < MAX_GROUPS; i++)
+        _groups[i].resume();
+}
+
+bool
+SGSubsystemMgr::is_suspended () const
+{
+    return false;
+}
+
+void
+SGSubsystemMgr::add (const char * name, SGSubsystem * subsystem,
+                     GroupType group, double min_time_sec)
+{
+    SG_LOG(SG_GENERAL, SG_INFO, "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");
+    }
+    _subsystem_map[name] = subsystem;
+}
+
+SGSubsystemGroup *
+SGSubsystemMgr::get_group (GroupType group)
+{
+    return &(_groups[group]);
+}
+
+SGSubsystem *
+SGSubsystemMgr::get_subsystem (const string &name)
+{
+    map<string,SGSubsystem *>::iterator s =_subsystem_map.find(name);
+
+    if (s == _subsystem_map.end())
+        return 0;
+    else
+        return s->second;
+}
+
+// end of fgfs.cxx
diff --git a/simgear/structure/subsystem_mgr.hxx b/simgear/structure/subsystem_mgr.hxx
new file mode 100644 (file)
index 0000000..cd61233
--- /dev/null
@@ -0,0 +1,345 @@
+// Written by David Megginson, started 2000-12
+//
+// Copyright (C) 2000  David Megginson, david@megginson.com
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+
+
+#ifndef __SUBSYSTEM_MGR_HXX
+#define __SUBSYSTEM_MGR_HXX 1
+
+
+#include <simgear/compiler.h>
+
+#if 0
+#ifdef HAVE_WINDOWS_H
+#  include <windows.h>                     
+#  include <float.h>                    
+#endif
+
+#include STL_STRING
+SG_USING_STD(string);
+
+#include <vector>
+SG_USING_STD(vector);
+#endif
+
+#include <map>
+SG_USING_STD(map);
+
+#include <simgear/props/props.hxx>
+
+
+\f
+/**
+ * Basic interface for all FlightGear subsystems.
+ *
+ * <p>This is an abstract interface that all FlightGear subsystems
+ * will eventually implement.  It defines the basic operations for
+ * each subsystem: initialization, property binding and unbinding, and
+ * updating.  Interfaces may define additional methods, but the
+ * preferred way of exchanging information with other subsystems is
+ * through the property tree.</p>
+ *
+ * <p>To publish information through a property, a subsystem should
+ * bind it to a variable or (if necessary) a getter/setter pair in the
+ * bind() method, and release the property in the unbind() method:</p>
+ *
+ * <pre>
+ * void MySubsystem::bind ()
+ * {
+ *   fgTie("/controls/flight/elevator", &_elevator);
+ *   fgSetArchivable("/controls/flight/elevator");
+ * }
+ *
+ * void MySubsystem::unbind ()
+ * {
+ *   fgUntie("/controls/flight/elevator");
+ * }
+ * </pre>
+ *
+ * <p>To reference a property (possibly) from another subsystem, there
+ * are two alternatives.  If the property will be referenced only
+ * infrequently (say, in the init() method), then the fgGet* methods
+ * declared in fg_props.hxx are the simplest:</p>
+ *
+ * <pre>
+ * void MySubsystem::init ()
+ * {
+ *   _errorMargin = fgGetFloat("/display/error-margin-pct");
+ * }
+ * </pre>
+ *
+ * <p>On the other hand, if the property will be referenced frequently
+ * (say, in the update() method), then the hash-table lookup required
+ * by the fgGet* methods might be too expensive; instead, the
+ * subsystem should obtain a reference to the actual property node in
+ * its init() function and use that reference in the main loop:</p>
+ *
+ * <pre>
+ * void MySubsystem::init ()
+ * {
+ *   _errorNode = fgGetNode("/display/error-margin-pct", true);
+ * }
+ *
+ * void MySubsystem::update (double delta_time_sec)
+ * {
+ *   do_something(_errorNode.getFloatValue());
+ * }
+ * </pre>
+ *
+ * <p>The node returned will always be a pointer to SGPropertyNode,
+ * and the subsystem should <em>not</em> delete it in its destructor
+ * (the pointer belongs to the property tree, not the subsystem).</p>
+ *
+ * <p>The program may ask the subsystem to suspend or resume
+ * sim-time-dependent operations; by default, the suspend() and
+ * resume() methods set the protected variable <var>_suspended</var>,
+ * which the subsystem can reference in its update() method, but
+ * subsystems may also override the suspend() and resume() methods to
+ * take different actions.</p>
+ */
+class SGSubsystem
+{
+public:
+
+  /**
+   * Default constructor.
+   */
+  SGSubsystem ();
+
+  /**
+   * Virtual destructor to ensure that subclass destructors are called.
+   */
+  virtual ~SGSubsystem ();
+
+
+  /**
+   * Initialize the subsystem.
+   *
+   * <p>This method should set up the state of the subsystem, but
+   * should not bind any properties.  Note that any dependencies on
+   * the state of other subsystems should be placed here rather than
+   * in the constructor, so that FlightGear can control the
+   * initialization order.</p>
+   */
+  virtual void init ();
+
+
+  /**
+   * Reinitialize the subsystem.
+   *
+   * <p>This method should cause the subsystem to reinitialize itself,
+   * and (normally) to reload any configuration files.</p>
+   */
+  virtual void reinit ();
+
+
+  /**
+   * Acquire the subsystem's property bindings.
+   *
+   * <p>This method should bind all properties that the subsystem
+   * publishes.  It will be invoked after init, but before any
+   * invocations of update.</p>
+   */
+  virtual void bind ();
+
+
+  /**
+   * Release the subsystem's property bindings.
+   *
+   * <p>This method should release all properties that the subsystem
+   * publishes.  It will be invoked by FlightGear (not the destructor)
+   * just before the subsystem is removed.</p>
+   */
+  virtual void unbind ();
+
+
+  /**
+   * Update the subsystem.
+   *
+   * <p>FlightGear invokes this method every time the subsystem should
+   * update its state.</p>
+   *
+   * @param delta_time_sec The delta time, in seconds, since the last
+   * update.  On first update, delta time will be 0.
+   */
+  virtual void update (double delta_time_sec) = 0;
+
+
+  /**
+   * Suspend operation of this subsystem.
+   *
+   * <p>This method instructs the subsystem to suspend
+   * sim-time-dependent operations until asked to resume.  The update
+   * method will still be invoked so that the subsystem can take any
+   * non-time-dependent actions, such as updating the display.</p>
+   *
+   * <p>It is not an error for the suspend method to be invoked when
+   * the subsystem is already suspended; the invocation should simply
+   * be ignored.</p>
+   */
+  virtual void suspend ();
+
+
+  /**
+   * Suspend or resum operation of this subsystem.
+   *
+   * @param suspended true if the subsystem should be suspended, false
+   * otherwise.
+   */
+  virtual void suspend (bool suspended);
+
+
+  /**
+   * Resume operation of this subsystem.
+   *
+   * <p>This method instructs the subsystem to resume
+   * sim-time-depended operations.  It is not an error for the resume
+   * method to be invoked when the subsystem is not suspended; the
+   * invocation should simply be ignored.</p>
+   */
+  virtual void resume ();
+
+
+  /**
+   * Test whether this subsystem is suspended.
+   *
+   * @return true if the subsystem is suspended, false if it is not.
+   */
+  virtual bool is_suspended () const;
+
+
+protected:
+
+  bool _suspended;
+
+};
+
+
+\f
+/**
+ * A group of FlightGear subsystems.
+ */
+class SGSubsystemGroup : public SGSubsystem
+{
+public:
+
+    SGSubsystemGroup ();
+    virtual ~SGSubsystemGroup ();
+
+    virtual void init ();
+    virtual void reinit ();
+    virtual void bind ();
+    virtual void unbind ();
+    virtual void update (double delta_time_sec);
+    virtual void suspend ();
+    virtual void resume ();
+    virtual bool is_suspended () const;
+
+    virtual void set_subsystem (const string &name,
+                                SGSubsystem * subsystem,
+                                double min_step_sec = 0);
+    virtual SGSubsystem * 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;
+        SGSubsystem * subsystem;
+        double min_step_sec;
+        double elapsed_sec;
+    };
+
+    Member * get_member (const string &name, bool create = false);
+
+    vector<Member *> _members;
+};
+
+
+\f
+/**
+ * Manage subsystems for FlightGear.
+ *
+ * This top-level subsystem will eventually manage all of the
+ * subsystems in FlightGear: it broadcasts its life-cycle events
+ * (init, bind, etc.) to all of the subsystems it manages.  Subsystems
+ * are grouped to guarantee order of initialization and execution --
+ * currently, the only two groups are INIT and GENERAL, but others
+ * will appear in the future.
+ *
+ * All subsystems are named as well as grouped, and subsystems can be
+ * looked up by name and cast to the appropriate subtype when another
+ * subsystem needs to invoke specialized methods.
+ *
+ * The subsystem manager owns the pointers to all the subsystems in
+ * it.
+ */
+class SGSubsystemMgr : public SGSubsystem
+{
+public:
+
+    /**
+     * Types of subsystem groups.
+     */
+    enum GroupType {
+        INIT = 0,
+        GENERAL,
+        MAX_GROUPS
+    };
+
+    SGSubsystemMgr ();
+    virtual ~SGSubsystemMgr ();
+
+    virtual void init ();
+    virtual void reinit ();
+    virtual void bind ();
+    virtual void unbind ();
+    virtual void update (double delta_time_sec);
+    virtual void suspend ();
+    virtual void resume ();
+    virtual bool is_suspended () const;
+
+    virtual void add (const char * name,
+                      SGSubsystem * subsystem,
+                      GroupType group = GENERAL, 
+                      double min_time_sec = 0);
+
+    virtual SGSubsystemGroup * get_group (GroupType group);
+
+    virtual SGSubsystem * get_subsystem(const string &name);
+
+private:
+
+    SGSubsystemGroup _groups[MAX_GROUPS];
+    map<string,SGSubsystem *> _subsystem_map;
+
+};
+
+
+
+#endif // __SUBSYSTEM_MGR_HXX
+
index 348151efaa5e091d790dfa47b4d389eefa161c6e..d3f6a90ae5c8815686eea406158df1c4e786c062 100644 (file)
@@ -9,8 +9,7 @@
 #define __EASYXML_HXX
 
 #include <simgear/compiler.h>
-
-#include <simgear/misc/exception.hxx>
+#include <simgear/structure/exception.hxx>
 
 #include STL_IOSTREAM
 #include STL_STRING