You can subscribe to this list here.
2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(47) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
(140) |
Feb
(98) |
Mar
(152) |
Apr
(104) |
May
(71) |
Jun
(94) |
Jul
(169) |
Aug
(83) |
Sep
(47) |
Oct
(134) |
Nov
(7) |
Dec
(20) |
2004 |
Jan
(41) |
Feb
(14) |
Mar
(42) |
Apr
(47) |
May
(68) |
Jun
(143) |
Jul
(65) |
Aug
(29) |
Sep
(40) |
Oct
(34) |
Nov
(33) |
Dec
(97) |
2005 |
Jan
(29) |
Feb
(30) |
Mar
(9) |
Apr
(37) |
May
(13) |
Jun
(31) |
Jul
(22) |
Aug
(23) |
Sep
|
Oct
(37) |
Nov
(34) |
Dec
(117) |
2006 |
Jan
(48) |
Feb
(6) |
Mar
(2) |
Apr
(71) |
May
(10) |
Jun
(16) |
Jul
(7) |
Aug
(1) |
Sep
(14) |
Oct
(17) |
Nov
(25) |
Dec
(26) |
2007 |
Jan
(8) |
Feb
(2) |
Mar
(7) |
Apr
(26) |
May
|
Jun
(12) |
Jul
(30) |
Aug
(14) |
Sep
(9) |
Oct
(4) |
Nov
(7) |
Dec
(6) |
2008 |
Jan
(10) |
Feb
(10) |
Mar
(6) |
Apr
(8) |
May
|
Jun
(10) |
Jul
(18) |
Aug
(15) |
Sep
(16) |
Oct
(5) |
Nov
(3) |
Dec
(10) |
2009 |
Jan
(11) |
Feb
(2) |
Mar
|
Apr
(15) |
May
(31) |
Jun
(18) |
Jul
(11) |
Aug
(26) |
Sep
(52) |
Oct
(17) |
Nov
(4) |
Dec
|
2010 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <mk...@us...> - 2003-09-07 16:39:50
|
Update of /cvsroot/csp/APPLICATIONS/CSPSim/Source In directory sc8-pr-cvs1:/tmp/cvs-serv4650 Removed Files: Bus.cpp Log Message: see Bus.h --- Bus.cpp DELETED --- |
From: <mk...@us...> - 2003-09-07 16:39:07
|
Update of /cvsroot/csp/APPLICATIONS/CSPSim/Include In directory sc8-pr-cvs1:/tmp/cvs-serv4348 Added Files: Bus.h Log Message: bus/channel infrastructure --- NEW FILE: Bus.h --- // Combat Simulator Project - FlightSim Demo // Copyright (C) 2003 The Combat Simulator Project // http://csp.sourceforge.net // // 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** * @file Bus.h * **/ /* TODO * add warning/debug logging */ #include <Tools.h> #include <SimData/Ref.h> #include <sigc++/signal_system.h> #include <map> class Bus; /** Base class for channels on a bus. * * Channels are reference counted objects that are stored in * a bus and can be shared by components with access to the * bus. Each component can provide channels to the bus and * access channels provided by other components. Since the * channels are identified by strings, this provides a very * flexible way to share interfaces. Although the initial * retrieval and connection of a channel involves some over- * head, references to channels can be stored locally to * provide low-overhead data and method sharing between * components. */ class ChannelBase: public simdata::Referenced { friend class Bus; /// Identifier for this channel. std::string m_Name; /// Bitmask for channel options. mutable unsigned int m_Mask; protected: /// Channel state flags. enum { MASK_ENABLED = 0x00000001, MASK_BLOCKED = 0x00000002, MASK_SHARED = 0x00000004, DERIVED_MASK = 0xffff0000, }; typedef enum { ACCESS_LOCAL, ACCESS_SHARED, } AccessType; bool isMask(unsigned int bits) const { return (m_Mask & bits & DERIVED_MASK) != 0; } void setMask(unsigned int bits) const { m_Mask |= (bits & DERIVED_MASK); } void clearMask(unsigned int bits) const { m_Mask &= ~(bits & DERIVED_MASK); } unsigned int getMask() const { return m_Mask; } /** Mark a channel as enabled or disabled. * * The channel enabled/disabled flag is not actively * enforced. It is the responsibility of code using * the channel to test the channel status and behave * accordingly. */ void setEnabled(bool enabled) { m_Mask = (m_Mask & ~MASK_ENABLED) | (enabled ? MASK_ENABLED : 0); } public: /// ChannelBase reference (convenience) type for shared channels. typedef simdata::Ref< ChannelBase > Ref; /// ChannelBase reference (convenience) type for non-shared channels. typedef simdata::Ref< ChannelBase const > CRef; /** Get the (unique) identifier key for this channel. */ std::string const &getName() const { return m_Name; } /** Test if a channel is enabled. */ bool isEnabled() const { return m_Mask & MASK_ENABLED; } /** Test if this channel is shared. * * Shared channels can be updated by any system, whereas non-shared * channels are read-only (except for the system that creates them). */ bool isShared() const { return m_Mask & MASK_SHARED; } protected: /** Constructor. */ ChannelBase(std::string const &name, AccessType access = ACCESS_LOCAL): m_Name(name), m_Mask(0) { m_Mask |= (access == ACCESS_SHARED) ? MASK_SHARED : 0; } }; /** A channel for calling methods of a remote object. * * Method channels to allow components on a bus to call * methods of other components (and retrieve the results). * This is somewhat similar to "pull" data channels, except * that the called method can take arguments. The calling * mechanism is based on libsigc++ signals (see the * libsigc++ documentation for details on using signals). */ template <class SIGNAL> class MethodChannel: public ChannelBase { mutable SIGNAL m_Signal; SigC::Connection m_Connection; typedef typename SIGNAL::InSlotType InSlotType; public: typedef simdata::Ref<MethodChannel> Ref; typedef simdata::Ref<const MethodChannel> CRef; MethodChannel(std::string const &name, InSlotType const &slot): ChannelBase(name) { m_Connection = m_Signal.connect(slot); } SIGNAL &call() const { return m_Signal; } SigC::Connection &connection() { return m_Connection; } }; /** Base class for data channels on a bus. * * This class provides basic data channel functionality without * specializing to a particular data type. Data channels are * reference counted objects. The references are stored both in * the bus (which provides name-based channel lookups) and in * individual systems as member variable references. The data * channel may therefore persist even if the system originally * defining the channel is destroyed. * * Data channels support either push and pull based value updates, * and must be specialized when the first signal handler is * connected. For push channels, any change to the channel value * will send a signal to all callbacks connected to the channel. * For pull channels, any attempt to read a channel value will * first send a signal to a callback that can update the value. * In this case only one callback may be connected to the channel, * usually by the system that creates the channel. */ class DataChannelBase: public ChannelBase { private: /// Callback signal for push/pull channels. mutable SigC::Signal0<void> m_Signal; enum { MASK_HANDLER = 0x00010000, MASK_PUSH = 0x00020000, MASK_PULL = 0x00040000, MASK_DIRTY = 0x00080000, }; protected: typedef enum { NO_SIGNAL, PUSH_SIGNAL, PULL_SIGNAL, } SignalType; /** Construct a new channel. * * @param name The name of the channel (used to generate the * identifier key). * @param shared Shared channels may be accessed via the bus as * non-const references, allowing any system to * update the channel value. */ DataChannelBase(std::string const &name, AccessType access=ACCESS_LOCAL, SignalType signal=NO_SIGNAL): ChannelBase(name, access) { if (signal == PUSH_SIGNAL) { setMask(MASK_PUSH); } else if (signal == PULL_SIGNAL) { setMask(MASK_PULL | MASK_DIRTY); } } /** Test if the channel has had at least one signal handler * connected. * * Note that handlers are not tracked beyond their initial * connection to the channel, so it is possible for this * method to return true even if no handlers are currently * connected. This flag is used as an internal optimization * for channels that have never been connected to a signal * handler. */ bool hasHandler() const { return isMask(MASK_HANDLER); } /** Send a signal to all connected handlers. * * For push channels this is used to signal a change of the * data value, while for pull channels this signal is used * to update the data value. */ void signal() const { m_Signal.emit(); } /** Test if this is a push (or pull) channel. */ bool isPush() const { return isMask(MASK_PUSH); } bool isPull() const { return isMask(MASK_PULL); } public: void setDirty() { setMask(MASK_DIRTY); } void setClean() { clearMask(MASK_DIRTY); } bool isDirty() const { return isMask(MASK_DIRTY); } /** A convenience class for defining Python signal handlers using SWIG. */ class Handler: public SigC::Object { public: virtual ~Handler() {} void handle() { operator()(); } virtual void operator()(void)=0; }; /** Connect a signal handler to this channel. * * If push is true, this method may be called any number of times to * connect multiple handlers. If push is false, no additional calls * to <tt>connect</tt> may be made. The first call to <tt>connect</tt> * permanently establishes whether the channel is push or pull. * * @param object The instance providing the handler. * @param callback The class method used to handle the signal. * @param push Connect a push (or pull) handler. */ template <class T> SigC::Connection connect(T *object, void (T::*callback)()) const { assert(isPush() || (isPull() && !hasHandler())); setMask(MASK_HANDLER); return m_Signal.connect(SigC::slot(object, callback)); } /** Connect a signal handler to this channel. * * See <tt>connect(T*, void (T::*)(), bool)</tt>. * * @param handler The callback handler. * @param push Connect a push (or pull) handler. */ SigC::Connection connect(Handler *handler) const { return connect(handler, &Handler::handle); } }; /** Channel for passing data between systems over a Bus. * * Channels are type-specialized objects which store a data * value and can be shared (by reference) by multiple systems * connected to a data bus. In addition to the push/pull * signaling functionality provided by the ChannelBase base * class, this subclass defines accessor methods for the * underlying data value. */ template <typename T> class DataChannel: public DataChannelBase { /// The data value provided by the channel. T m_Value; void pull() const { if (isDirty() && hasHandler() && !isPush()) { signal(); } } public: /// Channel reference (convenience) type for shared channels. typedef simdata::Ref< DataChannel<T> > Ref; /// Channel reference (convenience) type for non-shared channels. typedef simdata::Ref< DataChannel<T> const > CRef; void push() const { assert(isPush()); if (hasHandler() && isPush()) { signal(); } } T &value() { return m_Value; } /** Get the value of a channel. * * For pull channels, this method sends a signal to the update * handler before reading the data value. */ T const &value() const { pull(); return m_Value; } /** Construct and initialize a new channel. * * This constructor can be used to create either a shared or * non-shared channel, and allows the channel data value to be * explicitly initialized. * * @param name The string indetifier of the channel. * @param value The initial value of the channel data. * @param shared Create a shared (or non-shared) channel. */ DataChannel(std::string const &name, T const &value, AccessType access=ACCESS_LOCAL, SignalType signal=NO_SIGNAL): m_Value(value), DataChannelBase(name, access, signal) {} static DataChannel<T> *newLocal(std::string const &name, T const &value) { return new DataChannel(name, value, ACCESS_LOCAL, NO_SIGNAL); } static DataChannel<T> *newLocalPull(std::string const &name, T const &value) { return new DataChannel(name, value, ACCESS_LOCAL, PULL_SIGNAL); } static DataChannel<T> *newLocalPush(std::string const &name, T const &value) { return new DataChannel(name, value, ACCESS_LOCAL, PUSH_SIGNAL); } static DataChannel<T> *newShared(std::string const &name, T const &value) { return new DataChannel(name, value, ACCESS_SHARED, NO_SIGNAL); } static DataChannel<T> *newSharedPull(std::string const &name, T const &value) { return new DataChannel(name, value, ACCESS_SHARED, PULL_SIGNAL); } static DataChannel<T> *newSharedPush(std::string const &name, T const &value) { return new DataChannel(name, value, ACCESS_SHARED, PUSH_SIGNAL); } }; /** A data bus class for passing data between multiple Systems. * * Bus instances are essentially just collections of data channels, * providing some convenience methods for accessing channels and * connecting systems. Systems connected by a Bus can exchange * information synchonously or asynchronously using an efficient * string-based interface. No detailed (compile-time) knowledge * of the system class interfaces is required, which allows for a * much more flexible design of system class hierarchies. */ class Bus: public simdata::Referenced { /// name to channel map type typedef std::map<std::string, ChannelBase::Ref> ChannelMap; /// Map of all channels connected to the bus ChannelMap m_Channels; typedef std::map<std::string, std::vector<ChannelBase::Ref> > GroupMap; GroupMap m_Groups; /// Internal flag to help ensure proper bus construction. bool m_Bound; /// The identifier string of this bus. std::string m_Name; /// The status (0-1) used for damage modelling. float m_Status; /// Internal state of the bus. bool m_Enabled; public: /// Bus reference (convenience) type typedef simdata::Ref<Bus> Ref; /** Test if a particular data channel is available. */ bool hasChannel(std::string const &name) { return getChannel(name).valid(); } /** Register a new channel. * * This method is typically called from a system's registerChannels * method to register all data channels that the system provides * via this bus. The return value can be used to store a local * reference to the new channel. */ ChannelBase* registerChannel(ChannelBase *channel, std::string const &groups = "") { assert(channel); std::string name = channel->getName(); assert(m_Channels.find(name) == m_Channels.end()); m_Channels[name] = channel; StringTokenizer grouplist(groups, " "); StringTokenizer::iterator group = grouplist.begin(); for (; group != grouplist.end(); ++group) { m_Groups[*group].push_back(channel); } return channel; } /** Some registration helpers for data channels */ //@{ template <typename T> ChannelBase *registerLocalDataChannel(std::string const &name, T const &init) { return registerChannel(DataChannel<T>::newLocal(name, init)); } template <typename T> ChannelBase *registerLocalPullChannel(std::string const &name, T const &init) { return registerChannel(DataChannel<T>::newLocalPull(name, init)); } template <typename T> ChannelBase *registerLocalPushChannel(std::string const &name, T const &init) { return registerChannel(DataChannel<T>::newLocalPush(name, init)); } template <typename T> ChannelBase *registerSharedDataChannel(std::string const &name, T const &init) { return registerChannel(DataChannel<T>::newShared(name, init)); } template <typename T> ChannelBase *registerSharedPullChannel(std::string const &name, T const &init) { return registerChannel(DataChannel<T>::newSharedPull(name, init)); } template <typename T> ChannelBase *registerSharedPushChannel(std::string const &name, T const &init) { return registerChannel(DataChannel<T>::newSharedPush(name, init)); } //@} /** Some registration helpers for method channels */ //@{ template <typename R, class O, class O2> ChannelBase* registerMethodChannel(std::string const &name, O *obj, R (O2::*method)()) { return registerChannel( new MethodChannel< SigC::Signal0<R> >(name, SigC::slot(obj, method)) ); } template <typename R, typename P1, class O, class O2> ChannelBase* registerMethodChannel(std::string const &name, O *obj, R (O2::*method)(P1)) { return registerChannel( new MethodChannel< SigC::Signal1<R,P1> >(name, SigC::slot(obj, method)) ); } template <typename R, typename P1, typename P2, class O, class O2> ChannelBase* registerMethodChannel(std::string const &name, R (O2::*method)(P1,P2)) { return registerChannel( new MethodChannel< SigC::Signal2<R,P1,P2> >(name, SigC::slot(obj, method)) ); } template <typename R, typename P1, typename P2, typename P3, class O, class O2> ChannelBase* registerMethodChannel(std::string const &name, R (O2::*method)(P1,P2,P3)) { return registerChannel( new MethodChannel< SigC::Signal3<R,P1,P2,P3> >(name, SigC::slot(obj, method)) ); } template <typename R, typename P1, typename P2, typename P3, typename P4, class O, class O2> ChannelBase* registerMethodChannel(std::string const &name, R (O2::*method)(P1,P2,P3,P4)) { return registerChannel( new MethodChannel< SigC::Signal4<R,P1,P2,P3,P4> >(name, SigC::slot(obj, method)) ); } //@} /** Get the name of this bus. */ std::string const &getName() const { return m_Name; } /** Get a reference to a shared data channel. * * This method will raise an assertion if the channel is non-shared. * * @param name The name of the channel. * @param required If true, an assertion will be raised if the * requested channel does not exist. Otherwise * missing channels will be returned as null * references. * @returns A non-const reference to the data channel or a null * reference if the data channel is not found and required * is false. */ ChannelBase::Ref getSharedChannel(std::string const &name, bool required = true) { ChannelMap::iterator iter = m_Channels.find(name); if (iter == m_Channels.end()) { assert(!required); return 0; } assert(iter->second->isShared()); return iter->second; } /** Get a reference to a shared or non-shared data channel. * * This method is identical to getSharedChannel, but returns a * const reference to the channel so that the data value may be * read but not modified. */ ChannelBase::CRef getChannel(std::string const &name, bool required = true) { ChannelMap::iterator iter = m_Channels.find(name); if (iter == m_Channels.end()) { assert(!required); return 0; } return iter->second; } /** Get the bus status value. */ float getStatus() const { return m_Status; } /** Test if the bus is enabled. */ bool isEnabled() const { return m_Enabled; } /** Enable or disable the bus. */ void setEnabled(bool enabled) { if (enabled == m_Enabled) return; for (ChannelMap::iterator iter = m_Channels.begin(); iter != m_Channels.end(); ++iter) { iter->second->setEnabled(enabled); } m_Enabled = enabled; } /** Change the bus status value. */ virtual void setStatus(float status) { m_Status = status; // disable or enable a proportionate number of accessors } /** Construct a new Bus. * * The bus is enabled by default. * * @param name The name of the bus. */ Bus(std::string const &name): m_Name(name), m_Bound(false), m_Status(1.0), m_Enabled(true) { } }; |
From: <mk...@us...> - 2003-09-06 08:52:47
|
Update of /cvsroot/csp/APPLICATIONS/SimData In directory sc8-pr-cvs1:/tmp/cvs-serv6390 Modified Files: Tag: b0_4_0 CHANGES.current Log Message: Index: CHANGES.current =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/CHANGES.current,v retrieving revision 1.75.2.3 retrieving revision 1.75.2.4 diff -C2 -d -r1.75.2.3 -r1.75.2.4 *** CHANGES.current 6 Sep 2003 01:37:21 -0000 1.75.2.3 --- CHANGES.current 6 Sep 2003 08:52:06 -0000 1.75.2.4 *************** *** 5,8 **** --- 5,12 ---- implementing the Composite/Visitor design pattern. + Improved doxygen comments, small bug fixes, added + isContainer and canBeAdded properties, adding logging + of warning messages. + 2003-09-04: onsight Changed Referenced from a nonvirtual to a virtual base class |
From: <mk...@us...> - 2003-09-06 08:52:47
|
Update of /cvsroot/csp/APPLICATIONS/SimData/Include/SimData In directory sc8-pr-cvs1:/tmp/cvs-serv6390/Include/SimData Modified Files: Tag: b0_4_0 Composite.h Log Message: Index: Composite.h =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/Include/SimData/Attic/Composite.h,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -C2 -d -r1.1.2.2 -r1.1.2.3 *** Composite.h 6 Sep 2003 07:06:30 -0000 1.1.2.2 --- Composite.h 6 Sep 2003 08:52:06 -0000 1.1.2.3 *************** *** 35,38 **** --- 35,39 ---- #include <vector> #include <SimData/Ref.h> + #include <SimData/Log.h> *************** *** 238,242 **** */ virtual bool addChild(Node *node) { ! if (containsNode(node)) return false; _children.push_back(node); node->addParent(this); --- 239,258 ---- */ virtual bool addChild(Node *node) { ! if (!isContainer()) { ! SIMDATA_LOG(LOG_ALL, LOG_WARNING, "simdata::Composite<>::addChild() to non-container."); ! return false; ! } ! if (!node) { ! SIMDATA_LOG(LOG_ALL, LOG_WARNING, "simdata::Composite<>::addChild() null node."); ! return false; ! } ! if (!node->canBeAdded()) { ! SIMDATA_LOG(LOG_ALL, LOG_WARNING, "simdata::Composite<>::addChild() cannot be added."); ! return false; ! } ! if (containsNode(node)) { ! SIMDATA_LOG(LOG_ALL, LOG_WARNING, "simdata::Composite<>::addChild() duplicate node."); ! return false; ! } _children.push_back(node); node->addParent(this); *************** *** 263,267 **** unsigned int end = pos + count; if (end > _children.size()) { ! // TODO log warning end = _children.size(); } --- 279,283 ---- unsigned int end = pos + count; if (end > _children.size()) { ! SIMDATA_LOG(LOG_ALL, LOG_WARNING, "simdata::Composite<>::removeChild() index range truncated."); end = _children.size(); } *************** *** 360,363 **** --- 376,382 ---- */ inline unsigned int getNumParents() const { return _parents.size(); } + + virtual bool isContainer() const { return true; } + virtual bool canBeAdded() const { return true; } protected: |
From: <mk...@us...> - 2003-09-06 07:06:34
|
Update of /cvsroot/csp/APPLICATIONS/SimData/Include/SimData In directory sc8-pr-cvs1:/tmp/cvs-serv25534 Modified Files: Tag: b0_4_0 Composite.h Log Message: Index: Composite.h =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/Include/SimData/Attic/Composite.h,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** Composite.h 6 Sep 2003 01:37:07 -0000 1.1.2.1 --- Composite.h 6 Sep 2003 07:06:30 -0000 1.1.2.2 *************** *** 47,56 **** class Visitable; ! #define SIMDATA_VISITOR(visitor) \ ! typedef SIMDATA(Ref)<visitor> Ref; \ ! using SIMDATA(Visitor)<visitor>::apply; ! #define SIMDATA_VISITABLE(visitor) \ ! virtual SIMDATA(Ref)<visitor> accept(SIMDATA(Ref)<visitor> v) { \ v->apply(*this); \ return v; \ --- 47,56 ---- class Visitable; ! #define SIMDATA_VISITOR(__visitor) \ ! typedef SIMDATA(Ref)<__visitor> Ref; \ ! using SIMDATA(Visitor)<__visitor>::apply; ! #define SIMDATA_VISITABLE(__visitor) \ ! virtual SIMDATA(Ref)<__visitor> accept(SIMDATA(Ref)<__visitor> v) { \ v->apply(*this); \ return v; \ *************** *** 77,94 **** class VisitorCore: public VisitorBase { public: typedef enum { ! TRAVERSE_NONE, ! TRAVERSE_CHILDREN, ! TRAVERSE_PARENTS, } TraversalMode; TraversalMode getTraversalMode() const { return _traversal_mode; } typedef CompositeBase<N> Node; virtual void apply(Node &node) { traverse(node); } ! VisitorCore(): _traversal_mode(TRAVERSE_CHILDREN) {} protected: void traverse(Node &node) { if (_traversal_mode == TRAVERSE_CHILDREN) { --- 77,120 ---- class VisitorCore: public VisitorBase { public: + /// Composite traversal modes. typedef enum { ! TRAVERSE_NONE, //< Act on only the current node. ! TRAVERSE_CHILDREN, //< Act on the current node and all children ! TRAVERSE_PARENTS, //< Act on the current node and all parents } TraversalMode; + /** Get the mode for traversing the composite graph. + */ TraversalMode getTraversalMode() const { return _traversal_mode; } + + /// Base class type for nodes in the graph. typedef CompositeBase<N> Node; + /** Visit a node and propagate. + * + * This method is overloaded in the actual visitor classes + * to apply distinct operations to each type of node. Apply + * methods should generally conclude with a call to + * traverse(node) to continue progagation of the visitor + * through the graph. + */ virtual void apply(Node &node) { traverse(node); } ! /** Constructor. ! * ! * @param mode The initial traversal mode. The default is ! * TRAVERSE_CHILDREN. ! */ ! VisitorCore(TraversalMode mode = TRAVERSE_CHILDREN): ! _traversal_mode(mode) {} protected: + /** Propagate from a given node based on the current traversal + * mode. + * + * TRAVERSE_CHILDREN will visit the subgraph of the node + * (depth first), while TRAVERSE_PARENTS will visit all + * parents until the root of the graph is reached. + */ void traverse(Node &node) { if (_traversal_mode == TRAVERSE_CHILDREN) { *************** *** 100,106 **** --- 126,148 ---- } + /** Change the traversal mode. + * + * The initial traversal mode can be set as a contructor parameter. + * This method allows the traversal mode to be changed on the fly, + * for example to abort traversal of a graph once a condition is + * met (such as finding a matching node during a search). + */ + void setTraversalMode(TraversalMode mode) { _traversal_mode = mode; } + private: + /// The current traversal mode. TraversalMode _traversal_mode; + + /** Visit all parents of a node. + */ inline void ascend(Node &node); + + /** Visit all children of a node. + */ inline void descend(Node &node); *************** *** 116,120 **** --- 158,167 ---- friend class VisitorCore<N>; protected: + /** Propagate a visitor to all child nodes. + */ virtual void descend(VisitorBase *v) = 0; + + /** Propagate a visitor to all parent nodes. + */ virtual void ascend(VisitorBase *v) = 0; }; *************** *** 169,177 **** --- 216,240 ---- typedef Ref<V> VisitorRef; + /// A list of child node references. typedef std::vector< NodeRef > ChildList; + + /// A list of parent node pointers (which avoids circular references). typedef std::vector< Node* > ParentList; + /** Accept a visitor. + * + * This method must be implemented in each subclasses to + * ensure proper dispatch of the visitor's apply methods. + * See the Composite class documentation for details. + */ virtual VisitorRef accept(VisitorRef v)=0; + /** Add a child to this node. + * + * Extend this method to inforce constraints on the graph structure, + * such as preventing nodes from having multiple parents. + * + * @returns True if the child was added, false if it already exists. + */ virtual bool addChild(Node *node) { if (containsNode(node)) return false; *************** *** 181,188 **** --- 244,262 ---- } + /** Remove a child from this node. + * + * @returns True if the child was removed, false if it was not found. + */ virtual bool removeChild(Node *node) { return removeChild(getChildIndex(node)); } + /** Remove one or more children. + * + * @param pos The index of the first child to remove. + * @param count The number of children to remove (default 1). + * @returns True if one or more children were removed, false + * otherwise. + */ virtual bool removeChild(int pos, int count=1) { if (pos >= _children.size() || count <= 0) return false; *************** *** 199,204 **** --- 273,287 ---- } + /** Get the number of immediate children of this node. + */ inline unsigned int getNumChildren() const { return _children.size(); } + /** Replace an existing child node with a new one. + * + * The original node will be destroyed if it is not already + * referenced elsewhere. + * + * @returns True if the child was replaced, false otherwise. + */ virtual bool setChild(unsigned int i, Node* node) { if (i >= _children.size() || !node) return false; *************** *** 210,219 **** } ! inline Node* getChild(unsigned int i) { return _children[i].get(); } ! inline const Node* getChild(unsigned int i) const { return _children[i].get(); } inline ChildList const &getChildren() const { return _children; } inline bool containsNode(Node const *node) const { if (!node) return false; --- 293,322 ---- } ! /** Get a child by index number. ! * ! * @returns 0 if the index is out of range. ! */ ! inline Node* getChild(unsigned int i) { ! if (i >= _children.size()) return 0; ! return _children[i].get(); ! } ! /** Get a child by index number. ! * ! * @returns 0 if the index is out of range. ! */ ! inline const Node* getChild(unsigned int i) const { ! if (i >= _children.size()) return 0; ! return _children[i].get(); ! } + /** Get a list of immediate children of this node. + */ inline ChildList const &getChildren() const { return _children; } + /** Test if this node contains a given node. + * + * @returns True if the node is an immediate child, false otherwise. + */ inline bool containsNode(Node const *node) const { if (!node) return false; *************** *** 221,224 **** --- 324,331 ---- } + /** Get the index of a child node. + * + * @returns The index if found, otherwise the number of children. + */ inline unsigned int getChildIndex(Node const *node) const { for (int idx = 0; idx < _children.size(); ++idx) { *************** *** 228,242 **** } inline const ParentList &getParents() const { return _parents; } ! inline Node* getParent(unsigned int i) { return _parents[i]; } ! inline const Node* getParent(unsigned int i) const { return _parents[i]; } inline unsigned int getNumParents() const { return _parents.size(); } protected: inline ParentList getParents() { return _parents; } class AcceptOp { typename Composite::VisitorRef _visitor; --- 335,371 ---- } + /** Get a list of immediate parents of this node. + */ inline const ParentList &getParents() const { return _parents; } ! /** Get a parent by index number. ! * ! * @returns 0 if the index is out of range. ! */ ! inline Node* getParent(unsigned int i) { ! if (i >= _parents.size()) return 0; ! return _parents[i]; ! } ! /** Get a parent by index number. ! * ! * @returns 0 if the index is out of range. ! */ ! inline const Node* getParent(unsigned int i) const { ! if (i >= _parents.size()) return 0; ! return _parents[i]; ! } + /** Get the number of immediate parents of this node. + */ inline unsigned int getNumParents() const { return _parents.size(); } protected: + /** Get a copy of this node's parent list. + */ inline ParentList getParents() { return _parents; } + /** A function adapter for visiting child or parent nodes. + */ class AcceptOp { typename Composite::VisitorRef _visitor; *************** *** 246,253 **** --- 375,386 ---- }; + /** Propagate a visitor through all immediate children. + */ void descend(VisitorBase *visitor) { std::for_each(_children.begin(), _children.end(), AcceptOp(visitor)); } + /** Propagate a visitor through all immediate parents. + */ void ascend(VisitorBase *visitor) { std::for_each(_parents.begin(), _parents.end(), AcceptOp(visitor)); *************** *** 255,262 **** --- 388,399 ---- private: + /** Add a new parent to this node. + */ void addParent(Node *node) { _parents.push_back(node); } + /** Remove a parent from this node. + */ void removeParent(Node *node) { typename ParentList::iterator iter; *************** *** 265,269 **** --- 402,409 ---- } + /// The immediate children of this node. ChildList _children; + + /// The immediate parents of this node. ParentList _parents; }; *************** *** 324,327 **** --- 464,544 ---- class Visitor: public VisitorCore< Visitable<V> > {}; + + /** A visitor class for searching a node graph. + * + * The visitor traverses the graph until the match() + * method returns true. Implement this method in a + * derived class to specify the search condition. + * Traversal stops as soon as a match is found. After + * traversal the getNode() method can be used + * to retrieve the matching node (if any). + */ + template <class N, class V> + class FindVisitor: public V { + public: + /** The search condition. + * + * Implement this condition in derived classes to + * deterimine which node is found. + */ + virtual bool match(N &node) = 0; + + /** Search for a matching node. + * + * Don't call this directly; use node->accept(visitor); + */ + void apply(N &node) { + if (_node.valid()) return; + if (match(node)) { + _node = &node; + setTraversalMode(TRAVERSE_NONE); + } else { + traverse(node); + } + } + + /** Get the node that match the search condition, if any. + */ + Ref<N> getNode() const { return _node; } + private: + /// The matching node. + Ref<N> _node; + }; + + + /** A visitor class for searching a node graph. + * + * This visitor is similar to FindVisitor, but retrieves + * all nodes that match the condition. + */ + template <class N, class V> + class FindAllVisitor: public V { + public: + typedef std::vector< Ref<N> > NodeList; + + /** The search condition. + * + * Implement this condition in derived classes to + * deterimine which nodes are found. + */ + virtual bool match(N &node) = 0; + + /** Search for and accumulate matching nodes. + * + * Don't call this directly; use node->accept(visitor); + */ + void apply(N &node) { + if (match(node)) { + _nodes.push_back(&node); + } + traverse(node); + } + /** Get all nodes that match the search condition. + */ + NodeList getNodes() const { return _nodes; } + private: + /// The matching nodes. + NodeList _nodes; + }; |
From: <mk...@us...> - 2003-09-06 01:37:24
|
Update of /cvsroot/csp/APPLICATIONS/SimData In directory sc8-pr-cvs1:/tmp/cvs-serv13938 Modified Files: Tag: b0_4_0 CHANGES.current setup.py Log Message: Index: CHANGES.current =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/CHANGES.current,v retrieving revision 1.75.2.2 retrieving revision 1.75.2.3 diff -C2 -d -r1.75.2.2 -r1.75.2.3 *** CHANGES.current 22 Aug 2003 00:21:44 -0000 1.75.2.2 --- CHANGES.current 6 Sep 2003 01:37:21 -0000 1.75.2.3 *************** *** 1,4 **** --- 1,29 ---- Version 0.4.0 (in progress) =========================== + 2003-09-05: onsight + Added Composite.h, which contains template classes for + implementing the Composite/Visitor design pattern. + + 2003-09-04: onsight + Changed Referenced from a nonvirtual to a virtual base class + of Object. + + 2003-08-25: onsight + Refactored InterfaceProxy, moving most of the functionality + into the InterfaceProxyBase class. The base class now + maintains a list of ObjectInterface instances that is used + to access externalized member variables. MemberAccessor + classes are now fully encapsulated within the templated + ObjectInterface classes, so that the ObjectInterfaceBase + class can be extended in Python without any of the template + metaprogramming trickery that C++ demands. + + ObjectInterfaceBase now also keeps track of the object + interface hierarchy (both by class name and hash). + + Access to the ObjectInterface corresponding to a particular + member variable name is now via a std::map lookup, which + should be faster than the previous implementation involving + a linear search via base class method calls. 2003-08-21: onsight Index: setup.py =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/setup.py,v retrieving revision 1.30.2.1 retrieving revision 1.30.2.2 diff -C2 -d -r1.30.2.1 -r1.30.2.2 *** setup.py 22 Aug 2003 00:21:44 -0000 1.30.2.1 --- setup.py 6 Sep 2003 01:37:21 -0000 1.30.2.2 *************** *** 257,260 **** --- 257,261 ---- "Archive.h", "BaseType.h", + "Composite.h", "Conversions.h", "DataArchive.h", |
From: <mk...@us...> - 2003-09-06 01:37:11
|
Update of /cvsroot/csp/APPLICATIONS/SimData/Include/SimData In directory sc8-pr-cvs1:/tmp/cvs-serv13890 Added Files: Tag: b0_4_0 Composite.h Log Message: Composite and visitor pattern templates --- NEW FILE: Composite.h --- /* SimData: Data Infrastructure for Simulations * Copyright (C) 2002, 2003 Mark Rose <tm...@st...> * * This file is part of SimData. * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /** * @file Composite.h * * Composite and Visitor design pattern templates. * **/ #ifndef __SIMDATA_COMPOSITE_H__ #define __SIMDATA_COMPOSITE_H__ #include <iostream> #include <cstdio> #include <vector> #include <SimData/Ref.h> NAMESPACE_SIMDATA /** Interface for nodes that can accept visitors. * * V is a context specific visitor class. */ template<class V> class Visitable; #define SIMDATA_VISITOR(visitor) \ typedef SIMDATA(Ref)<visitor> Ref; \ using SIMDATA(Visitor)<visitor>::apply; #define SIMDATA_VISITABLE(visitor) \ virtual SIMDATA(Ref)<visitor> accept(SIMDATA(Ref)<visitor> v) { \ v->apply(*this); \ return v; \ } /** Interface for nodes that contain other nodes. * * N is a context specific visitable node type. */ template<class N> class CompositeBase; /** Common base class for all Visitors. */ class VisitorBase: public virtual Referenced { }; /** Core visitor functionality. * * N is a context specific visitable node type. */ template <class N> class VisitorCore: public VisitorBase { public: typedef enum { TRAVERSE_NONE, TRAVERSE_CHILDREN, TRAVERSE_PARENTS, } TraversalMode; TraversalMode getTraversalMode() const { return _traversal_mode; } typedef CompositeBase<N> Node; virtual void apply(Node &node) { traverse(node); } VisitorCore(): _traversal_mode(TRAVERSE_CHILDREN) {} protected: void traverse(Node &node) { if (_traversal_mode == TRAVERSE_CHILDREN) { descend(node); } else if (_traversal_mode == TRAVERSE_PARENTS) { ascend(node); } } private: TraversalMode _traversal_mode; inline void ascend(Node &node); inline void descend(Node &node); }; /** Base interface for composite (visitable) nodes. * * N is a context specific visitable node type. */ template <class N> class CompositeBase: public virtual Referenced { friend class VisitorCore<N>; protected: virtual void descend(VisitorBase *v) = 0; virtual void ascend(VisitorBase *v) = 0; }; /** A visitable node class that can have multiple children and parents. * * Composite should be used as a base class for nodes * in a Composite/Visitor design pattern. First declare * a context specific visitor class (see Visitor), then * create use Composite<> as a base class for the * primary node type. Starting from a context specific * visitor (see Visitor for details) named MyNodeVisitor, * one would declare MyNode as: * * class MyNode: public Composite<MyNodeVisitor> { * public: * SIMDATA_VISITABLE(MyNodeVisitor); * // the rest of MyNode's declaration... * }; * * MyNode and each of its subclasses must define an * accept() method, which is just a couple lines of * boilerplate code handled by the SIMDATA_VISITABLE * macro (feel free to write it out by hand if you * despise macros). Defining accept() in each subclass * allows the overloaded apply() method in MyNodeVisitor * to be correctly selected based on the type of each * node. * * Notes: * * Although Composite supports multiple parents, this * capability can easily be disabled within a given * context by overriding the addChild() method of the * primary node class and testing that getNumOfParents() * equals zero for each child to be added. * * The current implementation does not support non- * composite leaf nodes. Any node can contain other * nodes, although again this feature can be disabled * for specific node classes simply by overriding * addChild(). * * @param V is a context specific visitor class. */ template <class V> class Composite: public Visitable<V>, public CompositeBase< Visitable<V> > { public: typedef Composite Node; typedef Ref<Node> NodeRef; typedef Ref<V> VisitorRef; typedef std::vector< NodeRef > ChildList; typedef std::vector< Node* > ParentList; virtual VisitorRef accept(VisitorRef v)=0; virtual bool addChild(Node *node) { if (containsNode(node)) return false; _children.push_back(node); node->addParent(this); return true; } virtual bool removeChild(Node *node) { return removeChild(getChildIndex(node)); } virtual bool removeChild(int pos, int count=1) { if (pos >= _children.size() || count <= 0) return false; unsigned int end = pos + count; if (end > _children.size()) { // TODO log warning end = _children.size(); } for (unsigned int i = pos; i < end; ++i) { _children[i]->removeParent(this); } _children.erase(_children.begin()+pos,_children.begin()+end); return true; } inline unsigned int getNumChildren() const { return _children.size(); } virtual bool setChild(unsigned int i, Node* node) { if (i >= _children.size() || !node) return false; NodeRef original = _children[i]; original->removeParent(this); _children[i] = node; node->addParent(this); return true; } inline Node* getChild(unsigned int i) { return _children[i].get(); } inline const Node* getChild(unsigned int i) const { return _children[i].get(); } inline ChildList const &getChildren() const { return _children; } inline bool containsNode(Node const *node) const { if (!node) return false; return std::find(_children.begin(), _children.end(), node) != _children.end(); } inline unsigned int getChildIndex(Node const *node) const { for (int idx = 0; idx < _children.size(); ++idx) { if (_children[idx] == node) return idx; } return _children.size(); // not found } inline const ParentList &getParents() const { return _parents; } inline Node* getParent(unsigned int i) { return _parents[i]; } inline const Node* getParent(unsigned int i) const { return _parents[i]; } inline unsigned int getNumParents() const { return _parents.size(); } protected: inline ParentList getParents() { return _parents; } class AcceptOp { typename Composite::VisitorRef _visitor; public: AcceptOp(VisitorBase *visitor) { _visitor = visitor; } void operator()(NodeRef node) { node->accept(_visitor); } }; void descend(VisitorBase *visitor) { std::for_each(_children.begin(), _children.end(), AcceptOp(visitor)); } void ascend(VisitorBase *visitor) { std::for_each(_parents.begin(), _parents.end(), AcceptOp(visitor)); } private: void addParent(Node *node) { _parents.push_back(node); } void removeParent(Node *node) { typename ParentList::iterator iter; iter = std::find(_parents.begin(), _parents.end(), node); if (iter != _parents.end()) _parents.erase(iter); } ChildList _children; ParentList _parents; }; template <class N> void VisitorCore<N>::descend(CompositeBase<N> &node) { node.descend(this); }; template <class N> void VisitorCore<N>::ascend(CompositeBase<N> &node) { node.ascend(this); }; template <class V> class Visitable: public virtual Referenced { public: virtual Ref<V> accept(Ref<V> v)=0; }; /** A context specific visitor class. * * Subclass Visitor to define a custom visitor class * for a specific context. Although somewhat counter * intuitive, the template parameter must be the sub- * class being defined. For example: * * class MyNode; * class MySpecialNode; * // forward declarations of other subclasses of MyNode * * class MyNodeVisitor: public Visitor<MyNodeVisitor> { * public: * using Visitor<MyNodeVisitor>::apply; * virtual void apply(MyNode &node) { apply((Node&)node); } * virtual void apply(MySpecialNode &node) { apply((MyNode&)node); } * // apply stubs for any other subclasses of MyNode * } * * Note first that the base class apply() method must be brought * into scope with a using directive. There is also a macro * SIMDATA_VISITOR() which does this and defines a Ref typedef, * if you prefer using macros for boilerplate. * * The rest of the class should define apply() stubs for each of * the node classes in the current context. Each of these node * classes must be forward declared, and the apply stubs should * chain from subclass to baseclass, ending finally with a call * to apply((Node&)node), where Node is a type defined by Visitor * that will be a base class of MyNode as long as MyNode * derives from Composite<>. See Composite for more details. */ template <class V> class Visitor: public VisitorCore< Visitable<V> > {}; NAMESPACE_SIMDATA_END #endif // __SIMDATA_COMPOSITE_H__ |
From: <mk...@us...> - 2003-09-05 08:40:11
|
Update of /cvsroot/csp/APPLICATIONS/CSPSim/Include In directory sc8-pr-cvs1:/tmp/cvs-serv15965 Added Files: Updater.h Log Message: synchronous timed update interface --- NEW FILE: Updater.h --- // Combat Simulator Project - CSPSim // Copyright (C) 2003 The Combat Simulator Project // http://csp.sourceforge.net // // 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** * @file Updater.h * **/ #ifndef __UPDATER_H__ #define __UPDATER_H__ #include <SimData/Ref.h> #include <sigc++/signal_system.h> #include <list> /** An interface for implementing synchronous timed updates. * * The simulation calls update(dt) after each frame, with * dt equal to the time between frames. This method in * turn calls onUpdate(), which should be extended by * subclasses to implement time-dependent behavior. The * onUpdate() method returns the minimum time to sleep * before the next call. A return value of zero means to * call onUpdate() again as soon as the next update() call * occurs. Longer return values will mean that several * update() calls will take place before the next onUpdate() * call. * * Additional support is provided for timed callbacks and * chaining update calls to child objects. */ class Updater: public virtual simdata::Referenced, public virtual SigC::Object { public: /// Updater reference (convenience) type. typedef simdata::Ref<Updater> Ref; protected: /// A signal type for interval timer callbacks typedef SigC::Signal1<void,double> UpdateSignal; /** * Default constructor. */ Updater(): m_Sleep(0.0), m_Time(0.0) {} private: /** An internal structure for storing timed update states. */ struct TimedUpdate: public simdata::Referenced { UpdateSignal _signal; double _interval; double _lapse; int _count; bool _dead; bool update(double dt) { _lapse += dt; if (!_dead && _lapse > _interval) { _signal.emit(_lapse); _lapse = 0.0; if (_count > 0 && --_count == 0) { _dead = true; } } return _dead; } TimedUpdate(double interval, int count): _interval(interval), _lapse(0.0), _count(count) { } }; /** An internal function adapter for updating TimedUpdates */ struct UpdateAndExpireOp { double dt; UpdateAndExpireOp(double dt_): dt(dt_) {} bool operator()(simdata::Ref<TimedUpdate> &tu) { return tu->update(dt); } }; /** An internal predicate for updater removal. */ struct MatchesSignalOp { UpdateSignal const &signal; MatchesSignalOp(UpdateSignal const &signal_): signal(signal_) {} void operator()(simdata::Ref<TimedUpdate> &tu) { if (&(tu->_signal) == &signal) { tu->_dead = true; } } }; /** An internal helper for updating and culling the timed updates list. */ template<typename C, typename T> T UpdateAndCull(C &c, T t) { c.erase(std::remove_if(c.begin(), c.end(), t), c.end()); return t; } /** A list of active timed updates. */ std::list< simdata::Ref<TimedUpdate> > m_TimedUpdates; /** An internal predicate for updating child objects. */ class UpdateOp { double m_dt; public: UpdateOp(double dt): m_dt(dt) {} void operator()(Updater::Ref u) { u->update(m_dt); } }; /// Time remaining until next onUpdate() call. double m_Sleep; /// Time interval between calls to onUpdate(). double m_Interval; /** Internal method to drive timed updates and call onUpdate(). */ void __update() { double dt = m_Interval - m_Sleep; UpdateAndCull(m_TimedUpdates, UpdateAndExpireOp(dt)); m_Interval = onUpdate(dt); m_Sleep = m_Interval; } protected: /** Create a new timed update signal. * * Connect callback slots to the returned update signal, * which will then be called automatically at regular * intervals during the usual onUpdate() handler. * * @param interval The time interval between update signals * in seconds. * @param count The number of calls before the signal is * destroyed (0 for perpetual). * @returns A SigC signal object (see the libsigc++ documentation * for details on connecting callback methods). */ UpdateSignal &addTimedUpdate(double interval, int count=0) { simdata::Ref<TimedUpdate> tu = new TimedUpdate(interval, count); m_TimedUpdates.push_back(tu); return tu->_signal; } /** Remove a timed update signal. * * @param signal The UpdateSignal reference returned by * addTimedUpdate. */ void removeTimedUpdate(UpdateSignal const &signal) { std::for_each(m_TimedUpdates.begin(), m_TimedUpdates.end(), MatchesSignalOp(signal)); } /** A helper template for updating child objects. * * @param children An STL forward container supporting begin() and end(). * @param dt The time interval since the last update. */ template <typename C> void updateChildren(C &children, double dt) { std::for_each(children.begin(), children.end(), UpdateOp(dt)); } /** An update method to be implemented in derived classes. * * This method is called by update() to drive time-dependent * behavior in derived classes. Subclasses that have child * components stored in a list should use updateChildren() to * propagate the update, or they may simply call each child's * update() method by hand. The return value is the minimum * time interval to "sleep" until the next onUpdate() call. * This value should be used by Objects that do not need * frequent updates to reduce processing overhead. Bear in * mind that the minimum time resolution for the sleep interval * is determined by frequency of update() calls. It is also * very important to note that the timed update callbacks (set * with addTimedUpdate) are only checked when onUpdate() is * called, so long sleep intervals can interfere with these * updates. * * @param dt Time since the last call to onUpdate(). * @returns The minimum time to sleep (in seconds) until the * next onUpdate() call. Returning zero gives the * maximum rate of once per update() call. */ virtual double onUpdate(double dt) = 0; public: /** Update this object. * * This method waits until the time to sleep from the last * onUpdate() call has expired, then drives the timed * interval callbacks and calls onUpdate(). * * @param dt The time interval since the last call to update(). */ inline void update(double dt) { m_Sleep -= dt; if (m_Sleep < 0.0) __update(); } }; #endif // __UPDATER_H__ |
From: <mk...@us...> - 2003-09-03 03:09:07
|
Update of /cvsroot/csp/APPLICATIONS/CSPSim/Source In directory sc8-pr-cvs1:/tmp/cvs-serv7663 Modified Files: Bus.cpp Log Message: Index: Bus.cpp =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/CSPSim/Source/Bus.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Bus.cpp 2 Sep 2003 20:39:25 -0000 1.1 --- Bus.cpp 3 Sep 2003 03:09:04 -0000 1.2 *************** *** 1,3 **** ! #include <SimData/Ref.h> #include <SimData/Key.h> #include <map> --- 1,28 ---- ! // Combat Simulator Project - FlightSim Demo ! // Copyright (C) 2003 The Combat Simulator Project ! // http://csp.sourceforge.net ! // ! // 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! ! ! /** ! * @file Bus.cpp ! * ! **/ ! ! ! #include <SimData/Object.h> #include <SimData/Key.h> #include <map> *************** *** 14,21 **** direct comments to the csp developer's forum. ! The code compiles with gcc-3.3 under Linux, but has not been ! tested at all under Windows. To build an executable you will ! need to install libsigc++ (Google: libsigc++). The following ! command works for me but may need tweaking on other systems: g++-3.3 -I/usr/include/python2.2 --- 39,47 ---- direct comments to the csp developer's forum. ! The code builds with gcc-3.2 and gcc-3.3 under Linux, but has ! not been tested at all under Windows. To build an executable ! you will need to install libsigc++ (Google: libsigc++). The ! following command works for me but may need tweaking on other ! systems: g++-3.3 -I/usr/include/python2.2 *************** *** 24,32 **** -L/usr/lib/python2.2/site-packages/SimData -g -O2 ! bus.cpp -lSimData -lsigc -lpthread */ class Bus; --- 50,60 ---- -L/usr/lib/python2.2/site-packages/SimData -g -O2 ! Bus.cpp ! -o BusTest -lSimData -lsigc -lpthread */ class Bus; + class Model; *************** *** 42,48 **** * by other systems over the bus. */ ! class System: public simdata::Referenced, public SigC::Object { friend class Bus; protected: /** Register channels for access to internal data by other * systems on the bus. --- 70,115 ---- * by other systems over the bus. */ ! class System: public simdata::Object, public SigC::Object { friend class Bus; + friend class Model; + protected: + + typedef SigC::Signal1<void,double> UpdateSignal; + + private: + + Model* m_Model; + std::string m_Name; + + struct TimedUpdate: public simdata::Referenced { + UpdateSignal _signal; + double _interval; + double _lapse; + void update(double dt) { + _lapse += dt; + if (_lapse > _interval) { + _signal.emit(_lapse); + _lapse = 0.0; + } + } + TimedUpdate(double interval): _interval(interval), _lapse(0.0) {} + }; + + struct TimedUpdater { + double dt; + TimedUpdater(double dt_): dt(dt_) {} + void operator()(simdata::Ref<TimedUpdate> &tu) { tu->update(dt); } + }; + + std::vector< simdata::Ref<TimedUpdate> > m_TimedUpdates; + + protected: + UpdateSignal &addTimedUpdate(double interval) { + simdata::Ref<TimedUpdate> tu = new TimedUpdate(interval); + m_TimedUpdates.push_back(tu); + return tu->_signal; + } + /** Register channels for access to internal data by other * systems on the bus. *************** *** 51,55 **** * if the system may be attached to more than one bus. */ ! virtual void registerChannels(Bus *bus) {} /** Bind to channels provided by other systems on the bus. --- 118,122 ---- * if the system may be attached to more than one bus. */ ! virtual void registerChannels() {} /** Bind to channels provided by other systems on the bus. *************** *** 60,73 **** * system member variables for later use. */ ! virtual void bind(Bus *bus) {} ! public: ! /** System reference (convenience) type. ! */ ! typedef simdata::Ref< System > Ref; /** Destructor. */ virtual ~System() {} }; --- 127,159 ---- * system member variables for later use. */ ! virtual void bind() {} ! inline void setModel(Model *model); ! ! // XXX use raw pointers here to prevent circular references ! // that keep the model alive. the model pointer is only ! // for internal use by the system instance, which will be ! // destroyed when the model goes out of scope. ! inline Model* getModel() const; /** Destructor. */ virtual ~System() {} + public: + + System(std::string const &name): m_Name(name) {} + + std::string const &getName() const { return m_Name; } + + virtual void onUpdate(double dt) { + std::for_each(m_TimedUpdates.begin(), + m_TimedUpdates.end(), + TimedUpdater(dt)); + } + + /** System reference (convenience) type. + */ + typedef simdata::Ref<System> Ref; + }; *************** *** 316,328 **** class Bus: public simdata::Referenced { - /// Key to system map type - typedef std::map<simdata::Key, System::Ref> SystemMap; - /// Key to channl map type typedef std::map<simdata::Key, ChannelBase::Ref> ChannelMap; - /// Map of all systems connected to the bus - SystemMap m_Systems; - /// Map of all channels connected to the bus ChannelMap m_Channels; --- 402,408 ---- *************** *** 344,368 **** typedef simdata::Ref<Bus> Ref; - /** Attach a system to this bus. - * - * Any number of systems may be attached to the bus prior - * to calling bind(). Systems are identified internally by - * a hash key generated from their name. These keys must be - * unique and an assertion will be raised if a system with - * the same hash key has already been added to the bus. - * - * This method calls the system's registerChannels() method. - * - * @param system The system to attach. - * @param name The string identifier of the system. - */ - void attachSystem(System::Ref system, std::string const &name) { - assert(!m_Bound); - assert(!hasSystem(name)); - simdata::Key key(name); - m_Systems[key] = system; - system->registerChannels(this); - } - /** Test if a particular data channel is available. */ --- 424,427 ---- *************** *** 371,380 **** } - /** Test if a particular system is connected. - */ - bool hasSystem(std::string const &name) { - return getSystem(name).valid(); - } - /** Register a new channel. * --- 430,433 ---- *************** *** 391,419 **** } - /** Bind all connected systems to data channels on the bus. - * - * Bus construction is a two step process. First systems are - * added using attachSystem(). This method in turn calls each - * system's registerChannels method to declare all the channels - * that the system exports. Once all systems are attached, - * bindSystems() calls each system's bind() method to allow it to - * obtain references to data channels provided by other systems. - * This is only done once, and subsequent calls to bindSystems() - * have no effect. - * - * It is currently an (assertion) error to call attachSystem() - * after bindSystems() has been called. If the need arises - * to provide greater flexibility for dynamically attaching - * systems to the bus, this requirement can be relaxed. - */ - void bindSystems() { - if (m_Bound) return; - for (SystemMap::iterator iter = m_Systems.begin(); - iter != m_Systems.end(); ++iter) { - iter->second->bind(this); - } - m_Bound = true; - } - /** Get the name of this bus. */ --- 444,447 ---- *************** *** 460,475 **** } - /** Get a system by name. - * - * @returns A reference to the system or a null reference if the - * system is not connected to the bus. - */ - System::Ref getSystem(std::string const &name) { - simdata::Key key(name); - SystemMap::iterator iter = m_Systems.find(key); - if (iter == m_Systems.end()) return 0; - return iter->second; - } - /** Get the bus status value. */ --- 488,491 ---- *************** *** 515,518 **** --- 531,612 ---- + class Model: public simdata::Object { + + typedef std::map<std::string, Bus::Ref> BusMap; + + typedef std::map<std::string, System::Ref> SystemMap; + + BusMap m_Buses; + + SystemMap m_Systems; + + protected: + + Bus* addBus(std::string const &name) { + assert(m_Buses.find(name) == m_Buses.end()); + Bus *bus = new Bus(name); + m_Buses[name] = bus; + return bus; + } + + System* addSystem(System *system) { + assert(system); + std::string name = system->getName(); + assert(m_Systems.find(name) == m_Systems.end()); + m_Systems[system->getName()] = system; + system->setModel(this); + system->registerChannels(); + return system; + } + + void bindSystems() { + for (SystemMap::iterator iter = m_Systems.begin(); + iter != m_Systems.end(); ++iter) { + iter->second->bind(); + } + } + + virtual ~Model() { + } + + public: + + Bus::Ref getBus(std::string const &name, bool required = true) const { + BusMap::const_iterator iter = m_Buses.find(name); + if (iter == m_Buses.end()) { + assert(!required); + return 0; + } + return iter->second; + } + + System::Ref getSystem(std::string const &name, bool required = true) const { + SystemMap::const_iterator iter = m_Systems.find(name); + if (iter == m_Systems.end()) { + assert(!required); + return 0; + } + return iter->second; + } + + Model(): simdata::Object() {} + + virtual void onUpdate(double dt) { + SystemMap::iterator iter = m_Systems.begin(); + for (; iter != m_Systems.end(); ++iter) { + iter->second->onUpdate(dt); + } + } + + }; + + + void System::setModel(Model *model) { + assert(m_Model == 0); + m_Model = model; + } + + Model* System::getModel() const { return m_Model; } + *************** *** 526,530 **** struct MFD: public System { ! void registerChannels(Bus *bus); Channel<int>::Ref m_MasterMode; Channel<int>::Ref m_Submode; --- 620,625 ---- struct MFD: public System { ! MFD(std::string const &name = "MFD"): System(name) {} ! void registerChannels(); Channel<int>::Ref m_MasterMode; Channel<int>::Ref m_Submode; *************** *** 532,546 **** }; ! void MFD::registerChannels(Bus *bus) { ! if (bus->getName()=="A") { ! m_MasterMode = bus->registerChannel(new Channel<int>("MasterMode", 0)); ! m_Submode = bus->registerChannel(new Channel<int>("Submode", 1)); ! m_Submode->connect(this, &MFD::getSubMode, false); ! } m_MasterMode->set(1); } struct FCS: public System { ! void bind(Bus *bus); void onMasterMode(); Channel<int>::CRef m_MasterMode; --- 627,641 ---- }; ! void MFD::registerChannels() { ! Bus::Ref bus = getModel()->getBus("A"); ! m_MasterMode = bus->registerChannel(new Channel<int>("MasterMode", 0)); ! m_Submode = bus->registerChannel(new Channel<int>("Submode", 1)); ! m_Submode->connect(this, &MFD::getSubMode, false); m_MasterMode->set(1); } struct FCS: public System { ! FCS(std::string const &name = "FCS"): System(name) {} ! void bind(); void onMasterMode(); Channel<int>::CRef m_MasterMode; *************** *** 548,559 **** }; ! void FCS::bind(Bus *bus) { ! if (bus->getName()=="A") { ! m_MasterMode = bus->getChannel("MasterMode"); ! m_MasterMode->connect(this, &FCS::onMasterMode); ! m_Submode = bus->getChannel("Submode"); ! std::cout << m_Submode->get() << " is the answer?\n"; ! ! } } --- 643,653 ---- }; ! void FCS::bind() { ! Bus::Ref bus = getModel()->getBus("A"); ! assert(bus.valid()); ! m_MasterMode = bus->getChannel("MasterMode"); ! m_MasterMode->connect(this, &FCS::onMasterMode); ! m_Submode = bus->getChannel("Submode"); ! std::cout << m_Submode->get() << " is the answer?\n"; } *************** *** 571,603 **** } ! void AvionicsSuite() { ! std::cout << "avionics suite\n"; ! Bus::Ref busA = new Bus("A"); ! System::Ref m_FCS = new FCS(); ! System::Ref m_MFD = new MFD(); ! busA->attachSystem(m_FCS, "FCS"); ! busA->attachSystem(m_MFD, "MFD"); ! busA->bindSystems(); ! Channel<int>::Ref mm = busA->getSharedChannel("MasterMode"); ! Channel<int>::Ref sm = busA->getSharedChannel("Submode"); ! std::cout << sizeof(*mm) << " bytes\n"; ! simdata::SimTime t0, t1; ! t0 = simdata::SimDate::getSystemTime(); ! for (int i = 0; i < 1000000; i++) { ! mm->set(i); } ! t1 = simdata::SimDate::getSystemTime(); ! std::cout << (t1-t0) << " us\n"; ! t0 = simdata::SimDate::getSystemTime(); ! for (int i = 0; i < 1000000; i++) { ! sm->set(i); } - t1 = simdata::SimDate::getSystemTime(); - std::cout << (t1-t0) << " us\n"; }; int main() { ! AvionicsSuite(); return 0; } ! --- 665,710 ---- } ! struct Avionics: public Model { ! void init() { ! addBus("A"); ! addSystem(new MFD("MFD")); ! addSystem(new FCS("FCS")); ! bindSystems(); } ! ! void test() { ! std::cout << "avionics suite\n"; ! System::Ref m_FCS = getSystem("FCS"); ! System::Ref m_MFD = getSystem("MFD"); ! Bus::Ref busA = getBus("A"); ! Channel<int>::Ref mm = busA->getSharedChannel("MasterMode"); ! Channel<int>::Ref sm = busA->getSharedChannel("Submode"); ! std::cout << sizeof(*mm) << " bytes\n"; ! simdata::SimTime t0, t1; ! t0 = simdata::SimDate::getSystemTime(); ! for (int i = 0; i < 1000000; i++) { ! mm->set(i); ! } ! t1 = simdata::SimDate::getSystemTime(); ! std::cout << (t1-t0) << " us\n"; ! t0 = simdata::SimDate::getSystemTime(); ! for (int i = 0; i < 1000000; i++) { ! sm->set(i); ! } ! t1 = simdata::SimDate::getSystemTime(); ! std::cout << (t1-t0) << " us\n"; ! } ! ! ~Avionics() { ! std::cout << "~Avionics\n"; } }; + /* int main() { ! Avionics a; ! a.init(); ! a.test(); return 0; } ! */ |
From: <mk...@us...> - 2003-09-02 20:39:59
|
Update of /cvsroot/csp/APPLICATIONS/CSPSim/Source In directory sc8-pr-cvs1:/tmp/cvs-serv4428 Added Files: Bus.cpp Log Message: Data bus implementation --- NEW FILE: Bus.cpp --- #include <SimData/Ref.h> #include <SimData/Key.h> #include <map> #include <sigc++/signal_system.h> /* README This a preliminary implementation of a data bus architecture for sharing data between multiple systems comprising a detailed vehicle model. This code is not yet part of CSPSim but has been added to CVS for safekeeping and public access. Please direct comments to the csp developer's forum. The code compiles with gcc-3.3 under Linux, but has not been tested at all under Windows. To build an executable you will need to install libsigc++ (Google: libsigc++). The following command works for me but may need tweaking on other systems: g++-3.3 -I/usr/include/python2.2 -I/usr/include/sigc++-1.0 -I/usr/lib/sigc++-1.0/include -L/usr/lib/python2.2/site-packages/SimData -g -O2 bus.cpp -lSimData -lsigc -lpthread */ class Bus; /** Base class for vehicle system components that can be connected * to a data bus. * * Subclasses should implement registerChannels() and bind(). The * former is used to expose internal data that can be accessed by * other systems over the bus, and is called automatically by the * bus when the system is first attached. The bind() method is * called once by the bus after all systems have been attached and * registered. Use this method to bind to data channels provided * by other systems over the bus. */ class System: public simdata::Referenced, public SigC::Object { friend class Bus; protected: /** Register channels for access to internal data by other * systems on the bus. * * Use bus->getName() to select which channels to register * if the system may be attached to more than one bus. */ virtual void registerChannels(Bus *bus) {} /** Bind to channels provided by other systems on the bus. * * Call bus->getChannel() and bus->getSharedChannel() to * obtain references to data channels available on the * bus. These references should generally be stored as * system member variables for later use. */ virtual void bind(Bus *bus) {} public: /** System reference (convenience) type. */ typedef simdata::Ref< System > Ref; /** Destructor. */ virtual ~System() {} }; /** Base class for data channels on a bus. * * This class provides basic data channel functionality without * specializing to a particular data type. Data channels are * reference counted objects. The references are stored both in * the bus (which provides name-based channel lookups) and in * individual systems as member variable references. The data * channel may therefore persist even if the system originally * defining the channel is destroyed. * * Data channels support either push and pull based value updates, * and must be specialized when the first signal handler is * connected. For push channels, any change to the channel value * will send a signal to all callbacks connected to the channel. * For pull channels, any attempt to read a channel value will * first send a signal to a callback that can update the value. * In this case only one callback may be connected to the channel, * usually by the system that creates the channel. */ class ChannelBase: public simdata::Referenced { friend class Bus; private: /// Channel state flags. enum { ENABLED = 1, BLOCKED = 2, HANDLER = 4, PUSH = 8, SHARED = 16, }; /// Hash key identifier for this channel. simdata::Key m_Key; /// Bitmask for channel options. mutable unsigned int m_Mask; /// Callback signal for push/pull channels. mutable SigC::Signal0<void> m_Signal; protected: /** Get the (unique) identifier key for this channel. */ simdata::Key const &getKey() const { return m_Key; } /** Mark a channel as enabled or disabled. * * The channel enabled/disabled flag is not actively * enforced. It is the responsibility of code using * the channel to test the channel status and behave * accordingly. */ void setEnabled(bool enabled) { m_Mask = (m_Mask & ~ENABLED) | (enabled ? ENABLED : 0); } /** Construct a new channel. * * @param name The name of the channel (used to generate the * identifier key). * @param shared Shared channels may be accessed via the bus as * non-const references, allowing any system to * update the channel value. */ ChannelBase(std::string const &name, bool shared=true): m_Mask(0) { simdata::Key key(name); m_Key = key; m_Mask |= shared ? SHARED : 0; } /** Test if the channel has had at least one signal handler * connected. * * Note that handlers are not tracked beyond their initial * connection to the channel, so it is possible for this * method to return true even if no handlers are currently * connected. This flag is used as an internal optimization * for channels that have never been connected to a signal * handler. */ int hasHandler() const { return m_Mask & HANDLER; } /** Send a signal to all connected handlers. * * For push channels this is used to signal a change of the * data value, while for pull channels this signal is used * to update the data value. */ void signal() const { m_Signal.emit(); } /** Test if this is a push (or pull) channel. */ bool isPush() const { return m_Mask & PUSH; } public: /// ChannelBase reference (convenience) type for shared channels. typedef simdata::Ref< ChannelBase > Ref; /// ChannelBase reference (convenience) type for non-shared channels. typedef simdata::Ref< ChannelBase const > CRef; /** Test if a channel is enabled. */ bool isEnabled() const { return m_Mask & ENABLED; } /** Test if this channel is shared. * * Shared channels can be updated by any system, whereas non-shared * channels are read-only (except for the system that creates them). */ bool isShared() const { return m_Mask & SHARED; } /** A convenience class for defining Python signal handlers using SWIG. */ class Handler: public SigC::Object { public: virtual ~Handler() {} void handle() { operator()(); } virtual void operator()(void)=0; }; /** Connect a signal handler to this channel. * * If push is true, this method may be called any number of times to * connect multiple handlers. If push is false, no additional calls * to <tt>connect</tt> may be made. The first call to <tt>connect</tt> * permanently establishes whether the channel is push or pull. * * @param object The instance providing the handler. * @param callback The class method used to handle the signal. * @param push Connect a push (or pull) handler. */ template <class T> SigC::Connection connect(T *object, void (T::*callback)(), bool push=true) const { assert(push == isPush() || !hasHandler()); if (push) m_Mask |= PUSH; m_Mask |= HANDLER; return m_Signal.connect(SigC::slot(object, callback)); } /** Connect a signal handler to this channel. * * See <tt>connect(T*, void (T::*)(), bool)</tt>. * * @param handler The callback handler. * @param push Connect a push (or pull) handler. */ SigC::Connection connect(Handler *handler, bool push=true) const { return connect(handler, &Handler::handle, push); } }; /** Channel for passing data between systems over a Bus. * * Channels are type-specialized objects which store a data * value and can be shared (by reference) by multiple systems * connected to a data bus. In addition to the push/pull * signaling functionality provided by the ChannelBase base * class, this subclass defines accessor methods for the * underlying data value. */ template <typename T> class Channel: public ChannelBase { /// The data value provided by the channel. T m_Value; public: /// Channel reference (convenience) type for shared channels. typedef simdata::Ref< Channel<T> > Ref; /// Channel reference (convenience) type for non-shared channels. typedef simdata::Ref< Channel<T> const > CRef; /** Set the value of a channel. * * See set(). */ T const & operator = (T const &value) { bool changed = hasHandler() && isPush() && (m_Value != value); m_Value = value; if (changed) { signal(); } } /** Get the value of a channel. * * For pull channels, this method sends a signal to the update * handler before reading the data value. */ T const &get() const { if (hasHandler() && !isPush()) { signal(); } return m_Value; } /** Set the value of a channel. * * For push channels this method sends a signal to all connected * handlers after the data value changes. */ void set(T const &value) { *this = value; } /** Construct a new shared channel. * * This constructor does not explicitly initialize the data value * provided by the channel. * * @param name The string identifier of the channel. */ Channel(std::string const &name): ChannelBase(name, true) {} /** Construct and initialize a new channel. * * This constructor can be used to create either a shared or * non-shared channel, and allows the channel data value to be * explicitly initialized. * * @param name The string indetifier of the channel. * @param value The initial value of the channel data. * @param shared Create a shared (or non-shared) channel. */ Channel(std::string const &name, T const &value, bool shared=true): m_Value(value), ChannelBase(name, shared) {} }; /** A data bus class for passing data between multiple Systems. * * Bus instances are essentially just collections of data channels, * providing some convenience methods for accessing channels and * connecting systems. Systems connected by a Bus can exchange * information synchonously or asynchronously using an efficient * string-based interface. No detailed (compile-time) knowledge * of the system class interfaces is required, which allows for a * much more flexible design of system class hierarchies. */ class Bus: public simdata::Referenced { /// Key to system map type typedef std::map<simdata::Key, System::Ref> SystemMap; /// Key to channl map type typedef std::map<simdata::Key, ChannelBase::Ref> ChannelMap; /// Map of all systems connected to the bus SystemMap m_Systems; /// Map of all channels connected to the bus ChannelMap m_Channels; /// Internal flag to help ensure proper bus construction. bool m_Bound; /// The identifier string of this bus. std::string m_Name; /// The status (0-1) used for damage modelling. float m_Status; /// Internal state of the bus. bool m_Enabled; public: /// Bus reference (convenience) type typedef simdata::Ref<Bus> Ref; /** Attach a system to this bus. * * Any number of systems may be attached to the bus prior * to calling bind(). Systems are identified internally by * a hash key generated from their name. These keys must be * unique and an assertion will be raised if a system with * the same hash key has already been added to the bus. * * This method calls the system's registerChannels() method. * * @param system The system to attach. * @param name The string identifier of the system. */ void attachSystem(System::Ref system, std::string const &name) { assert(!m_Bound); assert(!hasSystem(name)); simdata::Key key(name); m_Systems[key] = system; system->registerChannels(this); } /** Test if a particular data channel is available. */ bool hasChannel(std::string const &name) { return getChannel(name).valid(); } /** Test if a particular system is connected. */ bool hasSystem(std::string const &name) { return getSystem(name).valid(); } /** Register a new channel. * * This method is typically called from a system's registerChannels * method to register all data channels that the system provides * via this bus. The return value can be used to store a local * reference to the new channel. */ ChannelBase* registerChannel(ChannelBase *channel) { simdata::Key key = channel->getKey(); assert(m_Channels.find(key) == m_Channels.end()); m_Channels[key] = channel; return channel; } /** Bind all connected systems to data channels on the bus. * * Bus construction is a two step process. First systems are * added using attachSystem(). This method in turn calls each * system's registerChannels method to declare all the channels * that the system exports. Once all systems are attached, * bindSystems() calls each system's bind() method to allow it to * obtain references to data channels provided by other systems. * This is only done once, and subsequent calls to bindSystems() * have no effect. * * It is currently an (assertion) error to call attachSystem() * after bindSystems() has been called. If the need arises * to provide greater flexibility for dynamically attaching * systems to the bus, this requirement can be relaxed. */ void bindSystems() { if (m_Bound) return; for (SystemMap::iterator iter = m_Systems.begin(); iter != m_Systems.end(); ++iter) { iter->second->bind(this); } m_Bound = true; } /** Get the name of this bus. */ std::string const &getName() const { return m_Name; } /** Get a reference to a shared data channel. * * This method will raise an assertion if the channel is non-shared. * * @param name The name of the channel. * @param required If true, an assertion will be raised if the * requested channel does not exist. Otherwise * missing channels will be returned as null * references. * @returns A non-const reference to the data channel or a null * reference if the data channel is not found and required * is false. */ ChannelBase::Ref getSharedChannel(std::string const &name, bool required = true) { simdata::Key key(name); ChannelMap::iterator iter = m_Channels.find(key); if (iter == m_Channels.end()) { assert(!required); return 0; } assert(iter->second->isShared()); return iter->second; } /** Get a reference to a shared or non-shared data channel. * * This method is identical to getSharedChannel, but returns a * const reference to the channel so that the data value may be * read but not modified. */ ChannelBase::CRef getChannel(std::string const &name, bool required = true) { simdata::Key key(name); ChannelMap::iterator iter = m_Channels.find(key); if (iter == m_Channels.end()) { assert(!required); return 0; } return iter->second; } /** Get a system by name. * * @returns A reference to the system or a null reference if the * system is not connected to the bus. */ System::Ref getSystem(std::string const &name) { simdata::Key key(name); SystemMap::iterator iter = m_Systems.find(key); if (iter == m_Systems.end()) return 0; return iter->second; } /** Get the bus status value. */ float getStatus() const { return m_Status; } /** Test if the bus is enabled. */ bool isEnabled() const { return m_Enabled; } /** Enable or disable the bus. */ void setEnabled(bool enabled) { if (enabled == m_Enabled) return; for (ChannelMap::iterator iter = m_Channels.begin(); iter != m_Channels.end(); ++iter) { iter->second->setEnabled(enabled); } m_Enabled = enabled; } /** Change the bus status value. */ virtual void setStatus(float status) { m_Status = status; // disable or enable a proportionate number of accessors } /** Construct a new Bus. * * The bus is enabled by default. * * @param name The name of the bus. */ Bus(std::string const &name): m_Name(name), m_Bound(false), m_Status(1.0), m_Enabled(true) { } }; ///////////////////////////////////////////////////////////////////////////////////// // TESTING ///////////////////////////////////////////////////////////////////////////////////// #include <SimData/Date.h> #include <iostream> #include <cstdio> struct MFD: public System { void registerChannels(Bus *bus); Channel<int>::Ref m_MasterMode; Channel<int>::Ref m_Submode; void getSubMode() { *m_Submode = 42; } }; void MFD::registerChannels(Bus *bus) { if (bus->getName()=="A") { m_MasterMode = bus->registerChannel(new Channel<int>("MasterMode", 0)); m_Submode = bus->registerChannel(new Channel<int>("Submode", 1)); m_Submode->connect(this, &MFD::getSubMode, false); } m_MasterMode->set(1); } struct FCS: public System { void bind(Bus *bus); void onMasterMode(); Channel<int>::CRef m_MasterMode; Channel<int>::CRef m_Submode; }; void FCS::bind(Bus *bus) { if (bus->getName()=="A") { m_MasterMode = bus->getChannel("MasterMode"); m_MasterMode->connect(this, &FCS::onMasterMode); m_Submode = bus->getChannel("Submode"); std::cout << m_Submode->get() << " is the answer?\n"; } } void FCS::onMasterMode() { return; int mode = m_MasterMode->get(); if (mode < 0) std::cout << "master mode set to " << mode << "\n"; switch (mode) { case 0: // ... break; case 1: // ... break; // ... } } void AvionicsSuite() { std::cout << "avionics suite\n"; Bus::Ref busA = new Bus("A"); System::Ref m_FCS = new FCS(); System::Ref m_MFD = new MFD(); busA->attachSystem(m_FCS, "FCS"); busA->attachSystem(m_MFD, "MFD"); busA->bindSystems(); Channel<int>::Ref mm = busA->getSharedChannel("MasterMode"); Channel<int>::Ref sm = busA->getSharedChannel("Submode"); std::cout << sizeof(*mm) << " bytes\n"; simdata::SimTime t0, t1; t0 = simdata::SimDate::getSystemTime(); for (int i = 0; i < 1000000; i++) { mm->set(i); } t1 = simdata::SimDate::getSystemTime(); std::cout << (t1-t0) << " us\n"; t0 = simdata::SimDate::getSystemTime(); for (int i = 0; i < 1000000; i++) { sm->set(i); } t1 = simdata::SimDate::getSystemTime(); std::cout << (t1-t0) << " us\n"; }; int main() { AvionicsSuite(); return 0; } |
From: <mk...@us...> - 2003-08-22 20:44:00
|
Update of /cvsroot/csp/APPLICATIONS/SimData/Include/SimData In directory sc8-pr-cvs1:/tmp/cvs-serv23876/Include/SimData Modified Files: Vector3.h Log Message: Index: Vector3.h =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/Include/SimData/Vector3.h,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** Vector3.h 20 Aug 2003 03:41:40 -0000 1.15 --- Vector3.h 21 Aug 2003 04:13:54 -0000 1.16 *************** *** 237,241 **** /// Get the length squared of the vector = v*v ! inline doublelength2() const { return _x*_x + _y*_y + _z*_z; } --- 237,241 ---- /// Get the length squared of the vector = v*v ! inline double length2() const { return _x*_x + _y*_y + _z*_z; } |
From: <mk...@us...> - 2003-08-22 03:42:25
|
Update of /cvsroot/csp/APPLICATIONS/SimData In directory sc8-pr-cvs1:/tmp/cvs-serv23966 Modified Files: CHANGES.current Log Message: Index: CHANGES.current =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/CHANGES.current,v retrieving revision 1.72 retrieving revision 1.73 diff -C2 -d -r1.72 -r1.73 *** CHANGES.current 20 Aug 2003 02:47:09 -0000 1.72 --- CHANGES.current 21 Aug 2003 04:14:19 -0000 1.73 *************** *** 2,5 **** --- 2,8 ---- =========================== + 2003-08-20: onsight + Fixed typo in Vector3.h + 2003-08-19: onsight Added documentation. |
From: <mk...@us...> - 2003-08-22 03:34:53
|
Update of /cvsroot/csp/APPLICATIONS/SimData In directory sc8-pr-cvs1:/tmp/cvs-serv25844 Modified Files: CHANGES.current Log Message: Index: CHANGES.current =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/CHANGES.current,v retrieving revision 1.74 retrieving revision 1.75 diff -C2 -d -r1.74 -r1.75 *** CHANGES.current 21 Aug 2003 04:20:11 -0000 1.74 --- CHANGES.current 21 Aug 2003 04:34:48 -0000 1.75 *************** *** 1,6 **** ! Version 0.4.0 (in progress) =========================== 2003-08-20: onsight ! Tagged r0_3_4, version 0_4_0 started. --- 1,7 ---- ! Version 0.3.5 (in progress) =========================== 2003-08-20: onsight ! Tagged r0_3_4, version 0_3_5 started. ! Version 0.4.0 branch started. |
From: <mk...@us...> - 2003-08-22 02:15:00
|
Update of /cvsroot/csp/APPLICATIONS/SimData In directory sc8-pr-cvs1:/tmp/cvs-serv26288 Modified Files: Tag: b0_4_0 CHANGES.current Log Message: Index: CHANGES.current =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/CHANGES.current,v retrieving revision 1.75 retrieving revision 1.75.2.1 diff -C2 -d -r1.75 -r1.75.2.1 *** CHANGES.current 21 Aug 2003 04:34:48 -0000 1.75 --- CHANGES.current 21 Aug 2003 04:39:32 -0000 1.75.2.1 *************** *** 1,3 **** ! Version 0.3.5 (in progress) =========================== --- 1,3 ---- ! Version 0.4.0 (in progress) =========================== |
From: <mk...@us...> - 2003-08-22 00:21:52
|
Update of /cvsroot/csp/APPLICATIONS/SimData In directory sc8-pr-cvs1:/tmp/cvs-serv20073 Modified Files: Tag: b0_4_0 CHANGES.current setup.py Added Files: Tag: b0_4_0 runtests.py Log Message: --- NEW FILE: runtests.py --- #!/usr/bin/env python import sys sys.path = ['.', 'SimData/Tests'] + sys.path import SimData import SimData.Tests Index: CHANGES.current =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/CHANGES.current,v retrieving revision 1.75.2.1 retrieving revision 1.75.2.2 diff -C2 -d -r1.75.2.1 -r1.75.2.2 *** CHANGES.current 21 Aug 2003 04:39:32 -0000 1.75.2.1 --- CHANGES.current 22 Aug 2003 00:21:44 -0000 1.75.2.2 *************** *** 2,5 **** --- 2,47 ---- =========================== + 2003-08-21: onsight + Convertied from pack/unpack to serialize for BaseType + serialization: + + o Removed Pack.i, Pack.h, Pack.cpp + o Added Archive.h, Archive.i + o Appropriate changes to setup.py and Source/Makefile + + Object classes should now only implement serialize(Archive&) + to save and load themselves from data archives. The Archive + parameter is a functor, which handles both saving and + loading transparently. So instead of one list of + Packer.pack(...) methods, and another identical list of + UnPacker.unpack(..) methods, you now just make one list of + archive(..) calls: + + void MyClass::serialize(Archive& archive) { + MyBaseClass::serialize(archive); + archive(member_var1); + archive(member_var2); + ... + } + + See the basic data type implementations for additional examples. + Note however that the basic data types generally have more + complicated serialization routines than most object classes will + require. Many basic data types test whether the archive is + loading or saving and respond differently depending on the + situation. For object classes this should almost always be + unnecessary. + + Added equality and inequality operators to several base types. + + Modified the Python serialization interface (still subject to + further changes). + + Added a unit testing framework based on Python's unittest module: + o runtests.py runs all the tests (not many so far) + o SimData/Tests contains the unit test modules + o SimData/Tests/ArchiveTests tests storage and retrieval + of many basic data types (not complete yet) + 2003-08-20: onsight Tagged r0_3_4, version 0_3_5 started. Index: setup.py =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/setup.py,v retrieving revision 1.30 retrieving revision 1.30.2.1 diff -C2 -d -r1.30 -r1.30.2.1 *** setup.py 16 Aug 2003 10:29:43 -0000 1.30 --- setup.py 22 Aug 2003 00:21:44 -0000 1.30.2.1 *************** *** 245,249 **** "Object", "Noise", - "Pack", "Path", "Quat", --- 245,248 ---- *************** *** 256,259 **** --- 255,259 ---- headers = [ + "Archive.h", "BaseType.h", "Conversions.h", *************** *** 285,289 **** "ObjectInterface.h", "osg.h", - "Pack.h", "Path.h", "PTS.h", --- 285,288 ---- *************** *** 302,305 **** --- 301,305 ---- interfaces = [ "cSimData.i", + "Archive.i", "BaseType.i", "Conversions.i", *************** *** 323,327 **** "Noise.i", "Object.i", - "Pack.i", "Path.i", "Quat.i", --- 323,326 ---- |
From: <mk...@us...> - 2003-08-22 00:21:51
|
Update of /cvsroot/csp/APPLICATIONS/SimData/SimData/Tests In directory sc8-pr-cvs1:/tmp/cvs-serv20073/SimData/Tests Added Files: Tag: b0_4_0 ArchiveTests.py __init__.py Log Message: --- NEW FILE: ArchiveTests.py --- import SimData import os from unittest import TestCase, TestSuite, makeSuite def round8(x): return long((x*1e+8)+0.5)*1e-8; def round5(x): return long((x*1e+5)+0.5)*1e-5; class ArchiveTest(TestCase): def setUp(self): self.f = open('__test__.dar', 'wb') self.archive = SimData.Packer(self.f) def setRead(self): self.size = self.archive.getCount() self.archive = None self.f.close() self.f = open('__test__.dar', 'rb') self.data = self.f.read(self.size) self.f.close() os.unlink('__test__.dar') self.archive = SimData.UnPacker(self.data) def tearDown(self): self.failUnless(self.archive.isComplete()) class TypeArchiveTest(ArchiveTest): def testSimDate(self): """Test storage and retrieval of SimDate""" date0 = SimData.SimDate(2003, 2, 28, 01, 14, 59.6) date0str = str(date0) self.assertEqual(date0str, '2003/02/28 01:14:59z') self.archive._basetype(date0) self.assertEqual(str(date0), date0str) self.setRead() self.assertEqual(self.size, 8) date1 = self.archive._SimDate() # test times to 1 part in 10^8 (approx 1 ms) self.assertEqual(round8(date0.getJulianDate()), round8(date1.getJulianDate())) def testVector3(self): """Test storage and retrieval of Vector3""" x0 = SimData.Vector3(1.0, -2.0, 3.3) y0 = SimData.Vector3(1.0, -2.0, 3.3) self.assertEqual(x0, y0) self.assertEqual(x0.x, 1.0) self.assertEqual(x0.y, -2.0) self.assertEqual(x0.z, 3.3) self.archive._basetype(x0) self.assertEqual(x0, y0) self.setRead() self.assertEqual(self.size, 24) x1 = self.archive._Vector3() self.assertEqual(x0, x1) def testMatrix3(self): """Test storage and retrieval of Matrix3""" x0 = SimData.Matrix3(1.0, -2.0, 3.3, -1.0, -3.0, -5.0, 9.1, 8.4, 2.3) y0 = SimData.Matrix3(1.0, -2.0, 3.3, -1.0, -3.0, -5.0, 9.1, 8.4, 2.3) self.assertEqual(x0, y0) self.assertEqual(x0.getElement(0,0), 1.0) self.assertEqual(x0.getElement(1,0), -1.0) self.assertEqual(x0.getElement(2,2), 2.3) self.archive._basetype(x0) self.assertEqual(x0, y0) self.setRead() self.assertEqual(self.size, 72) x1 = self.archive._Matrix3() self.assertEqual(x0, x1) def testKey(self): """Test storage and retrieval of Key""" x0 = SimData.Key("KeyTest") y0 = SimData.Key("KeyTest") self.archive._basetype(x0) self.assertEqual(x0, y0) self.setRead() self.assertEqual(self.size, 4) x1 = self.archive._Key() self.assertEqual(x0, x1) def testReal(self): """Test storage and retrieval of Real""" x0 = SimData.Real(10.0, 1.0) y0 = SimData.Real(10.0, 1.0) self.archive._basetype(x0) self.assertEqual(x0.getMean(), y0.getMean()) self.assertEqual(x0.getSigma(), y0.getSigma()) self.setRead() self.assertEqual(self.size, 8) x1 = self.archive._Real() self.assertEqual(x0.getMean(), x1.getMean()) self.assertEqual(x0.getSigma(), x1.getSigma()) v = x1.getValue() # 5 sigma test ;-) self.failIf(v == 10.0 or v < 5.0 or v > 15.0) def testExternal(self): """Test storage and retrieval of External""" path = "foo/bar/baz.txt" x0 = SimData.External() x0.setSource(path) y0 = SimData.External() y0.setSource(path) self.archive._basetype(x0) self.assertEqual(x0, y0) self.setRead() self.assertEqual(self.size, len(path)+4) x1 = self.archive._External() self.assertEqual(x0, x1) def testQuat(self): """Test storage and retrieval of Quat""" x0 = SimData.Quat(1.0, -2.0, 3.3, -4.0) y0 = SimData.Quat(1.0, -2.0, 3.3, -4.0) self.assertEqual(x0, y0) self.assertEqual(x0.x, 1.0) self.assertEqual(x0.y, -2.0) self.assertEqual(x0.z, 3.3) self.assertEqual(x0.w, -4.0) self.archive._basetype(x0) self.assertEqual(x0, y0) self.setRead() self.assertEqual(self.size, 32) x1 = self.archive._Quat() self.assertEqual(x0, x1) def testPath(self): """Test storage and retrieval of Path""" path="x:a.b.c" x0 = SimData.Path(path) y0 = SimData.Path(path) self.assertEqual(x0, y0) self.archive._basetype(x0) self.assertEqual(x0, y0) self.setRead() self.assertEqual(self.size, 8) x1 = self.archive._Path() self.assertEqual(x0, x1) def testLLA(self): """Test storage and retrieval of LLA""" x0 = SimData.LLA(0.2, -1.1, 100.1) y0 = SimData.LLA(0.2, -1.1, 100.1) self.archive._basetype(x0) self.assertEqual(x0.latitude(), y0.latitude()) self.assertEqual(x0.longitude(), y0.longitude()) self.assertEqual(x0.altitude(), y0.altitude()) self.setRead() self.assertEqual(self.size, 24) x1 = self.archive._LLA() self.assertEqual(x0.latitude(), x1.latitude()) self.assertEqual(x0.longitude(), x1.longitude()) self.assertEqual(x0.altitude(), x1.altitude()) def testUTM(self): """Test storage and retrieval of UTM""" lla = SimData.LLA(0.2, -1.1, 100.1) x0 = SimData.UTM(lla) y0 = SimData.UTM(lla) self.archive._basetype(x0) self.assertEqual(x0.northing(), y0.northing()) self.assertEqual(x0.easting(), y0.easting()) self.assertEqual(x0.zone(), y0.zone()) self.assertEqual(x0.designator(), y0.designator()) self.assertEqual(x0.altitude(), y0.altitude()) self.setRead() self.assertEqual(self.size, 26) x1 = self.archive._UTM() self.assertEqual(x0.northing(), x1.northing()) self.assertEqual(x0.easting(), x1.easting()) self.assertEqual(x0.zone(), x1.zone()) self.assertEqual(x0.designator(), x1.designator()) self.assertEqual(x0.altitude(), x1.altitude()) def testECEF(self): """Test storage and retrieval of ECEF""" lla = SimData.LLA(0.2, -1.1, 100.1) x0 = SimData.ECEF(lla) y0 = SimData.ECEF(lla) self.assertEqual(x0.x, y0.x) self.assertEqual(x0.y, y0.y) self.assertEqual(x0.z, y0.z) self.archive._basetype(x0) self.setRead() self.assertEqual(self.size, 24) x1 = self.archive._ECEF() self.assertEqual(x0.x, x1.x) self.assertEqual(x0.y, x1.y) self.assertEqual(x0.z, x1.z) def testString(self): """Test storage and retrieval of String""" x0 = "hello world" y0 = "hello world" self.archive._string(x0) self.setRead() self.assertEqual(self.size, 15) x1 = self.archive._string() self.assertEqual(x0, x1) def testInt(self): """Test storage and retrieval of Int""" x0 = 42 self.archive._int(x0) self.setRead() self.assertEqual(self.size, 4) x1 = self.archive._int() self.assertEqual(x0, x1) def testDouble(self): """Test storage and retrieval of Double""" x0 = 42.6 self.archive._double(x0) self.setRead() self.assertEqual(self.size, 8) x1 = self.archive._double() self.assertEqual(x0, x1) def testFloat(self): """Test storage and retrieval of Float""" x0 = 42.6 self.archive._float(x0) self.setRead() self.assertEqual(self.size, 4) x1 = self.archive._float() self.assertEqual(round5(x0), round5(x1)) def testBool(self): """Test storage and retrieval of Bool""" x0 = 1 self.archive._bool(x0) self.setRead() self.assertEqual(self.size, 1) x1 = self.archive._bool() self.assertEqual(x0, x1) TypeArchiveSuite = makeSuite(TypeArchiveTest, 'test') suites = [TypeArchiveSuite] --- NEW FILE: __init__.py --- import unittest suites = [] def addTestSuites(module): mod = __import__(module) suites.extend(mod.suites) addTestSuites("ArchiveTests") runner = unittest.TextTestRunner() runner.run(unittest.TestSuite(suites)) |
From: <mk...@us...> - 2003-08-22 00:07:45
|
Update of /cvsroot/csp/APPLICATIONS/SimData/SimData/Tests In directory sc8-pr-cvs1:/tmp/cvs-serv18328/SimData/Tests Log Message: Directory /cvsroot/csp/APPLICATIONS/SimData/SimData/Tests added to the repository --> Using per-directory sticky tag `b0_4_0' |
From: <mk...@us...> - 2003-08-21 23:33:03
|
Update of /cvsroot/csp/APPLICATIONS/CSPSim In directory sc8-pr-cvs1:/tmp/cvs-serv20354 Modified Files: CHANGES CHANGES.current Log Message: Index: CHANGES =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/CSPSim/CHANGES,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** CHANGES 5 Aug 2003 04:24:49 -0000 1.6 --- CHANGES 21 Aug 2003 08:18:37 -0000 1.7 *************** *** 2,5 **** --- 2,43 ---- to CVS. + Version 0.3.4 (2003-08-20) + =========================== + + 2003-08-16: onsight + Applied patches by VI to add Tools/Terrain/* to the + build and fix some minor errors in tile.cpp and + Tools/Recorder/graph. + + Added -W -Wall to the build for Tools/Terrain/*, + and fixed a few small errors that uncovered. + + 2003-08-15: onsight + Updates related to SimData API changes (mostly use + of simdata::PI, toRadians, and toDegrees instead of + the G_PI, D2R, and R2D macros). + + Added a CSPSim.py option to set the SimData logging + level from the command line. + + 2003-08-12: onsight + Minor updates to Terrain/dem2dat and Terrain/tile to + sync with the latest SimData API changes. Improved + both Makefiles slightly but they're still very basic. + + 2003-08-05: onsight + Initial updates to use new SimData APIs for Random, + Vector3, Matrix3, Quat. Dynamics seem correct but + more testing is needed. + + Fixed euler angles. The new code preconverts to/from + CSP's internal coordinate system rather than relying + on a special method in SimData. + + 2003-08-04: onsight + Tagged version r0_3_3, starting version 0.3.4 + + + Version 0.3.3 (2003-08-04) =========================== Index: CHANGES.current =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/CSPSim/CHANGES.current,v retrieving revision 1.66 retrieving revision 1.67 diff -C2 -d -r1.66 -r1.67 *** CHANGES.current 17 Aug 2003 18:39:51 -0000 1.66 --- CHANGES.current 21 Aug 2003 08:18:37 -0000 1.67 *************** *** 1,36 **** ! Version 0.3.4 (in progress) =========================== ! 2003-08-16: onsight ! Applied patches by VI to add Tools/Terrain/* to the ! build and fix some minor errors in tile.cpp and ! Tools/Recorder/graph. ! ! Added -W -Wall to the build for Tools/Terrain/*, ! and fixed a few small errors that uncovered. ! ! 2003-08-15: onsight ! Updates related to SimData API changes (mostly use ! of simdata::PI, toRadians, and toDegrees instead of ! the G_PI, D2R, and R2D macros). ! ! Added a CSPSim.py option to set the SimData logging ! level from the command line. ! ! 2003-08-12: onsight ! Minor updates to Terrain/dem2dat and Terrain/tile to ! sync with the latest SimData API changes. Improved ! both Makefiles slightly but they're still very basic. ! ! 2003-08-05: onsight ! Initial updates to use new SimData APIs for Random, ! Vector3, Matrix3, Quat. Dynamics seem correct but ! more testing is needed. ! ! Fixed euler angles. The new code preconverts to/from ! CSP's internal coordinate system rather than relying ! on a special method in SimData. ! ! 2003-08-04: onsight ! Tagged version r0_3_3, starting version 0.3.4 --- 1,6 ---- ! Version 0.3.5 (in progress) =========================== ! 2003-08-20: onsight ! Tagged version r0_3_4, starting version 0.3.5 |
From: <mk...@us...> - 2003-08-21 16:11:45
|
Update of /cvsroot/csp/APPLICATIONS/SimData In directory sc8-pr-cvs1:/tmp/cvs-serv24512 Modified Files: CHANGES CHANGES.current Log Message: version 0.4.0 started Index: CHANGES =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/CHANGES,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** CHANGES 5 Aug 2003 04:21:46 -0000 1.5 --- CHANGES 21 Aug 2003 04:20:11 -0000 1.6 *************** *** 2,5 **** --- 2,188 ---- to CVS. + Version 0.3.4 (2003-08-20) + =========================== + + 2003-08-20: onsight + Fixed typo in Vector3.h + + 2003-08-19: onsight + Added documentation. + + Made BaseType::asString and BaseType::typeString pure virtual + to force them to be defined in each derived type. + + Implemented typeString in LUT, Table, and Curve. + + Added more complete error messages (including variable types) + to the TypeAdapter functions. + + Added additional error information to the MemberAccessor + classes to include the name of the variable being set if + TypeAdapter throws an exception. + + Added an 'addMessage()' method to Exception, which prepends + a newline-terminated string to the existing message. The + original 'appendMessage()' is unchanged. + + Added typeString to the SWIG interface for LUT to prevent + SWIG from thinking its is an abstract class. + + + 2003-08-18: onsight + More Doxygen fixes, reorganization, and added + documentation. + + 2003-08-17: onsight + Fixed assertion range errors in Matrix3.h + + Moved template metaprogramming structs into the + 'meta' namespace in PTS.h. + + Removed GlibCsp.h includes in GeoPos.cpp and + DataArchive.cpp, with associated fixups. + + Added byte-order tests to Uniform.h. + + Tried adding template-meta-programming-style fixed + integer size typedef mappings (e.g. uint32), but + SWIG chokes on these so it's back to hard-coded + typedefs. For now these should work on most systems + that SimData is likely to run on. Autoconf is the + obvious alternative, but I'd rather not use it at + this point. + + 2003-08-16: onsight + Replaced several old-school buffer allocations with + std::vector equivalents in DataArchive. + + 2003-08-15: onsight + More Doxygen work. + + Move loadcheck to BaseType.cpp, which is much more + likely to be linked to any application using SimData. + The load message can be disabled by building with + SIMDATA_NOLOADCHECK defined. + + Changed a couple sprintf/printf's to iostreams. + + Prefixed internal macro names in Object.h with 'SIMDATA'. + + Changed hash_string from a macro to an inline function + in the simdata namespace. + + Added Utility.h, removed GlibCSP.h from the setup.py + installation. + + Minor improvements to the DataArchive internal structures. + There more to do here, such as using std::vector instead + of hand-rolled allocations. + + 2003-08-14: onsight + Doxygen comment fixes. + + Removed GlibCsp, replacing what little we used with + a few typedefs in Uniform.h (now in the simdata + namespace). Eliminates many macro definitions and + unqualified names. + + Cleaned up HashUtility.h, eliminating dead code and + superfluous typemaps. + + Moved timing code inside the simdata namespace. + + 2003-08-13: onsight + Complete rewrite of the Enumeration classes, using Enum + templates, simdata::Ref, and an overall better design. The + new code allows the parent Enumerations to be bound to + member variable *types* duing static construction, so that + the possible values for a type can be querried without + instantiating the parent class. This is very useful for + introspecting classes, allowing a SimData XML editor to + determine a list of possible values for an Enum directly + from an ObjectInterface without creating an instance of + the corresponding class. The Python bindings for the + Enum classes have also been redesigned and improved. + + Changed some DataArchive and hash methods to use + std::string const& instead of const char*. + + Fixed some bugs in Date.h and Matrix.h that '-pedantic' + uncovered. Added more base class ctor calls to satisfy + '-pedantic' as well. + + Added isSubclass() method to ObjectInterface (and the + InterfaceProxy clases) to test the inherintance chain + using interfaces without creating object instances. The + class relationships used in the test are based on the + classes listed in the SIMDATA_XML_INTERFACE() macros, not + the full C++ class hierarchy. + + Added SIMDATA_SUBEXCEPTION macro for creating exception + hierarchies. + + Changed the default version string to report the build + date and time, which provides a helpful sanity check when + more than one version of the SimData is in your library + search path. + + 2003-08-10: onsight + Minor fixes/pragmas to reduce useless warning messages under + VS 2003. + + Added support to the object registry, object interfaces, + and member accessors for member variable type introspection. + BaseTypes other than Object must now override typeString() + to return a string identifier for their type (which should + start with "type::"). Other prefix convensions are as + follows: + * Type strings for builtin types (like 'float') start with + 'builtin::'. See ObjectInterface.h for a complete list. + * Type strings for BaseTypes other than Object start with + 'type::', followed by the name of the type (e.g. Date). + * Type strings for Objects are just the classname of the + object. + * Type strings for std::vectors start with 'vector::'. + * Type strings for templated classes are followed by the + template type (e.g. type::Link::SomeObjectClass). + + Added object interface lookup based on object id to DataArchive + and DataManager. Given an object ID (or path) you can now + determine the object class and introspect the member variables + without creating an instance of the object. + + 2003-08-07: onsight + Added SIMDATA_EXPORT to classes in Random.h + + Fixed #include <float.h> bug in Math.h under Windows + + Moved some inline friend declarations out of the Vector3 + class declaration to help MSVC find them. + + 2003-08-06: onsight + Removed Math.i and Vector3.inl from setup.py. + + 2003-08-05: onsight + Replaced Random, Vector3, Matrix3, and Quaternion classes with + GPL'd code. The APIs for these classes have changed significatly, + although the overall functionality should be similar. + + Copyright notices updated. + + ns-simdata.h renamed Namespace.h. + + NAMESPACE_END renamed NAMESPACE_SIMDATA_END + + A couple double/float comparison fixes. + + Fixed Marsenne -> Mersenne typos. + + ==========> VS USERS: remove Quaternion.cpp from the project and add Quat.cpp + + 2003-08-04: onsight + Tagged r0_3_3, version 0.3.4 started. + + Version 0.3.3 (2003-08-04) =========================== Index: CHANGES.current =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/CHANGES.current,v retrieving revision 1.73 retrieving revision 1.74 diff -C2 -d -r1.73 -r1.74 *** CHANGES.current 21 Aug 2003 04:14:19 -0000 1.73 --- CHANGES.current 21 Aug 2003 04:20:11 -0000 1.74 *************** *** 1,182 **** ! Version 0.3.4 (in progress) =========================== 2003-08-20: onsight ! Fixed typo in Vector3.h ! ! 2003-08-19: onsight ! Added documentation. ! ! Made BaseType::asString and BaseType::typeString pure virtual ! to force them to be defined in each derived type. ! ! Implemented typeString in LUT, Table, and Curve. ! ! Added more complete error messages (including variable types) ! to the TypeAdapter functions. ! ! Added additional error information to the MemberAccessor ! classes to include the name of the variable being set if ! TypeAdapter throws an exception. ! ! Added an 'addMessage()' method to Exception, which prepends ! a newline-terminated string to the existing message. The ! original 'appendMessage()' is unchanged. ! ! Added typeString to the SWIG interface for LUT to prevent ! SWIG from thinking its is an abstract class. ! ! ! 2003-08-18: onsight ! More Doxygen fixes, reorganization, and added ! documentation. ! ! 2003-08-17: onsight ! Fixed assertion range errors in Matrix3.h ! ! Moved template metaprogramming structs into the ! 'meta' namespace in PTS.h. ! ! Removed GlibCsp.h includes in GeoPos.cpp and ! DataArchive.cpp, with associated fixups. ! ! Added byte-order tests to Uniform.h. ! ! Tried adding template-meta-programming-style fixed ! integer size typedef mappings (e.g. uint32), but ! SWIG chokes on these so it's back to hard-coded ! typedefs. For now these should work on most systems ! that SimData is likely to run on. Autoconf is the ! obvious alternative, but I'd rather not use it at ! this point. ! ! 2003-08-16: onsight ! Replaced several old-school buffer allocations with ! std::vector equivalents in DataArchive. ! ! 2003-08-15: onsight ! More Doxygen work. ! ! Move loadcheck to BaseType.cpp, which is much more ! likely to be linked to any application using SimData. ! The load message can be disabled by building with ! SIMDATA_NOLOADCHECK defined. ! ! Changed a couple sprintf/printf's to iostreams. ! ! Prefixed internal macro names in Object.h with 'SIMDATA'. ! ! Changed hash_string from a macro to an inline function ! in the simdata namespace. ! ! Added Utility.h, removed GlibCSP.h from the setup.py ! installation. ! ! Minor improvements to the DataArchive internal structures. ! There more to do here, such as using std::vector instead ! of hand-rolled allocations. ! ! 2003-08-14: onsight ! Doxygen comment fixes. ! ! Removed GlibCsp, replacing what little we used with ! a few typedefs in Uniform.h (now in the simdata ! namespace). Eliminates many macro definitions and ! unqualified names. ! ! Cleaned up HashUtility.h, eliminating dead code and ! superfluous typemaps. ! ! Moved timing code inside the simdata namespace. ! ! 2003-08-13: onsight ! Complete rewrite of the Enumeration classes, using Enum ! templates, simdata::Ref, and an overall better design. The ! new code allows the parent Enumerations to be bound to ! member variable *types* duing static construction, so that ! the possible values for a type can be querried without ! instantiating the parent class. This is very useful for ! introspecting classes, allowing a SimData XML editor to ! determine a list of possible values for an Enum directly ! from an ObjectInterface without creating an instance of ! the corresponding class. The Python bindings for the ! Enum classes have also been redesigned and improved. ! ! Changed some DataArchive and hash methods to use ! std::string const& instead of const char*. ! ! Fixed some bugs in Date.h and Matrix.h that '-pedantic' ! uncovered. Added more base class ctor calls to satisfy ! '-pedantic' as well. ! ! Added isSubclass() method to ObjectInterface (and the ! InterfaceProxy clases) to test the inherintance chain ! using interfaces without creating object instances. The ! class relationships used in the test are based on the ! classes listed in the SIMDATA_XML_INTERFACE() macros, not ! the full C++ class hierarchy. ! ! Added SIMDATA_SUBEXCEPTION macro for creating exception ! hierarchies. ! ! Changed the default version string to report the build ! date and time, which provides a helpful sanity check when ! more than one version of the SimData is in your library ! search path. ! ! 2003-08-10: onsight ! Minor fixes/pragmas to reduce useless warning messages under ! VS 2003. ! ! Added support to the object registry, object interfaces, ! and member accessors for member variable type introspection. ! BaseTypes other than Object must now override typeString() ! to return a string identifier for their type (which should ! start with "type::"). Other prefix convensions are as ! follows: ! * Type strings for builtin types (like 'float') start with ! 'builtin::'. See ObjectInterface.h for a complete list. ! * Type strings for BaseTypes other than Object start with ! 'type::', followed by the name of the type (e.g. Date). ! * Type strings for Objects are just the classname of the ! object. ! * Type strings for std::vectors start with 'vector::'. ! * Type strings for templated classes are followed by the ! template type (e.g. type::Link::SomeObjectClass). ! ! Added object interface lookup based on object id to DataArchive ! and DataManager. Given an object ID (or path) you can now ! determine the object class and introspect the member variables ! without creating an instance of the object. ! ! 2003-08-07: onsight ! Added SIMDATA_EXPORT to classes in Random.h ! ! Fixed #include <float.h> bug in Math.h under Windows ! ! Moved some inline friend declarations out of the Vector3 ! class declaration to help MSVC find them. ! ! 2003-08-06: onsight ! Removed Math.i and Vector3.inl from setup.py. ! ! 2003-08-05: onsight ! Replaced Random, Vector3, Matrix3, and Quaternion classes with ! GPL'd code. The APIs for these classes have changed significatly, ! although the overall functionality should be similar. ! ! Copyright notices updated. ! ! ns-simdata.h renamed Namespace.h. ! ! NAMESPACE_END renamed NAMESPACE_SIMDATA_END ! ! A couple double/float comparison fixes. ! ! Fixed Marsenne -> Mersenne typos. ! ! ==========> VS USERS: remove Quaternion.cpp from the project and add Quat.cpp ! ! 2003-08-04: onsight ! Tagged r0_3_3, version 0.3.4 started. --- 1,6 ---- ! Version 0.4.0 (in progress) =========================== 2003-08-20: onsight ! Tagged r0_3_4, version 0_4_0 started. |
From: <mk...@us...> - 2003-08-20 03:55:38
|
Update of /cvsroot/csp/APPLICATIONS/SimData/Source In directory sc8-pr-cvs1:/tmp/cvs-serv6568/Source Modified Files: BaseType.cpp Exception.cpp Interpolate.cpp LUT.cpp Log Message: Index: BaseType.cpp =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/Source/BaseType.cpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** BaseType.cpp 16 Aug 2003 07:56:40 -0000 1.6 --- BaseType.cpp 20 Aug 2003 02:47:10 -0000 1.7 *************** *** 74,93 **** } - void BaseType::convertXML() { } - - std::string BaseType::asString() const { - return ""; - } - - std::string BaseType::typeString() const { - return ""; - } - std::ostream &operator <<(std::ostream &o, BaseType const &t) { return o << t.asString(); } NAMESPACE_SIMDATA_END --- 74,84 ---- } void BaseType::convertXML() { } std::ostream &operator <<(std::ostream &o, BaseType const &t) { return o << t.asString(); } + NAMESPACE_SIMDATA_END Index: Exception.cpp =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/Source/Exception.cpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** Exception.cpp 6 Aug 2003 06:36:25 -0000 1.6 --- Exception.cpp 20 Aug 2003 02:47:10 -0000 1.7 *************** *** 57,60 **** --- 57,64 ---- } + void ExceptionBase::addMessage(std::string const &msg) { + _msg = msg + "\n" + _msg; + } + void ExceptionBase::clear() { dump = false; Index: Interpolate.cpp =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/Source/Interpolate.cpp,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** Interpolate.cpp 19 Aug 2003 09:13:27 -0000 1.16 --- Interpolate.cpp 20 Aug 2003 02:47:10 -0000 1.17 *************** *** 221,224 **** --- 221,228 ---- } + std::string Curve::typeString() const { + return std::string("type::Curve"); + } + // class Table *************** *** 522,525 **** --- 526,533 ---- std::string Table::asString() const { return std::string("<simdata::Table>"); + } + + std::string Table::typeString() const { + return std::string("type::Table"); } Index: LUT.cpp =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/Source/LUT.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** LUT.cpp 15 Aug 2003 01:17:06 -0000 1.4 --- LUT.cpp 20 Aug 2003 02:47:10 -0000 1.5 *************** *** 22,25 **** --- 22,27 ---- #include <SimData/LUT.h> + #include <sstream> + #ifndef __SIMDATA_NO_LUT__ *************** *** 473,486 **** } - /** - * Return strig representation of type. - */ template <int N, class X> std::string LUT<N,X>::asString() const { ! char buff[128]; ! sprintf(buff, "<%d-Dimensional Lookup Table>", N); ! return buff; } --- 475,491 ---- } template <int N, class X> std::string LUT<N,X>::asString() const { ! std::stringstream ss; ! ss << "<simdata::" << N << "D Lookup Table>"; ! return ss.str(); } + template <int N, class X> + std::string LUT<N,X>::typeString() const { + std::stringstream ss; + ss << "type::LUT<" << N << ">"; + return ss.str(); + } *************** *** 738,744 **** template <typename X> std::string LUT<1,X>::asString() const { ! return "<1-Dimensional Lookup Table>"; } --- 743,753 ---- template <typename X> std::string LUT<1,X>::asString() const { ! return "<simdata::1D Lookup Table>"; } + template <typename X> + std::string LUT<1,X>::typeString() const { + return "type::LUT<1>"; + } |
From: <mk...@us...> - 2003-08-20 03:55:38
|
Update of /cvsroot/csp/APPLICATIONS/SimData/SimData In directory sc8-pr-cvs1:/tmp/cvs-serv6568/SimData Modified Files: Parse.py Log Message: Index: Parse.py =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/SimData/Parse.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** Parse.py 24 Jul 2003 20:25:32 -0000 1.11 --- Parse.py 20 Aug 2003 02:47:10 -0000 1.12 *************** *** 716,720 **** interface_names.sort() print "Known classes are:" ! print " ", "\n ".join(interface_names) raise NameError, msg if getDebugLevel() > 0: --- 716,720 ---- interface_names.sort() print "Known classes are:" ! print " " + "\n ".join(interface_names) raise NameError, msg if getDebugLevel() > 0: |
From: <mk...@us...> - 2003-08-20 03:55:37
|
Update of /cvsroot/csp/APPLICATIONS/SimData In directory sc8-pr-cvs1:/tmp/cvs-serv6568 Modified Files: CHANGES.current Log Message: Index: CHANGES.current =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/CHANGES.current,v retrieving revision 1.71 retrieving revision 1.72 diff -C2 -d -r1.71 -r1.72 *** CHANGES.current 19 Aug 2003 09:13:26 -0000 1.71 --- CHANGES.current 20 Aug 2003 02:47:09 -0000 1.72 *************** *** 2,5 **** --- 2,28 ---- =========================== + 2003-08-19: onsight + Added documentation. + + Made BaseType::asString and BaseType::typeString pure virtual + to force them to be defined in each derived type. + + Implemented typeString in LUT, Table, and Curve. + + Added more complete error messages (including variable types) + to the TypeAdapter functions. + + Added additional error information to the MemberAccessor + classes to include the name of the variable being set if + TypeAdapter throws an exception. + + Added an 'addMessage()' method to Exception, which prepends + a newline-terminated string to the existing message. The + original 'appendMessage()' is unchanged. + + Added typeString to the SWIG interface for LUT to prevent + SWIG from thinking its is an abstract class. + + 2003-08-18: onsight More Doxygen fixes, reorganization, and added |
From: <mk...@us...> - 2003-08-19 09:13:30
|
Update of /cvsroot/csp/APPLICATIONS/SimData/Source In directory sc8-pr-cvs1:/tmp/cvs-serv23476/Source Modified Files: GeoPos.cpp Interpolate.cpp Log Message: Index: GeoPos.cpp =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/Source/GeoPos.cpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** GeoPos.cpp 18 Aug 2003 03:47:10 -0000 1.6 --- GeoPos.cpp 19 Aug 2003 09:13:27 -0000 1.7 *************** *** 836,841 **** // UTM ! UTM::UTM(LLA const &lla, ReferenceEllipsoid const &ref, char zone_) { ! *this = LLAtoUTM(lla, ref, zone_); } --- 836,841 ---- // UTM ! UTM::UTM(LLA const &lla, ReferenceEllipsoid const &ref, char zone) { ! *this = LLAtoUTM(lla, ref, zone); } *************** *** 858,862 **** * the UTM limits (80S to 84N) * ! * @param lat latitude in radians */ char UTM::getDesignator(double latitude) --- 858,862 ---- * the UTM limits (80S to 84N) * ! * @param latitude latitude in radians */ char UTM::getDesignator(double latitude) Index: Interpolate.cpp =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/Source/Interpolate.cpp,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** Interpolate.cpp 15 Aug 2003 01:17:06 -0000 1.15 --- Interpolate.cpp 19 Aug 2003 09:13:27 -0000 1.16 *************** *** 58,72 **** template <typename T> ! T InterpolatedData<T>::getValue(T, T) const { return 0.0; } template <typename T> ! T InterpolatedData<T>::getPrecise(T, T) const { return 0.0; } template <typename T> ! typename InterpolatedData<T>::vector_t InterpolatedData<T>::_compute_second_derivatives(const typename InterpolatedData<T>::vector_t& breaks, const typename InterpolatedData<T>::vector_t& data) { int n = breaks.size(); vector_t z(n,0.0), u(n,0.0); --- 58,72 ---- template <typename T> ! typename InterpolatedData<T>::value_t InterpolatedData<T>::getValue(value_t, value_t) const { return 0.0; } template <typename T> ! typename InterpolatedData<T>::value_t InterpolatedData<T>::getPrecise(value_t, value_t) const { return 0.0; } template <typename T> ! typename InterpolatedData<T>::vector_t InterpolatedData<T>::_compute_second_derivatives(const vector_t& breaks, const vector_t& data) { int n = breaks.size(); vector_t z(n,0.0), u(n,0.0); *************** *** 88,92 **** template <typename T> ! int InterpolatedData<T>::find(vector_t b, T v) const { int lo = 0; int hi = b.size()-1; --- 88,92 ---- template <typename T> ! int InterpolatedData<T>::find(vector_t b, value_t v) const { int lo = 0; int hi = b.size()-1; |
From: <mk...@us...> - 2003-08-19 09:13:30
|
Update of /cvsroot/csp/APPLICATIONS/SimData In directory sc8-pr-cvs1:/tmp/cvs-serv23476 Modified Files: CHANGES.current Log Message: Index: CHANGES.current =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/CHANGES.current,v retrieving revision 1.70 retrieving revision 1.71 diff -C2 -d -r1.70 -r1.71 *** CHANGES.current 18 Aug 2003 03:47:10 -0000 1.70 --- CHANGES.current 19 Aug 2003 09:13:26 -0000 1.71 *************** *** 2,5 **** --- 2,9 ---- =========================== + 2003-08-18: onsight + More Doxygen fixes, reorganization, and added + documentation. + 2003-08-17: onsight Fixed assertion range errors in Matrix3.h |
From: <mk...@us...> - 2003-08-18 03:47:13
|
Update of /cvsroot/csp/APPLICATIONS/SimData/Source In directory sc8-pr-cvs1:/tmp/cvs-serv11553/Source Modified Files: DataArchive.cpp GeoPos.cpp Key.cpp Log Message: Index: DataArchive.cpp =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/Source/DataArchive.cpp,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** DataArchive.cpp 17 Aug 2003 10:50:21 -0000 1.14 --- DataArchive.cpp 18 Aug 2003 03:47:10 -0000 1.15 *************** *** 22,26 **** #include <SimData/DataManager.h> #include <SimData/InterfaceRegistry.h> - #include <SimData/GlibCsp.h> #include <SimData/Object.h> #include <SimData/Log.h> --- 22,25 ---- *************** *** 66,70 **** void DataArchive::writeMagic() { ! fprintf(_f, "RAWDAT-%c", (G_BYTE_ORDER == G_LITTLE_ENDIAN) ? 'L' : 'B'); } --- 65,69 ---- void DataArchive::writeMagic() { ! fprintf(_f, "RAWDAT-%c", isLittleEndian() ? 'L' : 'B'); } *************** *** 79,83 **** } bool data_little = (magic[7] == 'L'); ! bool machine_little = (G_BYTE_ORDER == G_LITTLE_ENDIAN); if (data_little != machine_little) { char msg[128]; --- 78,82 ---- } bool data_little = (magic[7] == 'L'); ! bool machine_little = isLittleEndian(); if (data_little != machine_little) { char msg[128]; Index: GeoPos.cpp =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/Source/GeoPos.cpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** GeoPos.cpp 16 Aug 2003 07:56:40 -0000 1.5 --- GeoPos.cpp 18 Aug 2003 03:47:10 -0000 1.6 *************** *** 29,33 **** #include <SimData/Math.h> #include <SimData/GeoPos.h> ! #include <SimData/GlibCsp.h> #include <SimData/Pack.h> --- 29,33 ---- #include <SimData/Math.h> #include <SimData/GeoPos.h> ! #include <SimData/Math.h> #include <SimData/Pack.h> *************** *** 124,128 **** } ! double lon0 = D2R * ((utm.zone() - 1) * 6 - 180 + 3); //+3 puts origin in middle of zone M = y / k0; --- 124,128 ---- } ! double lon0 = toRadians(((utm.zone() - 1) * 6.0 - 180.0 + 3.0)); //+3 puts origin in middle of zone M = y / k0; *************** *** 174,184 **** //Make sure the longitude is between -180.00 .. 179.9 ! if (lon >= G_PI) { ! int n = (int) (0.5 * lon / G_PI + 0.5); ! lon -= n * 2.0 * G_PI; } else ! if (lon < -G_PI) { ! int n = (int) (0.5 * lon / G_PI - 0.5); ! lon -= n * 2.0 * G_PI; } --- 174,184 ---- //Make sure the longitude is between -180.00 .. 179.9 ! if (lon >= PI) { ! int n = (int) (0.5 * lon / PI + 0.5); ! lon -= n * 2.0 * PI; } else ! if (lon < -PI) { ! int n = (int) (0.5 * lon / PI - 0.5); ! lon -= n * 2.0 * PI; } *************** *** 201,205 **** break; default: ! lon0 = G_PI / 180.0 * ((int(_zone) - 1)*6 - 180 + 3); } } --- 201,205 ---- break; default: ! lon0 = toRadians((int(_zone) - 1)*6.0 - 180.0 + 3.0); } } *************** *** 234,239 **** if (_zone == -1) { ! _zone = char((lon / G_PI + 1.0) * 30.0) + 1; ! lon0 = G_PI / 180.0 * ((int(_zone) - 1)*6 - 180 + 3); } --- 234,239 ---- if (_zone == -1) { ! _zone = char((lon / PI + 1.0) * 30.0) + 1; ! lon0 = toRadians((int(_zone) - 1)*6.0 - 180.0 + 3.0); } *************** *** 581,585 **** } ! double lon0 = D2R * ((getZoneNumber() - 1) * 6 - 180 + 3); //+3 puts origin in middle of zone M = y / k0; --- 581,585 ---- } ! double lon0 = toRadians((getZoneNumber() - 1) * 6.0 - 180.0 + 3.0); //+3 puts origin in middle of zone M = y / k0; *************** *** 649,659 **** //Make sure the longitude is between -180.00 .. 179.9 ! if (lon >= G_PI) { ! int n = (int) (0.5 * lon / G_PI + 0.5); ! lon -= n * 2.0 * G_PI; } else ! if (lon < -G_PI) { ! int n = (int) (0.5 * lon / G_PI - 0.5); ! lon -= n * 2.0 * G_PI; } --- 649,659 ---- //Make sure the longitude is between -180.00 .. 179.9 ! if (lon >= PI) { ! int n = (int) (0.5 * lon / PI + 0.5); ! lon -= n * 2.0 * PI; } else ! if (lon < -PI) { ! int n = (int) (0.5 * lon / PI - 0.5); ! lon -= n * 2.0 * PI; } *************** *** 689,694 **** if (_zone == -1) { ! _zone = char((lon / G_PI + 1.0) * 30.0) + 1; ! lon0 = G_PI / 180.0 * ((int(_zone) - 1)*6 - 180 + 3); } --- 689,694 ---- if (_zone == -1) { ! _zone = char((lon / PI + 1.0) * 30.0) + 1; ! lon0 = toRadians((int(_zone) - 1) * 6.0 - 180.0 + 3.0); } *************** *** 736,740 **** { static const char designator[] = "CDEFGHJKLMNPQRSTUVWXX"; ! latitude *= 180.0 / G_PI; if (latitude < -80.0 || latitude > 84.0) return 'Z'; return designator[(int)(latitude + 80.0)>>3]; --- 736,740 ---- { static const char designator[] = "CDEFGHJKLMNPQRSTUVWXX"; ! latitude = toDegrees(latitude); if (latitude < -80.0 || latitude > 84.0) return 'Z'; return designator[(int)(latitude + 80.0)>>3]; *************** *** 863,867 **** { static const char designator[] = "CDEFGHJKLMNPQRSTUVWXX"; ! latitude *= 180.0 / G_PI; if (latitude < -80.0 || latitude > 84.0) return 'Z'; return designator[(int)(latitude + 80.0)>>3]; --- 863,867 ---- { static const char designator[] = "CDEFGHJKLMNPQRSTUVWXX"; ! latitude = toDegrees(latitude); if (latitude < -80.0 || latitude > 84.0) return 'Z'; return designator[(int)(latitude + 80.0)>>3]; *************** *** 980,986 **** std::string LLA::asString() const { ! char buff[128]; ! sprintf(buff, "[%.3f %.3f, %.3f]", toDegrees(_lat), toDegrees(_lon), _alt); ! return buff; } --- 980,990 ---- std::string LLA::asString() const { ! std::stringstream ss; ! ss << std::fixed << std::setprecision(3); ! ss << "[" << toDegrees(_lat) ! << " " << toDegrees(_lon) ! << ", " << _alt ! << "]"; ! return ss.str(); } Index: Key.cpp =================================================================== RCS file: /cvsroot/csp/APPLICATIONS/SimData/Source/Key.cpp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Key.cpp 15 Aug 2003 06:59:16 -0000 1.3 --- Key.cpp 18 Aug 2003 03:47:10 -0000 1.4 *************** *** 22,25 **** --- 22,28 ---- #include <SimData/Pack.h> + #include <sstream> + #include <iomanip> + NAMESPACE_SIMDATA *************** *** 46,52 **** std::string Key::asString() const { ! char buff[32]; ! sprintf(buff, "Key<%08X>", _key); ! return buff; } --- 49,55 ---- std::string Key::asString() const { ! std::stringstream ss; ! ss << "Key<0x" << std::hex << std::uppercase << std::setw(8) << std::setfill('0') << _key << ">"; ! return ss.str(); } |