Simbody 3.7
Loading...
Searching...
No Matches
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
36namespace SimTK {
37
44typedef long long StageVersion;
45
52typedef long long ValueVersion;
53
66class Stage {
67public:
86
87 enum {
90 };
91
93 Stage() : level(Stage::Empty) {}
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
122 { assert(level<HighestValid); level=Level(level+1); return *this; }
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
175private:
176 Level level;
177};
178
179
180
181
182namespace Exception {
183
184#ifdef _MSC_VER
185#pragma warning(push)
186#pragma warning(disable:4996) // don't warn about sprintf, etc.
187#endif
188
190public:
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 }
200};
201
203public:
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
226class StageTooLow : public Base {
227public:
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
237class StageIsWrong : public Base {
238public:
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
248class StageTooHigh : public Base {
249public:
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
259class StageOutOfRange : public Base {
260public:
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
270class CacheEntryOutOfDate : public Base {
271public:
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.
286class RealizeCheckFailed : public Base {
287public:
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
310inline 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_
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:301
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
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
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
const Stage & operator++()
Definition Stage.h:121
bool operator>(Level other) const
Definition Stage.h:111
const Stage & operator--()
Definition Stage.h:123
Stage operator--(int)
Definition Stage.h:128
SimTK::String is a plug-compatible std::string replacement (plus some additional functionality) inten...
Definition String.h:62
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