1 // Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
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.
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.
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.
18 #ifndef HLAFederate_hxx
19 #define HLAFederate_hxx
23 #include "HLAObjectInstance.hxx"
24 #include "HLAObjectClass.hxx"
25 #include "HLAInteractionClass.hxx"
33 class HLAFederate : public SGWeakReferenced {
36 virtual ~HLAFederate();
44 /// The rti version backend to connect
45 Version getVersion() const;
46 bool setVersion(HLAFederate::Version version);
47 bool setVersion(const std::string& version);
49 /// The rti backends connect arguments, depends on the version
50 const std::list<std::string>& getConnectArguments() const;
51 bool setConnectArguments(const std::list<std::string>& connectArguments);
53 /// If true try to create on join and try to destroy on resign
54 bool getCreateFederationExecution() const;
55 bool setCreateFederationExecution(bool createFederationExecution);
57 /// The federation execution name to use on create, join and destroy
58 const std::string& getFederationExecutionName() const;
59 bool setFederationExecutionName(const std::string& federationExecutionName);
61 /// The federation object model name to use on create and possibly join
62 const std::string& getFederationObjectModel() const;
63 bool setFederationObjectModel(const std::string& federationObjectModel);
65 /// The federate type used on join
66 const std::string& getFederateType() const;
67 bool setFederateType(const std::string& federateType);
69 /// The federate name possibly used on join
70 const std::string& getFederateName() const;
71 bool setFederateName(const std::string& federateName);
74 bool connect(Version version, const std::list<std::string>& stringList);
78 /// Create a federation execution
79 /// Semantically this methods should be static,
80 /// but the nonstatic case could reuse the connection to the server
81 bool createFederationExecution(const std::string& federation, const std::string& objectModel);
82 bool destroyFederationExecution(const std::string& federation);
83 bool createFederationExecution();
84 bool destroyFederationExecution();
86 /// Join with federateType the federation execution
87 bool join(const std::string& federateType, const std::string& federation);
91 /// Try to create and join the federation execution.
92 bool createJoinFederationExecution();
93 bool resignDestroyFederationExecution();
98 /// If set to true, time constrained mode is entered on init
99 bool getTimeConstrained() const;
100 bool setTimeConstrained(bool timeConstrained);
102 /// If set to true, time advance is constrained by the local system clock
103 bool getTimeConstrainedByLocalClock() const;
104 bool setTimeConstrainedByLocalClock(bool timeConstrainedByLocalClock);
106 /// If set to true, time regulation mode is entered on init
107 bool getTimeRegulating() const;
108 bool setTimeRegulating(bool timeRegulating);
110 /// If set to a non zero value, this federate leads the federations
111 /// locical time advance by this amount of time.
112 const SGTimeStamp& getLeadTime() const;
113 bool setLeadTime(const SGTimeStamp& leadTime);
115 /// The time increment for use in the default update method.
116 const SGTimeStamp& getTimeIncrement() const;
117 bool setTimeIncrement(const SGTimeStamp& timeIncrement);
119 /// Actually enable time constrained mode.
120 /// This method blocks until time constrained mode is enabled.
121 bool enableTimeConstrained();
122 /// Actually disable time constrained mode.
123 bool disableTimeConstrained();
125 /// Actually enable time constrained by local clock mode.
126 bool enableTimeConstrainedByLocalClock();
128 /// Actually enable time regulation mode.
129 /// This method blocks until time regulation mode is enabled.
130 bool enableTimeRegulation(const SGTimeStamp& lookahead);
131 bool enableTimeRegulation();
132 /// Actually disable time regulation mode.
133 bool disableTimeRegulation();
134 /// Actually modify the lookahead time.
135 bool modifyLookahead(const SGTimeStamp& lookahead);
137 /// Advance the logical time by the given time increment.
138 /// Depending on the time constrained mode, this might
139 /// block until the time advance is granted.
140 bool timeAdvanceBy(const SGTimeStamp& timeIncrement);
141 /// Advance the logical time to the given time.
142 /// Depending on the time constrained mode, this might
143 /// block until the time advance is granted.
144 bool timeAdvance(const SGTimeStamp& timeStamp);
145 /// Advance the logical time as far as time advances are available.
146 /// This call should not block and advance the logical time
147 /// as far as currently possible.
148 bool timeAdvanceAvailable();
150 /// Get the current federates time
151 bool queryFederateTime(SGTimeStamp& timeStamp);
152 /// Get the current federates lookahead
153 bool queryLookahead(SGTimeStamp& timeStamp);
155 /// Process one messsage
156 bool processMessage();
157 /// Process one message but do not wait longer than the relative timeout.
158 bool processMessage(const SGTimeStamp& timeout);
159 /// Process messages until the federate can proceed with the
160 /// next simulation step. That is flush all pending messages and
161 /// depending on the time constrained mode process messages until
162 /// a pending time advance is granted.
163 bool processMessages();
165 class ObjectModelFactory {
167 virtual ~ObjectModelFactory()
170 virtual HLAObjectClass* createObjectClass(const std::string& name, HLAFederate& federate)
171 { return federate.createObjectClass(name); }
172 virtual bool subscribeObjectClass(const std::string& objectClassName, const std::string& sharing)
173 { return sharing.find("Subscribe") != std::string::npos; }
174 virtual bool publishObjectClass(const std::string& objectClassName, const std::string& sharing)
175 { return sharing.find("Publish") != std::string::npos; }
176 virtual bool subscribeAttribute(const std::string& objectClassName, const std::string& attributeName, const std::string& sharing)
177 { return sharing.find("Subscribe") != std::string::npos; }
178 virtual bool publishAttribute(const std::string& objectClassName, const std::string& attributeName, const std::string& sharing)
179 { return sharing.find("Publish") != std::string::npos; }
183 /// Read an omt xml file - deprecated
184 bool readObjectModelTemplate(const std::string& objectModel,
185 ObjectModelFactory& objectModelFactory);
187 /// Read an rti1.3 omt xml file
188 bool readRTI13ObjectModelTemplate(const std::string& objectModel);
189 /// Read an rti1516 omt xml file
190 bool readRTI1516ObjectModelTemplate(const std::string& objectModel);
191 /// Read an rti1516e omt xml file
192 bool readRTI1516EObjectModelTemplate(const std::string& objectModel);
194 /// Is called past a successful join to populate the rti classes
195 bool resolveObjectModel();
197 /// Access data types
198 const HLADataType* getDataType(const std::string& name) const;
199 // virtual const HLADataType* createDataType(const std::string& name);
200 bool insertDataType(const std::string& name, const SGSharedPtr<HLADataType>& dataType);
201 void recomputeDataTypeAlignment();
203 /// Get the interaction class of a given name
204 HLAInteractionClass* getInteractionClass(const std::string& name);
205 const HLAInteractionClass* getInteractionClass(const std::string& name) const;
206 /// Default create function. Creates a default interaction class
207 virtual HLAInteractionClass* createInteractionClass(const std::string& name);
209 /// Get the object class of a given name
210 HLAObjectClass* getObjectClass(const std::string& name);
211 const HLAObjectClass* getObjectClass(const std::string& name) const;
212 /// Default create function. Creates a default object class
213 virtual HLAObjectClass* createObjectClass(const std::string& name);
215 /// Get the object instance of a given name
216 HLAObjectInstance* getObjectInstance(const std::string& name);
217 const HLAObjectInstance* getObjectInstance(const std::string& name) const;
218 virtual HLAObjectInstance* createObjectInstance(HLAObjectClass* objectClass, const std::string& name);
220 /// Tells the main exec loop to continue or not.
221 void setDone(bool done);
222 bool getDone() const;
224 /// The user overridable slot that is called to set up an object model
225 /// By default, depending on the set up rti version, the apropriate
226 /// bool read{RTI13,RTI1516,RTI1516E}ObjectModelTemplate(const std::string& objectModel);
227 /// method is called.
228 /// Note that the RTI13 files do not contain any information about the data types.
229 /// A user needs to set up the data types and assign them to the object classes/
230 /// interaction classes theirselves.
231 /// Past reading the object model, it is still possible to change the subscription/publication
232 /// types without introducing traffic on the backend rti.
233 virtual bool readObjectModel();
235 virtual bool subscribe();
236 virtual bool publish();
239 virtual bool update();
240 virtual bool shutdown();
245 HLAFederate(const HLAFederate&);
246 HLAFederate& operator=(const HLAFederate&);
250 /// Internal helpers for interaction classes
251 bool _insertInteractionClass(const SGSharedPtr<HLAInteractionClass>& interactionClass);
252 /// Internal helpers for object classes
253 bool _insertObjectClass(const SGSharedPtr<HLAObjectClass>& objectClass);
254 /// Internal helpers for object instances
255 bool _insertObjectInstance(const SGSharedPtr<HLAObjectInstance>& objectInstance);
256 void _eraseObjectInstance(const std::string& name);
258 /// The underlying interface to the rti implementation
259 SGSharedPtr<RTIFederate> _rtiFederate;
261 /// Parameters required to connect to an rti
263 std::list<std::string> _connectArguments;
265 /// Parameters for the federation execution
266 std::string _federationExecutionName;
267 std::string _federationObjectModel;
268 bool _createFederationExecution;
270 /// Parameters for the federate
271 std::string _federateType;
272 std::string _federateName;
274 /// Time management related parameters
275 /// If true, the federate is expected to enter time constrained mode
276 bool _timeConstrained;
277 /// If true, the federate is expected to enter time regulating mode
278 bool _timeRegulating;
279 /// The amount of time this federate leads the others.
280 SGTimeStamp _leadTime;
281 /// The regular time increment we do on calling update()
282 SGTimeStamp _timeIncrement;
283 /// The reference system time at initialization time.
284 /// Is used to implement being time constrained on the
285 /// local system time.
286 bool _timeConstrainedByLocalClock;
287 SGTimeStamp _localClockOffset;
289 /// If true the exec method returns.
292 /// The Data Types by name
293 typedef std::map<std::string, SGSharedPtr<HLADataType> > DataTypeMap;
294 DataTypeMap _dataTypeMap;
296 /// The Interaction Classes by name
297 typedef std::map<std::string, SGSharedPtr<HLAInteractionClass> > InteractionClassMap;
298 InteractionClassMap _interactionClassMap;
300 /// The Object Classes by name
301 typedef std::map<std::string, SGSharedPtr<HLAObjectClass> > ObjectClassMap;
302 ObjectClassMap _objectClassMap;
304 /// The Object Instances by name
305 typedef std::map<std::string, SGSharedPtr<HLAObjectInstance> > ObjectInstanceMap;
306 ObjectInstanceMap _objectInstanceMap;
307 /// The Object Instances by name, the ones that have an explicit given name, may be not yet registered
308 // ObjectInstanceMap _explicitNamedObjectInstanceMap;
310 friend class HLAInteractionClass;
311 friend class HLAObjectClass;
312 friend class HLAObjectInstance;
315 } // namespace simgear