1 /**************************************************************************\
2 * Copyright (c) Kongsberg Oil & Gas Technologies AS
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * Neither the name of the copyright holder nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 \**************************************************************************/
32
33 #include <Inventor/scxml/ScXMLEvent.h>
34
35 /*!
36 \class ScXMLEvent ScXMLEvent.h Inventor/scxml/ScXMLEvent.h
37 \brief Base class for events sent to SCXML state machines.
38
39 \since Coin 3.0
40 \ingroup scxml
41 */
42
43 #include <cassert>
44 #include <cstring>
45 #include <map>
46
47 #include <Inventor/scxml/ScXML.h>
48
49 // *************************************************************************
50
51 class ScXMLEvent::PImpl {
52 public:
PImpl(void)53 PImpl(void) { }
~PImpl(void)54 ~PImpl(void)
55 {
56 // FIXME: delete strings in associations map (values only)
57 }
58
59 std::map<const char *, const char *> associations;
60 };
61
62 #define PRIVATE(obj) ((obj)->pimpl)
63
64 SCXML_OBJECT_SOURCE(ScXMLEvent);
65
66 void
initClass(void)67 ScXMLEvent::initClass(void)
68 {
69 SCXML_OBJECT_INIT_CLASS(ScXMLEvent, ScXMLObject, "ScXMLObject");
70 }
71
72 void
cleanClass(void)73 ScXMLEvent::cleanClass(void)
74 {
75 ScXMLEvent::classTypeId = SoType::badType();
76 }
77
ScXMLEvent(void)78 ScXMLEvent::ScXMLEvent(void)
79 : name(SbName::empty())
80 {
81 }
82
~ScXMLEvent(void)83 ScXMLEvent::~ScXMLEvent(void)
84 {
85 }
86
87 /*!
88 This method is for setting a string that will identifies this particular
89 event, having this particular state, and can be used for event matching
90 in the SCXML descriptions.
91
92 The string should, according to spec., be a set of tokens consisting
93 of alphanumeric characters, separated with periods (.). This limitation
94 is not enforced by this implementation.
95 */
96 void
setEventName(const SbName & namearg)97 ScXMLEvent::setEventName(const SbName & namearg)
98 {
99 this->name = namearg;
100 }
101
102 void
setAssociation(const char * key,const char * value)103 ScXMLEvent::setAssociation(const char * key, const char * value)
104 {
105 assert(key && value);
106 SbName dictentry(key);
107 std::map<const char *, const char *>::iterator findit =
108 PRIVATE(this)->associations.find(dictentry.getString());
109 char * valuecopy = new char [strlen(value) + 1];
110 strcpy(valuecopy, value);
111 if (findit != PRIVATE(this)->associations.end()) {
112 delete [] findit->second;
113 findit->second = valuecopy;
114 } else {
115 std::pair<const char *, const char *> newentry(dictentry.getString(), valuecopy);
116 PRIVATE(this)->associations.insert(newentry);
117 }
118 }
119
120 const char *
getAssociation(const char * key) const121 ScXMLEvent::getAssociation(const char * key) const
122 {
123 assert(key);
124 SbName dictentry(key);
125 std::map<const char *, const char *>::const_iterator findit =
126 PRIVATE(this)->associations.find(dictentry.getString());
127 if (findit != PRIVATE(this)->associations.end()) {
128 return findit->second;
129 }
130 return NULL;
131 }
132
133 size_t
getNumAssociations(void) const134 ScXMLEvent::getNumAssociations(void) const
135 {
136 return PRIVATE(this)->associations.size();
137 }
138
139 size_t
getAssociationKeys(SbList<const char * > & keys) const140 ScXMLEvent::getAssociationKeys(SbList<const char *> & keys) const
141 {
142 std::map<const char *, const char *>::const_iterator it =
143 PRIVATE(this)->associations.begin();
144 size_t count = 0;
145 while (it != PRIVATE(this)->associations.end()) {
146 keys.append(it->first);
147 ++count;
148 ++it;
149 }
150 return count;
151 }
152
153 ScXMLEvent *
clone(void) const154 ScXMLEvent::clone(void) const
155 {
156 SoType thistype = this->getTypeId();
157 assert(thistype.canCreateInstance());
158 ScXMLEvent * newevent = static_cast<ScXMLEvent *>(thistype.createInstance());
159 newevent->copyContents(this);
160 return newevent;
161 }
162
163 void
copyContents(const ScXMLEvent * rhs)164 ScXMLEvent::copyContents(const ScXMLEvent * rhs)
165 {
166 this->name = rhs->name;
167 SbList<const char *> keys;
168 size_t numkeys = rhs->getAssociationKeys(keys);
169 for (size_t i = 0; i < numkeys; ++i) {
170 this->setAssociation(keys[i], rhs->getAssociation(keys[i]));
171 }
172 }
173
174 #undef PRIVATE
175