]> git.mxchange.org Git - simgear.git/blob - simgear/hla/HLAInteractionClass.cxx
hla: Make use of SGLocation.
[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 bool
144 HLAInteractionClass::getDataElementIndex(HLADataElementIndex& dataElementIndex, const std::string& path) const
145 {
146     if (path.empty()) {
147         SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: failed to parse empty element path!");
148         return false;
149     }
150     std::string::size_type len = std::min(path.find_first_of("[."), path.size());
151     unsigned index = 0;
152     while (index < getNumParameters()) {
153         if (path.compare(0, len, getParameterName(index)) == 0)
154             break;
155         ++index;
156     }
157     if (getNumParameters() <= index) {
158         SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: faild to parse data element index \"" << path << "\":\n"
159                << "Parameter \"" << path.substr(0, len) << "\" not found in object class \""
160                << getName() << "\"!");
161         return false;
162     }
163     if (!getParameterDataType(index)) {
164         SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: faild to parse data element index \"" << path << "\":\n"
165                << "Undefined parameter data type in variant record data type \""
166                << getParameterName(index) << "\"!");
167         return false;
168     }
169     dataElementIndex.push_back(index);
170     return getParameterDataType(index)->getDataElementIndex(dataElementIndex, path, len);
171 }
172
173 HLADataElementIndex
174 HLAInteractionClass::getDataElementIndex(const std::string& path) const
175 {
176     HLADataElementIndex dataElementIndex;
177     getDataElementIndex(dataElementIndex, path);
178     return dataElementIndex;
179 }
180
181 bool
182 HLAInteractionClass::subscribe()
183 {
184     if (!_rtiInteractionClass) {
185         SG_LOG(SG_NETWORK, SG_WARN, "HLAInteractionClass::subscribe(): No RTIInteractionClass!");
186         return false;
187     }
188     switch (_subscriptionType) {
189     case HLAUnsubscribed:
190         return _rtiInteractionClass->unsubscribe();
191     case HLASubscribedActive:
192         return _rtiInteractionClass->subscribe(true);
193     case HLASubscribedPassive:
194         return _rtiInteractionClass->subscribe(false);
195     }
196     return false;
197 }
198
199 bool
200 HLAInteractionClass::unsubscribe()
201 {
202     if (!_rtiInteractionClass) {
203         SG_LOG(SG_NETWORK, SG_WARN, "HLAInteractionClass::unsubscribe(): No RTIInteractionClass!");
204         return false;
205     }
206     return _rtiInteractionClass->unsubscribe();
207 }
208
209 bool
210 HLAInteractionClass::publish()
211 {
212     if (!_rtiInteractionClass) {
213         SG_LOG(SG_NETWORK, SG_WARN, "HLAInteractionClass::publish(): No RTIInteractionClass\"!");
214         return false;
215     }
216     switch (_publicationType) {
217     case HLAUnpublished:
218         return _rtiInteractionClass->unpublish();
219     case HLAPublished:
220         return _rtiInteractionClass->publish();
221     }
222     return false;
223 }
224
225 bool
226 HLAInteractionClass::unpublish()
227 {
228     if (!_rtiInteractionClass) {
229         SG_LOG(SG_NETWORK, SG_WARN, "HLAInteractionClass::unpublish(): No RTIInteractionClass\"!");
230         return false;
231     }
232     return _rtiInteractionClass->unpublish();
233 }
234
235 void
236 HLAInteractionClass::_setRTIInteractionClass(RTIInteractionClass* interactionClass)
237 {
238     if (_rtiInteractionClass) {
239         SG_LOG(SG_NETWORK, SG_ALERT, "HLAInteractionClass: Setting RTIInteractionClass twice for interaction class \"" << getName() << "\"!");
240         return;
241     }
242     _rtiInteractionClass = interactionClass;
243     if (_rtiInteractionClass->_interactionClass != this) {
244         SG_LOG(SG_NETWORK, SG_ALERT, "HLAInteractionClass: backward reference does not match!");
245         return;
246     }
247     for (unsigned i = 0; i < _parameterVector.size(); ++i)
248         _resolveParameterIndex(_parameterVector[i]._name, i);
249 }
250
251 void
252 HLAInteractionClass::_resolveParameterIndex(const std::string& name, unsigned index)
253 {
254     if (!_rtiInteractionClass)
255         return;
256     if (!_rtiInteractionClass->resolveParameterIndex(name, index))
257         SG_LOG(SG_NETWORK, SG_ALERT, "HLAInteractionClass: Could not resolve parameter \""
258                << name << "\" for interaction class \"" << getName() << "\"!");
259 }
260
261 void
262 HLAInteractionClass::_clearRTIInteractionClass()
263 {
264     if (!_rtiInteractionClass)
265         return;
266     _rtiInteractionClass->_interactionClass = 0;
267     _rtiInteractionClass = 0;
268 }
269
270 } // namespace simgear