]> git.mxchange.org Git - simgear.git/blob - simgear/hla/HLAFederate.cxx
Add an initial implementation of a rti/hla dispatcher.
[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 "RTIFederate.hxx"
21 #include "RTIInteractionClass.hxx"
22 #include "RTIObjectClass.hxx"
23 #include "HLADataElement.hxx"
24 #include "HLADataType.hxx"
25 #include "HLAOMTXmlVisitor.hxx"
26
27 namespace simgear {
28
29 HLAFederate::HLAFederate(const SGSharedPtr<RTIFederate>& rtiFederate) :
30     _rtiFederate(rtiFederate)
31 {
32 }
33
34 HLAFederate::~HLAFederate()
35 {
36 }
37
38 const std::string&
39 HLAFederate::getFederateType() const
40 {
41     return _rtiFederate->getFederateType();
42 }
43
44 const std::string&
45 HLAFederate::getFederationName() const
46 {
47     return _rtiFederate->getFederationName();
48 }
49
50 bool
51 HLAFederate::createFederationExecution(const std::string& federation, const std::string& objectModel)
52 {
53     return _rtiFederate->createFederationExecution(federation, objectModel);
54 }
55
56 bool
57 HLAFederate::destroyFederationExecution(const std::string& federation)
58 {
59     return _rtiFederate->destroyFederationExecution(federation);
60 }
61
62 bool
63 HLAFederate::join(const std::string& federateType, const std::string& federation)
64 {
65     return _rtiFederate->join(federateType, federation);
66 }
67
68 bool
69 HLAFederate::resign()
70 {
71     return _rtiFederate->resign();
72 }
73
74 bool
75 HLAFederate::enableTimeConstrained()
76 {
77     return _rtiFederate->enableTimeConstrained();
78 }
79
80 bool
81 HLAFederate::disableTimeConstrained()
82 {
83     return _rtiFederate->disableTimeConstrained();
84 }
85
86 bool
87 HLAFederate::enableTimeRegulation(const SGTimeStamp& lookahead)
88 {
89     return _rtiFederate->enableTimeRegulation(lookahead);
90 }
91
92 bool
93 HLAFederate::disableTimeRegulation()
94 {
95     return _rtiFederate->disableTimeRegulation();
96 }
97
98 bool
99 HLAFederate::timeAdvanceRequestBy(const SGTimeStamp& dt)
100 {
101     return _rtiFederate->timeAdvanceRequestBy(dt);
102 }
103
104 bool
105 HLAFederate::timeAdvanceRequest(const SGTimeStamp& dt)
106 {
107     return _rtiFederate->timeAdvanceRequest(dt);
108 }
109
110 bool
111 HLAFederate::tick()
112 {
113     return _rtiFederate->tick();
114 }
115
116 bool
117 HLAFederate::tick(const double& minimum, const double& maximum)
118 {
119     return _rtiFederate->tick(minimum, maximum);
120 }
121
122 bool
123 HLAFederate::readObjectModelTemplate(const std::string& objectModel,
124                                      HLAFederate::ObjectModelFactory& objectModelFactory)
125 {
126     if (!_rtiFederate.valid()) {
127         SG_LOG(SG_IO, SG_ALERT, "Could not process HLA XML object model file: "
128                "No rti federate available!");
129         return false;
130     }
131
132     // The XML version of the federate object model.
133     // This one covers the generic attributes, parameters and data types.
134     HLAOMTXmlVisitor omtXmlVisitor;
135     try {
136         readXML(objectModel, omtXmlVisitor);
137     } catch (const sg_throwable& e) {
138         SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file: "
139                << e.getMessage());
140         return false;
141     } catch (...) {
142         SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file");
143         return false;
144     }
145
146     unsigned numObjectClasses = omtXmlVisitor.getNumObjectClasses();
147     for (unsigned i = 0; i < numObjectClasses; ++i) {
148         const HLAOMTXmlVisitor::ObjectClass* objectClass = omtXmlVisitor.getObjectClass(i);
149         std::string objectClassName = objectClass->getName();
150
151         SGSharedPtr<HLAObjectClass> hlaObjectClass = objectModelFactory.createObjectClass(objectClassName, *this);
152         if (!hlaObjectClass.valid()) {
153             SG_LOG(SG_IO, SG_INFO, "Ignoring object class \"" << objectClassName << "\".");
154             continue;
155         }
156
157         bool publish = objectModelFactory.publishObjectClass(objectClassName, objectClass->getSharing());
158         bool subscribe = objectModelFactory.subscribeObjectClass(objectClassName, objectClass->getSharing());
159
160         std::set<unsigned> subscriptions;
161         std::set<unsigned> publications;
162
163         // process the attributes
164         for (unsigned j = 0; j < objectClass->getNumAttributes(); ++j) {
165             const simgear::HLAOMTXmlVisitor::Attribute* attribute;
166             attribute = objectClass->getAttribute(j);
167
168             std::string attributeName = attribute->getName();
169             unsigned index = hlaObjectClass->getAttributeIndex(attributeName);
170
171             if (index == ~0u) {
172                 SG_LOG(SG_IO, SG_WARN, "RTI does not know the \"" << attributeName << "\" attribute!");
173                 continue;
174             }
175
176             SGSharedPtr<HLADataType> dataType;
177             dataType = omtXmlVisitor.getAttributeDataType(objectClassName, attributeName);
178             if (!dataType.valid()) {
179                 SG_LOG(SG_IO, SG_WARN, "Could not find data type for attribute \""
180                        << attributeName << "\" in object class \"" << objectClassName << "\"!");
181             }
182             hlaObjectClass->setAttributeDataType(index, dataType);
183
184             HLAUpdateType updateType = HLAUndefinedUpdate;
185             if (attribute->_updateType == "Periodic")
186                 updateType = HLAPeriodicUpdate;
187             else if (attribute->_updateType == "Static")
188                 updateType = HLAStaticUpdate;
189             else if (attribute->_updateType == "Conditional")
190                 updateType = HLAConditionalUpdate;
191             hlaObjectClass->setAttributeUpdateType(index, updateType);
192
193             if (subscribe && objectModelFactory.subscribeAttribute(objectClassName, attributeName, attribute->_sharing))
194                 subscriptions.insert(index);
195             if (publish && objectModelFactory.publishAttribute(objectClassName, attributeName, attribute->_sharing))
196                 publications.insert(index);
197         }
198
199         if (publish)
200             hlaObjectClass->publish(publications);
201         if (subscribe)
202             hlaObjectClass->subscribe(subscriptions, true);
203
204         _objectClassMap[objectClassName] = hlaObjectClass;
205     }
206
207     return true;
208 }
209
210 HLAObjectClass*
211 HLAFederate::getObjectClass(const std::string& name)
212 {
213     ObjectClassMap::const_iterator i = _objectClassMap.find(name);
214     if (i == _objectClassMap.end())
215         return 0;
216     return i->second.get();
217 }
218
219 const HLAObjectClass*
220 HLAFederate::getObjectClass(const std::string& name) const
221 {
222     ObjectClassMap::const_iterator i = _objectClassMap.find(name);
223     if (i == _objectClassMap.end())
224         return 0;
225     return i->second.get();
226 }
227
228 HLAInteractionClass*
229 HLAFederate::getInteractionClass(const std::string& name)
230 {
231     InteractionClassMap::const_iterator i = _interactionClassMap.find(name);
232     if (i == _interactionClassMap.end())
233         return 0;
234     return i->second.get();
235 }
236
237 const HLAInteractionClass*
238 HLAFederate::getInteractionClass(const std::string& name) const
239 {
240     InteractionClassMap::const_iterator i = _interactionClassMap.find(name);
241     if (i == _interactionClassMap.end())
242         return 0;
243     return i->second.get();
244 }
245
246 } // namespace simgear