Simbody
|
00001 #ifndef SimTK_SimTKCOMMON_EVENT_H_ 00002 #define SimTK_SimTKCOMMON_EVENT_H_ 00003 00004 /* -------------------------------------------------------------------------- * 00005 * SimTK Core: SimTKcommon * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK Core biosimulation toolkit originating from * 00008 * Simbios, the NIH National Center for Physics-Based Simulation of * 00009 * Biological Structures at Stanford, funded under the NIH Roadmap for * 00010 * Medical Research, grant U54 GM072970. See https://simtk.org. * 00011 * * 00012 * Portions copyright (c) 2008-9 Stanford University and the Authors. * 00013 * Authors: Michael Sherman * 00014 * Contributors: * 00015 * * 00016 * Permission is hereby granted, free of charge, to any person obtaining a * 00017 * copy of this software and associated documentation files (the "Software"), * 00018 * to deal in the Software without restriction, including without limitation * 00019 * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 00020 * and/or sell copies of the Software, and to permit persons to whom the * 00021 * Software is furnished to do so, subject to the following conditions: * 00022 * * 00023 * The above copyright notice and this permission notice shall be included in * 00024 * all copies or substantial portions of the Software. * 00025 * * 00026 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 00027 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 00028 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 00029 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 00030 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 00031 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 00032 * USE OR OTHER DEALINGS IN THE SOFTWARE. * 00033 * -------------------------------------------------------------------------- */ 00034 00040 #include "SimTKcommon/basics.h" 00041 00042 namespace SimTK { 00043 00048 SimTK_DEFINE_UNIQUE_INDEX_TYPE(SystemEventIndex); 00051 SimTK_DEFINE_UNIQUE_INDEX_TYPE(EventIndex); 00052 00058 SimTK_DEFINE_UNIQUE_INDEX_TYPE(SystemEventTriggerIndex); 00061 SimTK_DEFINE_UNIQUE_INDEX_TYPE(EventTriggerIndex); 00062 00069 SimTK_DEFINE_UNIQUE_INDEX_TYPE(SystemEventTriggerByStageIndex); 00072 SimTK_DEFINE_UNIQUE_INDEX_TYPE(EventTriggerByStageIndex); 00073 00089 class Event { 00090 public: 00091 00137 class Cause { 00138 public: 00139 enum Num { 00140 Initialization = 1, 00141 Triggered = 2, 00142 Scheduled = 3, 00143 TimeAdvanced = 4, 00144 Signaled = 5, 00145 Termination = 6, 00146 Invalid = -1 00147 }; 00148 00149 Cause() : value(Invalid) {} 00150 Cause(Num n) : value(n) {} // implicit conversion 00151 operator Num() const {return value;} // implicit conversion 00152 Cause& operator=(Num n) {value=n; return *this;} 00153 00154 bool isValid() const {return Initialization<=value && value<=Termination;} 00155 00156 private: 00157 Num value; 00158 }; 00159 00162 SimTK_SimTKCOMMON_EXPORT static const char* getCauseName(Cause); 00163 00164 00171 enum Trigger { 00172 NoEventTrigger =0x0000, // must be 0 00173 00174 PositiveToNegative =0x0001, // 1 00175 NegativeToPositive =0x0002, // 2 00176 00177 Falling =(PositiveToNegative), // 1 00178 Rising =(NegativeToPositive), // 2 00179 AnySignChange =(PositiveToNegative|NegativeToPositive) // 3 00180 }; 00181 00184 SimTK_SimTKCOMMON_EXPORT static std::string eventTriggerString(Trigger); 00185 00186 00192 static Trigger classifyTransition(int before, int after) { 00193 if (before==after) 00194 return NoEventTrigger; 00195 if (before==0) 00196 return NoEventTrigger; // Do not report transitions away from zero. 00197 if (before==1) 00198 return PositiveToNegative; 00199 // before==-1 00200 return NegativeToPositive; 00201 } 00202 00208 static Trigger maskTransition(Trigger transition, Trigger mask) { 00209 return Trigger(transition & mask); // we're depending on NoEventTrigger==0 00210 } 00211 00212 private: 00213 }; 00214 00217 SimTK_DEFINE_UNIQUE_INDEX_TYPE(EventId); 00218 00229 class SimTK_SimTKCOMMON_EXPORT EventTriggerInfo { 00230 public: 00231 EventTriggerInfo(); 00232 explicit EventTriggerInfo(EventId eventId); 00233 ~EventTriggerInfo(); 00234 EventTriggerInfo(const EventTriggerInfo&); 00235 EventTriggerInfo& operator=(const EventTriggerInfo&); 00236 00237 EventId getEventId() const; // returns -1 if not set 00238 bool shouldTriggerOnRisingSignTransition() const; // default=true 00239 bool shouldTriggerOnFallingSignTransition() const; // default=true 00240 Real getRequiredLocalizationTimeWindow() const; // default=0.1 00241 00242 // These return the modified 'this', like assignment operators. 00243 EventTriggerInfo& setEventId(EventId); 00244 EventTriggerInfo& setTriggerOnRisingSignTransition(bool); 00245 EventTriggerInfo& setTriggerOnFallingSignTransition(bool); 00246 EventTriggerInfo& setRequiredLocalizationTimeWindow(Real); 00247 00248 Event::Trigger calcTransitionMask() const { 00249 unsigned mask = 0; 00250 if (shouldTriggerOnRisingSignTransition()) { 00251 mask |= Event::NegativeToPositive; 00252 } 00253 if (shouldTriggerOnFallingSignTransition()) { 00254 mask |= Event::PositiveToNegative; 00255 } 00256 return Event::Trigger(mask); 00257 } 00258 00259 Event::Trigger calcTransitionToReport 00260 (Event::Trigger transitionSeen) const 00261 { 00262 // report -1 to 1 or 1 to -1 as appropriate 00263 if (transitionSeen & Event::Rising) 00264 return Event::NegativeToPositive; 00265 if (transitionSeen & Event::Falling) 00266 return Event::PositiveToNegative; 00267 assert(!"impossible event transition situation"); 00268 return Event::NoEventTrigger; 00269 } 00270 00271 private: 00272 class EventTriggerInfoRep; 00273 00274 // opaque implementation for binary compatibility 00275 EventTriggerInfoRep* rep; 00276 00277 const EventTriggerInfoRep& getRep() const {assert(rep); return *rep;} 00278 EventTriggerInfoRep& updRep() {assert(rep); return *rep;} 00279 }; 00280 00281 00282 00283 } // namespace SimTK 00284 00285 #endif // SimTK_SimTKCOMMON_EVENT_H_