Simbody  3.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Event.h
Go to the documentation of this file.
1 #ifndef SimTK_SimTKCOMMON_EVENT_H_
2 #define SimTK_SimTKCOMMON_EVENT_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) 2008-12 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 
32 #include "SimTKcommon/basics.h"
33 
34 namespace SimTK {
35 
40 
47 SimTK_DEFINE_UNIQUE_INDEX_TYPE(SystemEventTriggerIndex);
48 
57 SimTK_DEFINE_UNIQUE_INDEX_TYPE(SystemEventTriggerByStageIndex);
58 
62 SimTK_DEFINE_UNIQUE_INDEX_TYPE(EventTriggerByStageIndex);
63 
76 class Event {
77 public:
78 
123  class Cause {
124  public:
125  enum Num {
130  Signaled = 5,
132  Invalid = -1
133  };
134 
135  Cause() : value(Invalid) {}
136  Cause(Num n) : value(n) {} // implicit conversion
137  operator Num() const {return value;} // implicit conversion
138  Cause& operator=(Num n) {value=n; return *this;}
139 
140  bool isValid() const {return Initialization<=value && value<=Termination;}
141 
142  private:
143  Num value;
144  };
145 
148  SimTK_SimTKCOMMON_EXPORT static const char* getCauseName(Cause);
149 
150 
155  enum Trigger {
156  NoEventTrigger =0x0000, // must be 0
157 
158  PositiveToNegative =0x0001, // 1
159  NegativeToPositive =0x0002, // 2
160 
164  };
165 
169 
170 
174  static Trigger classifyTransition(int before, int after) {
175  if (before==after)
176  return NoEventTrigger;
177  if (before==0)
178  return NoEventTrigger; // Do not report transitions away from zero.
179  if (before==1)
180  return PositiveToNegative;
181  // before==-1
182  return NegativeToPositive;
183  }
184 
188  static Trigger maskTransition(Trigger transition, Trigger mask) {
189  // we're depending on NoEventTrigger==0
190  return Trigger(transition & mask);
191  }
192 
193 private:
194 };
195 
196 
206 public:
208  explicit EventTriggerInfo(EventId eventId);
209  ~EventTriggerInfo();
211  EventTriggerInfo& operator=(const EventTriggerInfo&);
212 
213  EventId getEventId() const; // returns -1 if not set
214  bool shouldTriggerOnRisingSignTransition() const; // default=true
215  bool shouldTriggerOnFallingSignTransition() const; // default=true
216  Real getRequiredLocalizationTimeWindow() const; // default=0.1
217 
218  // These return the modified 'this', like assignment operators.
219  EventTriggerInfo& setEventId(EventId);
220  EventTriggerInfo& setTriggerOnRisingSignTransition(bool);
221  EventTriggerInfo& setTriggerOnFallingSignTransition(bool);
222  EventTriggerInfo& setRequiredLocalizationTimeWindow(Real);
223 
225  unsigned mask = 0;
226  if (shouldTriggerOnRisingSignTransition()) {
228  }
229  if (shouldTriggerOnFallingSignTransition()) {
231  }
232  return Event::Trigger(mask);
233  }
234 
235  Event::Trigger calcTransitionToReport
236  (Event::Trigger transitionSeen) const
237  {
238  // report -1 to 1 or 1 to -1 as appropriate
239  if (transitionSeen & Event::Rising)
241  if (transitionSeen & Event::Falling)
243  assert(!"impossible event transition situation");
244  return Event::NoEventTrigger;
245  }
246 
247 private:
248  class EventTriggerInfoRep;
249 
250  // opaque implementation for binary compatibility
251  EventTriggerInfoRep* rep;
252 
253  const EventTriggerInfoRep& getRep() const {assert(rep); return *rep;}
254  EventTriggerInfoRep& updRep() {assert(rep); return *rep;}
255 };
256 
257 
258 
259 
260 //==============================================================================
261 // HANDLE EVENTS OPTIONS and HANDLE EVENTS RESULTS
262 //==============================================================================
266 public:
267  enum Option {
269  None = 0x0000,
273  DontThrow = 0x0001,
276  UseInfinityNorm = 0x0002
277  };
278 
279 
280  HandleEventsOptions() {clear();}
281  explicit HandleEventsOptions(Real accuracy)
282  { clear(); setAccuracy(accuracy); }
284  { clear(); setOption(opt); }
285 
290  { optionSet=0; setAccuracyDefaults(); return *this; }
291 
296  assert(accuracy > 0);
297  requiredAccuracy = accuracy;
298  return *this;
299  }
300 
303  HandleEventsOptions& clearOption(Option opt)
304  { optionSet &= ~(unsigned)opt; return *this; }
307  HandleEventsOptions& setOption (Option opt)
308  { optionSet |= (unsigned)opt; return *this; }
309 
311  Real getAccuracy() const {return requiredAccuracy;}
312 
313  bool isOptionSet(Option opt) const {return (optionSet&(unsigned)opt) != 0;}
314 
315  static Real getDefaultAccuracy() {return Real(1e-4);}
316 
317  // Set operators: not, or, and, set difference
318  HandleEventsOptions& operator|=(const HandleEventsOptions& opts)
319  { optionSet |= opts.optionSet; return *this; }
320  HandleEventsOptions& operator&=(const HandleEventsOptions& opts)
321  { optionSet &= opts.optionSet; return *this; }
322  HandleEventsOptions& operator-=(const HandleEventsOptions& opts)
323  { optionSet &= ~opts.optionSet; return *this; }
324 
325  HandleEventsOptions& operator|=(Option opt) {setOption(opt); return *this;}
326  HandleEventsOptions& operator-=(Option opt) {clearOption(opt); return *this;}
327 
328 private:
329  Real requiredAccuracy;
330  unsigned optionSet;
331 
332  void setAccuracyDefaults() {
333  requiredAccuracy = getDefaultAccuracy();
334  }
335 };
336 
342 public:
343  HandleEventsResults() : m_lowestModifiedStage(Stage::Infinity) {clear();}
344 
345  enum Status {
347  Invalid = -1,
350  Succeeded = 0,
354  ShouldTerminate = 1,
358  Failed = 2
359  };
360 
364  m_exitStatus = Invalid;
365  m_anyChangeMade = false;
366  m_lowestModifiedStage = Stage::Infinity; // i.e., nothing modified
367  m_message.clear();
368  return *this;
369  }
370  bool isValid() const {return m_exitStatus != Invalid;}
371  Status getExitStatus() const {return m_exitStatus;}
372 
373  bool getAnyChangeMade() const
374  { assert(isValid()); return m_anyChangeMade; }
375  Stage getLowestModifiedStage() const
376  { assert(isValid()); return m_lowestModifiedStage; }
377  const String& getMessage() const
378  { assert(isValid()); return m_message; }
379 
380  HandleEventsResults& setExitStatus(Status status)
381  { m_exitStatus=status; return *this; }
382  HandleEventsResults& setAnyChangeMade(bool changeMade)
383  { m_anyChangeMade=changeMade; return *this; }
384  HandleEventsResults& setLowestModifiedStage(Stage stage)
385  { m_lowestModifiedStage=stage; return *this; }
386  HandleEventsResults& setMessage(const String& message)
387  { m_message=message; return *this; }
388 private:
389  Status m_exitStatus;
390  bool m_anyChangeMade;
391  Stage m_lowestModifiedStage;
392  String m_message;
393 };
394 
395 } // namespace SimTK
396 
397 #endif // SimTK_SimTKCOMMON_EVENT_H_