1 /* -------------------------------------------------------------------------- *
2 * Simbody(tm): SimTKcommon *
3 * -------------------------------------------------------------------------- *
4 * This is part of the SimTK biosimulation toolkit originating from *
5 * Simbios, the NIH National Center for Physics-Based Simulation of *
6 * Biological Structures at Stanford, funded under the NIH Roadmap for *
7 * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
8 * *
9 * Portions copyright (c) 2008-14 Stanford University and the Authors. *
10 * Authors: Michael Sherman *
11 * Contributors: *
12 * *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may *
14 * not use this file except in compliance with the License. You may obtain a *
15 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
16 * *
17 * Unless required by applicable law or agreed to in writing, software *
18 * distributed under the License is distributed on an "AS IS" BASIS, *
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
20 * See the License for the specific language governing permissions and *
21 * limitations under the License. *
22 * -------------------------------------------------------------------------- */
23
24
25 /**@file
26 *
27 * Implementation of non-inline methods from the Event classes.
28 */
29
30 #include "SimTKcommon/basics.h"
31 #include "SimTKcommon/internal/Event.h"
32
33 #include <cassert>
34 #include <string>
35
36 namespace SimTK {
37
38
getCauseName(Cause cause)39 const char* Event::getCauseName(Cause cause) {
40 switch(cause) {
41 case Cause::Initialization: return "Initialization";
42 case Cause::Triggered: return "Triggered";
43 case Cause::Scheduled: return "Scheduled";
44 case Cause::TimeAdvanced: return "TimeAdvanced";
45 case Cause::Signaled: return "Signaled";
46 case Cause::Termination: return "Termination";
47 case Cause::Invalid: return "Invalid";
48 }
49 return "UNRECOGNIZED EVENT CAUSE";
50 }
51
52
eventTriggerString(Trigger e)53 std::string Event::eventTriggerString(Trigger e) {
54 // Catch special combos first
55 if (e==NoEventTrigger) return "NoEventTrigger";
56 if (e==Falling) return "Falling";
57 if (e==Rising) return "Rising";
58 if (e==AnySignChange) return "AnySignChange";
59
60 // Not a special combo; unmask one at a time.
61 const Trigger triggers[] =
62 { PositiveToNegative,NegativeToPositive,NoEventTrigger };
63 const char *triggerNames[] =
64 { "PositiveToNegative","NegativeToPositive" };
65
66 String s;
67 for (int i=0; triggers[i] != NoEventTrigger; ++i)
68 if (e & triggers[i]) {
69 if (s.size()) s += "|";
70 s += triggerNames[i];
71 e = Trigger((unsigned)e & ~((unsigned)triggers[i]));
72 }
73
74 // should have accounted for everything by now
75 if (e != NoEventTrigger) {
76 if (s.size()) s += " + ";
77 s += "UNRECOGNIZED EVENT TRIGGER GARBAGE ";
78 s += String((unsigned)e, "0x%x");
79 }
80 return s;
81 }
82
83
84
85 ////////////////////////////
86 // EVENT TRIGGER INFO REP //
87 ////////////////////////////
88
89 class EventTriggerInfo::EventTriggerInfoRep {
90 public:
EventTriggerInfoRep(EventTriggerInfo * h)91 explicit EventTriggerInfoRep(EventTriggerInfo* h)
92 : myHandle(h), eventId(EventId(InvalidIndex)), triggerOnRising(true),
93 triggerOnFalling(true), localizationWindow(Real(0.1))
94 {
95 assert(h);
96 }
97
98 private:
99 EventTriggerInfo* myHandle;
100 friend class EventTriggerInfo;
101
102 EventId eventId;
103 bool triggerOnRising;
104 bool triggerOnFalling;
105 Real localizationWindow;
106 };
107
108
109
110 ////////////////////////
111 // EVENT TRIGGER INFO //
112 ////////////////////////
113
EventTriggerInfo()114 EventTriggerInfo::EventTriggerInfo() : rep(0) {
115 rep = new EventTriggerInfoRep(this);
116 }
~EventTriggerInfo()117 EventTriggerInfo::~EventTriggerInfo() {
118 if (getRep().myHandle == this)
119 delete rep;
120 rep = 0;
121 }
122
EventTriggerInfo(EventId eventId)123 EventTriggerInfo::EventTriggerInfo(EventId eventId) : rep(0) {
124 rep = new EventTriggerInfoRep(this);
125 rep->eventId = eventId;
126 }
127
EventTriggerInfo(const EventTriggerInfo & src)128 EventTriggerInfo::EventTriggerInfo(const EventTriggerInfo& src) : rep(0) {
129 rep = new EventTriggerInfoRep(src.getRep());
130 rep->myHandle = this;
131 }
132
133 EventTriggerInfo&
operator =(const EventTriggerInfo & src)134 EventTriggerInfo::operator=(const EventTriggerInfo& src) {
135 if (&src != this) {
136 if (getRep().myHandle == this)
137 delete rep;
138 rep = new EventTriggerInfoRep(src.getRep());
139 rep->myHandle = this;
140 }
141 return *this;
142 }
143
getEventId() const144 EventId EventTriggerInfo::getEventId() const {
145 return getRep().eventId;
146 }
shouldTriggerOnRisingSignTransition() const147 bool EventTriggerInfo::shouldTriggerOnRisingSignTransition() const {
148 return getRep().triggerOnRising;
149 }
shouldTriggerOnFallingSignTransition() const150 bool EventTriggerInfo::shouldTriggerOnFallingSignTransition() const {
151 return getRep().triggerOnFalling;
152 }
getRequiredLocalizationTimeWindow() const153 Real EventTriggerInfo::getRequiredLocalizationTimeWindow() const {
154 return getRep().localizationWindow;
155 }
156
157 EventTriggerInfo&
setEventId(EventId id)158 EventTriggerInfo::setEventId(EventId id) {
159 updRep().eventId = id;
160 return *this;
161 }
162 EventTriggerInfo&
setTriggerOnRisingSignTransition(bool shouldTrigger)163 EventTriggerInfo::setTriggerOnRisingSignTransition(bool shouldTrigger) {
164 updRep().triggerOnRising = shouldTrigger;
165 return *this;
166 }
167 EventTriggerInfo&
setTriggerOnFallingSignTransition(bool shouldTrigger)168 EventTriggerInfo::setTriggerOnFallingSignTransition(bool shouldTrigger) {
169 updRep().triggerOnFalling = shouldTrigger;
170 return *this;
171 }
172 EventTriggerInfo&
setRequiredLocalizationTimeWindow(Real w)173 EventTriggerInfo::setRequiredLocalizationTimeWindow(Real w) {
174 assert(w > 0);
175 updRep().localizationWindow = w;
176 return *this;
177 }
178
179 } // namespace SimTK
180
181