HLAEnumeratedDataElement.cxx
HLAEnumeratedDataType.cxx
HLAFederate.cxx
+ HLAInteractionClass.cxx
HLAFixedRecordDataElement.cxx
HLAFixedRecordDataType.cxx
HLAObjectClass.cxx
if(RTI_FOUND)
set(RTI13_SOURCES
+ RTI13InteractionClass.cxx
RTI13ObjectClass.cxx
RTI13ObjectInstance.cxx
RTI13Federate.cxx
endif()
set(RTI_SOURCES
+ RTIInteractionClass.cxx
RTIObjectClass.cxx
RTIObjectInstance.cxx
RTIFederate.cxx
-// 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
return this;
}
+void
+HLAArrayDataType::releaseDataTypeReferences()
+{
+ _elementDataType = 0;
+ HLADataType::releaseDataTypeReferences();
+}
+
void
HLAArrayDataType::setElementDataType(const HLADataType* elementDataType)
{
- // FIXME this only works if we do not reset the alignment to something smaller
- if (getAlignment() < elementDataType->getAlignment())
- setAlignment(elementDataType->getAlignment());
_elementDataType = elementDataType;
}
_isString = isString;
}
+void
+HLAArrayDataType::_recomputeAlignmentImplementation()
+{
+ unsigned alignment = 1;
+ if (const HLADataType* dataType = getElementDataType())
+ alignment = std::max(alignment, dataType->getAlignment());
+ setAlignment(alignment);
+}
+
///////////////////////////////////////////////////////////////////////////////////
HLAFixedArrayDataType::HLAFixedArrayDataType(const std::string& name) :
}
void
-HLAVariableArrayDataType::setSizeDataType(const HLADataType* sizeDataType)
+HLAVariableArrayDataType::setSizeDataType(const HLABasicDataType* sizeDataType)
{
- // FIXME this only works if we do not reset the alignment to something smaller
- if (getAlignment() < sizeDataType->getAlignment())
- setAlignment(sizeDataType->getAlignment());
_sizeDataType = sizeDataType;
- // setAlignment(SGMisc<unsigned>::max(_sizeDataType->getAlignment(), _elementDataType->getAlignment());
+}
+
+void
+HLAVariableArrayDataType::_recomputeAlignmentImplementation()
+{
+ unsigned alignment = 1;
+ if (const HLADataType* dataType = getElementDataType())
+ alignment = std::max(alignment, dataType->getAlignment());
+ if (const HLADataType* dataType = getSizeDataType())
+ alignment = std::max(alignment, dataType->getAlignment());
+ setAlignment(alignment);
}
} // namespace simgear
-// 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
virtual const HLAArrayDataType* toArrayDataType() const;
+ virtual void releaseDataTypeReferences();
+
virtual bool decode(HLADecodeStream& stream, HLAAbstractArrayDataElement& value) const = 0;
virtual bool encode(HLAEncodeStream& stream, const HLAAbstractArrayDataElement& value) const = 0;
bool getIsString() const
{ return _isString; }
+protected:
+ virtual void _recomputeAlignmentImplementation();
+
private:
SGSharedPtr<const HLADataType> _elementDataType;
bool _isOpaque;
virtual bool decode(HLADecodeStream& stream, HLAAbstractArrayDataElement& value) const;
virtual bool encode(HLAEncodeStream& stream, const HLAAbstractArrayDataElement& value) const;
- void setSizeDataType(const HLADataType* sizeDataType);
- const HLADataType* getSizeDataType() const
+ void setSizeDataType(const HLABasicDataType* sizeDataType);
+ const HLABasicDataType* getSizeDataType() const
{ return _sizeDataType.get(); }
+protected:
+ virtual void _recomputeAlignmentImplementation();
+
private:
- SGSharedPtr<const HLADataType> _sizeDataType;
+ SGSharedPtr<const HLABasicDataType> _sizeDataType;
};
} // namespace simgear
-// Copyright (C) 2009 - 2010 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
-// Copyright (C) 2009 - 2010 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
visitor.apply(*this);
}
-const HLADataTypeReference*
-HLADataType::toDataTypeReference() const
-{
- return 0;
-}
-
const HLABasicDataType*
HLADataType::toBasicDataType() const
{
return 0;
}
+bool
+HLADataType::recomputeAlignment()
+{
+ unsigned alignment = getAlignment();
+ _recomputeAlignmentImplementation();
+ return alignment != getAlignment();
+}
+
+void
+HLADataType::releaseDataTypeReferences()
+{
+}
+
void
HLADataType::setAlignment(unsigned alignment)
{
_alignment = alignment;
}
-HLADataTypeReference::~HLADataTypeReference()
-{
-}
-
void
-HLADataTypeReference::accept(HLADataTypeVisitor& visitor) const
-{
- visitor.apply(*this);
-}
-
-const HLADataTypeReference*
-HLADataTypeReference::toDataTypeReference() const
+HLADataType::_recomputeAlignmentImplementation()
{
- return this;
}
}
-// Copyright (C) 2009 - 2010 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
class HLADataTypeVisitor;
-class HLADataTypeReference;
class HLABasicDataType;
class HLAArrayDataType;
class HLAEnumeratedDataType;
virtual void accept(HLADataTypeVisitor& visitor) const;
- virtual const HLADataTypeReference* toDataTypeReference() const;
virtual const HLABasicDataType* toBasicDataType() const;
virtual const HLAArrayDataType* toArrayDataType() const;
virtual const HLAEnumeratedDataType* toEnumeratedDataType() const;
const HLAVariantRecordDataType* toVariantDataType() const { return toVariantRecordDataType(); }
virtual const HLAVariantRecordDataType* toVariantRecordDataType() const;
+ /// Recompute the alignment value of this data type.
+ /// Return true if the alignment changed, false otherwise.
+ bool recomputeAlignment();
+ /// Release references to other data types. Since we can have cycles this is
+ /// required for propper feeing of memory.
+ virtual void releaseDataTypeReferences();
+
protected:
HLADataType(const std::string& name, unsigned alignment = 1);
void setAlignment(unsigned alignment);
+ virtual void _recomputeAlignmentImplementation();
+
private:
std::string _name;
std::string _semantics;
unsigned _alignment;
};
-// Weak reference to a data type. Used to implement self referencing data types
-class HLADataTypeReference : public HLADataType {
-public:
- HLADataTypeReference(const SGSharedPtr<HLADataType>& dataType) :
- HLADataType(dataType->getName(), dataType->getAlignment()),
- _dataType(dataType)
- { }
- virtual ~HLADataTypeReference();
-
- SGSharedPtr<const HLADataType> getDataType() const
- { return _dataType.lock(); }
-
- virtual void accept(HLADataTypeVisitor& visitor) const;
- virtual const HLADataTypeReference* toDataTypeReference() const;
-
-private:
- SGWeakPtr<const HLADataType> _dataType;
-};
-
} // namespace simgear
#endif
virtual void apply(const HLADataType& dataType)
{ }
- virtual void apply(const HLADataTypeReference& dataType)
- {
- SGSharedPtr<const HLADataType> dataTypeReference = dataType.getDataType();
- if (!dataTypeReference.valid()) {
- SG_LOG(SG_NETWORK, SG_WARN, "HLADataTypeReference weak reference vanished!");
- return;
- }
- dataTypeReference->accept(*this);
- }
-
virtual void apply(const HLABasicDataType& dataType)
{ apply(static_cast<const HLADataType&>(dataType)); }
virtual void apply(const HLAInt8DataType& dataType)
-// Copyright (C) 2009 - 2010 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
_map.swap(representationVisitor._map);
}
+void
+HLAEnumeratedDataType::_recomputeAlignmentImplementation()
+{
+ unsigned alignment = 1;
+ if (const HLADataType* dataType = getRepresentation())
+ alignment = std::max(alignment, dataType->getAlignment());
+ setAlignment(alignment);
+}
+
} // namespace simgear
-// Copyright (C) 2009 - 2010 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
return _map->getDataType();
}
+protected:
+ virtual void _recomputeAlignmentImplementation();
+
private:
class AbstractMap : public SGReferenced {
public:
#include "HLAFederate.hxx"
+#include <algorithm>
+
#include "simgear/debug/logstream.hxx"
#include "RTIFederate.hxx"
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
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
- _rtiFederate = 0;
+
+ _clearRTI();
return true;
}
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;
return false;
}
+ omtXmlVisitor.setDataTypesToFederate(*this);
+
unsigned numObjectClasses = omtXmlVisitor.getNumObjectClasses();
for (unsigned i = 0; i < numObjectClasses; ++i) {
const HLAOMTXmlVisitor::ObjectClass* objectClass = omtXmlVisitor.getObjectClass(i);
bool publish = objectModelFactory.publishObjectClass(objectClassName, objectClass->getSharing());
bool subscribe = objectModelFactory.subscribeObjectClass(objectClassName, objectClass->getSharing());
- std::set<unsigned> subscriptions;
- std::set<unsigned> 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<HLADataType> dataType;
- dataType = omtXmlVisitor.getAttributeDataType(objectClassName, attributeName);
+ // the attributes datatype
+ SGSharedPtr<const HLADataType> 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();
- _objectClassMap[objectClassName] = hlaObjectClass;
}
- return true;
+ return resolveObjectModel();
}
bool
bool
HLAFederate::readRTI1516ObjectModelTemplate(const std::string& objectModel)
{
- ObjectModelFactory objectModelFactory;
- return readObjectModelTemplate(objectModel, objectModelFactory);
+ // 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
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<HLADataType>& 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)
{
HLAObjectClass*
HLAFederate::createObjectClass(const std::string& name)
{
- return new HLAObjectClass(name, *this);
+ return new HLAObjectClass(name, this);
}
-HLAInteractionClass*
-HLAFederate::getInteractionClass(const std::string& name)
+HLAObjectInstance*
+HLAFederate::getObjectInstance(const std::string& name)
{
- 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();
}
-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)
{
bool
HLAFederate::readObjectModel()
{
- /// Currently empty, but is called at the right time so that
- /// the object model is present when it is needed
- // switch (getVersion()) {
- // case RTI13:
- // return readRTI13ObjectModelTemplate(getFederationObjectModel());
- // case RTI1516:
- // return readRTI1516ObjectModelTemplate(getFederationObjectModel());
- // case RTI1516E:
- // return readRTI1516EObjectModelTemplate(getFederationObjectModel());
- // }
- 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;
}
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<HLAInteractionClass>& 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<HLAObjectClass>& 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<HLAObjectInstance>& 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
/// Read an rti1516e omt xml file
bool readRTI1516EObjectModelTemplate(const std::string& objectModel);
+ /// Is called past a successful join to populate the rti classes
+ bool resolveObjectModel();
+
+ /// Access data types
+ const HLADataType* getDataType(const std::string& name) const;
+ // virtual const HLADataType* createDataType(const std::string& name);
+ bool insertDataType(const std::string& name, const SGSharedPtr<HLADataType>& dataType);
+ void recomputeDataTypeAlignment();
+
+ /// Get the interaction class of a given name
+ HLAInteractionClass* getInteractionClass(const std::string& name);
+ const HLAInteractionClass* getInteractionClass(const std::string& name) const;
+ /// Default create function. Creates a default interaction class
+ virtual HLAInteractionClass* createInteractionClass(const std::string& name);
+
/// Get the object class of a given name
HLAObjectClass* getObjectClass(const std::string& name);
const HLAObjectClass* getObjectClass(const std::string& name) const;
/// Default create function. Creates a default object class
virtual HLAObjectClass* createObjectClass(const std::string& name);
- /// Get the interaction class of a given name
- HLAInteractionClass* getInteractionClass(const std::string& name);
- const HLAInteractionClass* getInteractionClass(const std::string& name) const;
+ /// Get the object instance of a given name
+ HLAObjectInstance* getObjectInstance(const std::string& name);
+ const HLAObjectInstance* getObjectInstance(const std::string& name) const;
+ virtual HLAObjectInstance* createObjectInstance(HLAObjectClass* objectClass, const std::string& name);
/// Tells the main exec loop to continue or not.
void setDone(bool done);
bool getDone() const;
+ /// The user overridable slot that is called to set up an object model
+ /// By default, depending on the set up rti version, the apropriate
+ /// bool read{RTI13,RTI1516,RTI1516E}ObjectModelTemplate(const std::string& objectModel);
+ /// method is called.
+ /// Note that the RTI13 files do not contain any information about the data types.
+ /// A user needs to set up the data types and assign them to the object classes/
+ /// interaction classes theirselves.
+ /// Past reading the object model, it is still possible to change the subscription/publication
+ /// types without introducing traffic on the backend rti.
virtual bool readObjectModel();
virtual bool subscribe();
HLAFederate(const HLAFederate&);
HLAFederate& operator=(const HLAFederate&);
+ void _clearRTI();
+
+ /// Internal helpers for interaction classes
+ bool _insertInteractionClass(const SGSharedPtr<HLAInteractionClass>& interactionClass);
+ /// Internal helpers for object classes
+ bool _insertObjectClass(const SGSharedPtr<HLAObjectClass>& objectClass);
+ /// Internal helpers for object instances
+ bool _insertObjectInstance(const SGSharedPtr<HLAObjectInstance>& objectInstance);
+ void _eraseObjectInstance(const std::string& name);
+
/// The underlying interface to the rti implementation
SGSharedPtr<RTIFederate> _rtiFederate;
/// If true the exec method returns.
bool _done;
- typedef std::map<std::string, SGSharedPtr<HLAObjectClass> > ObjectClassMap;
- ObjectClassMap _objectClassMap;
+ /// The Data Types by name
+ typedef std::map<std::string, SGSharedPtr<HLADataType> > DataTypeMap;
+ DataTypeMap _dataTypeMap;
+ /// The Interaction Classes by name
typedef std::map<std::string, SGSharedPtr<HLAInteractionClass> > InteractionClassMap;
InteractionClassMap _interactionClassMap;
+ /// The Object Classes by name
+ typedef std::map<std::string, SGSharedPtr<HLAObjectClass> > ObjectClassMap;
+ ObjectClassMap _objectClassMap;
+
+ /// The Object Instances by name
+ typedef std::map<std::string, SGSharedPtr<HLAObjectInstance> > ObjectInstanceMap;
+ ObjectInstanceMap _objectInstanceMap;
+ /// The Object Instances by name, the ones that have an explicit given name, may be not yet registered
+ // ObjectInstanceMap _explicitNamedObjectInstanceMap;
+
friend class HLAInteractionClass;
friend class HLAObjectClass;
+ friend class HLAObjectInstance;
};
} // namespace simgear
-// Copyright (C) 2009 - 2010 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
return this;
}
+void
+HLAFixedRecordDataType::releaseDataTypeReferences()
+{
+ unsigned numFields = getNumFields();
+ for (unsigned i = 0; i < numFields; ++i)
+ _fieldList[i].releaseDataTypeReferences();
+}
+
bool
HLAFixedRecordDataType::decode(HLADecodeStream& stream, HLAAbstractFixedRecordDataElement& value) const
{
void
HLAFixedRecordDataType::addField(const std::string& name, const HLADataType* dataType)
{
- // FIXME this only works if we do not reset the alignment to something smaller
- if (getAlignment() < dataType->getAlignment())
- setAlignment(dataType->getAlignment());
_fieldList.push_back(Field(name, dataType));
}
+void
+HLAFixedRecordDataType::_recomputeAlignmentImplementation()
+{
+ unsigned alignment = 1;
+ for (unsigned i = 0; i < getNumFields(); ++i) {
+ if (const HLADataType* dataType = getFieldDataType(i))
+ alignment = std::max(alignment, dataType->getAlignment());
+ }
+ setAlignment(alignment);
+}
+
} // namespace simgear
-// Copyright (C) 2009 - 2010 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
virtual const HLAFixedRecordDataType* toFixedRecordDataType() const;
+ virtual void releaseDataTypeReferences();
+
virtual bool decode(HLADecodeStream& stream, HLAAbstractFixedRecordDataElement& value) const;
virtual bool encode(HLAEncodeStream& stream, const HLAAbstractFixedRecordDataElement& value) const;
void addField(const std::string& name, const HLADataType* dataType);
+protected:
+ virtual void _recomputeAlignmentImplementation();
+
private:
struct Field {
Field(const std::string& name, const HLADataType* dataType) :
const HLADataType* getDataType() const
{ return _dataType.get(); }
+ void releaseDataTypeReferences()
+ { _dataType = 0; }
private:
std::string _name;
--- /dev/null
+// 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
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#include "HLAInteractionClass.hxx"
+
+#include <simgear/debug/logstream.hxx>
+
+#include "HLADataElement.hxx"
+#include "HLAFederate.hxx"
+
+#include "RTIInteractionClass.hxx"
+
+namespace simgear {
+
+HLAInteractionClass::HLAInteractionClass(const std::string& name, HLAFederate* federate) :
+ _federate(federate),
+ _rtiInteractionClass(0),
+ _name(name),
+ _subscriptionType(HLAUnsubscribed),
+ _publicationType(HLAUnpublished)
+{
+ if (!federate) {
+ SG_LOG(SG_NETWORK, SG_ALERT, "HLAInteractionClass::HLAInteractionClass(): "
+ "No parent federate given for interaction class \"" << getName() << "\"!");
+ return;
+ }
+ federate->_insertInteractionClass(this);
+}
+
+HLAInteractionClass::~HLAInteractionClass()
+{
+ // HLAInteractionClass objects only get deleted when the parent federate
+ // dies. So we do not need to deregister there.
+
+ _clearRTIInteractionClass();
+}
+
+const std::string&
+HLAInteractionClass::getName() const
+{
+ return _name;
+}
+
+HLASubscriptionType
+HLAInteractionClass::getSubscriptionType() const
+{
+ return _subscriptionType;
+}
+
+void
+HLAInteractionClass::setSubscriptionType(HLASubscriptionType subscriptionType)
+{
+ _subscriptionType = subscriptionType;
+}
+
+HLAPublicationType
+HLAInteractionClass::getPublicationType() const
+{
+ return _publicationType;
+}
+
+void
+HLAInteractionClass::setPublicationType(HLAPublicationType publicationType)
+{
+ _publicationType = publicationType;
+}
+
+unsigned
+HLAInteractionClass::getNumParameters() const
+{
+ return _parameterVector.size();
+}
+
+unsigned
+HLAInteractionClass::addParameter(const std::string& name)
+{
+ unsigned index = _parameterVector.size();
+ _nameIndexMap[name] = index;
+ _parameterVector.push_back(Parameter(name));
+ _resolveParameterIndex(name, index);
+ return index;
+}
+
+unsigned
+HLAInteractionClass::getParameterIndex(const std::string& name) const
+{
+ NameIndexMap::const_iterator i = _nameIndexMap.find(name);
+ if (i == _nameIndexMap.end())
+ return ~0u;
+ return i->second;
+}
+
+std::string
+HLAInteractionClass::getParameterName(unsigned index) const
+{
+ if (_parameterVector.size() <= index)
+ return std::string();
+ return _parameterVector[index]._name;
+}
+
+const HLADataType*
+HLAInteractionClass::getParameterDataType(unsigned index) const
+{
+ if (_parameterVector.size() <= index)
+ return 0;
+ return _parameterVector[index]._dataType.get();
+}
+
+void
+HLAInteractionClass::setParameterDataType(unsigned index, const SGSharedPtr<const HLADataType>& dataType)
+{
+ if (_parameterVector.size() <= index)
+ return;
+ _parameterVector[index]._dataType = dataType;
+}
+
+HLADataElement::IndexPathPair
+HLAInteractionClass::getIndexPathPair(const HLADataElement::StringPathPair& stringPathPair) const
+{
+ unsigned index = getParameterIndex(stringPathPair.first);
+ if (getNumParameters() <= index) {
+ SG_LOG(SG_NETWORK, SG_ALERT, "HLAInteractionClass::getIndexPathPair(\""
+ << HLADataElement::toString(stringPathPair)
+ << "\"): Could not resolve attribute \"" << stringPathPair.first
+ << "\" for interaction class \"" << getName() << "\"!");
+ }
+ return HLADataElement::IndexPathPair(index, stringPathPair.second);
+}
+
+HLADataElement::IndexPathPair
+HLAInteractionClass::getIndexPathPair(const std::string& path) const
+{
+ return getIndexPathPair(HLADataElement::toStringPathPair(path));
+}
+
+bool
+HLAInteractionClass::subscribe()
+{
+ if (!_rtiInteractionClass) {
+ SG_LOG(SG_NETWORK, SG_WARN, "HLAInteractionClass::subscribe(): No RTIInteractionClass!");
+ return false;
+ }
+ switch (_subscriptionType) {
+ case HLAUnsubscribed:
+ return _rtiInteractionClass->unsubscribe();
+ case HLASubscribedActive:
+ return _rtiInteractionClass->subscribe(true);
+ case HLASubscribedPassive:
+ return _rtiInteractionClass->subscribe(false);
+ }
+ return false;
+}
+
+bool
+HLAInteractionClass::unsubscribe()
+{
+ if (!_rtiInteractionClass) {
+ SG_LOG(SG_NETWORK, SG_WARN, "HLAInteractionClass::unsubscribe(): No RTIInteractionClass!");
+ return false;
+ }
+ return _rtiInteractionClass->unsubscribe();
+}
+
+bool
+HLAInteractionClass::publish()
+{
+ if (!_rtiInteractionClass) {
+ SG_LOG(SG_NETWORK, SG_WARN, "HLAInteractionClass::publish(): No RTIInteractionClass\"!");
+ return false;
+ }
+ switch (_publicationType) {
+ case HLAUnpublished:
+ return _rtiInteractionClass->unpublish();
+ case HLAPublished:
+ return _rtiInteractionClass->publish();
+ }
+ return false;
+}
+
+bool
+HLAInteractionClass::unpublish()
+{
+ if (!_rtiInteractionClass) {
+ SG_LOG(SG_NETWORK, SG_WARN, "HLAInteractionClass::unpublish(): No RTIInteractionClass\"!");
+ return false;
+ }
+ return _rtiInteractionClass->unpublish();
+}
+
+void
+HLAInteractionClass::_setRTIInteractionClass(RTIInteractionClass* interactionClass)
+{
+ if (_rtiInteractionClass) {
+ SG_LOG(SG_NETWORK, SG_ALERT, "HLAInteractionClass: Setting RTIInteractionClass twice for interaction class \"" << getName() << "\"!");
+ return;
+ }
+ _rtiInteractionClass = interactionClass;
+ if (_rtiInteractionClass->_interactionClass != this) {
+ SG_LOG(SG_NETWORK, SG_ALERT, "HLAInteractionClass: backward reference does not match!");
+ return;
+ }
+ for (unsigned i = 0; i < _parameterVector.size(); ++i)
+ _resolveParameterIndex(_parameterVector[i]._name, i);
+}
+
+void
+HLAInteractionClass::_resolveParameterIndex(const std::string& name, unsigned index)
+{
+ if (!_rtiInteractionClass)
+ return;
+ if (!_rtiInteractionClass->resolveParameterIndex(name, index))
+ SG_LOG(SG_NETWORK, SG_ALERT, "HLAInteractionClass: Could not resolve parameter \""
+ << name << "\" for interaction class \"" << getName() << "\"!");
+}
+
+void
+HLAInteractionClass::_clearRTIInteractionClass()
+{
+ if (!_rtiInteractionClass)
+ return;
+ _rtiInteractionClass->_interactionClass = 0;
+ _rtiInteractionClass = 0;
+}
+
+} // namespace simgear
-// Copyright (C) 2009 - 2010 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
#ifndef HLAInteractionClass_hxx
#define HLAInteractionClass_hxx
+#include <map>
+#include <string>
+#include <vector>
+
+#include <simgear/structure/SGWeakReferenced.hxx>
+
+#include "HLADataElement.hxx"
+#include "HLADataType.hxx"
+#include "HLATypes.hxx"
+
namespace simgear {
class RTIInteractionClass;
+class HLADataType;
+class HLAFederate;
class HLAInteractionClass : public SGWeakReferenced {
public:
- virtual ~HLAInteractionClass() {}
+ HLAInteractionClass(const std::string& name, HLAFederate* federate);
+ virtual ~HLAInteractionClass();
+
+ const std::string& getName() const;
+
+ HLASubscriptionType getSubscriptionType() const;
+ void setSubscriptionType(HLASubscriptionType subscriptionType);
+
+ HLAPublicationType getPublicationType() const;
+ void setPublicationType(HLAPublicationType publicationType);
+
+ unsigned getNumParameters() const;
+ unsigned addParameter(const std::string& name);
+
+ unsigned getParameterIndex(const std::string& name) const;
+ std::string getParameterName(unsigned index) const;
+
+ const HLADataType* getParameterDataType(unsigned index) const;
+ void setParameterDataType(unsigned index, const SGSharedPtr<const HLADataType>& dataType);
+
+ HLADataElement::IndexPathPair getIndexPathPair(const HLADataElement::StringPathPair& stringPathPair) const;
+ HLADataElement::IndexPathPair getIndexPathPair(const std::string& path) const;
+
+ virtual bool subscribe();
+ virtual bool unsubscribe();
+
+ virtual bool publish();
+ virtual bool unpublish();
private:
HLAInteractionClass(const HLAInteractionClass&);
HLAInteractionClass& operator=(const HLAInteractionClass&);
+
+ void _setRTIInteractionClass(RTIInteractionClass* interactionClass);
+ void _resolveParameterIndex(const std::string& name, unsigned index);
+ void _clearRTIInteractionClass();
+
+ struct Parameter {
+ Parameter() {}
+ Parameter(const std::string& name) : _name(name) {}
+ std::string _name;
+ SGSharedPtr<const HLADataType> _dataType;
+ };
+ typedef std::vector<Parameter> ParameterVector;
+ typedef std::map<std::string,unsigned> NameIndexMap;
+
+ /// The parent federate.
+ SGWeakPtr<HLAFederate> _federate;
+
+ /// The rti class if already instantiated.
+ RTIInteractionClass* _rtiInteractionClass;
+
+ /// The interaction class name
+ std::string _name;
+
+ /// The configured subscription and publication type
+ HLASubscriptionType _subscriptionType;
+ HLAPublicationType _publicationType;
+
+ /// The parameter data
+ ParameterVector _parameterVector;
+ /// The mapping from parameter names to parameter indices
+ NameIndexMap _nameIndexMap;
+
+ friend class HLAFederate;
};
} // namespace simgear
#include "HLABasicDataType.hxx"
#include "HLADataTypeVisitor.hxx"
#include "HLAEnumeratedDataType.hxx"
+#include "HLAFederate.hxx"
#include "HLAFixedRecordDataType.hxx"
#include "HLAVariantRecordDataType.hxx"
return _attributes[index];
}
-const HLAOMTXmlVisitor::Attribute*
-HLAOMTXmlVisitor::ObjectClass::getAttribute(const std::string& name) const
-{
- for (AttributeList::const_iterator i = _attributes.begin(); i != _attributes.end(); ++i) {
- if ((*i)->_name != name)
- continue;
- return i->get();
- }
- SG_LOG(SG_IO, SG_ALERT, "Could not find class attribute \"" << name << "\".");
- return 0;
-}
-
const HLAOMTXmlVisitor::ObjectClass*
HLAOMTXmlVisitor::ObjectClass::getParentObjectClass() const
{
return _dimensions;
}
+const std::string&
+HLAOMTXmlVisitor::InteractionClass::getSharing() const
+{
+ return _sharing;
+}
+
const std::string&
HLAOMTXmlVisitor::InteractionClass::getTransportation() const
{
return _parameters[index];
}
-const HLAOMTXmlVisitor::Parameter*
-HLAOMTXmlVisitor::InteractionClass::getParameter(const std::string& name) const
-{
- for (ParameterList::const_iterator i = _parameters.begin(); i != _parameters.end(); ++i) {
- if ((*i)->_name != name)
- continue;
- return i->get();
- }
- SG_LOG(SG_IO, SG_ALERT, "Could not find parameter \"" << name << "\".");
- return 0;
-}
-
const HLAOMTXmlVisitor::InteractionClass*
HLAOMTXmlVisitor::InteractionClass::getParentInteractionClass() const
{
{
}
-unsigned
-HLAOMTXmlVisitor::getNumObjectClasses() const
-{
- return _objectClassList.size();
+void
+HLAOMTXmlVisitor::setDataTypesToFederate(HLAFederate& federate)
+{
+ // Provide all the data types
+ for (BasicDataMap::iterator i = _basicDataMap.begin(); i != _basicDataMap.end(); ++i)
+ federate.insertDataType(i->first, getDataType(i->first));
+ for (SimpleDataMap::iterator i = _simpleDataMap.begin(); i != _simpleDataMap.end(); ++i)
+ federate.insertDataType(i->first, getDataType(i->first));
+ for (EnumeratedDataMap::iterator i = _enumeratedDataMap.begin(); i != _enumeratedDataMap.end(); ++i)
+ federate.insertDataType(i->first, getDataType(i->first));
+ for (ArrayDataMap::iterator i = _arrayDataMap.begin(); i != _arrayDataMap.end(); ++i)
+ federate.insertDataType(i->first, getDataType(i->first));
+ for (FixedRecordDataMap::iterator i = _fixedRecordDataMap.begin(); i != _fixedRecordDataMap.end(); ++i)
+ federate.insertDataType(i->first, getDataType(i->first));
+ for (VariantRecordDataMap::iterator i = _variantRecordDataMap.begin(); i != _variantRecordDataMap.end(); ++i)
+ federate.insertDataType(i->first, getDataType(i->first));
+
+ // Finish alignment computations
+ federate.recomputeDataTypeAlignment();
}
-const HLAOMTXmlVisitor::ObjectClass*
-HLAOMTXmlVisitor::getObjectClass(unsigned i) const
+void
+HLAOMTXmlVisitor::setToFederate(HLAFederate& federate)
{
- if (_objectClassList.size() <= i)
- return 0;
- return _objectClassList[i];
-}
+ setDataTypesToFederate(federate);
-const HLAOMTXmlVisitor::ObjectClass*
-HLAOMTXmlVisitor::getObjectClass(const std::string& name) const
-{
- for (ObjectClassList::const_iterator i = _objectClassList.begin(); i != _objectClassList.end(); ++i) {
- if ((*i)->_name != name)
+ // Provide all interaction classes
+ unsigned numInteractionClasses = getNumInteractionClasses();
+ for (unsigned i = 0; i < numInteractionClasses; ++i) {
+ const InteractionClass* interactionClass = getInteractionClass(i);
+
+ SGSharedPtr<HLAInteractionClass> hlaInteractionClass;
+ hlaInteractionClass = federate.createInteractionClass(interactionClass->getName());
+ if (!hlaInteractionClass.valid()) {
+ SG_LOG(SG_IO, SG_INFO, "Ignoring Interaction class \"" << interactionClass->getName() << "\".");
continue;
- return i->get();
+ }
+
+ hlaInteractionClass->setSubscriptionType(interactionClass->getSubscriptionType());
+ hlaInteractionClass->setPublicationType(interactionClass->getPublicationType());
+
+ // process the parameters
+ for (unsigned j = 0; j < interactionClass->getNumParameters(); ++j) {
+ const Parameter* parameter = interactionClass->getParameter(j);
+ unsigned index = hlaInteractionClass->addParameter(parameter->getName());
+ hlaInteractionClass->setParameterDataType(index, federate.getDataType(parameter->getDataType()));
+ }
+ }
+
+ // Provide all object classes
+ unsigned numObjectClasses = getNumObjectClasses();
+ for (unsigned i = 0; i < numObjectClasses; ++i) {
+ const ObjectClass* objectClass = getObjectClass(i);
+
+ SGSharedPtr<HLAObjectClass> hlaObjectClass;
+ hlaObjectClass = federate.createObjectClass(objectClass->getName());
+ if (!hlaObjectClass.valid()) {
+ SG_LOG(SG_IO, SG_INFO, "Ignoring Object class \"" << objectClass->getName() << "\".");
+ continue;
+ }
+
+ // process the attributes
+ for (unsigned j = 0; j < objectClass->getNumAttributes(); ++j) {
+ const Attribute* attribute = objectClass->getAttribute(j);
+
+ unsigned index = hlaObjectClass->addAttribute(attribute->getName());
+ hlaObjectClass->setAttributeDataType(index, federate.getDataType(attribute->getDataType()));
+
+ hlaObjectClass->setAttributeSubscriptionType(index, attribute->getSubscriptionType());
+ hlaObjectClass->setAttributePublicationType(index, attribute->getPublicationType());
+ hlaObjectClass->setAttributeUpdateType(index, attribute->getUpdateType());
+ }
}
- SG_LOG(SG_IO, SG_ALERT, "Could not resolve ObjectClass \"" << name << "\".");
- return 0;
}
-const HLAOMTXmlVisitor::Attribute*
-HLAOMTXmlVisitor::getAttribute(const std::string& objectClassName, const std::string& attributeName) const
+unsigned
+HLAOMTXmlVisitor::getNumObjectClasses() const
{
- const ObjectClass* objectClass = getObjectClass(objectClassName);
- if (!objectClass)
- return 0;
- return objectClass->getAttribute(attributeName);
+ return _objectClassList.size();
}
-HLADataType*
-HLAOMTXmlVisitor::getAttributeDataType(const std::string& objectClassName, const std::string& attributeName) const
+const HLAOMTXmlVisitor::ObjectClass*
+HLAOMTXmlVisitor::getObjectClass(unsigned i) const
{
- const Attribute* attribute = getAttribute(objectClassName, attributeName);
- if (!attribute)
+ if (_objectClassList.size() <= i)
return 0;
- return getDataType(attribute->_dataType);
+ return _objectClassList[i];
}
unsigned
return _interactionClassList[i];
}
-const HLAOMTXmlVisitor::InteractionClass*
-HLAOMTXmlVisitor::getInteractionClass(const std::string& name) const
-{
- for (InteractionClassList::const_iterator i = _interactionClassList.begin(); i != _interactionClassList.end(); ++i) {
- if ((*i)->_name != name)
- continue;
- return i->get();
- }
- SG_LOG(SG_IO, SG_ALERT, "Could not resolve InteractionClass \"" << name << "\".");
- return 0;
-}
-
-const HLAOMTXmlVisitor::Parameter*
-HLAOMTXmlVisitor::getParameter(const std::string& interactionClassName, const std::string& parameterName) const
-{
- const InteractionClass* interactionClass = getInteractionClass(interactionClassName);
- if (!interactionClass)
- return 0;
- return interactionClass->getParameter(parameterName);
-}
-
-HLADataType*
-HLAOMTXmlVisitor::getParameterDataType(const std::string& interactionClassName, const std::string& parameterName) const
-{
- const Parameter* parameter = getParameter(interactionClassName, parameterName);
- if (!parameter)
- return 0;
- return getDataType(parameter->_dataType);
-}
-
-HLADataType*
-HLAOMTXmlVisitor::getDataType(const std::string& dataTypeName) const
-{
- SGSharedPtr<HLADataType> dataType;
- {
- // Playing dirty things with reference counts
- StringDataTypeMap dataTypeMap;
- dataType = getDataType(dataTypeName, dataTypeMap);
- }
- return dataType.release();
-}
-
SGSharedPtr<HLADataType>
-HLAOMTXmlVisitor::getDataType(const std::string& dataTypeName, HLAOMTXmlVisitor::StringDataTypeMap& dataTypeMap) const
+HLAOMTXmlVisitor::getDataType(const std::string& dataTypeName)
{
- StringDataTypeMap::const_iterator i = dataTypeMap.find(dataTypeName);
- if (i != dataTypeMap.end())
- return new HLADataTypeReference(i->second);
+ StringDataTypeMap::const_iterator i = _dataTypeMap.find(dataTypeName);
+ if (i != _dataTypeMap.end())
+ return i->second;
SGSharedPtr<HLADataType> dataType;
dataType = getBasicDataType(dataTypeName);
- if (dataType.valid())
+ if (dataType.valid()) {
+ _dataTypeMap[dataTypeName] = dataType;
return dataType;
+ }
dataType = getSimpleDataType(dataTypeName);
if (dataType.valid())
if (dataType.valid())
return dataType;
- dataType = getArrayDataType(dataTypeName, dataTypeMap);
+ dataType = getArrayDataType(dataTypeName);
if (dataType.valid())
return dataType;
- dataType = getFixedRecordDataType(dataTypeName, dataTypeMap);
+ dataType = getFixedRecordDataType(dataTypeName);
if (dataType.valid())
return dataType;
- dataType = getVariantRecordDataType(dataTypeName, dataTypeMap);
+ dataType = getVariantRecordDataType(dataTypeName);
if (dataType.valid())
return dataType;
}
SGSharedPtr<HLABasicDataType>
-HLAOMTXmlVisitor::getBasicDataType(const std::string& dataTypeName) const
+HLAOMTXmlVisitor::getBasicDataType(const std::string& dataTypeName)
{
BasicDataMap::const_iterator i = _basicDataMap.find(dataTypeName);
if (i == _basicDataMap.end())
}
SGSharedPtr<HLADataType>
-HLAOMTXmlVisitor::getSimpleDataType(const std::string& dataTypeName) const
+HLAOMTXmlVisitor::getSimpleDataType(const std::string& dataTypeName)
{
SimpleDataMap::const_iterator i = _simpleDataMap.find(dataTypeName);
if (i == _simpleDataMap.end())
}
SGSharedPtr<HLAEnumeratedDataType>
-HLAOMTXmlVisitor::getEnumeratedDataType(const std::string& dataTypeName) const
+HLAOMTXmlVisitor::getEnumeratedDataType(const std::string& dataTypeName)
{
EnumeratedDataMap::const_iterator i = _enumeratedDataMap.find(dataTypeName);
if (i == _enumeratedDataMap.end())
return 0;
SGSharedPtr<HLAEnumeratedDataType> enumeratedDataType = new HLAEnumeratedDataType(dataTypeName);
+ _dataTypeMap[dataTypeName] = enumeratedDataType;
enumeratedDataType->setRepresentation(getBasicDataType(i->second._representation));
for (EnumeratorList::const_iterator j = i->second._enumeratorList.begin();
}
SGSharedPtr<HLADataType>
-HLAOMTXmlVisitor::getArrayDataType(const std::string& dataTypeName, HLAOMTXmlVisitor::StringDataTypeMap& dataTypeMap) const
+HLAOMTXmlVisitor::getArrayDataType(const std::string& dataTypeName)
{
ArrayDataMap::const_iterator i = _arrayDataMap.find(dataTypeName);
if (i == _arrayDataMap.end())
return 0;
}
- dataTypeMap[dataTypeName] = arrayDataType;
- SGSharedPtr<HLADataType> elementDataType = getDataType(i->second._dataType, dataTypeMap);
+ _dataTypeMap[dataTypeName] = arrayDataType;
+ SGSharedPtr<HLADataType> elementDataType = getDataType(i->second._dataType);
if (!elementDataType.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Could not interpret dataType \""
<< i->second._dataType << "\" for array data type \""
<< dataTypeName << "\".");
- dataTypeMap.erase(dataTypeName);
+ _dataTypeMap.erase(dataTypeName);
return 0;
}
arrayDataType->setElementDataType(elementDataType.get());
}
SGSharedPtr<HLAFixedRecordDataType>
-HLAOMTXmlVisitor::getFixedRecordDataType(const std::string& dataTypeName, HLAOMTXmlVisitor::StringDataTypeMap& dataTypeMap) const
+HLAOMTXmlVisitor::getFixedRecordDataType(const std::string& dataTypeName)
{
FixedRecordDataMap::const_iterator i = _fixedRecordDataMap.find(dataTypeName);
if (i == _fixedRecordDataMap.end())
return 0;
SGSharedPtr<HLAFixedRecordDataType> dataType = new HLAFixedRecordDataType(dataTypeName);
- dataTypeMap[dataTypeName] = dataType;
+ _dataTypeMap[dataTypeName] = dataType;
for (FieldList::size_type j = 0; j < i->second._fieldList.size(); ++j) {
- SGSharedPtr<HLADataType> fieldDataType = getDataType(i->second._fieldList[j]._dataType, dataTypeMap);
+ SGSharedPtr<HLADataType> fieldDataType = getDataType(i->second._fieldList[j]._dataType);
if (!fieldDataType.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Could not get data type \"" << i->second._fieldList[j]._dataType
<< "\" for field " << j << "of fixed record data type \"" << dataTypeName << "\".");
- dataTypeMap.erase(dataTypeName);
+ _dataTypeMap.erase(dataTypeName);
return 0;
}
dataType->addField(i->second._fieldList[j]._name, fieldDataType.get());
}
SGSharedPtr<HLAVariantRecordDataType>
-HLAOMTXmlVisitor::getVariantRecordDataType(const std::string& dataTypeName, HLAOMTXmlVisitor::StringDataTypeMap& dataTypeMap) const
+HLAOMTXmlVisitor::getVariantRecordDataType(const std::string& dataTypeName)
{
VariantRecordDataMap::const_iterator i = _variantRecordDataMap.find(dataTypeName);
if (i == _variantRecordDataMap.end())
return 0;
SGSharedPtr<HLAVariantRecordDataType> dataType = new HLAVariantRecordDataType(dataTypeName);
- dataTypeMap[dataTypeName] = dataType;
+ _dataTypeMap[dataTypeName] = dataType;
SGSharedPtr<HLAEnumeratedDataType> enumeratedDataType = getEnumeratedDataType(i->second._dataType);
if (!enumeratedDataType.valid()) {
for (AlternativeList::const_iterator j = i->second._alternativeList.begin();
j != i->second._alternativeList.end(); ++j) {
- SGSharedPtr<HLADataType> alternativeDataType = getDataType(j->_dataType, dataTypeMap);
+ SGSharedPtr<HLADataType> alternativeDataType = getDataType(j->_dataType);
if (!alternativeDataType.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Could not resolve alternative dataType \"" << j->_dataType
<< "\" for alternative \"" << j->_name << "\".");
- dataTypeMap.erase(dataTypeName);
+ _dataTypeMap.erase(dataTypeName);
return 0;
}
if (!dataType->addAlternative(j->_name, j->_enumerator, alternativeDataType.get(), j->_semantics)) {
throw sg_exception("Internal parse error!");
// propagate parent attributes to the derived classes
+ // Note that this preserves the order og the attributes starting from the root object
for (ObjectClassList::const_iterator i = _objectClassList.begin(); i != _objectClassList.end(); ++i) {
SGSharedPtr<const ObjectClass> objectClass = (*i)->_parentObjectClass;
while (objectClass) {
}
// propagate parent parameter to the derived interactions
+ // Note that this preserves the order og the parameters starting from the root object
for (InteractionClassList::const_iterator i = _interactionClassList.begin(); i != _interactionClassList.end(); ++i) {
SGSharedPtr<const InteractionClass> interactionClass = (*i)->_parentInteractionClass;
while (interactionClass) {
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/xml/easyxml.hxx>
#include "HLADataType.hxx"
+#include "HLATypes.hxx"
namespace simgear {
+class HLAFederate;
+
class HLAOMTXmlVisitor : public XMLVisitor {
public:
/// structures representing the federate object model data
{ }
const std::string& getName() const
{ return _name; }
+ const std::string& getDataType() const
+ { return _dataType; }
+ const std::string& getSharing() const
+ { return _sharing; }
const std::string& getDimensions() const
{ return _dimensions; }
const std::string& getTransportation() const
const std::string& getOrder() const
{ return _order; }
+ HLASubscriptionType getSubscriptionType() const
+ {
+ if (_sharing.find("Subscribe") != std::string::npos)
+ return HLASubscribedActive;
+ else
+ return HLAUnsubscribed;
+ }
+
+ HLAPublicationType getPublicationType() const
+ {
+ if (_sharing.find("Publish") != std::string::npos)
+ return HLAPublished;
+ else
+ return HLAUnpublished;
+ }
+
+ HLAUpdateType getUpdateType() const
+ {
+ if (_updateType == "Periodic")
+ return HLAPeriodicUpdate;
+ else if (_updateType == "Static")
+ return HLAStaticUpdate;
+ else if (_updateType == "Conditional")
+ return HLAConditionalUpdate;
+ else
+ return HLAUndefinedUpdate;
+ }
+
std::string _name;
std::string _dataType;
std::string _updateType;
unsigned getNumAttributes() const;
const Attribute* getAttribute(unsigned index) const;
- const Attribute* getAttribute(const std::string& name) const;
const ObjectClass* getParentObjectClass() const;
const std::string& getName() const;
const std::string& getDimensions() const;
+ const std::string& getSharing() const;
const std::string& getTransportation() const;
const std::string& getOrder() const;
+ HLASubscriptionType getSubscriptionType() const
+ {
+ if (_sharing.find("Subscribe") != std::string::npos)
+ return HLASubscribedActive;
+ else
+ return HLAUnsubscribed;
+ }
+
+ HLAPublicationType getPublicationType() const
+ {
+ if (_sharing.find("Publish") != std::string::npos)
+ return HLAPublished;
+ else
+ return HLAUnpublished;
+ }
+
unsigned getNumParameters() const;
const Parameter* getParameter(unsigned index) const;
- const Parameter* getParameter(const std::string& name) const;
const InteractionClass* getParentInteractionClass() const;
friend class HLAOMTXmlVisitor;
std::string _name;
std::string _dimensions;
+ std::string _sharing;
std::string _transportation;
std::string _order;
ParameterList _parameters;
HLAOMTXmlVisitor();
~HLAOMTXmlVisitor();
+ void setDataTypesToFederate(HLAFederate& federate);
+ void setToFederate(HLAFederate& federate);
+
unsigned getNumObjectClasses() const;
const ObjectClass* getObjectClass(unsigned i) const;
- const ObjectClass* getObjectClass(const std::string& name) const;
-
- /// Return the data type from the fom data
- const Attribute* getAttribute(const std::string& objectClassName, const std::string& attributeName) const;
- /// Return the data type from the fom data
- HLADataType* getAttributeDataType(const std::string& objectClassName, const std::string& attributeName) const;
unsigned getNumInteractionClasses() const;
const InteractionClass* getInteractionClass(unsigned i) const;
- const InteractionClass* getInteractionClass(const std::string& name) const;
-
- /// Return the data type from the fom data
- const Parameter* getParameter(const std::string& interactionClassName, const std::string& parameterName) const;
-
- /// Return the data type from the fom data
- HLADataType* getParameterDataType(const std::string& interactionClassName, const std::string& parameterName) const;
-
- HLADataType* getDataType(const std::string& dataTypeName) const;
private:
- typedef std::map<std::string, SGSharedPtr<HLADataType> > StringDataTypeMap;
- SGSharedPtr<HLADataType> getDataType(const std::string& dataTypeName, StringDataTypeMap& dataTypeMap) const;
- SGSharedPtr<HLABasicDataType> getBasicDataType(const std::string& dataTypeName) const;
- SGSharedPtr<HLADataType> getSimpleDataType(const std::string& dataTypeName) const;
- SGSharedPtr<HLAEnumeratedDataType> getEnumeratedDataType(const std::string& dataTypeName) const;
- SGSharedPtr<HLADataType> getArrayDataType(const std::string& dataTypeName, StringDataTypeMap& dataTypeMap) const;
- SGSharedPtr<HLAFixedRecordDataType> getFixedRecordDataType(const std::string& dataTypeName, StringDataTypeMap& dataTypeMap) const;
- SGSharedPtr<HLAVariantRecordDataType> getVariantRecordDataType(const std::string& dataTypeName, StringDataTypeMap& dataTypeMap) const;
+ SGSharedPtr<HLADataType> getDataType(const std::string& dataTypeName);
+ SGSharedPtr<HLABasicDataType> getBasicDataType(const std::string& dataTypeName);
+ SGSharedPtr<HLADataType> getSimpleDataType(const std::string& dataTypeName);
+ SGSharedPtr<HLAEnumeratedDataType> getEnumeratedDataType(const std::string& dataTypeName);
+ SGSharedPtr<HLADataType> getArrayDataType(const std::string& dataTypeName);
+ SGSharedPtr<HLAFixedRecordDataType> getFixedRecordDataType(const std::string& dataTypeName);
+ SGSharedPtr<HLAVariantRecordDataType> getVariantRecordDataType(const std::string& dataTypeName);
enum Mode {
UnknownMode,
virtual void startElement(const char* name, const XMLAttributes& atts);
virtual void endElement(const char* name);
- std::string getAttribute(const char* name, const XMLAttributes& atts);
- std::string getAttribute(const std::string& name, const XMLAttributes& atts);
+ static std::string getAttribute(const char* name, const XMLAttributes& atts);
+ static std::string getAttribute(const std::string& name, const XMLAttributes& atts);
struct BasicData {
// std::string _name;
InteractionClassList _interactionClassList;
InteractionClassList _interactionClassStack;
+ typedef std::map<std::string, SGSharedPtr<HLADataType> > StringDataTypeMap;
+ StringDataTypeMap _dataTypeMap;
+
/// DataType definitions
BasicDataMap _basicDataMap;
SimpleDataMap _simpleDataMap;
-// Copyright (C) 2009 - 2010 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
#include "HLAObjectClass.hxx"
+#include "simgear/debug/logstream.hxx"
#include "RTIFederate.hxx"
#include "RTIObjectClass.hxx"
#include "RTIObjectInstance.hxx"
{
}
-HLAObjectClass::HLAObjectClass(const std::string& name, HLAFederate& federate) :
+HLAObjectClass::HLAObjectClass(const std::string& name, HLAFederate* federate) :
+ _federate(federate),
_name(name)
{
- _rtiObjectClass = federate._rtiFederate->createObjectClass(name, this);
- if (!_rtiObjectClass.valid())
- SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::HLAObjectClass(): No RTIObjectClass found for \"" << name << "\"!");
+ if (!federate) {
+ SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass::HLAObjectClass(): "
+ "No parent federate given for object class \"" << getName() << "\"!");
+ return;
+ }
+ federate->_insertObjectClass(this);
}
HLAObjectClass::~HLAObjectClass()
{
+ // HLAObjectClass objects only get deleted when the parent federate
+ // dies. So we do not need to deregister there.
+
+ _clearRTIObjectClass();
+}
+
+const std::string&
+HLAObjectClass::getName() const
+{
+ return _name;
}
unsigned
HLAObjectClass::getNumAttributes() const
{
- if (!_rtiObjectClass.valid()) {
- SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::getAttributeIndex(): No RTIObject class for object class \"" << getName() << "\"!");
- return 0;
- }
- return _rtiObjectClass->getNumAttributes();
+ return _attributeVector.size();
+}
+
+unsigned
+HLAObjectClass::addAttribute(const std::string& name)
+{
+ unsigned index = _attributeVector.size();
+ _nameIndexMap[name] = index;
+ _attributeVector.push_back(Attribute(name));
+ _resolveAttributeIndex(name, index);
+ return index;
}
unsigned
HLAObjectClass::getAttributeIndex(const std::string& name) const
{
- if (!_rtiObjectClass.valid()) {
- SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::getAttributeIndex(): No RTIObject class for object class \"" << getName() << "\"!");
+ NameIndexMap::const_iterator i = _nameIndexMap.find(name);
+ if (i == _nameIndexMap.end())
return ~0u;
- }
- return _rtiObjectClass->getOrCreateAttributeIndex(name);
+ return i->second;
}
std::string
HLAObjectClass::getAttributeName(unsigned index) const
{
- if (!_rtiObjectClass.valid()) {
- SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::getAttributeIndex(): No RTIObject class for object class \"" << getName() << "\"!");
- return 0;
- }
- return _rtiObjectClass->getAttributeName(index);
+ if (_attributeVector.size() <= index)
+ return std::string();
+ return _attributeVector[index]._name;
}
const HLADataType*
HLAObjectClass::getAttributeDataType(unsigned index) const
{
- if (!_rtiObjectClass.valid()) {
- SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::getAttributeDataType(): No RTIObject class for object class \"" << getName() << "\"!");
+ if (_attributeVector.size() <= index)
return 0;
- }
- return _rtiObjectClass->getAttributeDataType(index);
+ return _attributeVector[index]._dataType.get();
}
void
HLAObjectClass::setAttributeDataType(unsigned index, const HLADataType* dataType)
{
- if (!_rtiObjectClass.valid()) {
- SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::setAttributeDataType(): No RTIObject class for object class \"" << getName() << "\"!");
+ if (_attributeVector.size() <= index)
return;
- }
- _rtiObjectClass->setAttributeDataType(index, dataType);
+ _attributeVector[index]._dataType = dataType;
}
HLAUpdateType
HLAObjectClass::getAttributeUpdateType(unsigned index) const
{
- if (!_rtiObjectClass.valid()) {
- SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::getAttributeUpdateType(): No RTIObject class for object class \"" << getName() << "\"!");
+ if (_attributeVector.size() <= index)
return HLAUndefinedUpdate;
- }
- return _rtiObjectClass->getAttributeUpdateType(index);
+ return _attributeVector[index]._updateType;
}
void
HLAObjectClass::setAttributeUpdateType(unsigned index, HLAUpdateType updateType)
{
- if (!_rtiObjectClass.valid()) {
- SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::setAttributeUpdateType(): "
- "No RTIObject class for object class \"" << getName() << "\"!");
+ if (_attributeVector.size() <= index)
return;
- }
- _rtiObjectClass->setAttributeUpdateType(index, updateType);
+ _attributeVector[index]._updateType = updateType;
+}
+
+HLASubscriptionType
+HLAObjectClass::getAttributeSubscriptionType(unsigned index) const
+{
+ if (_attributeVector.size() <= index)
+ return HLAUnsubscribed;
+ return _attributeVector[index]._subscriptionType;
+}
+
+void
+HLAObjectClass::setAttributeSubscriptionType(unsigned index, HLASubscriptionType subscriptionType)
+{
+ if (_attributeVector.size() <= index)
+ return;
+ _attributeVector[index]._subscriptionType = subscriptionType;
+}
+
+HLAPublicationType
+HLAObjectClass::getAttributePublicationType(unsigned index) const
+{
+ if (_attributeVector.size() <= index)
+ return HLAUnpublished;
+ return _attributeVector[index]._publicationType;
+}
+
+void
+HLAObjectClass::setAttributePublicationType(unsigned index, HLAPublicationType publicationType)
+{
+ if (_attributeVector.size() <= index)
+ return;
+ _attributeVector[index]._publicationType = publicationType;
}
HLADataElement::IndexPathPair
}
bool
-HLAObjectClass::subscribe(const std::set<unsigned>& indexSet, bool active)
+HLAObjectClass::subscribe()
{
if (!_rtiObjectClass.valid()) {
- SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::subscribe(): No RTIObject class for object class \"" << getName() << "\"!");
+ SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::subscribe(): "
+ "No RTIObject class for object class \"" << getName() << "\"!");
return false;
}
- return _rtiObjectClass->subscribe(indexSet, active);
+
+ HLAIndexList indexList;
+ for (unsigned i = 1; i < getNumAttributes(); ++i) {
+ if (_attributeVector[i]._subscriptionType != HLASubscribedActive)
+ continue;
+ indexList.push_back(i);
+ }
+ if (!indexList.empty()) {
+ if (!_rtiObjectClass->subscribe(indexList, true))
+ return false;
+ }
+
+ indexList.clear();
+ for (unsigned i = 1; i < getNumAttributes(); ++i) {
+ if (_attributeVector[i]._subscriptionType != HLASubscribedPassive)
+ continue;
+ indexList.push_back(i);
+ }
+ if (!indexList.empty()) {
+ if (!_rtiObjectClass->subscribe(indexList, false))
+ return false;
+ }
+ return true;
}
bool
HLAObjectClass::unsubscribe()
{
if (!_rtiObjectClass.valid()) {
- SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::unsubscribe(): No RTIObject class for object class \"" << getName() << "\"!");
+ SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::unsubscribe(): "
+ "No RTIObject class for object class \"" << getName() << "\"!");
return false;
}
return _rtiObjectClass->unsubscribe();
}
bool
-HLAObjectClass::publish(const std::set<unsigned>& indexSet)
+HLAObjectClass::publish()
{
if (!_rtiObjectClass.valid()) {
- SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::publish(): No RTIObject class for object class \"" << getName() << "\"!");
+ SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::publish(): "
+ "No RTIObject class for object class \"" << getName() << "\"!");
return false;
}
- return _rtiObjectClass->publish(indexSet);
+
+ HLAIndexList indexList;
+ for (unsigned i = 1; i < getNumAttributes(); ++i) {
+ if (_attributeVector[i]._publicationType == HLAUnpublished)
+ continue;
+ indexList.push_back(i);
+ }
+ if (indexList.empty())
+ return true;
+ if (!_rtiObjectClass->publish(indexList))
+ return false;
+ return true;
}
bool
HLAObjectClass::unpublish()
{
if (!_rtiObjectClass.valid()) {
- SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::unpublish(): No RTIObject class for object class \"" << getName() << "\"!");
+ SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::unpublish(): "
+ "No RTIObject class for object class \"" << getName() << "\"!");
return false;
}
return _rtiObjectClass->unpublish();
}
HLAObjectInstance*
-HLAObjectClass::createObjectInstance(RTIObjectInstance* rtiObjectInstance)
+HLAObjectClass::createObjectInstance(const std::string& name)
{
- return new HLAObjectInstance(this, rtiObjectInstance);
+ HLAObjectInstance* objectInstance = createObjectInstance();
+ if (objectInstance)
+ return objectInstance;
+ SGSharedPtr<HLAFederate> federate = _federate.lock();
+ if (!federate.valid())
+ return 0;
+ return federate->createObjectInstance(this, name);
}
-void
-HLAObjectClass::discoverInstance(RTIObjectInstance* objectInstance, const RTIData& tag)
-{
- SGSharedPtr<HLAObjectInstance> hlaObjectInstance = createObjectInstance(objectInstance);
- if (hlaObjectInstance.valid()) {
- SG_LOG(SG_NETWORK, SG_INFO, "RTI: create new object instance for discovered \""
- << hlaObjectInstance->getName() << "\" object");
- _objectInstanceSet.insert(hlaObjectInstance);
- discoverInstanceCallback(*hlaObjectInstance, tag);
- } else {
- SG_LOG(SG_NETWORK, SG_INFO, "RTI: local delete of \"" << objectInstance->getName() << "\"");
- objectInstance->localDeleteObjectInstance();
- }
+HLAObjectInstance*
+HLAObjectClass::createObjectInstance()
+{
+ return 0;
}
void
-HLAObjectClass::removeInstance(HLAObjectInstance& hlaObjectInstance, const RTIData& tag)
+HLAObjectClass::_setRTIObjectClass(RTIObjectClass* objectClass)
{
- SG_LOG(SG_NETWORK, SG_INFO, "RTI: remove object instance \"" << hlaObjectInstance.getName() << "\"");
- removeInstanceCallback(hlaObjectInstance, tag);
- _objectInstanceSet.erase(&hlaObjectInstance);
+ if (_rtiObjectClass) {
+ SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: Setting RTIObjectClass twice for object class \"" << getName() << "\"!");
+ return;
+ }
+ _rtiObjectClass = objectClass;
+ if (_rtiObjectClass->_objectClass != this) {
+ SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: backward reference does not match!");
+ return;
+ }
+ for (unsigned i = 0; i < _attributeVector.size(); ++i)
+ _resolveAttributeIndex(_attributeVector[i]._name, i);
}
void
-HLAObjectClass::registerInstance(HLAObjectInstance& objectInstance)
+HLAObjectClass::_resolveAttributeIndex(const std::string& name, unsigned index)
{
- _objectInstanceSet.insert(&objectInstance);
- registerInstanceCallback(objectInstance);
+ if (!_rtiObjectClass)
+ return;
+ if (!_rtiObjectClass->resolveAttributeIndex(name, index))
+ SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: Could not resolve attribute \""
+ << name << "\" for object class \"" << getName() << "\"!");
}
void
-HLAObjectClass::deleteInstance(HLAObjectInstance& objectInstance)
+HLAObjectClass::_clearRTIObjectClass()
{
- deleteInstanceCallback(objectInstance);
- _objectInstanceSet.erase(&objectInstance);
+ if (!_rtiObjectClass.valid())
+ return;
+ _rtiObjectClass->_objectClass = 0;
+ _rtiObjectClass = 0;
}
void
-HLAObjectClass::discoverInstanceCallback(HLAObjectInstance& objectInstance, const RTIData& tag) const
+HLAObjectClass::_discoverInstance(RTIObjectInstance* rtiObjectInstance, const RTIData& tag)
{
- if (!_instanceCallback.valid())
+ SGSharedPtr<HLAFederate> federate = _federate.lock();
+ if (!federate.valid()) {
+ SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not find parent federate while discovering object instance");
+ return;
+ }
+
+ SGSharedPtr<HLAObjectInstance> objectInstance = createObjectInstance(rtiObjectInstance->getName());
+ if (!objectInstance.valid()) {
+ SG_LOG(SG_NETWORK, SG_INFO, "RTI: could not create new object instance for discovered \""
+ << rtiObjectInstance->getName() << "\" object");
+ return;
+ }
+ SG_LOG(SG_NETWORK, SG_INFO, "RTI: create new object instance for discovered \""
+ << rtiObjectInstance->getName() << "\" object");
+ objectInstance->_setRTIObjectInstance(rtiObjectInstance);
+ if (!federate->_insertObjectInstance(objectInstance)) {
+ SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not insert new object instance for discovered \""
+ << rtiObjectInstance->getName() << "\" object");
return;
- _instanceCallback->discoverInstance(*this, objectInstance, tag);
+ }
+ if (_instanceCallback.valid())
+ _instanceCallback->discoverInstance(*this, *objectInstance, tag);
}
void
-HLAObjectClass::removeInstanceCallback(HLAObjectInstance& objectInstance, const RTIData& tag) const
+HLAObjectClass::_removeInstance(HLAObjectInstance& objectInstance, const RTIData& tag)
{
- if (!_instanceCallback.valid())
+ SGSharedPtr<HLAFederate> federate = _federate.lock();
+ if (!federate.valid()) {
+ SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not find parent federate while removing object instance");
return;
- _instanceCallback->removeInstance(*this, objectInstance, tag);
+ }
+ SG_LOG(SG_NETWORK, SG_INFO, "RTI: remove object instance \"" << objectInstance.getName() << "\"");
+ if (_instanceCallback.valid())
+ _instanceCallback->removeInstance(*this, objectInstance, tag);
+ federate->_eraseObjectInstance(objectInstance.getName());
}
void
-HLAObjectClass::registerInstanceCallback(HLAObjectInstance& objectInstance) const
+HLAObjectClass::_registerInstance(HLAObjectInstance* objectInstance)
{
- if (!_instanceCallback.valid())
+ SGSharedPtr<HLAFederate> federate = _federate.lock();
+ if (!federate.valid()) {
+ SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not find parent federate while registering object instance");
return;
- _instanceCallback->registerInstance(*this, objectInstance);
+ }
+ if (!objectInstance)
+ return;
+ // We can only register object instances with a valid name at the rti.
+ // So, we cannot do that at HLAObjectInstance creation time.
+ if (!federate->_insertObjectInstance(objectInstance)) {
+ SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not insert new object instance \""
+ << objectInstance->getName() << "\" object");
+ return;
+ }
+ if (_instanceCallback.valid())
+ _instanceCallback->registerInstance(*this, *objectInstance);
}
void
-HLAObjectClass::deleteInstanceCallback(HLAObjectInstance& objectInstance) const
+HLAObjectClass::_deleteInstance(HLAObjectInstance& objectInstance)
{
- if (!_instanceCallback.valid())
+ SGSharedPtr<HLAFederate> federate = _federate.lock();
+ if (!federate.valid()) {
+ SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not find parent federate while deleting object instance");
return;
- _instanceCallback->deleteInstance(*this, objectInstance);
+ }
+ if (_instanceCallback.valid())
+ _instanceCallback->deleteInstance(*this, objectInstance);
+ federate->_eraseObjectInstance(objectInstance.getName());
}
void
-HLAObjectClass::startRegistrationCallback()
+HLAObjectClass::_startRegistration()
{
if (_registrationCallback.valid())
_registrationCallback->startRegistration(*this);
}
void
-HLAObjectClass::stopRegistrationCallback()
+HLAObjectClass::_stopRegistration()
{
if (_registrationCallback.valid())
_registrationCallback->stopRegistration(*this);
-// Copyright (C) 2009 - 2010 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
#ifndef HLAObjectClass_hxx
#define HLAObjectClass_hxx
-#include <set>
#include <string>
#include <vector>
class HLAObjectClass : public SGWeakReferenced {
public:
- HLAObjectClass(const std::string& name, HLAFederate& federate);
+ HLAObjectClass(const std::string& name, HLAFederate* federate);
virtual ~HLAObjectClass();
- const std::string& getName() const
- { return _name; }
+ /// Return the name of this object class
+ const std::string& getName() const;
+ /// Return the number of attributes in this object class
unsigned getNumAttributes() const;
+
+ /// Adds a new attribute to this object class, return the index
+ unsigned addAttribute(const std::string& name);
+
+ /// Return the attribute index for the attribute with the given name
unsigned getAttributeIndex(const std::string& name) const;
+ /// Return the attribute name for the attribute with the given index
std::string getAttributeName(unsigned index) const;
+ /// Return the data type of the attribute with the given index
const HLADataType* getAttributeDataType(unsigned index) const;
- void setAttributeDataType(unsigned index, const HLADataType*);
+ /// Sets the data type of the attribute with the given index to dataType
+ void setAttributeDataType(unsigned index, const HLADataType* dataType);
+ /// Return the update type of the attribute with the given index
HLAUpdateType getAttributeUpdateType(unsigned index) const;
+ /// Sets the update type of the attribute with the given index to updateType
void setAttributeUpdateType(unsigned index, HLAUpdateType updateType);
+ /// Return the subscription type of the attribute with the given index
+ HLASubscriptionType getAttributeSubscriptionType(unsigned index) const;
+ /// Sets the subscription type of the attribute with the given index to subscriptionType
+ void setAttributeSubscriptionType(unsigned index, HLASubscriptionType subscriptionType);
+
+ /// Return the publication type of the attribute with the given index
+ HLAPublicationType getAttributePublicationType(unsigned index) const;
+ /// Sets the publication type of the attribute with the given index to publicationType
+ void setAttributePublicationType(unsigned index, HLAPublicationType publicationType);
+
+ /// Return the index, path pair for the given string path pair
HLADataElement::IndexPathPair getIndexPathPair(const HLADataElement::StringPathPair&) const;
+ /// Return the index, path pair for the given string path
HLADataElement::IndexPathPair getIndexPathPair(const std::string& path) const;
- bool subscribe(const std::set<unsigned>& indexSet, bool active);
- bool unsubscribe();
+ virtual bool subscribe();
+ virtual bool unsubscribe();
- bool publish(const std::set<unsigned>& indexSet);
- bool unpublish();
+ virtual bool publish();
+ virtual bool unpublish();
// Object instance creation and destruction
class InstanceCallback : public SGReferenced {
const SGSharedPtr<InstanceCallback>& getInstanceCallback() const
{ return _instanceCallback; }
+ // Is called by the default registration callback if installed
+ // Should register the already known object instances of this class.
+ virtual void startRegistration() const;
+ virtual void stopRegistration() const;
+
// Handles startRegistrationForObjectClass and stopRegistrationForObjectClass events
class RegistrationCallback : public SGReferenced {
public:
const SGSharedPtr<RegistrationCallback>& getRegistrationCallback() const
{ return _registrationCallback; }
- // Is called by the default registration callback if installed
- void startRegistration() const;
- void stopRegistration() const;
-
-protected:
- virtual HLAObjectInstance* createObjectInstance(RTIObjectInstance* rtiObjectInstance);
+ /// Create a new instance of this class.
+ virtual HLAObjectInstance* createObjectInstance(const std::string& name);
+ virtual HLAObjectInstance* createObjectInstance(); // deprecated
private:
HLAObjectClass(const HLAObjectClass&);
HLAObjectClass& operator=(const HLAObjectClass&);
+ void _setRTIObjectClass(RTIObjectClass* objectClass);
+ void _resolveAttributeIndex(const std::string& name, unsigned index);
+ void _clearRTIObjectClass();
+
// The internal entry points from the RTILObjectClass callback functions
- void discoverInstance(RTIObjectInstance* objectInstance, const RTIData& tag);
- void removeInstance(HLAObjectInstance& objectInstance, const RTIData& tag);
- void registerInstance(HLAObjectInstance& objectInstance);
- void deleteInstance(HLAObjectInstance& objectInstance);
-
- void discoverInstanceCallback(HLAObjectInstance& objectInstance, const RTIData& tag) const;
- void removeInstanceCallback(HLAObjectInstance& objectInstance, const RTIData& tag) const;
- void registerInstanceCallback(HLAObjectInstance& objectInstance) const;
- void deleteInstanceCallback(HLAObjectInstance& objectInstance) const;
-
- void startRegistrationCallback();
- void stopRegistrationCallback();
+ void _discoverInstance(RTIObjectInstance* objectInstance, const RTIData& tag);
+ void _removeInstance(HLAObjectInstance& objectInstance, const RTIData& tag);
+ void _registerInstance(HLAObjectInstance* objectInstance);
+ void _deleteInstance(HLAObjectInstance& objectInstance);
+
+ void _startRegistration();
+ void _stopRegistration();
+
friend class HLAObjectInstance;
friend class RTIObjectClass;
- // The object class name
+ struct Attribute {
+ Attribute() : _subscriptionType(HLAUnsubscribed), _publicationType(HLAUnpublished), _updateType(HLAUndefinedUpdate) {}
+ Attribute(const std::string& name) : _name(name), _subscriptionType(HLAUnsubscribed), _publicationType(HLAUnpublished), _updateType(HLAUndefinedUpdate) {}
+ std::string _name;
+ SGSharedPtr<const HLADataType> _dataType;
+ HLASubscriptionType _subscriptionType;
+ HLAPublicationType _publicationType;
+ HLAUpdateType _updateType;
+ };
+ typedef std::vector<Attribute> AttributeVector;
+ typedef std::map<std::string,unsigned> NameIndexMap;
+
+ /// The parent federate.
+ SGWeakPtr<HLAFederate> _federate;
+
+ /// The object class name
std::string _name;
- // The underlying rti dispatcher class
+ /// The underlying rti dispatcher class
SGSharedPtr<RTIObjectClass> _rtiObjectClass;
+ /// The attribute data
+ AttributeVector _attributeVector;
+ /// The mapping from attribute names to attribute indices
+ NameIndexMap _nameIndexMap;
+
// Callback classes
SGSharedPtr<InstanceCallback> _instanceCallback;
SGSharedPtr<RegistrationCallback> _registrationCallback;
- // The set of active objects
- typedef std::set<SGSharedPtr<HLAObjectInstance> > ObjectInstanceSet;
- ObjectInstanceSet _objectInstanceSet;
+ friend class HLAFederate;
};
} // namespace simgear
#include "HLAObjectInstance.hxx"
#include <algorithm>
+#include "simgear/debug/logstream.hxx"
#include "HLAArrayDataElement.hxx"
#include "HLABasicDataElement.hxx"
#include "HLADataElement.hxx"
#include "HLAEnumeratedDataElement.hxx"
+#include "HLAFederate.hxx"
#include "HLAFixedRecordDataElement.hxx"
#include "HLAObjectClass.hxx"
#include "HLAVariantRecordDataElement.hxx"
namespace simgear {
-HLAObjectInstance::HLAObjectInstance(HLAObjectClass* objectClass) :
- _objectClass(objectClass)
+HLAObjectInstance::UpdateCallback::~UpdateCallback()
{
}
-HLAObjectInstance::HLAObjectInstance(HLAObjectClass* objectClass, RTIObjectInstance* rtiObjectInstance) :
- _objectClass(objectClass),
- _rtiObjectInstance(rtiObjectInstance)
+HLAObjectInstance::ReflectCallback::~ReflectCallback()
{
- _rtiObjectInstance->_hlaObjectInstance = this;
- _name = _rtiObjectInstance->getName();
}
-HLAObjectInstance::~HLAObjectInstance()
+HLAObjectInstance::HLAObjectInstance(HLAObjectClass* objectClass) :
+ _federate(objectClass->_federate),
+ _objectClass(objectClass)
{
}
-SGSharedPtr<HLAObjectClass>
-HLAObjectInstance::getObjectClass() const
+HLAObjectInstance::~HLAObjectInstance()
{
- return _objectClass.lock();
+ _clearRTIObjectInstance();
}
unsigned
HLAObjectInstance::getNumAttributes() const
{
- if (!_rtiObjectInstance.valid()) {
- SG_LOG(SG_IO, SG_ALERT, "Trying to get number of attributes for inactive object!");
- return 0;
- }
- return _rtiObjectInstance->getNumAttributes();
+ return _objectClass->getNumAttributes();
}
unsigned
HLAObjectInstance::getAttributeIndex(const std::string& name) const
{
- if (!_rtiObjectInstance.valid()) {
- SG_LOG(SG_IO, SG_ALERT, "Trying to get attribute index for inactive object!");
- return 0;
- }
- return _rtiObjectInstance->getAttributeIndex(name);
+ return _objectClass->getAttributeIndex(name);
}
std::string
HLAObjectInstance::getAttributeName(unsigned index) const
{
- if (!_rtiObjectInstance.valid()) {
- SG_LOG(SG_IO, SG_ALERT, "Trying to get attribute name for inactive object!");
- return std::string();
- }
- return _rtiObjectInstance->getAttributeName(index);
+ return _objectClass->getAttributeName(index);
}
-const HLADataType*
-HLAObjectInstance::getAttributeDataType(unsigned index) const
+bool
+HLAObjectInstance::getAttributeOwned(unsigned index) const
{
- if (!_rtiObjectInstance.valid()) {
- SG_LOG(SG_IO, SG_ALERT, "Trying to get attribute index for inactive object!");
- return 0;
- }
- return _rtiObjectInstance->getAttributeDataType(index);
+ if (!_rtiObjectInstance.valid())
+ return false;
+ return _rtiObjectInstance->getAttributeOwned(index);
}
-void
-HLAObjectInstance::setAttributeDataElement(unsigned index, SGSharedPtr<HLADataElement> dataElement)
+const HLADataType*
+HLAObjectInstance::getAttributeDataType(unsigned index) const
{
- if (!_rtiObjectInstance.valid()) {
- SG_LOG(SG_IO, SG_ALERT, "Trying to set data element for inactive object!");
- return;
- }
- _rtiObjectInstance->setDataElement(index, dataElement);
+ return _objectClass->getAttributeDataType(index);
}
HLADataElement*
HLAObjectInstance::getAttributeDataElement(unsigned index)
{
- if (!_rtiObjectInstance.valid()) {
- SG_LOG(SG_IO, SG_ALERT, "Trying to set data element for inactive object!");
+ if (_attributeVector.size() <= index)
return 0;
- }
- return _rtiObjectInstance->getDataElement(index);
+ return _attributeVector[index]._dataElement.get();
}
const HLADataElement*
HLAObjectInstance::getAttributeDataElement(unsigned index) const
{
- if (!_rtiObjectInstance.valid()) {
- SG_LOG(SG_IO, SG_ALERT, "Trying to set data element for inactive object!");
+ if (_attributeVector.size() <= index)
return 0;
+ return _attributeVector[index]._dataElement.get();
+}
+
+bool
+HLAObjectInstance::getAttributeData(unsigned index, RTIData& data) const
+{
+ if (!_rtiObjectInstance.valid()) {
+ SG_LOG(SG_IO, SG_ALERT, "Trying to get raw attribute data without rti object instance for \"" << getName() << "\"!");
+ return false;
}
- return _rtiObjectInstance->getDataElement(index);
+ return _rtiObjectInstance->getAttributeData(index, data);
+}
+
+void
+HLAObjectInstance::setAttributeDataElement(unsigned index, const SGSharedPtr<HLADataElement>& dataElement)
+{
+ unsigned numAttributes = getNumAttributes();
+ if (numAttributes <= index)
+ return;
+ _attributeVector.resize(numAttributes);
+ _attributeVector[index]._dataElement = dataElement;
+ if (getAttributeOwned(index))
+ encodeAttributeValue(index);
}
class HLAObjectInstance::DataElementFactoryVisitor : public HLADataElementFactoryVisitor {
{
const HLADataType* dataType = getAttributeDataType(index);
if (!dataType) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot get attribute data type for setting attribute at index "
- << index << "!");
+ SG_LOG(SG_IO, SG_ALERT, "Cannot get attribute data type for setting attribute \""
+ << getAttributeName(index) << "\" at index " << index << "!");
return;
}
SG_LOG(SG_IO, SG_ALERT, "Trying to register object " << getName() << " already known to the RTI!");
return;
}
- SGSharedPtr<HLAObjectClass> objectClass = _objectClass.lock();
- if (!objectClass.valid()) {
+ if (!_objectClass.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Could not register object with unknown object class!");
return;
}
// This error must have been flagged before
- if (!objectClass->_rtiObjectClass.valid())
+ if (!_objectClass->_rtiObjectClass.valid())
return;
- _rtiObjectInstance = objectClass->_rtiObjectClass->registerObjectInstance(this);
+ _setRTIObjectInstance(_objectClass->_rtiObjectClass->registerObjectInstance(this));
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Could not register object at the RTI!");
return;
}
- _name = _rtiObjectInstance->getName();
- objectClass->registerInstance(*this);
+ _objectClass->_registerInstance(this);
}
void
SG_LOG(SG_IO, SG_ALERT, "Trying to delete inactive object!");
return;
}
- SGSharedPtr<HLAObjectClass> objectClass = _objectClass.lock();
- if (!objectClass.valid())
+ if (!_objectClass.valid())
return;
- objectClass->deleteInstance(*this);
+ _objectClass->_deleteInstance(*this);
_rtiObjectInstance->deleteObjectInstance(tag);
}
void
HLAObjectInstance::updateAttributeValues(const RTIData& tag)
+{
+ if (_attributeCallback.valid())
+ _attributeCallback->updateAttributeValues(*this, tag);
+ if (_updateCallback.valid()) {
+ _updateCallback->updateAttributeValues(*this, tag);
+ } else {
+ encodeAttributeValues();
+ sendAttributeValues(tag);
+ }
+}
+
+void
+HLAObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag)
+{
+ if (_attributeCallback.valid())
+ _attributeCallback->updateAttributeValues(*this, tag);
+ if (_updateCallback.valid()) {
+ _updateCallback->updateAttributeValues(*this, timeStamp, tag);
+ } else {
+ encodeAttributeValues();
+ sendAttributeValues(timeStamp, tag);
+ }
+}
+
+void
+HLAObjectInstance::encodeAttributeValues()
+{
+ unsigned numAttributes = _attributeVector.size();
+ for (unsigned i = 0; i < numAttributes;++i) {
+ if (!_attributeVector[i]._unconditionalUpdate)
+ continue;
+ encodeAttributeValue(i);
+ }
+}
+
+void
+HLAObjectInstance::encodeAttributeValue(unsigned index)
+{
+ if (!_rtiObjectInstance.valid()) {
+ SG_LOG(SG_IO, SG_INFO, "Not updating inactive object!");
+ return;
+ }
+ const HLADataElement* dataElement = getAttributeDataElement(index);
+ if (!dataElement)
+ return;
+ _rtiObjectInstance->encodeAttributeData(index, *dataElement);
+}
+
+void
+HLAObjectInstance::sendAttributeValues(const RTIData& tag)
{
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_INFO, "Not updating inactive object!");
return;
}
- if (_attributeCallback.valid())
- _attributeCallback->updateAttributeValues(*this, tag);
_rtiObjectInstance->updateAttributeValues(tag);
}
void
-HLAObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag)
+HLAObjectInstance::sendAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag)
{
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_INFO, "Not updating inactive object!");
return;
}
- if (_attributeCallback.valid())
- _attributeCallback->updateAttributeValues(*this, tag);
_rtiObjectInstance->updateAttributeValues(timeStamp, tag);
}
void
-HLAObjectInstance::removeInstance(const RTIData& tag)
+HLAObjectInstance::reflectAttributeValues(const HLAIndexList& indexList, const RTIData& tag)
+{
+ for (HLAIndexList::const_iterator i = indexList.begin(); i != indexList.end(); ++i)
+ reflectAttributeValue(*i, tag);
+}
+
+void
+HLAObjectInstance::reflectAttributeValues(const HLAIndexList& indexList,
+ const SGTimeStamp& timeStamp, const RTIData& tag)
+{
+ for (HLAIndexList::const_iterator i = indexList.begin(); i != indexList.end(); ++i)
+ reflectAttributeValue(*i, timeStamp, tag);
+}
+
+void
+HLAObjectInstance::reflectAttributeValue(unsigned index, const RTIData& tag)
{
- SGSharedPtr<HLAObjectClass> objectClass = _objectClass.lock();
- if (!objectClass.valid())
+ HLADataElement* dataElement = getAttributeDataElement(index);
+ if (!dataElement)
return;
- objectClass->removeInstanceCallback(*this, tag);
+ _rtiObjectInstance->decodeAttributeData(index, *dataElement);
}
void
-HLAObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const RTIData& tag)
+HLAObjectInstance::reflectAttributeValue(unsigned index, const SGTimeStamp& timeStamp, const RTIData& tag)
{
- if (!_attributeCallback.valid())
+ HLADataElement* dataElement = getAttributeDataElement(index);
+ if (!dataElement)
return;
- _attributeCallback->reflectAttributeValues(*this, dataPairList, tag);
+ // dataElement->setTimeStamp(timeStamp);
+ _rtiObjectInstance->decodeAttributeData(index, *dataElement);
}
void
-HLAObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList,
- const SGTimeStamp& timeStamp, const RTIData& tag)
+HLAObjectInstance::_setRTIObjectInstance(RTIObjectInstance* rtiObjectInstance)
+{
+ _rtiObjectInstance = rtiObjectInstance;
+ _rtiObjectInstance->setObjectInstance(this);
+ _name = _rtiObjectInstance->getName();
+
+ unsigned numAttributes = getNumAttributes();
+ _attributeVector.resize(numAttributes);
+ for (unsigned i = 0; i < numAttributes; ++i) {
+ HLAUpdateType updateType = getObjectClass()->getAttributeUpdateType(i);
+ if (getAttributeOwned(i) && updateType != HLAUndefinedUpdate) {
+ _attributeVector[i]._enabledUpdate = true;
+ _attributeVector[i]._unconditionalUpdate = (updateType == HLAPeriodicUpdate);
+ // In case of an owned attribute, now encode its value
+ encodeAttributeValue(i);
+ } else {
+ _attributeVector[i]._enabledUpdate = false;
+ _attributeVector[i]._unconditionalUpdate = false;
+ }
+ }
+
+ // This makes sense with any new object. Even if we registered one, there might be unpublished attributes.
+ HLAIndexList indexList;
+ for (unsigned i = 0; i < numAttributes; ++i) {
+ HLAUpdateType updateType = getObjectClass()->getAttributeUpdateType(i);
+ if (getAttributeOwned(i))
+ continue;
+ if (updateType == HLAUndefinedUpdate)
+ continue;
+ if (updateType == HLAPeriodicUpdate)
+ continue;
+ indexList.push_back(i);
+ }
+ _rtiObjectInstance->requestObjectAttributeValueUpdate(indexList);
+}
+
+void
+HLAObjectInstance::_clearRTIObjectInstance()
+{
+ if (!_rtiObjectInstance.valid())
+ return;
+
+ for (unsigned i = 0; i < _attributeVector.size(); ++i) {
+ _attributeVector[i]._enabledUpdate = false;
+ _attributeVector[i]._unconditionalUpdate = false;
+ }
+
+ _rtiObjectInstance->setObjectInstance(0);
+ _rtiObjectInstance = 0;
+}
+
+void
+HLAObjectInstance::_removeInstance(const RTIData& tag)
{
- if (!_attributeCallback.valid())
+ if (!_objectClass.valid())
return;
- _attributeCallback->reflectAttributeValues(*this, dataPairList, timeStamp, tag);
+ _objectClass->_removeInstance(*this, tag);
+}
+
+void
+HLAObjectInstance::_reflectAttributeValues(const HLAIndexList& indexList, const RTIData& tag)
+{
+ if (_reflectCallback.valid()) {
+ _reflectCallback->reflectAttributeValues(*this, indexList, tag);
+ } else if (_attributeCallback.valid()) {
+ reflectAttributeValues(indexList, tag);
+
+ RTIIndexDataPairList dataPairList;
+ for (HLAIndexList::const_iterator i = indexList.begin(); i != indexList.end(); ++i) {
+ dataPairList.push_back(RTIIndexDataPair());
+ dataPairList.back().first = *i;
+ getAttributeData(*i, dataPairList.back().second);
+ }
+ _attributeCallback->reflectAttributeValues(*this, dataPairList, tag);
+ } else {
+ reflectAttributeValues(indexList, tag);
+ }
+}
+
+void
+HLAObjectInstance::_reflectAttributeValues(const HLAIndexList& indexList, const SGTimeStamp& timeStamp, const RTIData& tag)
+{
+ if (_reflectCallback.valid()) {
+ _reflectCallback->reflectAttributeValues(*this, indexList, timeStamp, tag);
+ } else if (_attributeCallback.valid()) {
+ reflectAttributeValues(indexList, timeStamp, tag);
+
+ RTIIndexDataPairList dataPairList;
+ for (HLAIndexList::const_iterator i = indexList.begin(); i != indexList.end(); ++i) {
+ dataPairList.push_back(RTIIndexDataPair());
+ dataPairList.back().first = *i;
+ getAttributeData(*i, dataPairList.back().second);
+ }
+ _attributeCallback->reflectAttributeValues(*this, dataPairList, timeStamp, tag);
+ } else {
+ reflectAttributeValues(indexList, timeStamp, tag);
+ }
}
} // namespace simgear
-// Copyright (C) 2009 - 2010 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
#ifndef HLAObjectInstance_hxx
#define HLAObjectInstance_hxx
+#include <vector>
+
#include <simgear/structure/SGWeakPtr.hxx>
#include "HLADataElement.hxx"
+#include "HLATypes.hxx"
class SGTimeStamp;
namespace simgear {
class RTIObjectInstance;
+class HLAFederate;
class HLAObjectClass;
class HLAObjectInstance : public SGWeakReferenced {
public:
HLAObjectInstance(HLAObjectClass* objectClass);
- HLAObjectInstance(HLAObjectClass* objectClass, RTIObjectInstance* rtiObjectInstance);
virtual ~HLAObjectInstance();
+ /// Return the name of this object instance
const std::string& getName() const
{ return _name; }
- SGSharedPtr<HLAObjectClass> getObjectClass() const;
+ /// Return the object class of this instance.
+ /// Should always return a valid object class.
+ const SGSharedPtr<HLAObjectClass>& getObjectClass() const
+ { return _objectClass; }
+ /// Return the number of attributes
unsigned getNumAttributes() const;
+
+ /// Return the attribute index for the attribute with the given name
unsigned getAttributeIndex(const std::string& name) const;
+ /// Return the attribute name for the attribute with the given index
std::string getAttributeName(unsigned index) const;
+ /// Return true if the attribute with the given index is owned by this federate
+ bool getAttributeOwned(unsigned index) const;
+
+ /// Return the data type of the attribute with the given index
const HLADataType* getAttributeDataType(unsigned index) const;
- void setAttributeDataElement(unsigned index, SGSharedPtr<HLADataElement> dataElement);
+ /// Return the data element of the attribute with the given index
HLADataElement* getAttributeDataElement(unsigned index);
const HLADataElement* getAttributeDataElement(unsigned index) const;
+
+ /// Write the raw attribute data value into data, works only of the object is backed up with an rti object instance
+ bool getAttributeData(unsigned index, RTIData& data) const;
+
+ /// Sets the data element of the attribute with the given index to dataElement
+ void setAttributeDataElement(unsigned index, const SGSharedPtr<HLADataElement>& dataElement);
+ /// Sets the data element of the attribute with the given index to the content of pathElementMap
void setAttribute(unsigned index, const HLAPathElementMap& pathElementMap);
void setAttributes(const HLAAttributePathElementMap& attributePathElementMap);
void registerInstance();
void deleteInstance(const RTIData& tag);
+ // Push the current values into the RTI
+ virtual void updateAttributeValues(const RTIData& tag);
+ virtual void updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag);
+ // encode periodic and dirty attribute values for the next sendAttributeValues
+ void encodeAttributeValues();
+ // encode the attribute value at index i for the next sendAttributeValues
+ void encodeAttributeValue(unsigned index);
+
+ // Really sends the prepared attribute update values into the RTI
+ void sendAttributeValues(const RTIData& tag);
+ void sendAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag);
+
+ class UpdateCallback : public SGReferenced {
+ public:
+ virtual ~UpdateCallback();
+
+ virtual void updateAttributeValues(HLAObjectInstance&, const RTIData&) = 0;
+ virtual void updateAttributeValues(HLAObjectInstance&, const SGTimeStamp&, const RTIData&) = 0;
+ };
+
+ void setUpdateCallback(const SGSharedPtr<UpdateCallback>& updateCallback)
+ { _updateCallback = updateCallback; }
+ const SGSharedPtr<UpdateCallback>& getUpdateCallback() const
+ { return _updateCallback; }
+
+
+ // Reflects the indices given in the index vector into the attributes HLADataElements.
+ virtual void reflectAttributeValues(const HLAIndexList& indexList, const RTIData& tag);
+ virtual void reflectAttributeValues(const HLAIndexList& indexList, const SGTimeStamp& timeStamp, const RTIData& tag);
+ // Reflect a single attribute value at the given index into the attributes HLADataELement.
+ virtual void reflectAttributeValue(unsigned index, const RTIData& tag);
+ virtual void reflectAttributeValue(unsigned index, const SGTimeStamp& timeStamp, const RTIData& tag);
+
+ class ReflectCallback : public SGReferenced {
+ public:
+ virtual ~ReflectCallback();
+
+ virtual void reflectAttributeValues(HLAObjectInstance&, const HLAIndexList&, const RTIData&) = 0;
+ virtual void reflectAttributeValues(HLAObjectInstance&, const HLAIndexList&, const SGTimeStamp&, const RTIData&) = 0;
+ };
+
+ void setReflectCallback(const SGSharedPtr<ReflectCallback>& reflectCallback)
+ { _reflectCallback = reflectCallback; }
+ const SGSharedPtr<ReflectCallback>& getReflectCallback() const
+ { return _reflectCallback; }
+
+ // deprecated.
class AttributeCallback : public SGReferenced {
public:
virtual ~AttributeCallback() {}
- // Notification about reflect and whatever TBD
- // Hmm, don't know yet how this should look like
virtual void updateAttributeValues(HLAObjectInstance& objectInstance, const RTIData& tag)
{ }
-
virtual void reflectAttributeValues(HLAObjectInstance& objectInstance,
const RTIIndexDataPairList& dataPairList, const RTIData& tag)
{ }
const SGSharedPtr<AttributeCallback>& getAttributeCallback() const
{ return _attributeCallback; }
- // Push the current values into the RTI
- void updateAttributeValues(const RTIData& tag);
- void updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag);
-
private:
- void removeInstance(const RTIData& tag);
- void reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const RTIData& tag);
- void reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const SGTimeStamp& timeStamp, const RTIData& tag);
- friend class RTIObjectInstance;
- friend class HLAObjectClass;
+ void _setRTIObjectInstance(RTIObjectInstance* rtiObjectInstance);
+ void _clearRTIObjectInstance();
+
+ // The callback entry points from the RTI interface classes.
+ void _removeInstance(const RTIData& tag);
+ void _reflectAttributeValues(const HLAIndexList& indexList, const RTIData& tag);
+ void _reflectAttributeValues(const HLAIndexList& indexList, const SGTimeStamp& timeStamp, const RTIData& tag);
class DataElementFactoryVisitor;
+ struct Attribute {
+ Attribute() : _enabledUpdate(false), _unconditionalUpdate(false) {}
+ SGSharedPtr<HLADataElement> _dataElement;
+ // SGSharedPtr<HLADataElement::TimeStamp> _timeStamp;
+ bool _enabledUpdate;
+ bool _unconditionalUpdate;
+ // HLAIndexList::iterator _unconditionalUpdateAttributeIndexListIterator;
+ // HLAIndexList::iterator _conditionalUpdateAttributeIndexListIterator;
+ };
+ typedef std::vector<Attribute> AttributeVector;
+
+ // At some time we want these: Until then, use the _enabledUpdate and _unconditionalUpdate flags in the Attribute struct.
+ // HLAIndexList _unconditionalUpdateAttributeIndexList;
+ // HLAIndexList _conditionalUpdateAttributeIndexList;
+
+ /// The parent Federate
+ SGWeakPtr<HLAFederate> _federate;
+
+ /// The ObjectClass
+ SGSharedPtr<HLAObjectClass> _objectClass;
+
+ /// The name as known in the RTI
std::string _name;
- SGWeakPtr<HLAObjectClass> _objectClass;
+ // /// The name as given by the local created instance
+ // std::string _givenName;
+
+ /// The underlying rti dispatcher class
SGSharedPtr<RTIObjectInstance> _rtiObjectInstance;
+
+ /// The attribute data
+ AttributeVector _attributeVector;
+
+ // Callback classes
+ SGSharedPtr<UpdateCallback> _updateCallback;
+ SGSharedPtr<ReflectCallback> _reflectCallback;
SGSharedPtr<AttributeCallback> _attributeCallback;
+
+ friend class HLAFederate;
+ friend class HLAObjectClass;
+ friend class RTIObjectInstance;
};
} // namespace simgear
#ifndef HLATypes_hxx
#define HLATypes_hxx
+#include <list>
+
namespace simgear {
enum HLASubscriptionType {
HLAUndefinedUpdate
};
+typedef std::list<unsigned> HLAIndexList;
+
} // namespace simgear
#endif
return this;
}
+void
+HLAVariantRecordDataType::releaseDataTypeReferences()
+{
+ for (AlternativeList::iterator i = _alternativeList.begin(); i != _alternativeList.end(); ++i)
+ i->_dataType = 0;
+}
+
bool
HLAVariantRecordDataType::decode(HLADecodeStream& stream, HLAAbstractVariantRecordDataElement& value) const
{
_alternativeList[index]._name = name;
_alternativeList[index]._dataType = dataType;
_alternativeList[index]._semantics = semantics;
- setAlignment(SGMisc<unsigned>::max(getAlignment(), dataType->getAlignment()));
return true;
}
+void
+HLAVariantRecordDataType::_recomputeAlignmentImplementation()
+{
+ unsigned alignment = 1;
+ if (const HLADataType* dataType = getEnumeratedDataType())
+ alignment = std::max(alignment, dataType->getAlignment());
+ for (unsigned i = 0; i < getNumAlternatives(); ++i) {
+ if (const HLADataType* dataType = getAlternativeDataType(i))
+ alignment = std::max(alignment, dataType->getAlignment());
+ }
+ setAlignment(alignment);
+}
+
} // namespace simgear
virtual const HLAVariantRecordDataType* toVariantRecordDataType() const;
+ virtual void releaseDataTypeReferences();
+
virtual bool decode(HLADecodeStream& stream, HLAAbstractVariantRecordDataElement& value) const;
virtual bool encode(HLAEncodeStream& stream, const HLAAbstractVariantRecordDataElement& value) const;
std::string getAlternativeSemantics(const std::string& enumerator) const
{ return getAlternativeSemantics(getAlternativeIndex(enumerator)); }
+protected:
+ virtual void _recomputeAlignmentImplementation();
+
private:
SGSharedPtr<HLAEnumeratedDataType> _enumeratedDataType;
{ _rtiAmbassador.publishObjectClass(handle, attributeHandleSet); }
void unpublishObjectClass(const RTI::ObjectClassHandle& handle)
{ _rtiAmbassador.unpublishObjectClass(handle); }
+
+ void publishInteractionClass(const RTI::InteractionClassHandle& handle)
+ { _rtiAmbassador.publishInteractionClass(handle); }
+ void unpublishInteractionClass(const RTI::InteractionClassHandle& handle)
+ { _rtiAmbassador.unpublishInteractionClass(handle); }
+
void subscribeObjectClassAttributes(const RTI::ObjectClassHandle& handle, const RTI::AttributeHandleSet& attributeHandleSet, bool active)
{ _rtiAmbassador.subscribeObjectClassAttributes(handle, attributeHandleSet, active ? RTI::RTI_TRUE : RTI::RTI_FALSE); }
void unsubscribeObjectClass(const RTI::ObjectClassHandle& handle)
{ _rtiAmbassador.unsubscribeObjectClass(handle); }
+ void subscribeInteractionClass(const RTI::InteractionClassHandle& handle, bool active)
+ { _rtiAmbassador.subscribeInteractionClass(handle, active ? RTI::RTI_TRUE : RTI::RTI_FALSE); }
+ void unsubscribeInteractionClass(const RTI::InteractionClassHandle& handle)
+ { _rtiAmbassador.unsubscribeInteractionClass(handle); }
+
RTI::ObjectHandle registerObjectInstance(const RTI::ObjectClassHandle& handle)
{ return _rtiAmbassador.registerObjectInstance(handle); }
void updateAttributeValues(const RTI::ObjectHandle& objectHandle, const RTI::AttributeHandleValuePairSet& attributeValues,
// }
// return false;
// }
- // bool isAttributeOwnedByFederate(const RTIHandle& objectHandle, const RTIHandle& attributeHandle)
- // {
- // try {
- // return _rtiAmbassador.isAttributeOwnedByFederate(objectHandle, attributeHandle);
- // } catch (RTI::ObjectNotKnown& e) {
- // } catch (RTI::AttributeNotDefined& e) {
- // } catch (RTI::FederateNotExecutionMember& e) {
- // } catch (RTI::ConcurrentAccessAttempted& e) {
- // } catch (RTI::SaveInProgress& e) {
- // } catch (RTI::RestoreInProgress& e) {
- // } catch (RTI::RTIinternalError& e) {
- // }
- // return false;
- // }
+ bool isAttributeOwnedByFederate(const RTI::ObjectHandle& objectHandle, const RTI::AttributeHandle& attributeHandle)
+ { return _rtiAmbassador.isAttributeOwnedByFederate(objectHandle, attributeHandle); }
/// Time Management
std::string getAttributeName(const RTI::AttributeHandle& attributeHandle, const RTI::ObjectClassHandle& objectClassHandle)
{ return rtiToStdString(_rtiAmbassador.getAttributeName(attributeHandle, objectClassHandle)); }
- // RTIHandle getInteractionClassHandle(const std::string& name)
- // {
- // try {
- // return _rtiAmbassador.getInteractionClassHandle(name.c_str());
- // } catch (RTI::NameNotFound& e) {
- // } catch (RTI::FederateNotExecutionMember& e) {
- // } catch (RTI::ConcurrentAccessAttempted& e) {
- // } catch (RTI::RTIinternalError& e) {
- // }
- // return RTIHandle(-1);
- // }
- // std::string getInteractionClassName(const RTIHandle& handle)
- // {
- // std::string name;
- // try {
- // rtiToStdString(name, _rtiAmbassador.getInteractionClassName(handle));
- // } catch (RTI::InteractionClassNotDefined& e) {
- // } catch (RTI::FederateNotExecutionMember& e) {
- // } catch (RTI::ConcurrentAccessAttempted& e) {
- // } catch (RTI::RTIinternalError& e) {
- // }
- // return name;
- // }
+ RTI::InteractionClassHandle getInteractionClassHandle(const std::string& name)
+ { return _rtiAmbassador.getInteractionClassHandle(name.c_str()); }
+ std::string getInteractionClassName(const RTI::InteractionClassHandle& handle)
+ { return rtiToStdString(_rtiAmbassador.getInteractionClassName(handle)); }
- // RTIHandle getParameterHandle(const std::string& parameterName, const RTIHandle& interactionClassHandle)
- // {
- // try {
- // return _rtiAmbassador.getParameterHandle(parameterName.c_str(), interactionClassHandle);
- // } catch (RTI::InteractionClassNotDefined& e) {
- // } catch (RTI::NameNotFound& e) {
- // } catch (RTI::FederateNotExecutionMember& e) {
- // } catch (RTI::ConcurrentAccessAttempted& e) {
- // } catch (RTI::RTIinternalError& e) {
- // }
- // return RTIHandle(-1);
- // }
- // std::string getParameterName(const RTIHandle& parameterHandle, const RTIHandle& interactionClassHandle)
- // {
- // std::string parameterName;
- // try {
- // rtiToStdString(parameterName, _rtiAmbassador.getParameterName(parameterHandle, interactionClassHandle));
- // } catch (RTI::InteractionClassNotDefined& e) {
- // } catch (RTI::InteractionParameterNotDefined& e) {
- // } catch (RTI::FederateNotExecutionMember& e) {
- // } catch (RTI::ConcurrentAccessAttempted& e) {
- // } catch (RTI::RTIinternalError& e) {
- // }
- // return parameterName;
- // }
+ RTI::ParameterHandle getParameterHandle(const std::string& parameterName, const RTI::InteractionClassHandle& interactionClassHandle)
+ { return _rtiAmbassador.getParameterHandle(parameterName.c_str(), interactionClassHandle); }
+ std::string getParameterName(const RTI::ParameterHandle& parameterHandle, const RTI::InteractionClassHandle& interactionClassHandle)
+ { return rtiToStdString(_rtiAmbassador.getParameterName(parameterHandle, interactionClassHandle)); }
RTI::ObjectHandle getObjectInstanceHandle(const std::string& name)
{ return _rtiAmbassador.getObjectInstanceHandle(name.c_str()); }
return;
if (!i->second.valid())
return;
- SGSharedPtr<RTI13ObjectInstance> objectInstance = new RTI13ObjectInstance(objectHandle, 0, i->second, _rtiAmbassador.get(), false);
+ SGSharedPtr<RTI13ObjectInstance> objectInstance = new RTI13ObjectInstance(objectHandle, 0, i->second, _rtiAmbassador.get());
_objectInstanceMap[objectHandle] = objectInstance;
i->second->discoverInstance(objectInstance.get(), tag);
}
return;
if (!i->second.valid())
return;
- i->second->reflectAttributeValues(attributeHandleDataPairList, timeStamp, tag);
+ i->second->reflectAttributeValues(attributeHandleDataPairList, timeStamp, tag, _indexPool);
}
class ReflectAttributeValuesCallback : public TagQueueCallback {
return;
if (!i->second.valid())
return;
- i->second->reflectAttributeValues(attributeHandleDataPairList, tag);
+ i->second->reflectAttributeValues(attributeHandleDataPairList, tag, _indexPool);
}
virtual void receiveInteraction(RTI::InteractionClassHandle interactionClassHandle, const RTI::ParameterHandleValuePairSet& parameters,
void freeAttributeHandleDataPairList(RTI13AttributeHandleDataPairList& attributeHandleDataPairList)
{ _attributeHandleDataPairPool.splice(_attributeHandleDataPairPool.end(), attributeHandleDataPairList); }
+ // For attribute reflection, pool or indices
+ HLAIndexList _indexPool;
+
// Top level information for dispatching federate object attribute updates
typedef std::map<RTI::ObjectHandle, SGSharedPtr<RTI13ObjectInstance> > ObjectInstanceMap;
// Map of all available objects
typedef std::map<RTI::ObjectClassHandle, SGSharedPtr<RTI13ObjectClass> > ObjectClassMap;
ObjectClassMap _objectClassMap;
+ // Top level information for dispatching creation of federate objects
+ typedef std::map<RTI::InteractionClassHandle, SGSharedPtr<RTI13InteractionClass> > InteractionClassMap;
+ InteractionClassMap _interactionClassMap;
+
bool _timeRegulationEnabled;
bool _timeConstrainedEnabled;
bool _timeAdvancePending;
}
}
+RTI13InteractionClass*
+RTI13Federate::createInteractionClass(const std::string& interactionClassName, HLAInteractionClass* interactionClass)
+{
+ try {
+ RTI::InteractionClassHandle interactionClassHandle;
+ interactionClassHandle = _ambassador->getInteractionClassHandle(interactionClassName);
+ if (_federateAmbassador->_interactionClassMap.find(interactionClassHandle) != _federateAmbassador->_interactionClassMap.end()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not create interaction class, interaction class already exists!");
+ return 0;
+ }
+ RTI13InteractionClass* rtiInteractionClass;
+ rtiInteractionClass = new RTI13InteractionClass(interactionClass, interactionClassHandle, _ambassador.get());
+ _federateAmbassador->_interactionClassMap[interactionClassHandle] = rtiInteractionClass;
+ return rtiInteractionClass;
+ } catch (RTI::NameNotFound& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get interaction class: " << e._name << " " << e._reason);
+ return 0;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get interaction class: " << e._name << " " << e._reason);
+ return 0;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get interaction class: " << e._name << " " << e._reason);
+ return 0;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get interaction class: " << e._name << " " << e._reason);
+ return 0;
+ }
+}
+
RTI13ObjectInstance*
RTI13Federate::getObjectInstance(const std::string& objectInstanceName)
{
#include <RTI.hh>
#include "RTIFederate.hxx"
+#include "RTI13InteractionClass.hxx"
#include "RTI13ObjectClass.hxx"
#include "RTI13ObjectInstance.hxx"
virtual bool processMessages(const double& minimum, const double& maximum);
virtual RTI13ObjectClass* createObjectClass(const std::string& name, HLAObjectClass* hlaObjectClass);
+ virtual RTI13InteractionClass* createInteractionClass(const std::string& name, HLAInteractionClass* interactionClass);
virtual RTI13ObjectInstance* getObjectInstance(const std::string& name);
void insertObjectInstance(RTI13ObjectInstance* objectInstance);
--- /dev/null
+// 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
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#include "RTI13InteractionClass.hxx"
+
+#include "RTI13Ambassador.hxx"
+
+namespace simgear {
+
+RTI13InteractionClass::RTI13InteractionClass(HLAInteractionClass* interactionClass, const RTI::InteractionClassHandle& handle, RTI13Ambassador* ambassador) :
+ RTIInteractionClass(interactionClass),
+ _handle(handle),
+ _ambassador(ambassador)
+{
+}
+
+RTI13InteractionClass::~RTI13InteractionClass()
+{
+}
+
+bool
+RTI13InteractionClass::resolveParameterIndex(const std::string& name, unsigned index)
+{
+ if (!_ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
+ return false;
+ }
+
+ if (index != _parameterHandleVector.size()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Resolving needs to happen in growing index order!");
+ return false;
+ }
+
+ try {
+ RTI::ParameterHandle parameterHandle = _ambassador->getParameterHandle(name, _handle);
+
+ ParameterHandleIndexMap::const_iterator i = _parameterHandleIndexMap.find(parameterHandle);
+ if (i != _parameterHandleIndexMap.end()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Resolving parameterIndex for parameter \"" << name << "\" twice!");
+ return false;
+ }
+
+ _parameterHandleIndexMap[parameterHandle] = index;
+ _parameterHandleVector.push_back(parameterHandle);
+
+ return true;
+
+ } catch (RTI::NameNotFound& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get interaction class parameter: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get interaction class parameter: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get interaction class parameter: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get interaction class parameter: " << e._name << " " << e._reason);
+ return false;
+ } catch (...) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get interaction class parameter.");
+ return false;
+ }
+
+ return false;
+}
+
+bool
+RTI13InteractionClass::publish()
+{
+ if (!_ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
+ return false;
+ }
+
+ try {
+ _ambassador->publishInteractionClass(_handle);
+ return true;
+ } catch (RTI::InteractionClassNotDefined& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (...) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish interaction class.");
+ return false;
+ }
+
+ return false;
+}
+
+bool
+RTI13InteractionClass::unpublish()
+{
+ if (!_ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
+ return false;
+ }
+
+ try {
+ _ambassador->unpublishInteractionClass(_handle);
+ return true;
+ } catch (RTI::InteractionClassNotDefined& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::InteractionClassNotPublished& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (...) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish interaction class.");
+ return false;
+ }
+
+ return false;
+}
+
+bool
+RTI13InteractionClass::subscribe(bool active)
+{
+ if (!_ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
+ return false;
+ }
+
+ try {
+ _ambassador->subscribeInteractionClass(_handle, active);
+ return true;
+ } catch (RTI::InteractionClassNotDefined& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederateLoggingServiceCalls& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (...) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe interaction class.");
+ return false;
+ }
+
+ return false;
+}
+
+bool
+RTI13InteractionClass::unsubscribe()
+{
+ if (!_ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
+ return false;
+ }
+
+ try {
+ _ambassador->unsubscribeInteractionClass(_handle);
+ return true;
+ } catch (RTI::InteractionClassNotDefined& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::InteractionClassNotSubscribed& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe interaction class: " << e._name << " " << e._reason);
+ return false;
+ } catch (...) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe interaction class.");
+ return false;
+ }
+
+ return false;
+}
+
+}
--- /dev/null
+// 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
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef RTI13InteractionClass_hxx
+#define RTI13InteractionClass_hxx
+
+#include <map>
+#include <vector>
+
+#ifndef RTI_USES_STD_FSTREAM
+#define RTI_USES_STD_FSTREAM
+#endif
+
+#include <RTI.hh>
+
+#include "RTIInteractionClass.hxx"
+
+#include <simgear/structure/SGSharedPtr.hxx>
+
+namespace simgear {
+
+class RTI13Ambassador;
+
+class RTI13InteractionClass : public RTIInteractionClass {
+public:
+ RTI13InteractionClass(HLAInteractionClass* interactionClass, const RTI::InteractionClassHandle& handle, RTI13Ambassador* ambassador);
+ virtual ~RTI13InteractionClass();
+
+ virtual bool resolveParameterIndex(const std::string& name, unsigned index);
+
+ virtual bool publish();
+ virtual bool unpublish();
+
+ virtual bool subscribe(bool);
+ virtual bool unsubscribe();
+
+private:
+ RTI::InteractionClassHandle _handle;
+ SGSharedPtr<RTI13Ambassador> _ambassador;
+
+ typedef std::map<RTI::ParameterHandle, unsigned> ParameterHandleIndexMap;
+ ParameterHandleIndexMap _parameterHandleIndexMap;
+
+ typedef std::vector<RTI::ParameterHandle> ParameterHandleVector;
+ ParameterHandleVector _parameterHandleVector;
+};
+
+}
+
+#endif
-// Copyright (C) 2009 - 2010 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
namespace simgear {
-RTI13ObjectClass::RTI13ObjectClass(HLAObjectClass* hlaObjectClass, RTI::ObjectClassHandle& handle, RTI13Ambassador* ambassador) :
+RTI13ObjectClass::RTI13ObjectClass(HLAObjectClass* hlaObjectClass, const RTI::ObjectClassHandle& handle, RTI13Ambassador* ambassador) :
RTIObjectClass(hlaObjectClass),
_handle(handle),
_ambassador(ambassador)
{
- if (0 != getOrCreateAttributeIndex("privilegeToDelete") &&
- 0 != getOrCreateAttributeIndex("HLAprivilegeToDeleteObject"))
- SG_LOG(SG_NETWORK, SG_WARN, "RTI13ObjectClass: Cannot find object root attribute.");
}
RTI13ObjectClass::~RTI13ObjectClass()
{
}
-std::string
-RTI13ObjectClass::getName() const
-{
- if (!_ambassador.valid()) {
- SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
- return std::string();
- }
- return _ambassador->getObjectClassName(_handle);
-}
-
-unsigned
-RTI13ObjectClass::getNumAttributes() const
-{
- return _attributeHandleVector.size();
-}
-
-unsigned
-RTI13ObjectClass::getAttributeIndex(const std::string& name) const
+bool
+RTI13ObjectClass::resolveAttributeIndex(const std::string& name, unsigned index)
{
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
- return ~0u;
- }
-
- try {
- RTI::AttributeHandle attributeHandle = _ambassador->getAttributeHandle(name, _handle);
-
- AttributeHandleIndexMap::const_iterator i = _attributeHandleIndexMap.find(attributeHandle);
- if (i != _attributeHandleIndexMap.end())
- return i->second;
-
- return ~0u;
-
- } catch (RTI::ObjectClassNotDefined& e) {
- SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
- return ~0u;
- } catch (RTI::NameNotFound& e) {
- SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
- return ~0u;
- } catch (RTI::FederateNotExecutionMember& e) {
- SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
- return ~0u;
- } catch (RTI::ConcurrentAccessAttempted& e) {
- SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
- return ~0u;
- } catch (RTI::RTIinternalError& e) {
- SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
- return ~0u;
- } catch (...) {
- SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute.");
- return ~0u;
+ return false;
}
-}
-unsigned
-RTI13ObjectClass::getOrCreateAttributeIndex(const std::string& name)
-{
- if (!_ambassador.valid()) {
- SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
- return ~0u;
+ if (index != _attributeHandleVector.size()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Resolving needs to happen in growing index order!");
+ return false;
}
try {
RTI::AttributeHandle attributeHandle = _ambassador->getAttributeHandle(name, _handle);
AttributeHandleIndexMap::const_iterator i = _attributeHandleIndexMap.find(attributeHandle);
- if (i != _attributeHandleIndexMap.end())
- return i->second;
+ if (i != _attributeHandleIndexMap.end()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Resolving attributeIndex for attribute \"" << name << "\" twice!");
+ return false;
+ }
- unsigned index = _attributeHandleVector.size();
_attributeHandleIndexMap[attributeHandle] = index;
_attributeHandleVector.push_back(attributeHandle);
- _attributeDataVector.push_back(name);
- return index;
+ return true;
} catch (RTI::ObjectClassNotDefined& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
- return ~0u;
+ return false;
} catch (RTI::NameNotFound& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
- return ~0u;
+ return false;
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
- return ~0u;
+ return false;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
- return ~0u;
+ return false;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
- return ~0u;
+ return false;
} catch (...) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute.");
- return ~0u;
+ return false;
}
}
-// std::string
-// RTI13ObjectClass::getAttributeName(unsigned index) const
-// {
-// SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
-// if (!ambassador.valid()) {
-// SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
-// return std::string();
-// }
-
-// try {
-// return ambassador->getAttributeName(getAttributeHandle(index), _handle);
-// } catch (RTI::ObjectClassNotDefined& e) {
-// SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute name: " << e._name << " " << e._reason);
-// return std::string();
-// } catch (RTI::AttributeNotDefined& e) {
-// SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute name: " << e._name << " " << e._reason);
-// return std::string();
-// } catch (RTI::FederateNotExecutionMember& e) {
-// SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute name: " << e._name << " " << e._reason);
-// return std::string();
-// } catch (RTI::ConcurrentAccessAttempted& e) {
-// SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute name: " << e._name << " " << e._reason);
-// return std::string();
-// } catch (RTI::RTIinternalError& e) {
-// SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute name: " << e._name << " " << e._reason);
-// return std::string();
-// } catch (...) {
-// SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute name.");
-// return std::string();
-// }
-// }
+unsigned
+RTI13ObjectClass::getNumAttributes() const
+{
+ return _attributeHandleVector.size();
+}
bool
-RTI13ObjectClass::publish(const std::set<unsigned>& indexSet)
+RTI13ObjectClass::publish(const HLAIndexList& indexList)
{
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
}
try {
- std::auto_ptr<RTI::AttributeHandleSet> attributeHandleSet(RTI::AttributeHandleSetFactory::create(indexSet.size()));
- for (std::set<unsigned>::const_iterator i = indexSet.begin(); i != indexSet.end(); ++i) {
+ unsigned numAttributes = getNumAttributes();
+ std::auto_ptr<RTI::AttributeHandleSet> attributeHandleSet(RTI::AttributeHandleSetFactory::create(numAttributes));
+ for (HLAIndexList::const_iterator i = indexList.begin(); i != indexList.end(); ++i) {
if (_attributeHandleVector.size() <= *i) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI13ObjectClass::publish(): Invalid attribute index!");
continue;
_ambassador->publishObjectClass(_handle, *attributeHandleSet);
- for (unsigned i = 0; i < getNumAttributes(); ++i) {
- _attributeDataVector[i]._published = true;
- }
-
return true;
} catch (RTI::ObjectClassNotDefined& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish object class: " << e._name << " " << e._reason);
try {
_ambassador->unpublishObjectClass(_handle);
- for (unsigned i = 0; i < getNumAttributes(); ++i) {
- _attributeDataVector[i]._published = false;
- }
-
return true;
} catch (RTI::ObjectClassNotDefined& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish object class: " << e._name << " " << e._reason);
}
bool
-RTI13ObjectClass::subscribe(const std::set<unsigned>& indexSet, bool active)
+RTI13ObjectClass::subscribe(const HLAIndexList& indexList, bool active)
{
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
}
try {
- std::auto_ptr<RTI::AttributeHandleSet> attributeHandleSet(RTI::AttributeHandleSetFactory::create(indexSet.size()));
- for (std::set<unsigned>::const_iterator i = indexSet.begin();
- i != indexSet.end(); ++i) {
+ unsigned numAttributes = getNumAttributes();
+ std::auto_ptr<RTI::AttributeHandleSet> attributeHandleSet(RTI::AttributeHandleSetFactory::create(numAttributes));
+ for (HLAIndexList::const_iterator i = indexList.begin(); i != indexList.end(); ++i) {
if (_attributeHandleVector.size() <= *i) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI13ObjectClass::subscribe(): Invalid attribute index!");
continue;
_ambassador->subscribeObjectClassAttributes(_handle, *attributeHandleSet, active);
- for (unsigned i = 0; i < getNumAttributes(); ++i) {
- _attributeDataVector[i]._subscribed = true;
- }
-
return true;
} catch (RTI::ObjectClassNotDefined& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe object class: " << e._name << " " << e._reason);
try {
_ambassador->unsubscribeObjectClass(_handle);
- for (unsigned i = 0; i < getNumAttributes(); ++i) {
- _attributeDataVector[i]._subscribed = false;
- }
-
return true;
} catch (RTI::ObjectClassNotDefined& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe object class: " << e._name << " " << e._reason);
try {
RTI::ObjectHandle objectHandle = _ambassador->registerObjectInstance(getHandle());
- RTI13ObjectInstance* objectInstance = new RTI13ObjectInstance(objectHandle, hlaObjectInstance, this, _ambassador.get(), true);
+ RTI13ObjectInstance* objectInstance = new RTI13ObjectInstance(objectHandle, hlaObjectInstance, this, _ambassador.get());
federate->insertObjectInstance(objectInstance);
return objectInstance;
} catch (RTI::ObjectClassNotDefined& e) {
-// Copyright (C) 2009 - 2010 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
class RTI13ObjectClass : public RTIObjectClass {
public:
- RTI13ObjectClass(HLAObjectClass* hlaObjectClass, RTI::ObjectClassHandle& handle, RTI13Ambassador* ambassador);
+ RTI13ObjectClass(HLAObjectClass* hlaObjectClass, const RTI::ObjectClassHandle& handle, RTI13Ambassador* ambassador);
virtual ~RTI13ObjectClass();
const RTI::ObjectClassHandle& getHandle() const
{ return _handle; }
- virtual std::string getName() const;
+ virtual bool resolveAttributeIndex(const std::string& name, unsigned index);
virtual unsigned getNumAttributes() const;
- virtual unsigned getAttributeIndex(const std::string& name) const;
- virtual unsigned getOrCreateAttributeIndex(const std::string& name);
unsigned getAttributeIndex(const RTI::AttributeHandle& handle) const
{
return _attributeHandleVector[index];
}
- virtual bool publish(const std::set<unsigned>& indexSet);
+ virtual bool publish(const HLAIndexList& indexList);
virtual bool unpublish();
- virtual bool subscribe(const std::set<unsigned>& indexSet, bool);
+ virtual bool subscribe(const HLAIndexList& indexList, bool);
virtual bool unsubscribe();
virtual RTIObjectInstance* registerObjectInstance(HLAObjectInstance* hlaObjectInstance);
namespace simgear {
-RTI13ObjectInstance::RTI13ObjectInstance(const RTI::ObjectHandle& handle, HLAObjectInstance* hlaObjectInstance,
- const RTI13ObjectClass* objectClass, RTI13Ambassador* ambassador, bool owned) :
- RTIObjectInstance(hlaObjectInstance),
+RTI13ObjectInstance::RTI13ObjectInstance(const RTI::ObjectHandle& handle, HLAObjectInstance* objectInstance,
+ const RTI13ObjectClass* objectClass, RTI13Ambassador* ambassador) :
+ RTIObjectInstance(objectInstance),
_handle(handle),
_objectClass(objectClass),
_ambassador(ambassador),
_attributeValuePairSet(RTI::AttributeSetFactory::create(objectClass->getNumAttributes()))
{
- updateAttributesFromClass(owned);
+ _setNumAttributes(getNumAttributes());
}
RTI13ObjectInstance::~RTI13ObjectInstance()
}
void
-RTI13ObjectInstance::reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList, const RTIData& tag)
+RTI13ObjectInstance::reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList,
+ const RTIData& tag, HLAIndexList& indexPool)
{
- // Retrieve an empty update struct from the memory pool
- RTIIndexDataPairList indexDataPairList;
+ HLAIndexList reflectedIndices;
for (RTI13AttributeHandleDataPairList::iterator i = attributeHandleDataPairList.begin();
i != attributeHandleDataPairList.end(); ++i) {
unsigned index = getAttributeIndex(i->first);
- // Get a RTIData from the data pool
- getDataFromPool(indexDataPairList);
- indexDataPairList.back().first = index;
- indexDataPairList.back().second.swap(i->second);
- }
+ _attributeData[index]._data.swap(i->second);
- RTIObjectInstance::reflectAttributeValues(indexDataPairList, tag);
-
- RTIIndexDataPairList::iterator j = indexDataPairList.begin();
- for (RTI13AttributeHandleDataPairList::iterator i = attributeHandleDataPairList.begin();
- i != attributeHandleDataPairList.end(); ++i, ++j) {
- i->second.swap(j->second);
+ if (indexPool.empty())
+ reflectedIndices.push_back(index);
+ else {
+ reflectedIndices.splice(reflectedIndices.end(), indexPool, indexPool.begin());
+ reflectedIndices.back() = index;
+ }
}
- // Return the update data back to the pool
- putDataToPool(indexDataPairList);
+ RTIObjectInstance::reflectAttributeValues(reflectedIndices, tag);
+
+ // Return the index list to the pool
+ indexPool.splice(indexPool.end(), reflectedIndices);
}
void
RTI13ObjectInstance::reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList,
- const SGTimeStamp& timeStamp, const RTIData& tag)
+ const SGTimeStamp& timeStamp, const RTIData& tag, HLAIndexList& indexPool)
{
- // Retrieve an empty update struct from the memory pool
- RTIIndexDataPairList indexDataPairList;
+ HLAIndexList reflectedIndices;
for (RTI13AttributeHandleDataPairList::iterator i = attributeHandleDataPairList.begin();
i != attributeHandleDataPairList.end(); ++i) {
unsigned index = getAttributeIndex(i->first);
- // Get a RTIData from the data pool
- getDataFromPool(indexDataPairList);
- indexDataPairList.back().first = index;
- indexDataPairList.back().second.swap(i->second);
- }
-
- RTIObjectInstance::reflectAttributeValues(indexDataPairList, timeStamp, tag);
+ _attributeData[index]._data.swap(i->second);
- RTIIndexDataPairList::iterator j = indexDataPairList.begin();
- for (RTI13AttributeHandleDataPairList::iterator i = attributeHandleDataPairList.begin();
- i != attributeHandleDataPairList.end(); ++i, ++j) {
- i->second.swap(j->second);
+ if (indexPool.empty())
+ reflectedIndices.push_back(index);
+ else {
+ reflectedIndices.splice(reflectedIndices.end(), indexPool, indexPool.begin());
+ reflectedIndices.back() = index;
+ }
}
- // Return the update data back to the pool
- putDataToPool(indexDataPairList);
+ RTIObjectInstance::reflectAttributeValues(reflectedIndices, timeStamp, tag);
+
+ // Return the index list to the pool
+ indexPool.splice(indexPool.end(), reflectedIndices);
}
void
-RTI13ObjectInstance::requestObjectAttributeValueUpdate()
+RTI13ObjectInstance::requestObjectAttributeValueUpdate(const HLAIndexList& indexList)
{
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return;
}
+ if (indexList.empty())
+ return;
+
try {
unsigned numAttributes = getNumAttributes();
std::auto_ptr<RTI::AttributeHandleSet> attributeHandleSet(RTI::AttributeHandleSetFactory::create(numAttributes));
- for (unsigned i = 0; i < numAttributes; ++i) {
- if (!getRequestAttributeUpdate(i))
+ for (HLAIndexList::const_iterator i = indexList.begin(); i != indexList.end(); ++i) {
+ if (getAttributeOwned(*i)) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI13ObjectInstance::requestObjectAttributeValueUpdate(): "
+ "Invalid attribute index!");
continue;
- attributeHandleSet->add(getAttributeHandle(i));
+ }
+ attributeHandleSet->add(getAttributeHandle(*i));
}
if (!attributeHandleSet->size())
return;
_ambassador->requestObjectAttributeValueUpdate(_handle, *attributeHandleSet);
- for (unsigned i = 0; i < numAttributes; ++i)
- setRequestAttributeUpdate(i, false);
-
return;
} catch (RTI::ObjectNotKnown& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
size_t numAttribs = attributeHandleSet.size();
for (RTI::ULong i = 0; i < numAttribs; ++i) {
unsigned index = getAttributeIndex(attributeHandleSet[i]);
- setAttributeForceUpdate(index);
+ _attributeData[index]._dirty = true;
}
}
unsigned numAttributes = getNumAttributes();
for (unsigned i = 0; i < numAttributes; ++i) {
- if (!getAttributeEffectiveUpdateEnabled(i))
- continue;
- const HLADataElement* dataElement = getDataElement(i);
- if (!dataElement)
+ if (!_attributeData[i]._dirty)
continue;
- // FIXME cache somewhere
- RTIData data;
- HLAEncodeStream stream(data);
- dataElement->encode(stream);
+ const RTIData& data = _attributeData[i]._data;
_attributeValuePairSet->add(getAttributeHandle(i), data.data(), data.size());
}
_ambassador->updateAttributeValues(_handle, *_attributeValuePairSet, tag);
for (unsigned i = 0; i < numAttributes; ++i) {
- setAttributeUpdated(i);
+ _attributeData[i]._dirty = false;
}
} catch (RTI::ObjectNotKnown& e) {
unsigned numAttributes = getNumAttributes();
for (unsigned i = 0; i < numAttributes; ++i) {
- if (!getAttributeEffectiveUpdateEnabled(i))
+ if (!_attributeData[i]._dirty)
continue;
- const HLADataElement* dataElement = getDataElement(i);
- if (!dataElement)
- continue;
- // FIXME cache somewhere
- RTIData data;
- HLAEncodeStream stream(data);
- dataElement->encode(stream);
+ const RTIData& data = _attributeData[i]._data;
_attributeValuePairSet->add(getAttributeHandle(i), data.data(), data.size());
}
_ambassador->updateAttributeValues(_handle, *_attributeValuePairSet, timeStamp, tag);
for (unsigned i = 0; i < numAttributes; ++i) {
- setAttributeUpdated(i);
+ _attributeData[i]._dirty = false;
}
} catch (RTI::ObjectNotKnown& e) {
}
}
+bool
+RTI13ObjectInstance::isAttributeOwnedByFederate(unsigned index) const
+{
+ if (!_ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
+ return false;
+ }
+ try {
+ RTI::AttributeHandle attributeHandle = getAttributeHandle(index);
+ return _ambassador->isAttributeOwnedByFederate(_handle, attributeHandle);
+ } catch (RTI::ObjectNotKnown& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query attribute ownership for index " << index << ": "
+ << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::AttributeNotDefined& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query attribute ownership for index " << index << ": "
+ << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query attribute ownership for index " << index << ": "
+ << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query attribute ownership for index " << index << ": "
+ << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query attribute ownership for index " << index << ": "
+ << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query attribute ownership for index " << index << ": "
+ << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query attribute ownership for index " << index << ": "
+ << e._name << " " << e._reason);
+ return false;
+ }
+ return false;
+ }
+
void
RTI13ObjectInstance::requestAttributeOwnershipAssumption(const std::vector<RTI::AttributeHandle>& attributes, const RTIData& tag)
{
class RTI13ObjectInstance : public RTIObjectInstance {
public:
- RTI13ObjectInstance(const RTI::ObjectHandle& handle, HLAObjectInstance* hlaObjectInstance, const RTI13ObjectClass* objectClass, RTI13Ambassador* ambassador, bool owned);
+ RTI13ObjectInstance(const RTI::ObjectHandle& handle, HLAObjectInstance* hlaObjectInstance, const RTI13ObjectClass* objectClass, RTI13Ambassador* ambassador);
virtual ~RTI13ObjectInstance();
const RTI::ObjectHandle& getHandle() const
unsigned getNumAttributes() const
{ return get13ObjectClass()->getNumAttributes(); }
- unsigned getAttributeIndex(const std::string& name) const
- { return get13ObjectClass()->getAttributeIndex(name); }
unsigned getAttributeIndex(const RTI::AttributeHandle& handle) const
{ return get13ObjectClass()->getAttributeIndex(handle); }
RTI::AttributeHandle getAttributeHandle(unsigned index) const
virtual void deleteObjectInstance(const SGTimeStamp& timeStamp, const RTIData& tag);
virtual void localDeleteObjectInstance();
- void reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList, const RTIData& tag);
- void reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList, const SGTimeStamp& timeStamp, const RTIData& tag);
- virtual void requestObjectAttributeValueUpdate();
+ void reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList,
+ const RTIData& tag, HLAIndexList& indexPool);
+ void reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList,
+ const SGTimeStamp& timeStamp, const RTIData& tag, HLAIndexList& indexPool);
+ virtual void requestObjectAttributeValueUpdate(const HLAIndexList& indexList);
void provideAttributeValueUpdate(const std::vector<RTI::AttributeHandle>& attributes);
virtual void updateAttributeValues(const RTIData& tag);
virtual void updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag);
+ virtual bool isAttributeOwnedByFederate(unsigned index) const;
+
void attributesInScope(const std::vector<RTI::AttributeHandle>& attributes);
void attributesOutOfScope(const std::vector<RTI::AttributeHandle>& attributes);
-// 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
#include <string>
#include "simgear/structure/SGWeakReferenced.hxx"
+#include "RTIInteractionClass.hxx"
#include "RTIObjectClass.hxx"
#include "RTIObjectInstance.hxx"
virtual bool processMessages(const double& minimum, const double& maximum) = 0;
virtual RTIObjectClass* createObjectClass(const std::string& name, HLAObjectClass* hlaObjectClass) = 0;
- // virtual RTIInteractionClass* createInteractionClass(const std::string& name) = 0;
+ virtual RTIInteractionClass* createInteractionClass(const std::string& name, HLAInteractionClass* interactionClass) = 0;
virtual RTIObjectInstance* getObjectInstance(const std::string& name) = 0;
--- /dev/null
+// 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
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#include "RTIInteractionClass.hxx"
+
+namespace simgear {
+
+RTIInteractionClass::RTIInteractionClass(HLAInteractionClass* interactionClass) :
+ _interactionClass(interactionClass)
+{
+}
+
+RTIInteractionClass::~RTIInteractionClass()
+{
+ _interactionClass = 0;
+}
+
+}
-// Copyright (C) 2009 - 2010 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
#ifndef RTIInteractionClass_hxx
#define RTIInteractionClass_hxx
-#include <set>
#include <string>
-#include <vector>
#include "simgear/structure/SGReferenced.hxx"
-#include "simgear/structure/SGSharedPtr.hxx"
-#include "simgear/structure/SGReferenced.hxx"
-#include "RTIData.hxx"
namespace simgear {
+class HLAInteractionClass;
+
class RTIInteractionClass : public SGReferenced {
public:
- RTIInteractionClass(const std::string& name);
+ RTIInteractionClass(HLAInteractionClass* interactionClass);
virtual ~RTIInteractionClass();
- const std::string& getName() const
- { return _name; }
-
- virtual unsigned getNumParameters() const = 0;
- virtual unsigned getParameterIndex(const std::string& name) const = 0;
- virtual unsigned getOrCreateParameterIndex(const std::string& name) = 0;
+ virtual bool resolveParameterIndex(const std::string& name, unsigned index) = 0;
- virtual bool publish(const std::set<unsigned>& indexSet) = 0;
+ virtual bool publish() = 0;
virtual bool unpublish() = 0;
- virtual bool subscribe(const std::set<unsigned>& indexSet, bool) = 0;
+ virtual bool subscribe(bool) = 0;
virtual bool unsubscribe() = 0;
- virtual void send(const RTIData& tag) = 0;
- virtual void send(const SGTimeStamp& timeStamp, const RTIData& tag) = 0;
-
- class ReceiveCallback : public SGReferenced {
- public:
- virtual ~ReceiveCallback() {}
- };
+ // virtual void send(const RTIData& tag) = 0;
+ // virtual void send(const SGTimeStamp& timeStamp, const RTIData& tag) = 0;
private:
- std::string _name;
+ HLAInteractionClass* _interactionClass;
+
+ friend class HLAInteractionClass;
};
}
-// Copyright (C) 2009 - 2010 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
#include "RTIObjectClass.hxx"
+#include "simgear/debug/logstream.hxx"
#include "RTIObjectInstance.hxx"
namespace simgear {
-RTIObjectClass::RTIObjectClass(HLAObjectClass* hlaObjectClass) :
- _hlaObjectClass(hlaObjectClass)
+RTIObjectClass::RTIObjectClass(HLAObjectClass* objectClass) :
+ _objectClass(objectClass)
{
}
void
RTIObjectClass::discoverInstance(RTIObjectInstance* objectInstance, const RTIData& tag) const
{
- SGSharedPtr<HLAObjectClass> hlaObjectClass = _hlaObjectClass.lock();
- if (!hlaObjectClass.valid()) {
+ if (!_objectClass) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Invalid hla object class pointer in RTIObjectClass::discoverInstance().");
return;
}
- hlaObjectClass->discoverInstance(objectInstance, tag);
- objectInstance->requestObjectAttributeValueUpdate();
+ _objectClass->_discoverInstance(objectInstance, tag);
}
void
RTIObjectClass::startRegistration() const
{
- SGSharedPtr<HLAObjectClass> hlaObjectClass = _hlaObjectClass.lock();
- if (!hlaObjectClass.valid()) {
+ if (!_objectClass) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Invalid hla object class pointer in RTIObjectClass::startRegstration().");
return;
}
- hlaObjectClass->startRegistrationCallback();
+ _objectClass->_startRegistration();
}
void
RTIObjectClass::stopRegistration() const
{
- SGSharedPtr<HLAObjectClass> hlaObjectClass = _hlaObjectClass.lock();
- if (!hlaObjectClass.valid()) {
+ if (!_objectClass) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Invalid hla object class pointer in RTIObjectClass::stopRegistration().");
return;
}
- hlaObjectClass->stopRegistrationCallback();
+ _objectClass->_stopRegistration();
}
}
-// Copyright (C) 2009 - 2010 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
#define RTIObjectClass_hxx
#include <string>
-#include <vector>
#include "simgear/structure/SGReferenced.hxx"
-#include "simgear/structure/SGSharedPtr.hxx"
-#include "simgear/structure/SGWeakPtr.hxx"
#include "RTIData.hxx"
#include "HLAObjectClass.hxx"
namespace simgear {
+class RTIData;
class RTIObjectInstance;
class HLAObjectClass;
class RTIObjectClass : public SGReferenced {
public:
- RTIObjectClass(HLAObjectClass* hlaObjectClass);
+ RTIObjectClass(HLAObjectClass* objectClass);
virtual ~RTIObjectClass();
- virtual std::string getName() const = 0;
+ virtual bool resolveAttributeIndex(const std::string& name, unsigned index) = 0;
virtual unsigned getNumAttributes() const = 0;
- virtual unsigned getAttributeIndex(const std::string& name) const = 0;
- virtual unsigned getOrCreateAttributeIndex(const std::string& name) = 0;
- virtual bool publish(const std::set<unsigned>& indexSet) = 0;
+ virtual bool publish(const HLAIndexList& indexList) = 0;
virtual bool unpublish() = 0;
- virtual bool subscribe(const std::set<unsigned>& indexSet, bool) = 0;
+ virtual bool subscribe(const HLAIndexList& indexList, bool) = 0;
virtual bool unsubscribe() = 0;
// Factory to create an object instance that can be used in this current federate
virtual RTIObjectInstance* registerObjectInstance(HLAObjectInstance*) = 0;
+ // Call back into HLAObjectClass
void discoverInstance(RTIObjectInstance* objectInstance, const RTIData& tag) const;
void startRegistration() const;
void stopRegistration() const;
- void setAttributeDataType(unsigned index, SGSharedPtr<const HLADataType> dataType)
- {
- if (_attributeDataVector.size() <= index)
- return;
- _attributeDataVector[index]._dataType = dataType;
- }
- const HLADataType* getAttributeDataType(unsigned index) const
- {
- if (_attributeDataVector.size() <= index)
- return 0;
- return _attributeDataVector[index]._dataType.get();
- }
-
- HLAUpdateType getAttributeUpdateType(unsigned index) const
- {
- if (_attributeDataVector.size() <= index)
- return HLAUndefinedUpdate;
- return _attributeDataVector[index]._updateType;
- }
- void setAttributeUpdateType(unsigned index, HLAUpdateType updateType)
- {
- if (_attributeDataVector.size() <= index)
- return;
- _attributeDataVector[index]._updateType = updateType;
- }
-
- bool getAttributeSubscribed(unsigned index) const
- {
- if (_attributeDataVector.size() <= index)
- return false;
- return _attributeDataVector[index]._subscribed;
- }
- bool getAttributePublished(unsigned index) const
- {
- if (_attributeDataVector.size() <= index)
- return false;
- return _attributeDataVector[index]._published;
- }
- std::string getAttributeName(unsigned index) const
- {
- if (_attributeDataVector.size() <= index)
- return std::string();
- return _attributeDataVector[index]._name;
- }
-
-protected:
- struct AttributeData {
- AttributeData(const std::string& name) : _name(name), _subscribed(false), _published(false), _updateType(HLAUndefinedUpdate) {}
- std::string _name;
- SGSharedPtr<const HLADataType> _dataType;
- bool _subscribed;
- bool _published;
- HLAUpdateType _updateType;
- };
- typedef std::vector<AttributeData> AttributeDataVector;
- AttributeDataVector _attributeDataVector;
-
private:
- SGWeakPtr<HLAObjectClass> _hlaObjectClass;
+ HLAObjectClass* _objectClass;
+
+ friend class HLAObjectClass;
};
}
namespace simgear {
RTIObjectInstance::RTIObjectInstance(HLAObjectInstance* hlaObjectInstance) :
- _hlaObjectInstance(hlaObjectInstance),
- _pendingAttributeUpdateRequest(false)
+ _objectInstance(hlaObjectInstance)
{
}
return getObjectClass()->getNumAttributes();
}
-unsigned
-RTIObjectInstance::getAttributeIndex(const std::string& name) const
-{
- return getObjectClass()->getAttributeIndex(name);
-}
-
-std::string
-RTIObjectInstance::getAttributeName(unsigned index) const
-{
- return getObjectClass()->getAttributeName(index);
-}
-
void
RTIObjectInstance::removeInstance(const RTIData& tag)
{
- SGSharedPtr<HLAObjectInstance> hlaObjectInstance = _hlaObjectInstance.lock();
- if (!hlaObjectInstance.valid())
+ if (!_objectInstance)
return;
- hlaObjectInstance->removeInstance(tag);
+ _objectInstance->_removeInstance(tag);
}
void
-RTIObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const RTIData& tag)
+RTIObjectInstance::reflectAttributeValues(const HLAIndexList& indexList, const RTIData& tag)
{
- for (RTIIndexDataPairList::const_iterator i = dataPairList.begin();
- i != dataPairList.end(); ++i) {
- reflectAttributeValue(i->first, i->second);
- }
-
- SGSharedPtr<HLAObjectInstance> hlaObjectInstance = _hlaObjectInstance.lock();
- if (!hlaObjectInstance.valid())
+ if (!_objectInstance)
return;
- hlaObjectInstance->reflectAttributeValues(dataPairList, tag);
+ _objectInstance->_reflectAttributeValues(indexList, tag);
}
void
-RTIObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList,
+RTIObjectInstance::reflectAttributeValues(const HLAIndexList& indexList,
const SGTimeStamp& timeStamp, const RTIData& tag)
{
- for (RTIIndexDataPairList::const_iterator i = dataPairList.begin();
- i != dataPairList.end(); ++i) {
- reflectAttributeValue(i->first, i->second);
- }
-
- SGSharedPtr<HLAObjectInstance> hlaObjectInstance = _hlaObjectInstance.lock();
- if (!hlaObjectInstance.valid())
+ if (!_objectInstance)
return;
- hlaObjectInstance->reflectAttributeValues(dataPairList, timeStamp, tag);
+ _objectInstance->_reflectAttributeValues(indexList, timeStamp, tag);
}
}
#ifndef RTIObjectInstance_hxx
#define RTIObjectInstance_hxx
-#include <list>
-#include <map>
#include <string>
#include <vector>
-#include "simgear/debug/logstream.hxx"
#include "simgear/structure/SGReferenced.hxx"
-#include "simgear/structure/SGWeakPtr.hxx"
#include "simgear/timing/timestamp.hxx"
#include "RTIData.hxx"
#include "RTIObjectClass.hxx"
class RTIObjectInstance : public SGReferenced {
public:
- RTIObjectInstance(HLAObjectInstance* hlaObjectInstance);
+ RTIObjectInstance(HLAObjectInstance* objectInstance);
virtual ~RTIObjectInstance();
+ void setObjectInstance(HLAObjectInstance* objectInstance)
+ { _objectInstance = objectInstance; }
+
virtual const RTIObjectClass* getObjectClass() const = 0;
virtual std::string getName() const = 0;
unsigned getNumAttributes() const;
- unsigned getAttributeIndex(const std::string& name) const;
- std::string getAttributeName(unsigned index) const;
virtual void deleteObjectInstance(const RTIData& tag) = 0;
virtual void deleteObjectInstance(const SGTimeStamp& timeStamp, const RTIData& tag) = 0;
virtual void localDeleteObjectInstance() = 0;
- virtual void requestObjectAttributeValueUpdate() = 0;
+ virtual void requestObjectAttributeValueUpdate(const HLAIndexList& indexList) = 0;
virtual void updateAttributeValues(const RTIData& tag) = 0;
virtual void updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag) = 0;
+ virtual bool isAttributeOwnedByFederate(unsigned index) const = 0;
+
void removeInstance(const RTIData& tag);
- void reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const RTIData& tag);
- void reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const SGTimeStamp& timeStamp, const RTIData& tag);
- void reflectAttributeValue(unsigned i, const RTIData& data)
- {
- if (_attributeData.size() <= i)
- return;
- HLADataElement* dataElement = _attributeData[i]._dataElement.get();
- if (!dataElement)
- return;
- HLADecodeStream stream(data);
- dataElement->decode(stream);
- }
+ void reflectAttributeValues(const HLAIndexList& indexList, const RTIData& tag);
+ void reflectAttributeValues(const HLAIndexList& indexList, const SGTimeStamp& timeStamp, const RTIData& tag);
- const HLADataType* getAttributeDataType(unsigned i) const
+ bool encodeAttributeData(unsigned index, const HLADataElement& dataElement)
{
- return getObjectClass()->getAttributeDataType(i);
- }
- HLAUpdateType getAttributeUpdateType(unsigned i) const
- {
- return getObjectClass()->getAttributeUpdateType(i);
- }
- bool getAttributeSubscribed(unsigned i) const
- {
- return getObjectClass()->getAttributeSubscribed(i);
- }
- bool getAttributePublished(unsigned i) const
- {
- return getObjectClass()->getAttributePublished(i);
+ if (_attributeData.size() <= index)
+ return false;
+ return _attributeData[index].encodeAttributeData(dataElement);
}
- HLADataElement* getDataElement(unsigned i)
- {
- if (_attributeData.size() <= i)
- return 0;
- return _attributeData[i]._dataElement.get();
- }
- const HLADataElement* getDataElement(unsigned i) const
- {
- if (_attributeData.size() <= i)
- return 0;
- return _attributeData[i]._dataElement.get();
- }
- void setDataElement(unsigned i, HLADataElement* dataElement)
+ bool decodeAttributeData(unsigned index, HLADataElement& dataElement) const
{
- if (_attributeData.size() <= i)
- return;
- _attributeData[i]._dataElement = dataElement;
+ if (_attributeData.size() <= index)
+ return false;
+ return _attributeData[index].decodeAttributeData(dataElement);
}
- void updateAttributesFromClass(bool owned)
+ bool getAttributeData(unsigned index, RTIData& data) const
{
- // FIXME: rethink that!!!
- unsigned numAttributes = getNumAttributes();
- unsigned i = 0;
- for (; i < _attributeData.size(); ++i) {
- if (getAttributePublished(i)) {
- } else {
- _attributeData[i].setUpdateEnabled(false);
- _attributeData[i].setOwned(false);
- if (getAttributeSubscribed(i))
- _attributeData[i].setRequestUpdate(true);
- }
- }
- _attributeData.resize(numAttributes);
- for (; i < numAttributes; ++i) {
- if (getAttributePublished(i)) {
- _attributeData[i].setUpdateEnabled(true);
- _attributeData[i].setOwned(owned);
- if (!owned && getAttributeSubscribed(i))
- _attributeData[i].setRequestUpdate(true);
- } else {
- _attributeData[i].setUpdateEnabled(false);
- _attributeData[i].setOwned(false);
- if (getAttributeSubscribed(i))
- _attributeData[i].setRequestUpdate(true);
- }
- }
+ if (_attributeData.size() <= index)
+ return false;
+ data = _attributeData[index]._data;
+ return true;
}
- void setAttributeForceUpdate(unsigned i)
+ bool getAttributeOwned(unsigned index) const
{
- if (_attributeData.size() <= i)
- return;
- _attributeData[i].setForceUpdate(true);
+ if (_attributeData.size() <= index)
+ return false;
+ return _attributeData[index]._owned;
}
+
void setAttributeInScope(unsigned i, bool inScope)
{
if (_attributeData.size() <= i)
return;
- _attributeData[i].setInScope(inScope);
+ _attributeData[i]._inScope = inScope;
}
void setAttributeUpdateEnabled(unsigned i, bool enabled)
{
if (_attributeData.size() <= i)
return;
- _attributeData[i].setUpdateEnabled(enabled);
- }
- void setAttributeUpdated(unsigned i)
- {
- if (_attributeData.size() <= i)
- return;
- _attributeData[i].setForceUpdate(false);
- }
- bool getAttributeEffectiveUpdateEnabled(unsigned i)
- {
- if (_attributeData.size() <= i)
- return false;
- if (!getAttributePublished(i))
- return false;
- if (!_attributeData[i]._updateEnabled)
- return false;
- if (!_attributeData[i]._inScope)
- return false;
- if (_attributeData[i]._forceUpdate)
- return true;
- switch (getAttributeUpdateType(i)) {
- case HLAPeriodicUpdate:
- return true;
- case HLAConditionalUpdate:
- return true; // FIXME
- case HLAStaticUpdate:
- return false;
- default:
- return false;
- }
- }
- void setRequestAttributeUpdate(bool request)
- {
- for (unsigned i = 0; i < getNumAttributes(); ++i) {
- if (getAttributeUpdateType(i) == HLAPeriodicUpdate)
- continue;
- setRequestAttributeUpdate(i, request);
- }
- }
- void setRequestAttributeUpdate(unsigned i, bool request)
- {
- if (_attributeData.size() <= i)
- return;
- _attributeData[i].setRequestUpdate(request);
- if (request) {
- if (!_pendingAttributeUpdateRequest) {
- _pendingAttributeUpdateRequest = true;
- }
- }
- }
- bool getRequestAttributeUpdate(unsigned i) const
- {
- if (_attributeData.size() <= i)
- return false;
- return _attributeData[i]._requestUpdate;
- }
-
- void flushPendingRequests()
- {
- if (_pendingAttributeUpdateRequest) {
- requestObjectAttributeValueUpdate();
- _pendingAttributeUpdateRequest = false;
- }
+ _attributeData[i]._updateEnabled = enabled;
}
protected:
- // The backward reference to the user visible object
- SGWeakPtr<HLAObjectInstance> _hlaObjectInstance;
-
- // Is true if we should emit a requestattr
- bool _pendingAttributeUpdateRequest;
-
- // Pool of update list entries
- RTIIndexDataPairList _indexDataPairList;
-
- // This adds raw storage for attribute index i to the end of the dataPairList.
- void getDataFromPool(RTIIndexDataPairList& dataPairList)
+ // Initially set the number of attributes, do an initial query for the attribute ownership
+ void _setNumAttributes(unsigned numAttributes)
{
- // Nothing left in the pool - so allocate something
- if (_indexDataPairList.empty()) {
- dataPairList.push_back(RTIIndexDataPairList::value_type());
- return;
- }
-
- // Take one from the pool
- dataPairList.splice(dataPairList.end(), _indexDataPairList, _indexDataPairList.begin());
+ _attributeData.resize(numAttributes);
+ for (unsigned i = 0; i < numAttributes; ++i)
+ _attributeData[i]._owned = isAttributeOwnedByFederate(i);
}
- void putDataToPool(RTIIndexDataPairList& dataPairList)
- {
- _indexDataPairList.splice(_indexDataPairList.begin(), dataPairList);
- }
+ // The backward reference to the user visible object
+ HLAObjectInstance* _objectInstance;
struct AttributeData {
- AttributeData() : _owned(false), _inScope(true), _updateEnabled(true), _forceUpdate(false), _requestUpdate(false)
+ AttributeData() : _owned(false), _inScope(true), _updateEnabled(true), _dirty(false)
{ }
- // The hla level data element with tha actual local program
- // accessible data.
- SGSharedPtr<HLADataElement> _dataElement;
- // SGSharedPtr<HLADataElement::TimeStamp> _timeStamp;
+ bool encodeAttributeData(const HLADataElement& dataElement)
+ {
+ _dirty = true;
+ _data.resize(0);
+ HLAEncodeStream stream(_data);
+ return dataElement.encode(stream);
+ }
- // Pool of already allocated raw data used for reflection of updates
- RTIIndexDataPairList _indexDataPairList;
+ bool decodeAttributeData(HLADataElement& dataElement) const
+ {
+ HLADecodeStream stream(_data);
+ return dataElement.decode(stream);
+ }
- void setOwned(bool owned)
- { _owned = owned; }
- void setInScope(bool inScope)
- { _inScope = inScope; }
- void setUpdateEnabled(bool updateEnabled)
- { _updateEnabled = updateEnabled; }
- void setForceUpdate(bool forceUpdate)
- { _forceUpdate = forceUpdate; }
- void setRequestUpdate(bool requestUpdate)
- { _requestUpdate = requestUpdate; }
+ // The rti level raw data element
+ RTIData _data;
+ // The state of the attribute as tracked from the rti.
bool _owned;
bool _inScope;
bool _updateEnabled;
- bool _forceUpdate;
- bool _requestUpdate;
+
+ // Is set to true if _data has be reencoded
+ bool _dirty;
};
std::vector<AttributeData> _attributeData;
-
- friend class HLAObjectInstance;
};
}