]> git.mxchange.org Git - simgear.git/blob - simgear/hla/HLAInteractionClass.cxx
a9693d9822067c4c75dc2e70094ce57ca307011e
[simgear.git] / simgear / hla / HLAInteractionClass.cxx
1 // Copyright (C) 2009 - 2012  Mathias Froehlich - Mathias.Froehlich@web.de
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Library General Public
5 // License as published by the Free Software Foundation; either
6 // version 2 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Library General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16 //
17
18 #ifdef HAVE_CONFIG_H
19 #  include <simgear_config.h>
20 #endif
21
22 #include <simgear/compiler.h>
23
24 #include "HLAInteractionClass.hxx"
25
26 #include <simgear/debug/logstream.hxx>
27
28 #include "HLADataElement.hxx"
29 #include "HLAFederate.hxx"
30
31 #include "RTIInteractionClass.hxx"
32
33 namespace simgear {
34
35 HLAInteractionClass::HLAInteractionClass(const std::string& name, HLAFederate* federate) :
36     _federate(federate),
37     _rtiInteractionClass(0),
38     _name(name),
39     _subscriptionType(HLAUnsubscribed),
40     _publicationType(HLAUnpublished)
41 {
42     if (!federate) {
43         SG_LOG(SG_NETWORK, SG_ALERT, "HLAInteractionClass::HLAInteractionClass(): "
44                "No parent federate given for interaction class \"" << getName() << "\"!");
45         return;
46     }
47     federate->_insertInteractionClass(this);
48 }
49
50 HLAInteractionClass::~HLAInteractionClass()
51 {
52     // HLAInteractionClass objects only get deleted when the parent federate
53     // dies. So we do not need to deregister there.
54
55     _clearRTIInteractionClass();
56 }
57
58 const std::string&
59 HLAInteractionClass::getName() const
60 {
61     return _name;
62 }
63
64 const SGWeakPtr<HLAFederate>&
65 HLAInteractionClass::getFederate() const
66 {
67     return _federate;
68 }
69
70 HLASubscriptionType
71 HLAInteractionClass::getSubscriptionType() const
72 {
73     return _subscriptionType;
74 }
75
76 void
77 HLAInteractionClass::setSubscriptionType(HLASubscriptionType subscriptionType)
78 {
79     _subscriptionType = subscriptionType;
80 }
81
82 HLAPublicationType
83 HLAInteractionClass::getPublicationType() const
84 {
85     return _publicationType;
86 }
87
88 void
89 HLAInteractionClass::setPublicationType(HLAPublicationType publicationType)
90 {
91     _publicationType = publicationType;
92 }
93
94 unsigned
95 HLAInteractionClass::getNumParameters() const
96 {
97     return _parameterVector.size();
98 }
99
100 unsigned
101 HLAInteractionClass::addParameter(const std::string& name)
102 {
103     unsigned index = _parameterVector.size();
104     _nameIndexMap[name] = index;
105     _parameterVector.push_back(Parameter(name));
106     _resolveParameterIndex(name, index);
107     return index;
108 }
109
110 unsigned
111 HLAInteractionClass::getParameterIndex(const std::string& name) const
112 {
113     NameIndexMap::const_iterator i = _nameIndexMap.find(name);
114     if (i == _nameIndexMap.end())
115         return ~0u;
116     return i->second;
117 }
118
119 std::string
120 HLAInteractionClass::getParameterName(unsigned index) const
121 {
122     if (_parameterVector.size() <= index)
123         return std::string();
124     return _parameterVector[index]._name;
125 }
126
127 const HLADataType*
128 HLAInteractionClass::getParameterDataType(unsigned index) const
129 {
130     if (_parameterVector.size() <= index)
131         return 0;
132     return _parameterVector[index]._dataType.get();
133 }
134
135 void
136 HLAInteractionClass::setParameterDataType(unsigned index, const SGSharedPtr<const HLADataType>& dataType)
137 {
138     if (_parameterVector.size() <= index)
139         return;
140     _parameterVector[index]._dataType = dataType;
141 }
142
143 HLADataElement::IndexPathPair
144 HLAInteractionClass::getIndexPathPair(const HLADataElement::StringPathPair& stringPathPair) const
145 {
146     unsigned index = getParameterIndex(stringPathPair.first);
147     if (getNumParameters() <= index) {
148         SG_LOG(SG_NETWORK, SG_ALERT, "HLAInteractionClass::getIndexPathPair(\""
149                << HLADataElement::toString(stringPathPair)
150                << "\"): Could not resolve attribute \"" << stringPathPair.first
151                << "\" for interaction class \"" << getName() << "\"!");
152     }
153     return HLADataElement::IndexPathPair(index, stringPathPair.second);
154 }
155
156 HLADataElement::IndexPathPair
157 HLAInteractionClass::getIndexPathPair(const std::string& path) const
158 {
159     return getIndexPathPair(HLADataElement::toStringPathPair(path));
160 }
161
162 bool
163 HLAInteractionClass::getDataElementIndex(HLADataElementIndex& dataElementIndex, const std::string& path) const
164 {
165     if (path.empty()) {
166         SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: failed to parse empty element path!");
167         return false;
168     }
169     std::string::size_type len = std::min(path.find_first_of("[."), path.size());
170     unsigned index = 0;
171     while (index < getNumParameters()) {
172         if (path.compare(0, len, getParameterName(index)) == 0)
173             break;
174         ++index;
175     }
176     if (getNumParameters() <= index) {
177         SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: faild to parse data element index \"" << path << "\":\n"
178                << "Parameter \"" << path.substr(0, len) << "\" not found in object class \""
179                << getName() << "\"!");
180         return false;
181     }
182     if (!getParameterDataType(index)) {
183         SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: faild to parse data element index \"" << path << "\":\n"
184                << "Undefined parameter data type in variant record data type \""
185                << getParameterName(index) << "\"!");
186         return false;
187     }
188     dataElementIndex.push_back(index);
189     return getParameterDataType(index)->getDataElementIndex(dataElementIndex, path, len);
190 }
191
192 HLADataElementIndex
193 HLAInteractionClass::getDataElementIndex(const std::string& path) const
194 {
195     HLADataElementIndex dataElementIndex;
196     getDataElementIndex(dataElementIndex, path);
197     return dataElementIndex;
198 }
199
200 bool
201 HLAInteractionClass::subscribe()
202 {
203     if (!_rtiInteractionClass) {
204         SG_LOG(SG_NETWORK, SG_WARN, "HLAInteractionClass::subscribe(): No RTIInteractionClass!");
205         return false;
206     }
207     switch (_subscriptionType) {
208     case HLAUnsubscribed:
209         return _rtiInteractionClass->unsubscribe();
210     case HLASubscribedActive:
211         return _rtiInteractionClass->subscribe(true);
212     case HLASubscribedPassive:
213         return _rtiInteractionClass->subscribe(false);
214     }
215     return false;
216 }
217
218 bool
219 HLAInteractionClass::unsubscribe()
220 {
221     if (!_rtiInteractionClass) {
222         SG_LOG(SG_NETWORK, SG_WARN, "HLAInteractionClass::unsubscribe(): No RTIInteractionClass!");
223         return false;
224     }
225     return _rtiInteractionClass->unsubscribe();
226 }
227
228 bool
229 HLAInteractionClass::publish()
230 {
231     if (!_rtiInteractionClass) {
232         SG_LOG(SG_NETWORK, SG_WARN, "HLAInteractionClass::publish(): No RTIInteractionClass\"!");
233         return false;
234     }
235     switch (_publicationType) {
236     case HLAUnpublished:
237         return _rtiInteractionClass->unpublish();
238     case HLAPublished:
239         return _rtiInteractionClass->publish();
240     }
241     return false;
242 }
243
244 bool
245 HLAInteractionClass::unpublish()
246 {
247     if (!_rtiInteractionClass) {
248         SG_LOG(SG_NETWORK, SG_WARN, "HLAInteractionClass::unpublish(): No RTIInteractionClass\"!");
249         return false;
250     }
251     return _rtiInteractionClass->unpublish();
252 }
253
254 void
255 HLAInteractionClass::_setRTIInteractionClass(RTIInteractionClass* interactionClass)
256 {
257     if (_rtiInteractionClass) {
258         SG_LOG(SG_NETWORK, SG_ALERT, "HLAInteractionClass: Setting RTIInteractionClass twice for interaction class \"" << getName() << "\"!");
259         return;
260     }
261     _rtiInteractionClass = interactionClass;
262     if (_rtiInteractionClass->_interactionClass != this) {
263         SG_LOG(SG_NETWORK, SG_ALERT, "HLAInteractionClass: backward reference does not match!");
264         return;
265     }
266     for (unsigned i = 0; i < _parameterVector.size(); ++i)
267         _resolveParameterIndex(_parameterVector[i]._name, i);
268 }
269
270 void
271 HLAInteractionClass::_resolveParameterIndex(const std::string& name, unsigned index)
272 {
273     if (!_rtiInteractionClass)
274         return;
275     if (!_rtiInteractionClass->resolveParameterIndex(name, index))
276         SG_LOG(SG_NETWORK, SG_ALERT, "HLAInteractionClass: Could not resolve parameter \""
277                << name << "\" for interaction class \"" << getName() << "\"!");
278 }
279
280 void
281 HLAInteractionClass::_clearRTIInteractionClass()
282 {
283     if (!_rtiInteractionClass)
284         return;
285     _rtiInteractionClass->_interactionClass = 0;
286     _rtiInteractionClass = 0;
287 }
288
289 } // namespace simgear