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
00061 class SimTK_SimTKCOMMON_EXPORT Stage : public Enumeration<Stage> {
00062 public:
00063 enum Num {
00064 EmptyIndex = 0,
00065 TopologyIndex = 1,
00066 ModelIndex = 2,
00067 InstanceIndex = 3,
00068 TimeIndex = 4,
00069 PositionIndex = 5,
00070 VelocityIndex = 6,
00071 DynamicsIndex = 7,
00072 AccelerationIndex = 8,
00073 ReportIndex = 9,
00074 InfinityIndex = 10
00075 };
00076 static const Stage Empty;
00077 static const Stage Topology;
00078 static const Stage Model;
00079 static const Stage Instance;
00080 static const Stage Time;
00081 static const Stage Position;
00082 static const Stage Velocity;
00083 static const Stage Dynamics;
00084 static const Stage Acceleration;
00085 static const Stage Report;
00086 static const Stage Infinity;
00087
00088 static const Stage LowestValid;
00089 static const Stage HighestValid;
00090 static const int NValid = InfinityIndex-EmptyIndex+1;
00091
00092
00093 static const Stage LowestRuntime;
00094 static const Stage HighestRuntime;
00095 static const int NRuntime = ReportIndex-ModelIndex+1;
00096
00097 Stage next() const { return getValue(getIndex()+1); }
00098 Stage prev() const { return getValue(getIndex()-1); }
00099
00100
00101 void invalidate(Stage tooHigh) {
00102 if (getIndex() >= tooHigh.getIndex())
00103 *this = tooHigh.prev();
00104 }
00105
00106 bool isInRuntimeRange() const {return Stage::LowestRuntime <= getIndex() && getIndex() <= Stage::HighestRuntime;}
00107
00108 private:
00109 Stage();
00110 Stage(const Stage& thisElement, int index, const char* name);
00111 static void initValues();
00112 friend class Enumeration<Stage>;
00113 };
00114
00115
00116 namespace Exception {
00117
00118 class RealizeTopologyMustBeCalledFirst : public Base {
00119 public:
00120 RealizeTopologyMustBeCalledFirst(const char* fn, int ln,
00121 const char* objectType,
00122 const char* objectName, const char* methodName) : Base(fn,ln)
00123 {
00124 setMessage(String(methodName) + ": " + String(objectType) + " " + String(objectName)
00125 + " topology has not yet been realized -- must call realizeTopology() first");
00126 }
00127 };
00128
00129 class StageTooLow : public Base {
00130 public:
00131 StageTooLow(const char* fn, int ln,
00132 Stage currentStage, Stage targetStage, const char* where) : Base(fn,ln)
00133 {
00134 setMessage("Expected stage to be at least " + targetStage.getName() + " in " + String(where)
00135 + " but current stage was " + currentStage.getName());
00136 }
00137 };
00138
00139 class StageIsWrong : public Base {
00140 public:
00141 StageIsWrong(const char* fn, int ln,
00142 Stage currentStage, Stage targetStage, const char* where) : Base(fn,ln)
00143 {
00144 setMessage("Expected stage to be " + targetStage.getName() + " in " + String(where)
00145 + " but current stage was " + currentStage.getName());
00146 }
00147 };
00148
00149 class StageTooHigh : public Base {
00150 public:
00151 StageTooHigh(const char* fn, int ln,
00152 Stage currentStage, Stage targetStage, const char* where) : Base(fn,ln)
00153 {
00154 setMessage("Expected stage to be less than " + targetStage.getName() + " in " + String(where)
00155 + " but current stage was " + currentStage.getName());
00156 }
00157 };
00158
00159 class StageOutOfRange : public Base {
00160 public:
00161 StageOutOfRange(const char* fn, int ln,
00162 Stage lower, Stage currentStage, Stage upper, const char* where) : Base(fn,ln)
00163 {
00164 setMessage("Expected (" + lower.getName() + " <= stage <= " + upper.getName() + ") in " + String(where)
00165 + " but stage was " + currentStage.getName());
00166 }
00167 };
00168
00169 class CacheEntryOutOfDate : public Base {
00170 public:
00171 CacheEntryOutOfDate(const char* fn, int ln,
00172 Stage currentStage, Stage dependsOn, int dependsOnVersion, int lastCalculatedVersion)
00173 : Base(fn,ln)
00174 {
00175 setMessage("State Cache entry was out of date at Stage " + currentStage.getName()
00176 + ". This entry depends on version " + String(dependsOnVersion)
00177 + " of Stage " + dependsOn.getName()
00178 + " but was last updated at version " + String(lastCalculatedVersion) + ".");
00179 }
00180 };
00181
00182
00183 class RealizeCheckFailed : public Base {
00184 public:
00185 RealizeCheckFailed(const char* fn, int ln, Stage g,
00186 int subsystemId, const char* subsystemName,
00187 const char* fmt ...) : Base(fn,ln)
00188 {
00189 char buf[1024];
00190 va_list args;
00191 va_start(args, fmt);
00192 vsprintf(buf, fmt, args);
00193 setMessage("Couldn't realize subsystem " + String(subsystemId)
00194 + "(" + String(subsystemName) + ") to Stage "
00195 + g.getName() + ": " + String(buf) + ".");
00196 va_end(args);
00197 }
00198 private:
00199 };
00200 }
00201
00202 inline std::ostream& operator<<(std::ostream& o, Stage g) { o << g.getName(); return o; }
00203
00204
00205 }
00206
00207
00208
00209
00210 #define SimTK_REALIZECHECK_ALWAYS(cond,stage,subsysIx,subsysName,msg) \
00211 do{if(!(cond))SimTK_THROW4(SimTK::Exception::RealizeCheckFailed, \
00212 (stage),(subsysIx),(subsysName),(msg)); \
00213 }while(false)
00214 #define SimTK_REALIZECHECK1_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1) \
00215 do{if(!(cond))SimTK_THROW5(SimTK::Exception::RealizeCheckFailed, \
00216 (stage),(subsysIx),(subsysName),(msg),(a1)); \
00217 }while(false)
00218 #define SimTK_REALIZECHECK2_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2)\
00219 do{if(!(cond))SimTK_THROW6(SimTK::Exception::RealizeCheckFailed, \
00220 (stage),(subsysIx),(subsysName),(msg),(a1),(a2)); \
00221 }while(false)
00222 #define SimTK_REALIZECHECK3_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2,a3) \
00223 do{if(!(cond))SimTK_THROW7(SimTK::Exception::RealizeCheckFailed, \
00224 (stage),(subsysIx),(subsysName),(msg),(a1),(a2),(a3)); \
00225 }while(false)
00226 #define SimTK_REALIZECHECK4_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2,a3,a4) \
00227 do{if(!(cond))SimTK_THROW8(SimTK::Exception::RealizeCheckFailed, \
00228 (stage),(subsysIx),(subsysName),(msg),(a1),(a2),(a3),(a4)); \
00229 }while(false)
00230 #define SimTK_REALIZECHECK5_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2,a3,a4,a5) \
00231 do{if(!(cond))SimTK_THROW9(SimTK::Exception::RealizeCheckFailed, \
00232 (stage),(subsysIx),(subsysName),(msg),(a1),(a2),(a3),(a4),(a5)); \
00233 }while(false)
00234
00235
00236 #endif // SimTK_SimTKCOMMON_STAGE_H_