]> git.mxchange.org Git - simgear.git/blob - simgear/hla/HLAFederate.cxx
Move the decision which rti to use into HLAFederate.
[simgear.git] / simgear / hla / HLAFederate.cxx
1 // Copyright (C) 2009 - 2010  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 "HLAFederate.hxx"
19
20 #include "RTI13Federate.hxx"
21 #include "RTIFederate.hxx"
22 #include "RTIInteractionClass.hxx"
23 #include "RTIObjectClass.hxx"
24 #include "HLADataElement.hxx"
25 #include "HLADataType.hxx"
26 #include "HLAOMTXmlVisitor.hxx"
27
28 namespace simgear {
29
30 HLAFederate::HLAFederate()
31 {
32 }
33
34 HLAFederate::~HLAFederate()
35 {
36 }
37
38 std::string
39 HLAFederate::getFederateType() const
40 {
41     if (!_rtiFederate.valid()) {
42         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
43         return std::string();
44     }
45     return _rtiFederate->getFederateType();
46 }
47
48 std::string
49 HLAFederate::getFederationName() const
50 {
51     if (!_rtiFederate.valid()) {
52         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
53         return std::string();
54     }
55     return _rtiFederate->getFederationName();
56 }
57
58 bool
59 HLAFederate::connect(Version version, const std::list<std::string>& stringList)
60 {
61     if (_rtiFederate.valid()) {
62         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Trying to connect to already connected federate!");
63         return false;
64     }
65     switch (version) {
66     case RTI13:
67         _rtiFederate = new RTI13Federate(stringList);
68         break;
69     case RTI1516:
70         SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516 not yet(!?) supported.");
71         // _rtiFederate = new RTI1516Federate(stringList);
72         break;
73     case RTI1516E:
74         SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516E not yet(!?) supported.");
75         // _rtiFederate = new RTI1516eFederate(stringList);
76         break;
77     default:
78         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Unknown rti version in connect!");
79     }
80     return _rtiFederate.valid();
81 }
82
83 bool
84 HLAFederate::disconnect()
85 {
86     if (!_rtiFederate.valid()) {
87         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
88         return false;
89     }
90     _rtiFederate = 0;
91     return true;
92 }
93
94 bool
95 HLAFederate::createFederationExecution(const std::string& federation, const std::string& objectModel)
96 {
97     if (!_rtiFederate.valid()) {
98         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
99         return false;
100     }
101     return _rtiFederate->createFederationExecution(federation, objectModel);
102 }
103
104 bool
105 HLAFederate::destroyFederationExecution(const std::string& federation)
106 {
107     if (!_rtiFederate.valid()) {
108         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
109         return false;
110     }
111     return _rtiFederate->destroyFederationExecution(federation);
112 }
113
114 bool
115 HLAFederate::join(const std::string& federateType, const std::string& federation)
116 {
117     if (!_rtiFederate.valid()) {
118         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
119         return false;
120     }
121     return _rtiFederate->join(federateType, federation);
122 }
123
124 bool
125 HLAFederate::resign()
126 {
127     if (!_rtiFederate.valid()) {
128         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
129         return false;
130     }
131     return _rtiFederate->resign();
132 }
133
134 bool
135 HLAFederate::enableTimeConstrained()
136 {
137     if (!_rtiFederate.valid()) {
138         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
139         return false;
140     }
141     return _rtiFederate->enableTimeConstrained();
142 }
143
144 bool
145 HLAFederate::disableTimeConstrained()
146 {
147     if (!_rtiFederate.valid()) {
148         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
149         return false;
150     }
151     return _rtiFederate->disableTimeConstrained();
152 }
153
154 bool
155 HLAFederate::enableTimeRegulation(const SGTimeStamp& lookahead)
156 {
157     if (!_rtiFederate.valid()) {
158         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
159         return false;
160     }
161     return _rtiFederate->enableTimeRegulation(lookahead);
162 }
163
164 bool
165 HLAFederate::disableTimeRegulation()
166 {
167     if (!_rtiFederate.valid()) {
168         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
169         return false;
170     }
171     return _rtiFederate->disableTimeRegulation();
172 }
173
174 bool
175 HLAFederate::timeAdvanceRequestBy(const SGTimeStamp& dt)
176 {
177     if (!_rtiFederate.valid()) {
178         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
179         return false;
180     }
181     return _rtiFederate->timeAdvanceRequestBy(dt);
182 }
183
184 bool
185 HLAFederate::timeAdvanceRequest(const SGTimeStamp& dt)
186 {
187     if (!_rtiFederate.valid()) {
188         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
189         return false;
190     }
191     return _rtiFederate->timeAdvanceRequest(dt);
192 }
193
194 bool
195 HLAFederate::queryFederateTime(SGTimeStamp& timeStamp)
196 {
197     if (!_rtiFederate.valid()) {
198         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
199         return false;
200     }
201     return _rtiFederate->queryFederateTime(timeStamp);
202 }
203
204 bool
205 HLAFederate::modifyLookahead(const SGTimeStamp& timeStamp)
206 {
207     if (!_rtiFederate.valid()) {
208         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
209         return false;
210     }
211     return _rtiFederate->modifyLookahead(timeStamp);
212 }
213
214 bool
215 HLAFederate::queryLookahead(SGTimeStamp& timeStamp)
216 {
217     if (!_rtiFederate.valid()) {
218         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
219         return false;
220     }
221     return _rtiFederate->queryLookahead(timeStamp);
222 }
223
224 bool
225 HLAFederate::tick()
226 {
227     if (!_rtiFederate.valid()) {
228         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
229         return false;
230     }
231     return _rtiFederate->tick();
232 }
233
234 bool
235 HLAFederate::tick(const double& minimum, const double& maximum)
236 {
237     if (!_rtiFederate.valid()) {
238         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
239         return false;
240     }
241     return _rtiFederate->tick(minimum, maximum);
242 }
243
244 bool
245 HLAFederate::readObjectModelTemplate(const std::string& objectModel,
246                                      HLAFederate::ObjectModelFactory& objectModelFactory)
247 {
248     if (!_rtiFederate.valid()) {
249         SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
250         return false;
251     }
252
253     // The XML version of the federate object model.
254     // This one covers the generic attributes, parameters and data types.
255     HLAOMTXmlVisitor omtXmlVisitor;
256     try {
257         readXML(objectModel, omtXmlVisitor);
258     } catch (const sg_throwable& e) {
259         SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file: "
260                << e.getMessage());
261         return false;
262     } catch (...) {
263         SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file");
264         return false;
265     }
266
267     unsigned numObjectClasses = omtXmlVisitor.getNumObjectClasses();
268     for (unsigned i = 0; i < numObjectClasses; ++i) {
269         const HLAOMTXmlVisitor::ObjectClass* objectClass = omtXmlVisitor.getObjectClass(i);
270         std::string objectClassName = objectClass->getName();
271
272         SGSharedPtr<HLAObjectClass> hlaObjectClass = objectModelFactory.createObjectClass(objectClassName, *this);
273         if (!hlaObjectClass.valid()) {
274             SG_LOG(SG_IO, SG_INFO, "Ignoring object class \"" << objectClassName << "\".");
275             continue;
276         }
277
278         bool publish = objectModelFactory.publishObjectClass(objectClassName, objectClass->getSharing());
279         bool subscribe = objectModelFactory.subscribeObjectClass(objectClassName, objectClass->getSharing());
280
281         std::set<unsigned> subscriptions;
282         std::set<unsigned> publications;
283
284         // process the attributes
285         for (unsigned j = 0; j < objectClass->getNumAttributes(); ++j) {
286             const simgear::HLAOMTXmlVisitor::Attribute* attribute;
287             attribute = objectClass->getAttribute(j);
288
289             std::string attributeName = attribute->getName();
290             unsigned index = hlaObjectClass->getAttributeIndex(attributeName);
291
292             if (index == ~0u) {
293                 SG_LOG(SG_IO, SG_WARN, "RTI does not know the \"" << attributeName << "\" attribute!");
294                 continue;
295             }
296
297             SGSharedPtr<HLADataType> dataType;
298             dataType = omtXmlVisitor.getAttributeDataType(objectClassName, attributeName);
299             if (!dataType.valid()) {
300                 SG_LOG(SG_IO, SG_WARN, "Could not find data type for attribute \""
301                        << attributeName << "\" in object class \"" << objectClassName << "\"!");
302             }
303             hlaObjectClass->setAttributeDataType(index, dataType);
304
305             HLAUpdateType updateType = HLAUndefinedUpdate;
306             if (attribute->_updateType == "Periodic")
307                 updateType = HLAPeriodicUpdate;
308             else if (attribute->_updateType == "Static")
309                 updateType = HLAStaticUpdate;
310             else if (attribute->_updateType == "Conditional")
311                 updateType = HLAConditionalUpdate;
312             hlaObjectClass->setAttributeUpdateType(index, updateType);
313
314             if (subscribe && objectModelFactory.subscribeAttribute(objectClassName, attributeName, attribute->_sharing))
315                 subscriptions.insert(index);
316             if (publish && objectModelFactory.publishAttribute(objectClassName, attributeName, attribute->_sharing))
317                 publications.insert(index);
318         }
319
320         if (publish)
321             hlaObjectClass->publish(publications);
322         if (subscribe)
323             hlaObjectClass->subscribe(subscriptions, true);
324
325         _objectClassMap[objectClassName] = hlaObjectClass;
326     }
327
328     return true;
329 }
330
331 HLAObjectClass*
332 HLAFederate::getObjectClass(const std::string& name)
333 {
334     ObjectClassMap::const_iterator i = _objectClassMap.find(name);
335     if (i == _objectClassMap.end())
336         return 0;
337     return i->second.get();
338 }
339
340 const HLAObjectClass*
341 HLAFederate::getObjectClass(const std::string& name) const
342 {
343     ObjectClassMap::const_iterator i = _objectClassMap.find(name);
344     if (i == _objectClassMap.end())
345         return 0;
346     return i->second.get();
347 }
348
349 HLAInteractionClass*
350 HLAFederate::getInteractionClass(const std::string& name)
351 {
352     InteractionClassMap::const_iterator i = _interactionClassMap.find(name);
353     if (i == _interactionClassMap.end())
354         return 0;
355     return i->second.get();
356 }
357
358 const HLAInteractionClass*
359 HLAFederate::getInteractionClass(const std::string& name) const
360 {
361     InteractionClassMap::const_iterator i = _interactionClassMap.find(name);
362     if (i == _interactionClassMap.end())
363         return 0;
364     return i->second.get();
365 }
366
367 } // namespace simgear