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