]> git.mxchange.org Git - simgear.git/blob - simgear/hla/HLAInteractionClass.cxx
hla: Fix buffer overrun in SGMath vector types.
[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 #include "HLAInteractionClass.hxx"
19
20 #include <simgear/debug/logstream.hxx>
21
22 #include "HLADataElement.hxx"
23 #include "HLAFederate.hxx"
24
25 #include "RTIInteractionClass.hxx"
26
27 namespace simgear {
28
29 HLAInteractionClass::HLAInteractionClass(const std::string& name, HLAFederate* federate) :
30     _federate(federate),
31     _rtiInteractionClass(0),
32     _name(name),
33     _subscriptionType(HLAUnsubscribed),
34     _publicationType(HLAUnpublished)
35 {
36     if (!federate) {
37         SG_LOG(SG_NETWORK, SG_ALERT, "HLAInteractionClass::HLAInteractionClass(): "
38                "No parent federate given for interaction class \"" << getName() << "\"!");
39         return;
40     }
41     federate->_insertInteractionClass(this);
42 }
43
44 HLAInteractionClass::~HLAInteractionClass()
45 {
46     // HLAInteractionClass objects only get deleted when the parent federate
47     // dies. So we do not need to deregister there.
48
49     _clearRTIInteractionClass();
50 }
51
52 const std::string&
53 HLAInteractionClass::getName() const
54 {
55     return _name;
56 }
57
58 HLASubscriptionType
59 HLAInteractionClass::getSubscriptionType() const
60 {
61     return _subscriptionType;
62 }
63
64 void
65 HLAInteractionClass::setSubscriptionType(HLASubscriptionType subscriptionType)
66 {
67     _subscriptionType = subscriptionType;
68 }
69
70 HLAPublicationType
71 HLAInteractionClass::getPublicationType() const
72 {
73     return _publicationType;
74 }
75
76 void
77 HLAInteractionClass::setPublicationType(HLAPublicationType publicationType)
78 {
79     _publicationType = publicationType;
80 }
81
82 unsigned
83 HLAInteractionClass::getNumParameters() const
84 {
85     return _parameterVector.size();
86 }
87
88 unsigned
89 HLAInteractionClass::addParameter(const std::string& name)
90 {
91     unsigned index = _parameterVector.size();
92     _nameIndexMap[name] = index;
93     _parameterVector.push_back(Parameter(name));
94     _resolveParameterIndex(name, index);
95     return index;
96 }
97
98 unsigned
99 HLAInteractionClass::getParameterIndex(const std::string& name) const
100 {
101     NameIndexMap::const_iterator i = _nameIndexMap.find(name);
102     if (i == _nameIndexMap.end())
103         return ~0u;
104     return i->second;
105 }
106
107 std::string
108 HLAInteractionClass::getParameterName(unsigned index) const
109 {
110     if (_parameterVector.size() <= index)
111         return std::string();
112     return _parameterVector[index]._name;
113 }
114
115 const HLADataType*
116 HLAInteractionClass::getParameterDataType(unsigned index) const
117 {
118     if (_parameterVector.size() <= index)
119         return 0;
120     return _parameterVector[index]._dataType.get();
121 }
122
123 void
124 HLAInteractionClass::setParameterDataType(unsigned index, const SGSharedPtr<const HLADataType>& dataType)
125 {
126     if (_parameterVector.size() <= index)
127         return;
128     _parameterVector[index]._dataType = dataType;
129 }
130
131 HLADataElement::IndexPathPair
132 HLAInteractionClass::getIndexPathPair(const HLADataElement::StringPathPair& stringPathPair) const
133 {
134     unsigned index = getParameterIndex(stringPathPair.first);
135     if (getNumParameters() <= index) {
136         SG_LOG(SG_NETWORK, SG_ALERT, "HLAInteractionClass::getIndexPathPair(\""
137                << HLADataElement::toString(stringPathPair)
138                << "\"): Could not resolve attribute \"" << stringPathPair.first
139                << "\" for interaction class \"" << getName() << "\"!");
140     }
141     return HLADataElement::IndexPathPair(index, stringPathPair.second);
142 }
143
144 HLADataElement::IndexPathPair
145 HLAInteractionClass::getIndexPathPair(const std::string& path) const
146 {
147     return getIndexPathPair(HLADataElement::toStringPathPair(path));
148 }
149
150 bool
151 HLAInteractionClass::subscribe()
152 {
153     if (!_rtiInteractionClass) {
154         SG_LOG(SG_NETWORK, SG_WARN, "HLAInteractionClass::subscribe(): No RTIInteractionClass!");
155         return false;
156     }
157     switch (_subscriptionType) {
158     case HLAUnsubscribed:
159         return _rtiInteractionClass->unsubscribe();
160     case HLASubscribedActive:
161         return _rtiInteractionClass->subscribe(true);
162     case HLASubscribedPassive:
163         return _rtiInteractionClass->subscribe(false);
164     }
165     return false;
166 }
167
168 bool
169 HLAInteractionClass::unsubscribe()
170 {
171     if (!_rtiInteractionClass) {
172         SG_LOG(SG_NETWORK, SG_WARN, "HLAInteractionClass::unsubscribe(): No RTIInteractionClass!");
173         return false;
174     }
175     return _rtiInteractionClass->unsubscribe();
176 }
177
178 bool
179 HLAInteractionClass::publish()
180 {
181     if (!_rtiInteractionClass) {
182         SG_LOG(SG_NETWORK, SG_WARN, "HLAInteractionClass::publish(): No RTIInteractionClass\"!");
183         return false;
184     }
185     switch (_publicationType) {
186     case HLAUnpublished:
187         return _rtiInteractionClass->unpublish();
188     case HLAPublished:
189         return _rtiInteractionClass->publish();
190     }
191     return false;
192 }
193
194 bool
195 HLAInteractionClass::unpublish()
196 {
197     if (!_rtiInteractionClass) {
198         SG_LOG(SG_NETWORK, SG_WARN, "HLAInteractionClass::unpublish(): No RTIInteractionClass\"!");
199         return false;
200     }
201     return _rtiInteractionClass->unpublish();
202 }
203
204 void
205 HLAInteractionClass::_setRTIInteractionClass(RTIInteractionClass* interactionClass)
206 {
207     if (_rtiInteractionClass) {
208         SG_LOG(SG_NETWORK, SG_ALERT, "HLAInteractionClass: Setting RTIInteractionClass twice for interaction class \"" << getName() << "\"!");
209         return;
210     }
211     _rtiInteractionClass = interactionClass;
212     if (_rtiInteractionClass->_interactionClass != this) {
213         SG_LOG(SG_NETWORK, SG_ALERT, "HLAInteractionClass: backward reference does not match!");
214         return;
215     }
216     for (unsigned i = 0; i < _parameterVector.size(); ++i)
217         _resolveParameterIndex(_parameterVector[i]._name, i);
218 }
219
220 void
221 HLAInteractionClass::_resolveParameterIndex(const std::string& name, unsigned index)
222 {
223     if (!_rtiInteractionClass)
224         return;
225     if (!_rtiInteractionClass->resolveParameterIndex(name, index))
226         SG_LOG(SG_NETWORK, SG_ALERT, "HLAInteractionClass: Could not resolve parameter \""
227                << name << "\" for interaction class \"" << getName() << "\"!");
228 }
229
230 void
231 HLAInteractionClass::_clearRTIInteractionClass()
232 {
233     if (!_rtiInteractionClass)
234         return;
235     _rtiInteractionClass->_interactionClass = 0;
236     _rtiInteractionClass = 0;
237 }
238
239 } // namespace simgear