00001 #ifndef SimTK_SimTKCOMMON_STAGE_H_
00002 #define SimTK_SimTKCOMMON_STAGE_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "SimTKcommon/internal/common.h"
00036 #include "SimTKcommon/internal/String.h"
00037 #include "SimTKcommon/internal/Exception.h"
00038 #include "SimTKcommon/internal/Enumeration.h"
00039
00040 #include <cassert>
00041 #include <iostream>
00042 #include <iomanip>
00043 #include <cstdarg>
00044
00045 namespace SimTK {
00046
00055 class SimTK_SimTKCOMMON_EXPORT Stage : public Enumeration<Stage> {
00056 public:
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 enum Num {
00074 EmptyIndex = 0,
00075 TopologyIndex = 1,
00076 ModelIndex = 2,
00077 InstanceIndex = 3,
00078 TimeIndex = 4,
00079 PositionIndex = 5,
00080 VelocityIndex = 6,
00081 DynamicsIndex = 7,
00082 AccelerationIndex = 8,
00083 ReportIndex = 9
00084 };
00085 static const Stage Empty;
00086 static const Stage Topology;
00087 static const Stage Model;
00088 static const Stage Instance;
00089 static const Stage Time;
00090 static const Stage Position;
00091 static const Stage Velocity;
00092 static const Stage Dynamics;
00093 static const Stage Acceleration;
00094 static const Stage Report;
00095
00096 static const Stage LowestValid;
00097 static const Stage HighestValid;
00098 static const int NValid = ReportIndex-EmptyIndex+1;
00099
00100
00101 static const Stage LowestRuntime;
00102 static const Stage HighestRuntime;
00103 static const int NRuntime = ReportIndex-ModelIndex+1;
00104
00105 Stage next() const { return getValue(getIndex()+1); }
00106 Stage prev() const { return getValue(getIndex()-1); }
00107
00108
00109 void invalidate(Stage tooHigh) {
00110 if (getIndex() >= tooHigh.getIndex())
00111 *this = tooHigh.prev();
00112 }
00113
00114 bool isInRuntimeRange() const {return Stage::LowestRuntime <= getIndex() && getIndex() <= Stage::HighestRuntime;}
00115
00116 private:
00117 Stage();
00118 Stage(const Stage& thisElement, int index, char* name);
00119 static void initValues();
00120 friend class Enumeration<Stage>;
00121
00122 };
00123
00124 namespace Exception {
00125
00126 class RealizeTopologyMustBeCalledFirst : public Base {
00127 public:
00128 RealizeTopologyMustBeCalledFirst(const char* fn, int ln,
00129 const char* objectType,
00130 const char* objectName, const char* methodName) : Base(fn,ln)
00131 {
00132 setMessage(String(methodName) + ": " + String(objectType) + " " + String(objectName)
00133 + " topology has not yet been realized -- must call realizeTopology() first");
00134 }
00135 };
00136
00137 class StageTooLow : public Base {
00138 public:
00139 StageTooLow(const char* fn, int ln,
00140 Stage currentStage, Stage targetStage, const char* where) : Base(fn,ln)
00141 {
00142 setMessage("Expected stage to be at least " + targetStage.getName() + " in " + String(where)
00143 + " but current stage was " + currentStage.getName());
00144 }
00145 };
00146
00147 class StageIsWrong : public Base {
00148 public:
00149 StageIsWrong(const char* fn, int ln,
00150 Stage currentStage, Stage targetStage, const char* where) : Base(fn,ln)
00151 {
00152 setMessage("Expected stage to be " + targetStage.getName() + " in " + String(where)
00153 + " but current stage was " + currentStage.getName());
00154 }
00155 };
00156
00157 class StageTooHigh : public Base {
00158 public:
00159 StageTooHigh(const char* fn, int ln,
00160 Stage currentStage, Stage targetStage, const char* where) : Base(fn,ln)
00161 {
00162 setMessage("Expected stage to be less than " + targetStage.getName() + " in " + String(where)
00163 + " but current stage was " + currentStage.getName());
00164 }
00165 };
00166
00167 class StageOutOfRange : public Base {
00168 public:
00169 StageOutOfRange(const char* fn, int ln,
00170 Stage lower, Stage currentStage, Stage upper, const char* where) : Base(fn,ln)
00171 {
00172 setMessage("Expected (" + lower.getName() + " <= stage <= " + upper.getName() + ") in " + String(where)
00173 + " but stage was " + currentStage.getName());
00174 }
00175 };
00176
00177
00178 class RealizeCheckFailed : public Base {
00179 public:
00180 RealizeCheckFailed(const char* fn, int ln, Stage g,
00181 int subsystemId, const char* subsystemName,
00182 const char* fmt ...) : Base(fn,ln)
00183 {
00184 char buf[1024];
00185 va_list args;
00186 va_start(args, fmt);
00187 vsprintf(buf, fmt, args);
00188 setMessage("Couldn't realize subsystem " + String(subsystemId)
00189 + "(" + String(subsystemName) + ") to Stage "
00190 + g.getName() + ": " + String(buf) + ".");
00191 va_end(args);
00192 }
00193 private:
00194 };
00195 }
00196
00197 inline std::ostream& operator<<(std::ostream& o, Stage g) { o << g.getName(); return o; }
00198
00199
00200 }
00201
00202
00203
00204
00205 #define SimTK_REALIZECHECK_ALWAYS(cond,stage,subsysIx,subsysName,msg) \
00206 do{if(!(cond))SimTK_THROW4(SimTK::Exception::RealizeCheckFailed, \
00207 (stage),(subsysIx),(subsysName),(msg)); \
00208 }while(false)
00209 #define SimTK_REALIZECHECK1_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1) \
00210 do{if(!(cond))SimTK_THROW5(SimTK::Exception::RealizeCheckFailed, \
00211 (stage),(subsysIx),(subsysName),(msg),(a1)); \
00212 }while(false)
00213 #define SimTK_REALIZECHECK2_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2)\
00214 do{if(!(cond))SimTK_THROW6(SimTK::Exception::RealizeCheckFailed, \
00215 (stage),(subsysIx),(subsysName),(msg),(a1),(a2)); \
00216 }while(false)
00217 #define SimTK_REALIZECHECK3_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2,a3) \
00218 do{if(!(cond))SimTK_THROW7(SimTK::Exception::RealizeCheckFailed, \
00219 (stage),(subsysIx),(subsysName),(msg),(a1),(a2),(a3)); \
00220 }while(false)
00221 #define SimTK_REALIZECHECK4_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2,a3,a4) \
00222 do{if(!(cond))SimTK_THROW8(SimTK::Exception::RealizeCheckFailed, \
00223 (stage),(subsysIx),(subsysName),(msg),(a1),(a2),(a3),(a4)); \
00224 }while(false)
00225 #define SimTK_REALIZECHECK5_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2,a3,a4,a5) \
00226 do{if(!(cond))SimTK_THROW9(SimTK::Exception::RealizeCheckFailed, \
00227 (stage),(subsysIx),(subsysName),(msg),(a1),(a2),(a3),(a4),(a5)); \
00228 }while(false)
00229
00230
00231 #endif // SimTK_SimTKCOMMON_STAGE_H_