SubsystemGuts.h

Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_SUBSYSTEM_GUTS_H_
00002 #define SimTK_SimTKCOMMON_SUBSYSTEM_GUTS_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                      SimTK Core: SimTKcommon                               *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK Core biosimulation toolkit originating from      *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
00011  *                                                                            *
00012  * Portions copyright (c) 2006-7 Stanford University and the Authors.         *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Permission is hereby granted, free of charge, to any person obtaining a    *
00017  * copy of this software and associated documentation files (the "Software"), *
00018  * to deal in the Software without restriction, including without limitation  *
00019  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
00020  * and/or sell copies of the Software, and to permit persons to whom the      *
00021  * Software is furnished to do so, subject to the following conditions:       *
00022  *                                                                            *
00023  * The above copyright notice and this permission notice shall be included in *
00024  * all copies or substantial portions of the Software.                        *
00025  *                                                                            *
00026  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
00027  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
00028  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
00029  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
00030  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
00031  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
00032  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
00033  * -------------------------------------------------------------------------- */
00034 
00035 #include "SimTKcommon/basics.h"
00036 #include "SimTKcommon/Simmatrix.h"
00037 #include "SimTKcommon/internal/State.h"
00038 #include "SimTKcommon/internal/System.h"
00039 
00040 #include <cassert>
00041 
00042 namespace SimTK {
00043 
00044 class System;
00045 class DecorativeGeometry;
00046 
00047 // See below for definitions.
00048 static void subsystemDestructImplLocator(Subsystem::Guts*);
00049 static Subsystem::Guts* subsystemCloneImplLocator(const Subsystem::Guts&);
00050 static int subsystemRealizeTopologyImplLocator(const Subsystem::Guts&, State&);
00051 static int subsystemRealizeModelImplLocator(const Subsystem::Guts&, State&);
00052 static int subsystemRealizeInstanceImplLocator(const Subsystem::Guts&, const State&);
00053 static int subsystemRealizeTimeImplLocator(const Subsystem::Guts&, const State&);
00054 static int subsystemRealizePositionImplLocator(const Subsystem::Guts&, const State&);
00055 static int subsystemRealizeVelocityImplLocator(const Subsystem::Guts&, const State&);
00056 static int subsystemRealizeDynamicsImplLocator(const Subsystem::Guts&, const State&);
00057 static int subsystemRealizeAccelerationImplLocator(const Subsystem::Guts&, const State&);
00058 static int subsystemRealizeReportImplLocator(const Subsystem::Guts&, const State&);
00059 static int subsystemCalcQUnitWeightsImplLocator(const Subsystem::Guts&, const State&, Vector&);
00060 static int subsystemCalcUUnitWeightsImplLocator(const Subsystem::Guts&, const State&, Vector&);
00061 static int subsystemCalcZUnitWeightsImplLocator(const Subsystem::Guts&, const State&, Vector&);
00062 static int subsystemCalcQErrUnitTolerancesImplLocator(const Subsystem::Guts&, const State&, Vector&);
00063 static int subsystemCalcUErrUnitTolerancesImplLocator(const Subsystem::Guts&, const State&, Vector&);
00064 static int subsystemCalcDecorativeGeometryAndAppendImplLocator
00065                 (const Subsystem::Guts&, const State&, Stage, std::vector<DecorativeGeometry>&);
00066 
00088 class SimTK_SimTKCOMMON_EXPORT Subsystem::Guts {
00089     class GutsRep;
00090     friend class GutsRep;
00091 
00092     // this is the only data member in the base class
00093     GutsRep* rep; // opaque implementation of Subsystem::Guts base class.
00094 public:
00095     Guts(const Guts&);
00096     Guts& operator=(const Guts&);
00097 
00098     // This constructor is for use by concrete Subsystems.
00099     // Constructor must be inline for binary compatibility. Note that this
00100     // serves as a default constructor since both arguments have defaults.
00101     inline explicit Guts(const String& name="<NONAME>", 
00102                          const String& version="0.0.0");
00103 
00104     // This won't be called directly from library-side code. Instead,
00105     // a method from the explicit virtual function table will be invoked
00106     // which will know where to find this on in the C++ VFT on the client side.
00107     virtual ~Guts() {librarySideDestruction();}
00108 
00109     const String& getName()    const;
00110     const String& getVersion() const;
00111 
00112     // These return views on State shared global resources. The views
00113     // are private to this subsystem, but the global resources themselves
00114     // are not allocated until the *System* advances to stage Model.
00115     // Note that there is no subsystem equivalent of the State's "y"
00116     // vector because in general a subsystem's state variables will
00117     // not be contiguous. However, a subsystem's q's, u's, and z's
00118     // will all be contiguous within those arrays.
00119     const Vector& getQ(const State&) const;
00120     const Vector& getU(const State&) const;
00121     const Vector& getZ(const State&) const;
00122     const Vector& getQDot(const State&) const;
00123     const Vector& getUDot(const State&) const;
00124     const Vector& getZDot(const State&) const;
00125     const Vector& getQDotDot(const State&) const;
00126     const Vector& getQErr(const State&) const;
00127     const Vector& getUErr(const State&) const;
00128     const Vector& getUDotErr(const State&) const;
00129     const Vector& getMultipliers(const State&) const;
00130 
00131     // These return writable access to this subsystem's partition in the
00132     // State pool of continuous variables. These can be called at Stage::Model
00133     // or higher, and if necesary they invalidate the Position (q), Velocity (u),
00134     // or Dynamics (z) stage respectively.
00135     Vector& updQ(State&) const; // invalidates Stage::Position
00136     Vector& updU(State&) const; // invalidates Stage::Velocity
00137     Vector& updZ(State&) const; // invalidates Stage::Dynamics
00138 
00139     // For convenience.
00140     void setQ(State& s, const Vector& q) const {
00141         assert(q.size() == getNQ(s));
00142         updQ(s) = q;
00143     }
00144     void setU(State& s, const Vector& u) const {
00145         assert(u.size() == getNU(s));
00146         updU(s) = u;
00147     }
00148     void setZ(State& s, const Vector& z) const {
00149         assert(z.size() == getNZ(s));
00150         updZ(s) = z;
00151     }
00152 
00153     // These update the State cache which is mutable; hence, const State. They
00154     // can be called only if the previous stage has already been realized, e.g.,
00155     // updQDot() is allowed only while realizing the Velocity stage, requiring
00156     // that Position stage has already been realized.
00157     Vector& updQDot(const State&) const;
00158     Vector& updUDot(const State&) const;
00159     Vector& updZDot(const State&) const;
00160     Vector& updQDotDot(const State&) const;
00161     Vector& updQErr(const State&) const;
00162     Vector& updUErr(const State&) const;
00163     Vector& updUDotErr(const State&) const;
00164     Vector& updMultipliers(const State&) const;
00165 
00166     // These pull out the State entries which belong exclusively to
00167     // this Subsystem. These variables and cache entries are available
00168     // as soon as this subsystem is at stage Model.
00169     Stage getStage(const State&) const;
00170     const AbstractValue& getDiscreteVariable(const State&, int index) const;
00171     // State is *not* mutable here -- must have write access to change state variables.
00172     AbstractValue& updDiscreteVariable(State&, int index) const;
00173     const AbstractValue& getCacheEntry(const State&, int index) const;
00174     // State is mutable here.
00175     AbstractValue& updCacheEntry(const State&, int index) const;
00176 
00177     // Dimensions. These are valid at System Stage::Model while access to the various
00178     // arrays may have stricter requirements. Hence it is better to use these
00179     // routines than to get a reference to a Vector above and ask for its size().
00180 
00181     int getQStart      (const State&) const;
00182     int getNQ          (const State&) const;
00183     int getUStart      (const State&) const;
00184     int getNU          (const State&) const;
00185     int getZStart      (const State&) const;
00186     int getNZ          (const State&) const;
00187     int getQErrStart   (const State&) const;
00188     int getNQErr       (const State&) const;
00189     int getUErrStart   (const State&) const;
00190     int getNUErr       (const State&) const;
00191     int getUDotErrStart(const State&) const;
00192     int getNUDotErr    (const State&) const;
00193     int getMultipliersStart(const State&) const;
00194     int getNMultipliers    (const State&) const;
00195 
00196     bool isInSystem() const;
00197     bool isInSameSystem(const Subsystem& otherSubsystem) const;
00198 
00199     const System& getSystem() const;
00200     System&       updSystem();
00201 
00202     SubsystemIndex getMySubsystemIndex() const;
00203 
00204     // Internal use only
00205     const Subsystem& getOwnerSubsystemHandle() const;
00206     Subsystem& updOwnerSubsystemHandle();
00207     void setOwnerSubsystemHandle(Subsystem&);
00208     bool hasOwnerSubsystemHandle() const;
00209 
00210     void setSystem(System&, SubsystemIndex);
00211 
00212     explicit Guts(class GutsRep* r) : rep(r) { }
00213     bool                hasRep() const {return rep!=0;}
00214     const GutsRep& getRep() const {assert(rep); return *rep;}
00215     GutsRep&       updRep() const {assert(rep); return *rep;}
00216     void setRep(GutsRep& r) {assert(!rep); rep = &r;}
00217 
00218     bool subsystemTopologyHasBeenRealized() const;
00219     void invalidateSubsystemTopologyCache() const;
00220 
00221     // Call this routine to invoke the client-side virtual destructor,
00222     // by going through the library-side explicit virtual function table.
00223     static void destruct(Subsystem::Guts*);
00224 
00225     // These are wrappers for the virtual methods defined below. They
00226     // are used to ensure good behavior, and most importantly only
00227     // access the virtual methods through the explicitly-built
00228     // virtual function table stored in the GutsRep class.
00229 
00230     Subsystem::Guts* clone() const;
00231 
00232     // Realize this subsystem's part of the State from Stage-1 to Stage
00233     // for the indicated stage. After doing some checking, these routines
00234     // call the concrete subsystem's corresponding virtual method, and
00235     // on return they make sure the stage has been properly updated.
00236     // Note that these will do nothing if the Subsystem stage is already
00237     // at or greater than the indicated stage.
00238     void realizeSubsystemTopology    (State&) const;
00239     void realizeSubsystemModel       (State&) const;
00240     void realizeSubsystemInstance    (const State&) const;
00241     void realizeSubsystemTime        (const State&) const;
00242     void realizeSubsystemPosition    (const State&) const;
00243     void realizeSubsystemVelocity    (const State&) const;
00244     void realizeSubsystemDynamics    (const State&) const;
00245     void realizeSubsystemAcceleration(const State&) const;
00246     void realizeSubsystemReport      (const State&) const;
00247 
00248 
00249 
00250     // Calculate weights and tolerances.
00251 
00252     // Given the current values of our own position variables,
00253     // calculate a "unit weighting" for changes to these position
00254     // variables. 
00255     // @param[out] weights must be resizable or already the right size
00256     // @pre State must be realized to >= Stage::Position (this subsystem).
00257     void calcQUnitWeights(const State&, Vector& weights) const;
00258 
00259     // Given the current values of our own position variables,
00260     // calculate a "unit weighting" for changes to our velocity
00261     // variables.
00262     // @param[out] weights must be resizable or already the right size
00263     // @pre State must be realized to >= Stage::Position (this subsystem).
00264     void calcUUnitWeights(const State&, Vector& weights) const;
00265 
00266     // Given the current values of our own position variables,
00267     // calculate a "unit weighting" for changes to our auxiliary
00268     // variables.
00269     // @param[out] weights must be resizable or already the right size
00270     // @pre State must be realized to >= Stage::Position (this subsystem).
00271     void calcZUnitWeights(const State&, Vector& weights) const;
00272 
00273     // Calculate a "unit tolerance" for errors in each of this subsystem's
00274     // position-level constraints.
00275     // @param[out] tolerances must be resizable or already the right size
00276     // @pre State must be realized to >= Stage::Model (this subsystem).
00277     // @remark Tolerances are expected to be constant during a study; typically
00278     //         they just reflect the units in which the contraint equations
00279     //         are calculated, e.g. angles or lengths.
00280     void calcQErrUnitTolerances(const State&, Vector& tolerances) const;
00281 
00282     // Calculate a "unit tolerance" for errors in each of this subsystem's
00283     // velocity-level constraints.
00284     // @param[out] tolerances must be resizable or already the right size
00285     // @pre State must be realized to >= Stage::Model (this subsystem).
00286     // @remark Tolerances are expected to be constant during a study; typically
00287     //         they just reflect the units in which the contraint equations
00288     //         are calculated, e.g. angles/time or lengths/time.
00289     void calcUErrUnitTolerances(const State&, Vector& tolerances) const;
00290 
00291     // Generate decorative geometry computable at a specific stage. This will
00292     // throw an exception if this subsystem's state hasn't already been realized
00293     // to that stage. Note that the list is not inclusive -- you have to
00294     // request geometry from each stage to get all of it.
00295     // The generated geometry will be *appended* to the supplied output vector.
00296     void calcDecorativeGeometryAndAppend(const State&, Stage, std::vector<DecorativeGeometry>&) const;
00297     
00298     void createScheduledEvent(State& state, EventId& eventId) const;
00299     void createTriggeredEvent(State& state, EventId& eventId, int& triggerFunctionIndex, Stage stage) const;
00300 
00301     // These methods are called by the corresponding methods of System.
00302     // Each subsystem is responsible for defining its own events, and
00303     // System then combines the information from them, and dispatches events
00304     // to the appropriate subsystems for handling when they occur.
00305     virtual void calcEventTriggerInfo(const State&, std::vector<System::EventTriggerInfo>&) const;
00306     virtual void calcTimeOfNextScheduledEvent(const State&, Real& tNextEvent, std::vector<EventId>& eventIds, bool includeCurrentTime) const;
00307     virtual void calcTimeOfNextScheduledReport(const State&, Real& tNextEvent, std::vector<EventId>& eventIds, bool includeCurrentTime) const;
00308     virtual void handleEvents(State&, System::EventCause, const std::vector<EventId>& eventIds,
00309         Real accuracy, const Vector& yWeights, const Vector& ooConstraintTols,
00310         Stage& lowestModified, bool& shouldTerminate) const;
00311     virtual void reportEvents(const State&, System::EventCause, const std::vector<EventId>& eventIds) const;
00312 protected:
00313     // These virtual methods should be overridden in concrete Subsystems as
00314     // necessary. They should never be called directly; instead call the
00315     // wrapper routines above, which have the same name but without the "Impl"
00316     // (implementation) at the end.
00317     
00318     // The "realize..." wrappers will call the "realize...Impl" methods below
00319     // only when the current stage for the Subsystem is the one just prior
00320     // to the stage being realized. For example, realizeSubsystemVelocityImpl()
00321     // is called by realizeSubsystemVelocity() only when the passed-in State
00322     // shows this subsystem's stage to be exactly Stage::Position.
00323     //
00324     // The default implementations provided here do nothing. That means the
00325     // wrappers will simply check that the current stage is correct and
00326     // advance it if necessary.
00327 
00328     // The destructor is already virtual; see above.
00329 
00330     virtual Subsystem::Guts* cloneImpl() const = 0;
00331 
00332     virtual int realizeSubsystemTopologyImpl(State& s) const;
00333     virtual int realizeSubsystemModelImpl(State& s) const;
00334     virtual int realizeSubsystemInstanceImpl(const State& s) const;
00335     virtual int realizeSubsystemTimeImpl(const State& s) const;
00336     virtual int realizeSubsystemPositionImpl(const State& s) const;
00337     virtual int realizeSubsystemVelocityImpl(const State& s) const;
00338     virtual int realizeSubsystemDynamicsImpl(const State& s) const;
00339     virtual int realizeSubsystemAccelerationImpl(const State& s) const;
00340     virtual int realizeSubsystemReportImpl(const State& s) const;
00341 
00342     virtual int calcQUnitWeightsImpl(const State& s, Vector& weights) const;
00343     virtual int calcUUnitWeightsImpl(const State& s, Vector& weights) const;
00344     virtual int calcZUnitWeightsImpl(const State& s, Vector& weights) const;
00345     virtual int calcQErrUnitTolerancesImpl(const State& s, Vector& tolerances) const;
00346     virtual int calcUErrUnitTolerancesImpl(const State& s, Vector& tolerances) const;
00347     virtual int calcDecorativeGeometryAndAppendImpl
00348        (const State&, Stage, std::vector<DecorativeGeometry>&) const;
00349 
00350     // Use these to allocate state variables and cache entries that are owned
00351     // by this Subsystem.
00352 
00353     // qdot, qdotdot also allocated in cache
00354     int allocateQ(State& s, const Vector& qInit) const;
00355     // udot is also allocated in the cache
00356     int allocateU(State& s, const Vector& uInit) const;
00357     // zdot is also allocated in the cache
00358     int allocateZ(State& s, const Vector& zInit) const;
00359     // qerr, uerr, udoterr are all cache entries, not variables
00360     // allocating udoterr also allocates matching multipliers
00361     int allocateQErr(State& s, int nqerr) const;
00362     int allocateUErr(State& s, int nuerr) const;
00363     int allocateUDotErr(State& s, int nudoterr) const;
00364     int allocateDiscreteVariable(State& s, Stage g, AbstractValue* v) const;
00365     int allocateCacheEntry(State& s, Stage g, AbstractValue* v) const;
00366     void advanceToStage(const State& s, Stage g) const;
00367 
00368 
00369 private:
00370 
00371     // These typedefs are used internally to manage the binary-compatible
00372     // handling of the virtual function table.
00373 
00374     typedef void (*DestructImplLocator)(Subsystem::Guts*);
00375     typedef Subsystem::Guts* (*CloneImplLocator)(const Subsystem::Guts&);
00376     typedef int (*RealizeWritableStateImplLocator)(const Subsystem::Guts&, State&);
00377     typedef int (*RealizeConstStateImplLocator)(const Subsystem::Guts&, const State&);
00378     typedef int (*CalcUnitWeightsImplLocator)(const Subsystem::Guts&, const State&, Vector& weights);
00379     typedef int (*CalcDecorativeGeometryAndAppendImplLocator)
00380        (const Subsystem::Guts&, const State&, Stage, std::vector<DecorativeGeometry>&);
00381 
00382     void librarySideConstruction(const String& name, const String& version);
00383     void librarySideDestruction();
00384 
00385     void registerDestructImpl(DestructImplLocator);
00386     void registerCloneImpl(CloneImplLocator);
00387 
00388     void registerRealizeTopologyImpl    (RealizeWritableStateImplLocator);
00389     void registerRealizeModelImpl       (RealizeWritableStateImplLocator);
00390     void registerRealizeInstanceImpl    (RealizeConstStateImplLocator);
00391     void registerRealizeTimeImpl        (RealizeConstStateImplLocator);
00392     void registerRealizePositionImpl    (RealizeConstStateImplLocator);
00393     void registerRealizeVelocityImpl    (RealizeConstStateImplLocator);
00394     void registerRealizeDynamicsImpl    (RealizeConstStateImplLocator);
00395     void registerRealizeAccelerationImpl(RealizeConstStateImplLocator);
00396     void registerRealizeReportImpl      (RealizeConstStateImplLocator);
00397 
00398     void registerCalcQUnitWeightsImpl(CalcUnitWeightsImplLocator);
00399     void registerCalcUUnitWeightsImpl(CalcUnitWeightsImplLocator);
00400     void registerCalcZUnitWeightsImpl(CalcUnitWeightsImplLocator);
00401     void registerCalcQErrUnitTolerancesImpl(CalcUnitWeightsImplLocator);
00402     void registerCalcUErrUnitTolerancesImpl(CalcUnitWeightsImplLocator);
00403     void registerCalcDecorativeGeometryAndAppendImpl(CalcDecorativeGeometryAndAppendImplLocator);
00404 
00405     // We want the locator functions to have access to the protected "Impl"
00406     // virtual methods, so we make them friends.
00407 
00408     friend void subsystemDestructImplLocator(Subsystem::Guts*);
00409     friend Subsystem::Guts* subsystemCloneImplLocator(const Subsystem::Guts&);
00410 
00411     friend int subsystemRealizeTopologyImplLocator(const Subsystem::Guts&, State&);
00412     friend int subsystemRealizeModelImplLocator(const Subsystem::Guts&, State&);
00413     friend int subsystemRealizeInstanceImplLocator(const Subsystem::Guts&, const State&);
00414     friend int subsystemRealizeTimeImplLocator(const Subsystem::Guts&, const State&);
00415     friend int subsystemRealizePositionImplLocator(const Subsystem::Guts&, const State&);
00416     friend int subsystemRealizeVelocityImplLocator(const Subsystem::Guts&, const State&);
00417     friend int subsystemRealizeDynamicsImplLocator(const Subsystem::Guts&, const State&);
00418     friend int subsystemRealizeAccelerationImplLocator(const Subsystem::Guts&, const State&);
00419     friend int subsystemRealizeReportImplLocator(const Subsystem::Guts&, const State&);
00420 
00421     friend int subsystemCalcQUnitWeightsImplLocator(const Subsystem::Guts&, const State&, Vector&);
00422     friend int subsystemCalcUUnitWeightsImplLocator(const Subsystem::Guts&, const State&, Vector&);
00423     friend int subsystemCalcZUnitWeightsImplLocator(const Subsystem::Guts&, const State&, Vector&);
00424     friend int subsystemCalcQErrUnitTolerancesImplLocator(const Subsystem::Guts&, const State&, Vector&);
00425     friend int subsystemCalcUErrUnitTolerancesImplLocator(const Subsystem::Guts&, const State&, Vector&);
00426     friend int subsystemCalcDecorativeGeometryAndAppendImplLocator
00427                 (const Subsystem::Guts&, const State&, Stage, std::vector<DecorativeGeometry>&);
00428 };
00429 
00430 
00431 // These are used to supply the client-side virtual function to the library, without
00432 // the client and library having to agree on the layout of the virtual function tables.
00433 
00434 static void subsystemDestructImplLocator(Subsystem::Guts* sysp)
00435   { delete sysp; } // invokes virtual destructor
00436 static Subsystem::Guts* subsystemCloneImplLocator(const Subsystem::Guts& sys)
00437   { return sys.cloneImpl(); }
00438 
00439 static int subsystemRealizeTopologyImplLocator(const Subsystem::Guts& sys, State& state)
00440   { return sys.realizeSubsystemTopologyImpl(state); }
00441 static int subsystemRealizeModelImplLocator(const Subsystem::Guts& sys, State& state)
00442   { return sys.realizeSubsystemModelImpl(state); }
00443 static int subsystemRealizeInstanceImplLocator(const Subsystem::Guts& sys, const State& state)
00444   { return sys.realizeSubsystemInstanceImpl(state); }
00445 static int subsystemRealizeTimeImplLocator(const Subsystem::Guts& sys, const State& state)
00446   { return sys.realizeSubsystemTimeImpl(state); }
00447 static int subsystemRealizePositionImplLocator(const Subsystem::Guts& sys, const State& state)
00448   { return sys.realizeSubsystemPositionImpl(state); }
00449 static int subsystemRealizeVelocityImplLocator(const Subsystem::Guts& sys, const State& state)
00450   { return sys.realizeSubsystemVelocityImpl(state); }
00451 static int subsystemRealizeDynamicsImplLocator(const Subsystem::Guts& sys, const State& state)
00452   { return sys.realizeSubsystemDynamicsImpl(state); }
00453 static int subsystemRealizeAccelerationImplLocator(const Subsystem::Guts& sys, const State& state)
00454   { return sys.realizeSubsystemAccelerationImpl(state); }
00455 static int subsystemRealizeReportImplLocator(const Subsystem::Guts& sys, const State& state)
00456   { return sys.realizeSubsystemReportImpl(state); }
00457 
00458 static int subsystemCalcQUnitWeightsImplLocator(const Subsystem::Guts& sys, const State& s, Vector& weights)
00459   { return sys.calcQUnitWeightsImpl(s,weights); }
00460 static int subsystemCalcUUnitWeightsImplLocator(const Subsystem::Guts& sys, const State& s, Vector& weights)
00461   { return sys.calcUUnitWeightsImpl(s,weights); }
00462 static int subsystemCalcZUnitWeightsImplLocator(const Subsystem::Guts& sys, const State& s, Vector& weights)
00463   { return sys.calcZUnitWeightsImpl(s,weights); }
00464 static int subsystemCalcQErrUnitTolerancesImplLocator(const Subsystem::Guts& sys, const State& s, Vector& tolerances)
00465   { return sys.calcQErrUnitTolerancesImpl(s,tolerances); }
00466 static int subsystemCalcUErrUnitTolerancesImplLocator(const Subsystem::Guts& sys, const State& s, Vector& tolerances)
00467   { return sys.calcUErrUnitTolerancesImpl(s,tolerances); }
00468 static int subsystemCalcDecorativeGeometryAndAppendImplLocator
00469    (const Subsystem::Guts& sys, const State& s, Stage g, std::vector<DecorativeGeometry>& geom)
00470   { return sys.calcDecorativeGeometryAndAppendImpl(s,g,geom); }
00471 
00472 
00473 // Default constructor must be inline so that it has access to the above static
00474 // functions which are private to the client-side compilation unit in which the
00475 // client-side virtual function table is understood.
00476 inline Subsystem::Guts::Guts(const String& name, const String& version) : rep(0)
00477 {
00478     librarySideConstruction(name, version);
00479 
00480     // Teach the library code how to call client side virtual functions by
00481     // calling through the client side compilation unit's private static
00482     // locator functions.
00483     registerDestructImpl(subsystemDestructImplLocator);
00484     registerCloneImpl(subsystemCloneImplLocator);
00485 
00486     registerRealizeTopologyImpl    (subsystemRealizeTopologyImplLocator);
00487     registerRealizeModelImpl       (subsystemRealizeModelImplLocator);
00488     registerRealizeInstanceImpl    (subsystemRealizeInstanceImplLocator);
00489     registerRealizeTimeImpl        (subsystemRealizeTimeImplLocator);
00490     registerRealizePositionImpl    (subsystemRealizePositionImplLocator);
00491     registerRealizeVelocityImpl    (subsystemRealizeVelocityImplLocator);
00492     registerRealizeDynamicsImpl    (subsystemRealizeDynamicsImplLocator);
00493     registerRealizeAccelerationImpl(subsystemRealizeAccelerationImplLocator);
00494     registerRealizeReportImpl      (subsystemRealizeReportImplLocator);
00495 
00496     registerCalcQUnitWeightsImpl(subsystemCalcQUnitWeightsImplLocator);
00497     registerCalcUUnitWeightsImpl(subsystemCalcUUnitWeightsImplLocator);
00498     registerCalcZUnitWeightsImpl(subsystemCalcZUnitWeightsImplLocator);
00499     registerCalcQErrUnitTolerancesImpl(subsystemCalcQErrUnitTolerancesImplLocator);
00500     registerCalcUErrUnitTolerancesImpl(subsystemCalcUErrUnitTolerancesImplLocator);
00501     registerCalcDecorativeGeometryAndAppendImpl(subsystemCalcDecorativeGeometryAndAppendImplLocator);
00502 }
00503 
00504 } // namespace SimTK
00505 
00506 #endif // SimTK_SimTKCOMMON_SUBSYSTEM_GUTS_H_

Generated on Thu Feb 28 01:34:32 2008 for SimTKcommon by  doxygen 1.4.7