Simbody  3.8
Stage.h
Go to the documentation of this file.
1 #ifndef SimTK_SimTKCOMMON_STAGE_H_
2 #define SimTK_SimTKCOMMON_STAGE_H_
3 
4 /* -------------------------------------------------------------------------- *
5  * Simbody(tm): SimTKcommon *
6  * -------------------------------------------------------------------------- *
7  * This is part of the SimTK biosimulation toolkit originating from *
8  * Simbios, the NIH National Center for Physics-Based Simulation of *
9  * Biological Structures at Stanford, funded under the NIH Roadmap for *
10  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11  * *
12  * Portions copyright (c) 2005-15 Stanford University and the Authors. *
13  * Authors: Michael Sherman *
14  * Contributors: *
15  * *
16  * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17  * not use this file except in compliance with the License. You may obtain a *
18  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19  * *
20  * Unless required by applicable law or agreed to in writing, software *
21  * distributed under the License is distributed on an "AS IS" BASIS, *
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23  * See the License for the specific language governing permissions and *
24  * limitations under the License. *
25  * -------------------------------------------------------------------------- */
26 
30 
31 #include <cassert>
32 #include <iostream>
33 #include <iomanip>
34 #include <cstdarg>
35 
36 namespace SimTK {
37 
44 typedef long long StageVersion;
45 
52 typedef long long ValueVersion;
53 
66 class Stage {
67 public:
68  enum Level {
69  Empty = 0,
70  Topology = 1,
71  Model = 2,
72  Instance = 3,
73  Time = 4,
74  Position = 5,
75  Velocity = 6,
76  Dynamics = 7,
78  Report = 9,
79  Infinity = 10,
80 
85  };
86 
87  enum {
90  };
91 
93  Stage() : level(Stage::Empty) {}
95  Stage(Level l) {
96  assert(LowestValid <= l && l <= HighestValid);
97  level = l;
98  }
100  explicit Stage(int l) {
101  assert(LowestValid <= l && l <= HighestValid);
102  level = Level(l);
103  }
105  operator int() const {return level;}
106 
107  bool operator==(Level other) const {return level==other;}
108  bool operator!=(Level other) const {return level!=other;}
109  bool operator<(Level other) const {return level<other;}
110  bool operator<=(Level other) const {return level<=other;}
111  bool operator>(Level other) const {return level>other;}
112  bool operator>=(Level other) const {return level>=other;}
113  bool operator==(Stage other) const {return level==other.level;}
114  bool operator!=(Stage other) const {return level!=other.level;}
115  bool operator<(Stage other) const {return level<other.level;}
116  bool operator<=(Stage other) const {return level<=other.level;}
117  bool operator>(Stage other) const {return level>other.level;}
118  bool operator>=(Stage other) const {return level>=other.level;}
119 
120  // Prefix operators
121  const Stage& operator++()
122  { assert(level<HighestValid); level=Level(level+1); return *this; }
123  const Stage& operator--()
124  { assert(level>LowestValid); level=Level(level-1); return *this;}
125  // Postfix operators
127  { assert(level<HighestValid); level=Level(level+1); return prev(); }
129  { assert(level>LowestValid); level=Level(level-1); return next(); }
130 
134  Stage next() const
135  { assert(level<HighestValid); return Stage(Level(level+1)); }
139  Stage prev() const
140  { assert(level>LowestValid); return Stage(Level(level-1)); }
141 
144  String getName() const {
145  switch (level) {
146  case Empty: return "Empty"; break;
147  case Topology: return "Topology"; break;
148  case Model: return "Model"; break;
149  case Instance: return "Instance"; break;
150  case Time: return "Time"; break;
151  case Position: return "Position"; break;
152  case Velocity: return "Velocity"; break;
153  case Dynamics: return "Dynamics"; break;
154  case Acceleration: return "Acceleration"; break;
155  case Report: return "Report"; break;
156  case Infinity: return "Infinity"; break;
157  default: assert(!"Stage::getName(): illegal level");
158  }
159  return String("INVALID STAGE LEVEL ") + String(level);
160  }
161 
163  void invalidate(Stage tooHigh) {
164  if (level >= tooHigh.level)
165  *this = tooHigh.prev();
166  }
167 
171  bool isInRuntimeRange() const
172  { return Stage::LowestRuntime <= level
173  && level <= Stage::HighestRuntime; }
174 
175 private:
176  Level level;
177 };
178 
179 
180 
181 
182 namespace Exception {
183 
184 #ifdef _MSC_VER
185 #pragma warning(push)
186 #pragma warning(disable:4996) // don't warn about sprintf, etc.
187 #endif
188 
190 public:
191  RealizeTopologyMustBeCalledFirst(const char* fn, int ln,
192  const char* objectType, // e.g., "System", "Subsystem"
193  const char* objectName, const char* methodName) : Base(fn,ln)
194  {
195  setMessage(String(methodName) + ": " + String(objectType) + " " + String(objectName)
196  + " topology has not been realized since the last topological change"
197  " -- you must call realizeTopology() first.");
198  }
199  virtual ~RealizeTopologyMustBeCalledFirst() throw() { }
200 };
201 
203 public:
205  const char* objectType, // e.g., "System", "Subsystem"
206  const char* objectName, const char* methodName,
207  int sysTopoVersion,
208  int stateTopoVersion) : Base(fn,ln)
209  {
210  setMessage(String(methodName)
211  + ": The given State's Topology stage version number ("
212  + String(stateTopoVersion)
213  + ") doesn't match the current topology cache version number ("
214  + String(sysTopoVersion)
215  + ") of " + String(objectType) + " " + String(objectName) + "."
216  + " That means there has been a topology change to this System since this"
217  " State was created so they are no longer compatible. You should create"
218  " a new State from the System's default State."
219  " (Loopholes exist for advanced users.)");
220  }
222 };
223 
224 
225 
226 class StageTooLow : public Base {
227 public:
228  StageTooLow(const char* fn, int ln,
229  Stage currentStage, Stage targetStage, const char* where) : Base(fn,ln)
230  {
231  setMessage("Expected stage to be at least " + targetStage.getName() + " in " + String(where)
232  + " but current stage was " + currentStage.getName());
233  }
234  virtual ~StageTooLow() throw() { }
235 };
236 
237 class StageIsWrong : public Base {
238 public:
239  StageIsWrong(const char* fn, int ln,
240  Stage currentStage, Stage targetStage, const char* where) : Base(fn,ln)
241  {
242  setMessage("Expected stage to be " + targetStage.getName() + " in " + String(where)
243  + " but current stage was " + currentStage.getName());
244  }
245  virtual ~StageIsWrong() throw() { }
246 };
247 
248 class StageTooHigh : public Base {
249 public:
250  StageTooHigh(const char* fn, int ln,
251  Stage currentStage, Stage targetStage, const char* where) : Base(fn,ln)
252  {
253  setMessage("Expected stage to be less than " + targetStage.getName() + " in " + String(where)
254  + " but current stage was " + currentStage.getName());
255  }
256  virtual ~StageTooHigh() throw() { }
257 };
258 
259 class StageOutOfRange : public Base {
260 public:
261  StageOutOfRange(const char* fn, int ln,
262  Stage lower, Stage currentStage, Stage upper, const char* where) : Base(fn,ln)
263  {
264  setMessage("Expected (" + lower.getName() + " <= stage <= " + upper.getName() + ") in " + String(where)
265  + " but stage was " + currentStage.getName());
266  }
267  virtual ~StageOutOfRange() throw() { }
268 };
269 
270 class CacheEntryOutOfDate : public Base {
271 public:
272  CacheEntryOutOfDate(const char* fn, int ln,
273  Stage currentStage, Stage dependsOn,
274  StageVersion dependsOnVersion, StageVersion lastCalculatedVersion)
275  : Base(fn,ln)
276  {
277  setMessage("State Cache entry was out of date at Stage " + currentStage.getName()
278  + ". This entry depends on version " + String(dependsOnVersion)
279  + " of Stage " + dependsOn.getName()
280  + " but was last updated at version " + String(lastCalculatedVersion) + ".");
281  }
282  virtual ~CacheEntryOutOfDate() throw() { }
283 };
284 
285 // An attempt to realize a particular subsystem to a particular stage failed.
286 class RealizeCheckFailed : public Base {
287 public:
288  RealizeCheckFailed(const char* fn, int ln, Stage g,
289  int subsystemId, const char* subsystemName,
290  const char* fmt, ...) : Base(fn,ln)
291  {
292  const int n = 1024;
293  char buf[n];
294  va_list args;
295  va_start(args, fmt);
296  vsnprintf(buf, n, fmt, args);
297  setMessage("Couldn't realize subsystem " + String(subsystemId)
298  + "(" + String(subsystemName) + ") to Stage "
299  + g.getName() + ": " + String(buf) + ".");
300  va_end(args);
301  }
302  virtual ~RealizeCheckFailed() throw() { }
303 };
304 
305 #ifdef _MSC_VER
306 #pragma warning(pop)
307 #endif
308 
309 } // namespace Exception
310 
311 inline std::ostream& operator<<(std::ostream& o, Stage g)
312 { o << g.getName(); return o; }
313 
314 
315 } // namespace SimTK
316 
317  // REALIZECHECKs: these should be used to catch and report problems that
318  // occur when realizing a subsystem.
319 
320 #define SimTK_REALIZECHECK_ALWAYS(cond,stage,subsysIx,subsysName,msg) \
321  do{if(!(cond))SimTK_THROW4(SimTK::Exception::RealizeCheckFailed, \
322  (stage),(subsysIx),(subsysName),(msg)); \
323  }while(false)
324 #define SimTK_REALIZECHECK1_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1) \
325  do{if(!(cond))SimTK_THROW5(SimTK::Exception::RealizeCheckFailed, \
326  (stage),(subsysIx),(subsysName),(msg),(a1)); \
327  }while(false)
328 #define SimTK_REALIZECHECK2_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2)\
329  do{if(!(cond))SimTK_THROW6(SimTK::Exception::RealizeCheckFailed, \
330  (stage),(subsysIx),(subsysName),(msg),(a1),(a2)); \
331  }while(false)
332 #define SimTK_REALIZECHECK3_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2,a3) \
333  do{if(!(cond))SimTK_THROW7(SimTK::Exception::RealizeCheckFailed, \
334  (stage),(subsysIx),(subsysName),(msg),(a1),(a2),(a3)); \
335  }while(false)
336 #define SimTK_REALIZECHECK4_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2,a3,a4) \
337  do{if(!(cond))SimTK_THROW8(SimTK::Exception::RealizeCheckFailed, \
338  (stage),(subsysIx),(subsysName),(msg),(a1),(a2),(a3),(a4)); \
339  }while(false)
340 #define SimTK_REALIZECHECK5_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2,a3,a4,a5) \
341  do{if(!(cond))SimTK_THROW9(SimTK::Exception::RealizeCheckFailed, \
342  (stage),(subsysIx),(subsysName),(msg),(a1),(a2),(a3),(a4),(a5)); \
343  }while(false)
344 
345 
346 #endif // SimTK_SimTKCOMMON_STAGE_H_
Mandatory first inclusion for any Simbody source or header file.
Definition: Exception.h:46
void setMessage(const std::string &msgin)
Definition: Exception.h:57
CacheEntryOutOfDate(const char *fn, int ln, Stage currentStage, Stage dependsOn, StageVersion dependsOnVersion, StageVersion lastCalculatedVersion)
Definition: Stage.h:272
virtual ~CacheEntryOutOfDate()
Definition: Stage.h:282
RealizeCheckFailed(const char *fn, int ln, Stage g, int subsystemId, const char *subsystemName, const char *fmt,...)
Definition: Stage.h:288
virtual ~RealizeCheckFailed()
Definition: Stage.h:302
RealizeTopologyMustBeCalledFirst(const char *fn, int ln, const char *objectType, const char *objectName, const char *methodName)
Definition: Stage.h:191
virtual ~RealizeTopologyMustBeCalledFirst()
Definition: Stage.h:199
Definition: Stage.h:237
StageIsWrong(const char *fn, int ln, Stage currentStage, Stage targetStage, const char *where)
Definition: Stage.h:239
virtual ~StageIsWrong()
Definition: Stage.h:245
Definition: Stage.h:259
StageOutOfRange(const char *fn, int ln, Stage lower, Stage currentStage, Stage upper, const char *where)
Definition: Stage.h:261
virtual ~StageOutOfRange()
Definition: Stage.h:267
Definition: Stage.h:248
StageTooHigh(const char *fn, int ln, Stage currentStage, Stage targetStage, const char *where)
Definition: Stage.h:250
virtual ~StageTooHigh()
Definition: Stage.h:256
Definition: Stage.h:226
StageTooLow(const char *fn, int ln, Stage currentStage, Stage targetStage, const char *where)
Definition: Stage.h:228
virtual ~StageTooLow()
Definition: Stage.h:234
StateAndSystemTopologyVersionsMustMatch(const char *fn, int ln, const char *objectType, const char *objectName, const char *methodName, int sysTopoVersion, int stateTopoVersion)
Definition: Stage.h:204
virtual ~StateAndSystemTopologyVersionsMustMatch()
Definition: Stage.h:221
This class is basically a glorified enumerated type, type-safe and range checked but permitting conve...
Definition: Stage.h:66
String getName() const
Return a printable name corresponding to the stage level currently stored in this Stage.
Definition: Stage.h:144
const Stage & operator--()
Definition: Stage.h:123
void invalidate(Stage tooHigh)
Set this Stage=min(stageNow, tooHigh-1).
Definition: Stage.h:163
Stage(int l)
You can explicitly create a Stage from an int if it is in range.
Definition: Stage.h:100
bool operator<=(Level other) const
Definition: Stage.h:110
Stage operator++(int)
Definition: Stage.h:126
bool isInRuntimeRange() const
Return true if this Stage has one of the meaningful values between Stage::Topology and Stage::Report,...
Definition: Stage.h:171
Stage(Level l)
This is an implicit conversion from Stage::Level to Stage.
Definition: Stage.h:95
@ NValid
Definition: Stage.h:88
@ NRuntime
Definition: Stage.h:89
const Stage & operator++()
Definition: Stage.h:121
bool operator<(Stage other) const
Definition: Stage.h:115
bool operator!=(Stage other) const
Definition: Stage.h:114
bool operator==(Level other) const
Definition: Stage.h:107
Stage prev() const
Return the Stage before this one, with Stage::Empty returned if this Stage is already at its lowest v...
Definition: Stage.h:139
bool operator!=(Level other) const
Definition: Stage.h:108
Stage()
Default construction gives Stage::Empty.
Definition: Stage.h:93
bool operator>=(Level other) const
Definition: Stage.h:112
Stage next() const
Return the Stage following this one, with Stage::Infinity returned if this Stage is already at its hi...
Definition: Stage.h:134
bool operator<=(Stage other) const
Definition: Stage.h:116
bool operator>=(Stage other) const
Definition: Stage.h:118
bool operator<(Level other) const
Definition: Stage.h:109
bool operator==(Stage other) const
Definition: Stage.h:113
Level
Definition: Stage.h:68
@ Time
A new time has been realized.
Definition: Stage.h:73
@ LowestRuntime
For iterating over meaningful stage values.
Definition: Stage.h:83
@ Topology
System topology realized.
Definition: Stage.h:70
@ Empty
Lower than any legitimate Stage.
Definition: Stage.h:69
@ HighestRuntime
Definition: Stage.h:84
@ Acceleration
Accelerations and multipliers calculated.
Definition: Stage.h:77
@ Position
Spatial configuration available.
Definition: Stage.h:74
@ Dynamics
Forces calculated.
Definition: Stage.h:76
@ Velocity
Spatial velocities available.
Definition: Stage.h:75
@ Model
Modeling choices made.
Definition: Stage.h:71
@ Infinity
Higher than any legitimate Stage.
Definition: Stage.h:79
@ Instance
Physical parameters set.
Definition: Stage.h:72
@ Report
Report-only quantities evaluated.
Definition: Stage.h:78
@ HighestValid
Definition: Stage.h:82
@ LowestValid
For iterating over all stage values.
Definition: Stage.h:81
bool operator>(Stage other) const
Definition: Stage.h:117
bool operator>(Level other) const
Definition: Stage.h:111
Stage operator--(int)
Definition: Stage.h:128
SimTK::String is a plug-compatible std::string replacement (plus some additional functionality) inten...
Definition: String.h:65
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37
long long StageVersion
This is the type to use for Stage version numbers that get incremented whenever a state variable chan...
Definition: Stage.h:44
long long ValueVersion
This is the type to use for state variable version numbers that get incremented whenever a state valu...
Definition: Stage.h:52
std::ostream & operator<<(std::ostream &o, const ContactForce &f)
Definition: CompliantContactSubsystem.h:387