Simbody  3.6
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  char buf[1024];
293  va_list args;
294  va_start(args, fmt);
295  vsprintf(buf, fmt, args);
296  setMessage("Couldn't realize subsystem " + String(subsystemId)
297  + "(" + String(subsystemName) + ") to Stage "
298  + g.getName() + ": " + String(buf) + ".");
299  va_end(args);
300  }
301  virtual ~RealizeCheckFailed() throw() { }
302 };
303 
304 #ifdef _MSC_VER
305 #pragma warning(pop)
306 #endif
307 
308 } // namespace Exception
309 
310 inline std::ostream& operator<<(std::ostream& o, Stage g)
311 { o << g.getName(); return o; }
312 
313 
314 } // namespace SimTK
315 
316  // REALIZECHECKs: these should be used to catch and report problems that
317  // occur when realizing a subsystem.
318 
319 #define SimTK_REALIZECHECK_ALWAYS(cond,stage,subsysIx,subsysName,msg) \
320  do{if(!(cond))SimTK_THROW4(SimTK::Exception::RealizeCheckFailed, \
321  (stage),(subsysIx),(subsysName),(msg)); \
322  }while(false)
323 #define SimTK_REALIZECHECK1_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1) \
324  do{if(!(cond))SimTK_THROW5(SimTK::Exception::RealizeCheckFailed, \
325  (stage),(subsysIx),(subsysName),(msg),(a1)); \
326  }while(false)
327 #define SimTK_REALIZECHECK2_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2)\
328  do{if(!(cond))SimTK_THROW6(SimTK::Exception::RealizeCheckFailed, \
329  (stage),(subsysIx),(subsysName),(msg),(a1),(a2)); \
330  }while(false)
331 #define SimTK_REALIZECHECK3_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2,a3) \
332  do{if(!(cond))SimTK_THROW7(SimTK::Exception::RealizeCheckFailed, \
333  (stage),(subsysIx),(subsysName),(msg),(a1),(a2),(a3)); \
334  }while(false)
335 #define SimTK_REALIZECHECK4_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2,a3,a4) \
336  do{if(!(cond))SimTK_THROW8(SimTK::Exception::RealizeCheckFailed, \
337  (stage),(subsysIx),(subsysName),(msg),(a1),(a2),(a3),(a4)); \
338  }while(false)
339 #define SimTK_REALIZECHECK5_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2,a3,a4,a5) \
340  do{if(!(cond))SimTK_THROW9(SimTK::Exception::RealizeCheckFailed, \
341  (stage),(subsysIx),(subsysName),(msg),(a1),(a2),(a3),(a4),(a5)); \
342  }while(false)
343 
344 
345 #endif // SimTK_SimTKCOMMON_STAGE_H_
SimTK::Stage::HighestRuntime
@ HighestRuntime
Definition: Stage.h:84
SimTK::Stage::Instance
@ Instance
Physical parameters set.
Definition: Stage.h:72
SimTK::Stage::operator--
const Stage & operator--()
Definition: Stage.h:123
SimTK::Exception::StageTooLow::~StageTooLow
virtual ~StageTooLow()
Definition: Stage.h:234
SimTK::Stage::operator==
bool operator==(Stage other) const
Definition: Stage.h:113
SimTK::Exception::Base
Definition: Exception.h:46
SimTK::Stage::operator>
bool operator>(Stage other) const
Definition: Stage.h:117
SimTK::Stage::operator<
bool operator<(Level other) const
Definition: Stage.h:109
SimTK::Stage::Stage
Stage(Level l)
This is an implicit conversion from Stage::Level to Stage.
Definition: Stage.h:95
SimTK::Stage::getName
String getName() const
Return a printable name corresponding to the stage level currently stored in this Stage.
Definition: Stage.h:144
SimTK::Exception::CacheEntryOutOfDate::~CacheEntryOutOfDate
virtual ~CacheEntryOutOfDate()
Definition: Stage.h:282
SimTK::Stage::operator<=
bool operator<=(Stage other) const
Definition: Stage.h:116
common.h
SimTK::Stage::operator>=
bool operator>=(Level other) const
Definition: Stage.h:112
SimTK::Exception::RealizeTopologyMustBeCalledFirst::~RealizeTopologyMustBeCalledFirst
virtual ~RealizeTopologyMustBeCalledFirst()
Definition: Stage.h:199
SimTK::Stage::operator--
Stage operator--(int)
Definition: Stage.h:128
SimTK::Stage::Velocity
@ Velocity
Spatial velocities available.
Definition: Stage.h:75
SimTK
This is a System that represents the dynamics of a particle moving along a smooth surface.
Definition: Assembler.h:37
SimTK::Stage::Model
@ Model
Modeling choices made.
Definition: Stage.h:71
SimTK::Exception::CacheEntryOutOfDate::CacheEntryOutOfDate
CacheEntryOutOfDate(const char *fn, int ln, Stage currentStage, Stage dependsOn, StageVersion dependsOnVersion, StageVersion lastCalculatedVersion)
Definition: Stage.h:272
SimTK::Stage::Report
@ Report
Report-only quantities evaluated.
Definition: Stage.h:78
SimTK::Stage::operator==
bool operator==(Level other) const
Definition: Stage.h:107
SimTK::Exception::RealizeCheckFailed::RealizeCheckFailed
RealizeCheckFailed(const char *fn, int ln, Stage g, int subsystemId, const char *subsystemName, const char *fmt,...)
Definition: Stage.h:288
SimTK::Exception::RealizeCheckFailed
Definition: Stage.h:286
SimTK::Stage::operator!=
bool operator!=(Level other) const
Definition: Stage.h:108
SimTK::Stage::operator>=
bool operator>=(Stage other) const
Definition: Stage.h:118
SimTK::Stage::Empty
@ Empty
Lower than any legitimate Stage.
Definition: Stage.h:69
SimTK::Exception::StageTooLow::StageTooLow
StageTooLow(const char *fn, int ln, Stage currentStage, Stage targetStage, const char *where)
Definition: Stage.h:228
SimTK::Stage::Level
Level
Definition: Stage.h:68
SimTK::Exception::StageTooHigh::~StageTooHigh
virtual ~StageTooHigh()
Definition: Stage.h:256
SimTK::Stage::Topology
@ Topology
System topology realized.
Definition: Stage.h:70
SimTK::StageVersion
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
Exception.h
SimTK::ValueVersion
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
SimTK::Exception::RealizeTopologyMustBeCalledFirst
Definition: Stage.h:189
SimTK::Stage::prev
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
SimTK::Stage::LowestValid
@ LowestValid
For iterating over all stage values.
Definition: Stage.h:81
SimTK::Stage::operator<
bool operator<(Stage other) const
Definition: Stage.h:115
SimTK::Stage::operator>
bool operator>(Level other) const
Definition: Stage.h:111
SimTK::Stage::isInRuntimeRange
bool isInRuntimeRange() const
Return true if this Stage has one of the meaningful values between Stage::Topology and Stage::Report,...
Definition: Stage.h:171
SimTK::Stage::Dynamics
@ Dynamics
Forces calculated.
Definition: Stage.h:76
SimTK::Stage::NRuntime
@ NRuntime
Definition: Stage.h:89
SimTK::Exception::StageOutOfRange
Definition: Stage.h:259
SimTK::Stage
This class is basically a glorified enumerated type, type-safe and range checked but permitting conve...
Definition: Stage.h:66
SimTK::Stage::invalidate
void invalidate(Stage tooHigh)
Set this Stage=min(stageNow, tooHigh-1).
Definition: Stage.h:163
SimTK::Exception::RealizeCheckFailed::~RealizeCheckFailed
virtual ~RealizeCheckFailed()
Definition: Stage.h:301
SimTK::Stage::Position
@ Position
Spatial configuration available.
Definition: Stage.h:74
SimTK::Exception::RealizeTopologyMustBeCalledFirst::RealizeTopologyMustBeCalledFirst
RealizeTopologyMustBeCalledFirst(const char *fn, int ln, const char *objectType, const char *objectName, const char *methodName)
Definition: Stage.h:191
SimTK::Exception::StateAndSystemTopologyVersionsMustMatch
Definition: Stage.h:202
SimTK::Exception::StateAndSystemTopologyVersionsMustMatch::StateAndSystemTopologyVersionsMustMatch
StateAndSystemTopologyVersionsMustMatch(const char *fn, int ln, const char *objectType, const char *objectName, const char *methodName, int sysTopoVersion, int stateTopoVersion)
Definition: Stage.h:204
SimTK::Exception::CacheEntryOutOfDate
Definition: Stage.h:270
SimTK::Stage::operator++
const Stage & operator++()
Definition: Stage.h:121
SimTK::Stage::next
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
SimTK::Exception::StageIsWrong
Definition: Stage.h:237
SimTK::Exception::StageOutOfRange::StageOutOfRange
StageOutOfRange(const char *fn, int ln, Stage lower, Stage currentStage, Stage upper, const char *where)
Definition: Stage.h:261
SimTK::Stage::Time
@ Time
A new time has been realized.
Definition: Stage.h:73
SimTK::Stage::operator++
Stage operator++(int)
Definition: Stage.h:126
SimTK::Exception::StageTooHigh
Definition: Stage.h:248
SimTK::Exception::Base::setMessage
void setMessage(const std::string &msgin)
Definition: Exception.h:57
SimTK::Stage::Acceleration
@ Acceleration
Accelerations and multipliers calculated.
Definition: Stage.h:77
SimTK::Stage::Stage
Stage()
Default construction gives Stage::Empty.
Definition: Stage.h:93
SimTK::Stage::Infinity
@ Infinity
Higher than any legitimate Stage.
Definition: Stage.h:79
SimTK::Stage::operator<=
bool operator<=(Level other) const
Definition: Stage.h:110
SimTK::Stage::LowestRuntime
@ LowestRuntime
For iterating over meaningful stage values.
Definition: Stage.h:83
String.h
SimTK::Exception::StateAndSystemTopologyVersionsMustMatch::~StateAndSystemTopologyVersionsMustMatch
virtual ~StateAndSystemTopologyVersionsMustMatch()
Definition: Stage.h:221
SimTK::Stage::HighestValid
@ HighestValid
Definition: Stage.h:82
SimTK::String
SimTK::String is a plug-compatible std::string replacement (plus some additional functionality) inten...
Definition: String.h:62
SimTK::Exception::StageIsWrong::StageIsWrong
StageIsWrong(const char *fn, int ln, Stage currentStage, Stage targetStage, const char *where)
Definition: Stage.h:239
SimTK::operator<<
std::ostream & operator<<(std::ostream &o, const ContactForce &f)
Definition: CompliantContactSubsystem.h:387
SimTK::Exception::StageTooHigh::StageTooHigh
StageTooHigh(const char *fn, int ln, Stage currentStage, Stage targetStage, const char *where)
Definition: Stage.h:250
SimTK::Stage::NValid
@ NValid
Definition: Stage.h:88
SimTK::Stage::Stage
Stage(int l)
You can explicitly create a Stage from an int if it is in range.
Definition: Stage.h:100
SimTK::Stage::operator!=
bool operator!=(Stage other) const
Definition: Stage.h:114
SimTK::Exception::StageTooLow
Definition: Stage.h:226
SimTK::Exception::StageOutOfRange::~StageOutOfRange
virtual ~StageOutOfRange()
Definition: Stage.h:267
SimTK::Exception::StageIsWrong::~StageIsWrong
virtual ~StageIsWrong()
Definition: Stage.h:245