X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fhla%2FHLAFederate.cxx;h=8cd173ad53ec0f1abb99d465dd7d8bdbb9a1b46e;hb=32ef925a79c323880fb0cfb4209aca8486467d17;hp=c5c70630f8297c2b3222019fe20811ae99324590;hpb=08cb2039c53cff49e93e621621a9796b1c43f574;p=simgear.git diff --git a/simgear/hla/HLAFederate.cxx b/simgear/hla/HLAFederate.cxx index c5c70630..8cd173ad 100644 --- a/simgear/hla/HLAFederate.cxx +++ b/simgear/hla/HLAFederate.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de +// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public @@ -15,10 +15,21 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + #include "HLAFederate.hxx" -#include "RTI13Federate.hxx" +#include + +#include "simgear/debug/logstream.hxx" + #include "RTIFederate.hxx" +#include "RTIFederateFactoryRegistry.hxx" +#include "RTI13FederateFactory.hxx" #include "RTIInteractionClass.hxx" #include "RTIObjectClass.hxx" #include "HLADataElement.hxx" @@ -35,10 +46,19 @@ HLAFederate::HLAFederate() : _timeConstrainedByLocalClock(false), _done(false) { + // For now instantiate the current only available factory here explicitly + RTI13FederateFactory::instance(); } HLAFederate::~HLAFederate() { + _clearRTI(); + + // Remove the data type references from the data types. + // This is to remove the cycles from the data types that might happen if a data type references itself + for (DataTypeMap::iterator i = _dataTypeMap.begin(); i != _dataTypeMap.end(); ++i) { + i->second->releaseDataTypeReferences(); + } } HLAFederate::Version @@ -58,6 +78,22 @@ HLAFederate::setVersion(HLAFederate::Version version) return true; } +bool +HLAFederate::setVersion(const std::string& version) +{ + if (version == "RTI13") + return setVersion(RTI13); + else if (version == "RTI1516") + return setVersion(RTI1516); + else if (version == "RTI1516E") + return setVersion(RTI1516E); + else { + /// at some time think about routing these down to the factory + SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Unknown version string in HLAFederate::setVersion!"); + return false; + } +} + const std::list& HLAFederate::getConnectArguments() const { @@ -159,28 +195,9 @@ HLAFederate::setFederateName(const std::string& federateName) bool HLAFederate::connect(Version version, const std::list& stringList) { - if (_rtiFederate.valid()) { - SG_LOG(SG_NETWORK, SG_WARN, "HLA: Trying to connect to already connected federate!"); - return false; - } - switch (version) { - case RTI13: - _rtiFederate = new RTI13Federate(stringList); - _version = version; - _connectArguments = stringList; - break; - case RTI1516: - SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516 not yet(!?) supported."); - // _rtiFederate = new RTI1516Federate(stringList); - break; - case RTI1516E: - SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516E not yet(!?) supported."); - // _rtiFederate = new RTI1516eFederate(stringList); - break; - default: - SG_LOG(SG_NETWORK, SG_WARN, "HLA: Unknown rti version in connect!"); - } - return _rtiFederate.valid(); + _version = version; + _connectArguments = stringList; + return connect(); } bool @@ -190,17 +207,22 @@ HLAFederate::connect() SG_LOG(SG_NETWORK, SG_WARN, "HLA: Trying to connect to already connected federate!"); return false; } + + SGSharedPtr registry = RTIFederateFactoryRegistry::instance(); + if (!registry) { + SG_LOG(SG_NETWORK, SG_ALERT, "HLA: RTIFederateFactoryRegistry is no longer available!"); + return false; + } + switch (_version) { case RTI13: - _rtiFederate = new RTI13Federate(_connectArguments); + _rtiFederate = registry->create("RTI13", _connectArguments); break; case RTI1516: - SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516 not yet(!?) supported."); - // _rtiFederate = new RTI1516Federate(_connectArguments); + _rtiFederate = registry->create("RTI1516", _connectArguments); break; case RTI1516E: - SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516E not yet(!?) supported."); - // _rtiFederate = new RTI1516eFederate(_connectArguments); + _rtiFederate = registry->create("RTI1516E", _connectArguments); break; default: SG_LOG(SG_NETWORK, SG_WARN, "HLA: Unknown rti version in connect!"); @@ -215,7 +237,8 @@ HLAFederate::disconnect() SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!"); return false; } - _rtiFederate = 0; + + _clearRTI(); return true; } @@ -648,14 +671,11 @@ HLAFederate::timeAdvanceAvailable() } SGTimeStamp timeStamp; - if (!_rtiFederate->queryGALT(timeStamp)) { - SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not query GALT!"); - return false; - } - - if (!_rtiFederate->timeAdvanceRequestAvailable(timeStamp)) { - SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!"); - return false; + if (_rtiFederate->queryGALT(timeStamp)) { + if (!_rtiFederate->timeAdvanceRequestAvailable(timeStamp)) { + SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!"); + return false; + } } return processMessages(); @@ -748,11 +768,6 @@ bool HLAFederate::readObjectModelTemplate(const std::string& objectModel, HLAFederate::ObjectModelFactory& objectModelFactory) { - if (!_rtiFederate.valid()) { - SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!"); - return false; - } - // The XML version of the federate object model. // This one covers the generic attributes, parameters and data types. HLAOMTXmlVisitor omtXmlVisitor; @@ -767,6 +782,8 @@ HLAFederate::readObjectModelTemplate(const std::string& objectModel, return false; } + omtXmlVisitor.setDataTypesToFederate(*this); + unsigned numObjectClasses = omtXmlVisitor.getNumObjectClasses(); for (unsigned i = 0; i < numObjectClasses; ++i) { const HLAOMTXmlVisitor::ObjectClass* objectClass = omtXmlVisitor.getObjectClass(i); @@ -781,56 +798,171 @@ HLAFederate::readObjectModelTemplate(const std::string& objectModel, bool publish = objectModelFactory.publishObjectClass(objectClassName, objectClass->getSharing()); bool subscribe = objectModelFactory.subscribeObjectClass(objectClassName, objectClass->getSharing()); - std::set subscriptions; - std::set publications; - // process the attributes for (unsigned j = 0; j < objectClass->getNumAttributes(); ++j) { const simgear::HLAOMTXmlVisitor::Attribute* attribute; attribute = objectClass->getAttribute(j); std::string attributeName = attribute->getName(); - unsigned index = hlaObjectClass->getAttributeIndex(attributeName); + unsigned index = hlaObjectClass->addAttribute(attributeName); if (index == ~0u) { SG_LOG(SG_IO, SG_WARN, "RTI does not know the \"" << attributeName << "\" attribute!"); continue; } - SGSharedPtr dataType; - dataType = omtXmlVisitor.getAttributeDataType(objectClassName, attributeName); + // the attributes datatype + SGSharedPtr dataType = getDataType(attribute->getDataType()); if (!dataType.valid()) { SG_LOG(SG_IO, SG_WARN, "Could not find data type for attribute \"" << attributeName << "\" in object class \"" << objectClassName << "\"!"); } hlaObjectClass->setAttributeDataType(index, dataType); - - HLAUpdateType updateType = HLAUndefinedUpdate; - if (attribute->_updateType == "Periodic") - updateType = HLAPeriodicUpdate; - else if (attribute->_updateType == "Static") - updateType = HLAStaticUpdate; - else if (attribute->_updateType == "Conditional") - updateType = HLAConditionalUpdate; - hlaObjectClass->setAttributeUpdateType(index, updateType); - + hlaObjectClass->setAttributeUpdateType(index, attribute->getUpdateType()); if (subscribe && objectModelFactory.subscribeAttribute(objectClassName, attributeName, attribute->_sharing)) - subscriptions.insert(index); + hlaObjectClass->setAttributeSubscriptionType(index, attribute->getSubscriptionType()); if (publish && objectModelFactory.publishAttribute(objectClassName, attributeName, attribute->_sharing)) - publications.insert(index); + hlaObjectClass->setAttributePublicationType(index, attribute->getPublicationType()); } if (publish) - hlaObjectClass->publish(publications); + hlaObjectClass->publish(); if (subscribe) - hlaObjectClass->subscribe(subscriptions, true); + hlaObjectClass->subscribe(); + + } + + return resolveObjectModel(); +} - _objectClassMap[objectClassName] = hlaObjectClass; +bool +HLAFederate::readRTI13ObjectModelTemplate(const std::string& objectModel) +{ + SG_LOG(SG_IO, SG_ALERT, "HLA version RTI13 not yet(!?) supported."); + return false; +} + +bool +HLAFederate::readRTI1516ObjectModelTemplate(const std::string& objectModel) +{ + // The XML version of the federate object model. + // This one covers the generic attributes, parameters and data types. + HLAOMTXmlVisitor omtXmlVisitor; + try { + readXML(objectModel, omtXmlVisitor); + } catch (const sg_throwable& e) { + SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file: " + << e.getMessage()); + return false; + } catch (...) { + SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file"); + return false; + } + + omtXmlVisitor.setToFederate(*this); + + return resolveObjectModel(); +} + +bool +HLAFederate::readRTI1516EObjectModelTemplate(const std::string& objectModel) +{ + SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516E not yet(!?) supported."); + return false; +} + +bool +HLAFederate::resolveObjectModel() +{ + if (!_rtiFederate.valid()) { + SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!"); + return false; + } + + for (InteractionClassMap::iterator i = _interactionClassMap.begin(); i != _interactionClassMap.end(); ++i) { + RTIInteractionClass* rtiInteractionClass = _rtiFederate->createInteractionClass(i->second->getName(), i->second.get()); + if (!rtiInteractionClass) { + SG_LOG(SG_NETWORK, SG_ALERT, "HLAFederate::_insertInteractionClass(): " + "No RTIInteractionClass found for \"" << i->second->getName() << "\"!"); + return false; + } + i->second->_setRTIInteractionClass(rtiInteractionClass); + } + + for (ObjectClassMap::iterator i = _objectClassMap.begin(); i != _objectClassMap.end(); ++i) { + RTIObjectClass* rtiObjectClass = _rtiFederate->createObjectClass(i->second->getName(), i->second.get()); + if (!rtiObjectClass) { + SG_LOG(SG_NETWORK, SG_ALERT, "HLAFederate::_insertObjectClass(): " + "No RTIObjectClass found for \"" << i->second->getName() << "\"!"); + return false; + } + i->second->_setRTIObjectClass(rtiObjectClass); } return true; } +const HLADataType* +HLAFederate::getDataType(const std::string& name) const +{ + DataTypeMap::const_iterator i = _dataTypeMap.find(name); + if (i == _dataTypeMap.end()) + return 0; + return i->second.get(); +} + +bool +HLAFederate::insertDataType(const std::string& name, const SGSharedPtr& dataType) +{ + if (!dataType.valid()) + return false; + if (_dataTypeMap.find(name) != _dataTypeMap.end()) { + SG_LOG(SG_IO, SG_ALERT, "HLAFederate::insertDataType: data type with name \"" + << name << "\" already known to federate!"); + return false; + } + _dataTypeMap.insert(DataTypeMap::value_type(name, dataType)); + return true; +} + +void +HLAFederate::recomputeDataTypeAlignment() +{ + // Finish alignment computations + bool changed; + do { + changed = false; + for (DataTypeMap::iterator i = _dataTypeMap.begin(); i != _dataTypeMap.end(); ++i) { + if (i->second->recomputeAlignment()) + changed = true; + } + } while (changed); +} + +HLAInteractionClass* +HLAFederate::getInteractionClass(const std::string& name) +{ + InteractionClassMap::const_iterator i = _interactionClassMap.find(name); + if (i == _interactionClassMap.end()) + return 0; + return i->second.get(); +} + +const HLAInteractionClass* +HLAFederate::getInteractionClass(const std::string& name) const +{ + InteractionClassMap::const_iterator i = _interactionClassMap.find(name); + if (i == _interactionClassMap.end()) + return 0; + return i->second.get(); +} + +HLAInteractionClass* +HLAFederate::createInteractionClass(const std::string& name) +{ + return new HLAInteractionClass(name, this); +} + HLAObjectClass* HLAFederate::getObjectClass(const std::string& name) { @@ -849,24 +981,36 @@ HLAFederate::getObjectClass(const std::string& name) const return i->second.get(); } -HLAInteractionClass* -HLAFederate::getInteractionClass(const std::string& name) +HLAObjectClass* +HLAFederate::createObjectClass(const std::string& name) { - InteractionClassMap::const_iterator i = _interactionClassMap.find(name); - if (i == _interactionClassMap.end()) + return new HLAObjectClass(name, this); +} + +HLAObjectInstance* +HLAFederate::getObjectInstance(const std::string& name) +{ + ObjectInstanceMap::const_iterator i = _objectInstanceMap.find(name); + if (i == _objectInstanceMap.end()) return 0; return i->second.get(); } -const HLAInteractionClass* -HLAFederate::getInteractionClass(const std::string& name) const +const HLAObjectInstance* +HLAFederate::getObjectInstance(const std::string& name) const { - InteractionClassMap::const_iterator i = _interactionClassMap.find(name); - if (i == _interactionClassMap.end()) + ObjectInstanceMap::const_iterator i = _objectInstanceMap.find(name); + if (i == _objectInstanceMap.end()) return 0; return i->second.get(); } +HLAObjectInstance* +HLAFederate::createObjectInstance(HLAObjectClass* objectClass, const std::string& name) +{ + return new HLAObjectInstance(objectClass); +} + void HLAFederate::setDone(bool done) { @@ -882,22 +1026,62 @@ HLAFederate::getDone() const bool HLAFederate::readObjectModel() { - /// Currently empty, but is called at the right time so that - /// the object model is present when it is needed - return true; + // Depending on the actual version, try to find an apropriate + // file format for the given file. The first one is always the + // version native object model file format. + switch (getVersion()) { + case RTI13: + if (readRTI13ObjectModelTemplate(getFederationObjectModel())) + return true; + if (readRTI1516ObjectModelTemplate(getFederationObjectModel())) + return true; + return readRTI1516EObjectModelTemplate(getFederationObjectModel()); + case RTI1516: + if (readRTI1516ObjectModelTemplate(getFederationObjectModel())) + return true; + if (readRTI1516EObjectModelTemplate(getFederationObjectModel())) + return true; + return readRTI13ObjectModelTemplate(getFederationObjectModel()); + case RTI1516E: + if (readRTI1516EObjectModelTemplate(getFederationObjectModel())) + return true; + if (readRTI1516ObjectModelTemplate(getFederationObjectModel())) + return true; + return readRTI13ObjectModelTemplate(getFederationObjectModel()); + default: + return false; + } } bool HLAFederate::subscribe() { - /// Currently empty, but is called at the right time + for (InteractionClassMap::iterator i = _interactionClassMap.begin(); i != _interactionClassMap.end(); ++i) { + if (!i->second->subscribe()) + return false; + } + + for (ObjectClassMap::iterator i = _objectClassMap.begin(); i != _objectClassMap.end(); ++i) { + if (!i->second->subscribe()) + return false; + } + return true; } bool HLAFederate::publish() { - /// Currently empty, but is called at the right time + for (InteractionClassMap::iterator i = _interactionClassMap.begin(); i != _interactionClassMap.end(); ++i) { + if (!i->second->publish()) + return false; + } + + for (ObjectClassMap::iterator i = _objectClassMap.begin(); i != _objectClassMap.end(); ++i) { + if (!i->second->publish()) + return false; + } + return true; } @@ -1009,4 +1193,75 @@ HLAFederate::exec() return true; } +void +HLAFederate::_clearRTI() +{ + for (InteractionClassMap::iterator i = _interactionClassMap.begin(); i != _interactionClassMap.end(); ++i) + i->second->_clearRTIInteractionClass(); + for (ObjectInstanceMap::iterator i = _objectInstanceMap.begin(); i != _objectInstanceMap.end(); ++i) + i->second->_clearRTIObjectInstance(); + for (ObjectClassMap::iterator i = _objectClassMap.begin(); i != _objectClassMap.end(); ++i) + i->second->_clearRTIObjectClass(); + + _rtiFederate = 0; +} + +bool +HLAFederate::_insertInteractionClass(const SGSharedPtr& interactionClass) +{ + if (!interactionClass.valid()) + return false; + if (_interactionClassMap.find(interactionClass->getName()) != _interactionClassMap.end()) { + SG_LOG(SG_IO, SG_ALERT, "HLA: _insertInteractionClass: object instance with name \"" + << interactionClass->getName() << "\" already known to federate!"); + return false; + } + _interactionClassMap.insert(InteractionClassMap::value_type(interactionClass->getName(), interactionClass)); + return true; +} + +bool +HLAFederate::_insertObjectClass(const SGSharedPtr& objectClass) +{ + if (!objectClass.valid()) + return false; + if (_objectClassMap.find(objectClass->getName()) != _objectClassMap.end()) { + SG_LOG(SG_IO, SG_ALERT, "HLA: _insertObjectClass: object instance with name \"" + << objectClass->getName() << "\" already known to federate!"); + return false; + } + _objectClassMap.insert(ObjectClassMap::value_type(objectClass->getName(), objectClass)); + return true; +} + +bool +HLAFederate::_insertObjectInstance(const SGSharedPtr& objectInstance) +{ + if (!objectInstance.valid()) + return false; + if (objectInstance->getName().empty()) { + SG_LOG(SG_IO, SG_ALERT, "HLA: _insertObjectInstance: trying to insert object instance with empty name!"); + return false; + } + if (_objectInstanceMap.find(objectInstance->getName()) != _objectInstanceMap.end()) { + SG_LOG(SG_IO, SG_WARN, "HLA: _insertObjectInstance: object instance with name \"" + << objectInstance->getName() << "\" already known to federate!"); + return false; + } + _objectInstanceMap.insert(ObjectInstanceMap::value_type(objectInstance->getName(), objectInstance)); + return true; +} + +void +HLAFederate::_eraseObjectInstance(const std::string& name) +{ + ObjectInstanceMap::iterator i = _objectInstanceMap.find(name); + if (i == _objectInstanceMap.end()) { + SG_LOG(SG_IO, SG_WARN, "HLA: _eraseObjectInstance: object instance with name \"" + << name << "\" not known to federate!"); + return; + } + _objectInstanceMap.erase(i); +} + } // namespace simgear