EXTRA_DIRS="${EXTRA_DIRS} $with_rti13"
fi
+# specify the rti13 location
+AC_ARG_WITH(rti1516, [ --with-rti1516=PREFIX Specify the prefix path to a HLA1516 rti])
+
+if test "x$with_rti1516" != "x" ; then
+ echo "rti1516 prefix is $with_rti1516"
+ EXTRA_DIRS="${EXTRA_DIRS} $with_rti1516"
+fi
+
dnl Determine an extra directories to add to include/lib search paths
case "${host}" in
*-apple-darwin* | *-*-cygwin* | *-*-mingw32*)
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "HLA13Federate.hxx"
+
+#include "RTI13Federate.hxx"
+
+namespace simgear {
+
+HLA13Federate::HLA13Federate() :
+ HLAFederate(new RTI13Federate)
+{
+}
+
+HLA13Federate::~HLA13Federate()
+{
+}
+
+} // namespace simgear
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLA13Federate_hxx
+#define HLA13Federate_hxx
+
+#include "HLAFederate.hxx"
+
+namespace simgear {
+
+class HLA13Federate : public HLAFederate {
+public:
+ HLA13Federate();
+ virtual ~HLA13Federate();
+};
+
+} // namespace simgear
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "HLAArrayDataElement.hxx"
+
+#include <simgear/debug/logstream.hxx>
+
+namespace simgear {
+
+HLAAbstractArrayDataElement::HLAAbstractArrayDataElement(const HLAArrayDataType* dataType) :
+ _dataType(dataType)
+{
+}
+
+HLAAbstractArrayDataElement::~HLAAbstractArrayDataElement()
+{
+}
+
+bool
+HLAAbstractArrayDataElement::decode(HLADecodeStream& stream)
+{
+ if (!_dataType.valid())
+ return false;
+ return _dataType->decode(stream, *this);
+}
+
+bool
+HLAAbstractArrayDataElement::encode(HLAEncodeStream& stream) const
+{
+ if (!_dataType.valid())
+ return false;
+ return _dataType->encode(stream, *this);
+}
+
+const HLAArrayDataType*
+HLAAbstractArrayDataElement::getDataType() const
+{
+ return _dataType.get();
+}
+
+bool
+HLAAbstractArrayDataElement::setDataType(const HLADataType* dataType)
+{
+ const HLAArrayDataType* arrayDataType = dynamic_cast<const HLAArrayDataType*>(dataType);
+ if (!arrayDataType) {
+ SG_LOG(SG_NETWORK, SG_WARN, "HLAArrayDataType: unable to set data type!");
+ return false;
+ }
+ _dataType = arrayDataType;
+ return true;
+}
+
+const HLADataType*
+HLAAbstractArrayDataElement::getElementDataType() const
+{
+ if (!_dataType.valid())
+ return 0;
+ return _dataType->getElementDataType();
+}
+
+////////////////////////////////////////////////////////////////////////
+
+HLAArrayDataElement::DataElementFactory::~DataElementFactory()
+{
+}
+
+HLAArrayDataElement::HLAArrayDataElement(const HLAArrayDataType* dataType) :
+ HLAAbstractArrayDataElement(dataType)
+{
+}
+
+HLAArrayDataElement::~HLAArrayDataElement()
+{
+}
+
+bool
+HLAArrayDataElement::setNumElements(unsigned size)
+{
+ unsigned oldSize = _elementVector.size();
+ if (size == oldSize)
+ return true;
+ _elementVector.resize(size);
+ for (unsigned i = oldSize; i < size; ++i)
+ _elementVector[i] = newElement(i);
+ return true;
+}
+
+bool
+HLAArrayDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
+{
+ HLADataElement* dataElement = getElement(i);
+ if (!dataElement)
+ return false;
+ return dataElement->decode(stream);
+}
+
+unsigned
+HLAArrayDataElement::getNumElements() const
+{
+ return _elementVector.size();
+}
+
+bool
+HLAArrayDataElement::encodeElement(HLAEncodeStream& stream, unsigned i) const
+{
+ const HLADataElement* dataElement = getElement(i);
+ if (!dataElement)
+ return false;
+ return dataElement->encode(stream);
+}
+
+const HLADataElement*
+HLAArrayDataElement::getElement(unsigned index) const
+{
+ if (_elementVector.size() <= index)
+ return 0;
+ return _elementVector[index].get();
+}
+
+HLADataElement*
+HLAArrayDataElement::getElement(unsigned index)
+{
+ if (_elementVector.size() <= index)
+ return 0;
+ return _elementVector[index].get();
+}
+
+HLADataElement*
+HLAArrayDataElement::getOrCreateElement(unsigned index)
+{
+ if (_elementVector.size() <= index)
+ if (!setNumElements(index + 1))
+ return 0;
+ return _elementVector[index].get();
+}
+
+void
+HLAArrayDataElement::setElement(unsigned index, HLADataElement* value)
+{
+ unsigned oldSize = _elementVector.size();
+ if (oldSize <= index) {
+ _elementVector.resize(index + 1);
+ for (unsigned j = oldSize; j < index; ++j)
+ _elementVector[j] = newElement(j);
+ }
+ _elementVector[index] = value;
+}
+
+void
+HLAArrayDataElement::setDataElementFactory(HLAArrayDataElement::DataElementFactory* dataElementFactory)
+{
+ _dataElementFactory = dataElementFactory;
+}
+
+HLAArrayDataElement::DataElementFactory*
+HLAArrayDataElement::getDataElementFactory()
+{
+ return _dataElementFactory.get();
+}
+
+HLADataElement*
+HLAArrayDataElement::newElement(unsigned index)
+{
+ if (!_dataElementFactory.valid())
+ return 0;
+ return _dataElementFactory->createElement(*this, index);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+HLAVariantArrayDataElement::HLAVariantArrayDataElement() :
+ HLAAbstractArrayDataElement(0)
+{
+}
+
+HLAVariantArrayDataElement::~HLAVariantArrayDataElement()
+{
+}
+
+bool
+HLAVariantArrayDataElement::setDataType(const HLADataType* dataType)
+{
+ const HLAArrayDataType* arrayDataType = dataType->toArrayDataType();
+ if (!arrayDataType) {
+ SG_LOG(SG_NETWORK, SG_WARN, "HLAVariantArrayDataType: unable to set data type, dataType is not an array data type!");
+ return false;
+ }
+ const HLAVariantDataType* variantDataType = arrayDataType->getElementDataType()->toVariantDataType();
+ if (!variantDataType) {
+ SG_LOG(SG_NETWORK, SG_WARN, "HLAVariantArrayDataType: unable to set data type: arrayDataTypes element data type is no a variant data type!");
+ return false;
+ }
+ _dataType = arrayDataType;
+ return true;
+}
+
+bool
+HLAVariantArrayDataElement::setNumElements(unsigned size)
+{
+ unsigned oldSize = _elementVector.size();
+ if (size == oldSize)
+ return true;
+ _elementVector.resize(size);
+ for (unsigned i = oldSize; i < size; ++i)
+ _elementVector[i] = newElement();
+ return true;
+}
+
+bool
+HLAVariantArrayDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
+{
+ HLAVariantDataElement* dataElement = getElement(i);
+ if (!dataElement)
+ return false;
+ return dataElement->decode(stream);
+}
+
+unsigned
+HLAVariantArrayDataElement::getNumElements() const
+{
+ return _elementVector.size();
+}
+
+bool
+HLAVariantArrayDataElement::encodeElement(HLAEncodeStream& stream, unsigned i) const
+{
+ const HLADataElement* dataElement = getElement(i);
+ if (!dataElement)
+ return false;
+ return dataElement->encode(stream);
+}
+
+const HLAVariantDataElement*
+HLAVariantArrayDataElement::getElement(unsigned index) const
+{
+ if (_elementVector.size() <= index)
+ return 0;
+ return _elementVector[index].get();
+}
+
+HLAVariantDataElement*
+HLAVariantArrayDataElement::getElement(unsigned index)
+{
+ if (_elementVector.size() <= index)
+ return 0;
+ return _elementVector[index].get();
+}
+
+HLAVariantDataElement*
+HLAVariantArrayDataElement::getOrCreateElement(unsigned index)
+{
+ if (_elementVector.size() <= index)
+ if (!setNumElements(index + 1))
+ return 0;
+ return _elementVector[index].get();
+}
+
+void
+HLAVariantArrayDataElement::setElement(unsigned index, HLAVariantDataElement* value)
+{
+ unsigned oldSize = _elementVector.size();
+ if (oldSize <= index) {
+ _elementVector.resize(index + 1);
+ for (unsigned j = oldSize; j < index; ++j)
+ _elementVector[j] = newElement();
+ }
+ _elementVector[index] = value;
+}
+
+void
+HLAVariantArrayDataElement::setAlternativeDataElementFactory(HLAVariantArrayDataElement::AlternativeDataElementFactory* alternativeDataElementFactory)
+{
+ _alternativeDataElementFactory = alternativeDataElementFactory;
+}
+
+HLAVariantArrayDataElement::AlternativeDataElementFactory*
+HLAVariantArrayDataElement::getAlternativeDataElementFactory()
+{
+ return _alternativeDataElementFactory.get();
+}
+
+HLAVariantDataElement*
+HLAVariantArrayDataElement::newElement()
+{
+ const HLAArrayDataType* arrayDataType = getDataType();
+ if (!arrayDataType)
+ return 0;
+ const HLADataType* elementDataType = arrayDataType->getElementDataType();
+ if (!elementDataType)
+ return 0;
+ const HLAVariantDataType* variantDataType = elementDataType->toVariantDataType();
+ if (!variantDataType)
+ return 0;
+ HLAVariantDataElement* variantDataElement = new HLAVariantDataElement(variantDataType);
+ variantDataElement->setDataElementFactory(_alternativeDataElementFactory.get());
+ return variantDataElement;
+}
+
+}
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLAArrayDataElement_hxx
+#define HLAArrayDataElement_hxx
+
+#include <string>
+#include <vector>
+#include <simgear/math/SGMath.hxx>
+#include "HLAArrayDataType.hxx"
+#include "HLADataElement.hxx"
+#include "HLAVariantDataElement.hxx"
+#include "HLADataTypeVisitor.hxx"
+
+namespace simgear {
+
+class HLAAbstractArrayDataElement : public HLADataElement {
+public:
+ HLAAbstractArrayDataElement(const HLAArrayDataType* dataType);
+ virtual ~HLAAbstractArrayDataElement();
+
+ virtual bool decode(HLADecodeStream& stream);
+ virtual bool encode(HLAEncodeStream& stream) const;
+
+ virtual const HLAArrayDataType* getDataType() const;
+ virtual bool setDataType(const HLADataType* dataType);
+
+ const HLADataType* getElementDataType() const;
+
+ virtual bool setNumElements(unsigned count) = 0;
+ virtual bool decodeElement(HLADecodeStream& stream, unsigned i) = 0;
+
+ virtual unsigned getNumElements() const = 0;
+ virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const = 0;
+
+protected:
+ SGSharedPtr<const HLAArrayDataType> _dataType;
+};
+
+class HLAArrayDataElement : public HLAAbstractArrayDataElement {
+public:
+ HLAArrayDataElement(const HLAArrayDataType* dataType = 0);
+ virtual ~HLAArrayDataElement();
+
+ virtual bool setNumElements(unsigned size);
+ virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
+ virtual unsigned getNumElements() const;
+ virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const;
+
+ const HLADataElement* getElement(unsigned index) const;
+ HLADataElement* getElement(unsigned index);
+ HLADataElement* getOrCreateElement(unsigned index);
+ void setElement(unsigned i, HLADataElement* value);
+
+ class DataElementFactory : public SGReferenced {
+ public:
+ virtual ~DataElementFactory();
+ virtual HLADataElement* createElement(const HLAArrayDataElement&, unsigned) = 0;
+ };
+
+ void setDataElementFactory(DataElementFactory* dataElementFactory);
+ DataElementFactory* getDataElementFactory();
+
+private:
+ HLADataElement* newElement(unsigned index);
+
+ typedef std::vector<SGSharedPtr<HLADataElement> > ElementVector;
+ ElementVector _elementVector;
+
+ SGSharedPtr<DataElementFactory> _dataElementFactory;
+};
+
+// Holds an array of variants.
+// Factors out common code for that use case.
+class HLAVariantArrayDataElement : public HLAAbstractArrayDataElement {
+public:
+ HLAVariantArrayDataElement();
+ virtual ~HLAVariantArrayDataElement();
+
+ // Overwrite this from the abstract class, need some more checks here
+ virtual bool setDataType(const HLADataType* dataType);
+
+ virtual bool setNumElements(unsigned size);
+ virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
+ virtual unsigned getNumElements() const;
+ virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const;
+
+ const HLAVariantDataElement* getElement(unsigned index) const;
+ HLAVariantDataElement* getElement(unsigned index);
+ HLAVariantDataElement* getOrCreateElement(unsigned index);
+ void setElement(unsigned index, HLAVariantDataElement* value);
+
+ typedef HLAVariantDataElement::DataElementFactory AlternativeDataElementFactory;
+
+ void setAlternativeDataElementFactory(AlternativeDataElementFactory* alternativeDataElementFactory);
+ AlternativeDataElementFactory* getAlternativeDataElementFactory();
+
+private:
+ HLAVariantDataElement* newElement();
+
+ typedef std::vector<SGSharedPtr<HLAVariantDataElement> > ElementVector;
+ ElementVector _elementVector;
+
+ SGSharedPtr<AlternativeDataElementFactory> _alternativeDataElementFactory;
+};
+
+class HLAStringDataElement : public HLAAbstractArrayDataElement {
+public:
+ HLAStringDataElement(const HLAArrayDataType* dataType = 0) :
+ HLAAbstractArrayDataElement(dataType)
+ {}
+ HLAStringDataElement(const HLAArrayDataType* dataType, const std::string& value) :
+ HLAAbstractArrayDataElement(dataType),
+ _value(value)
+ {}
+ const std::string& getValue() const
+ { return _value; }
+ void setValue(const std::string& value)
+ { _value = value; }
+
+ virtual bool setNumElements(unsigned count)
+ {
+ _value.resize(count);
+ return true;
+ }
+ virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
+ {
+ HLATemplateDecodeVisitor<std::string::value_type> visitor(stream);
+ getElementDataType()->accept(visitor);
+ _value[i] = visitor.getValue();
+ return true;
+ }
+
+ virtual unsigned getNumElements() const
+ {
+ return _value.size();
+ }
+ virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
+ {
+ HLATemplateEncodeVisitor<std::string::value_type> visitor(stream, _value[i]);
+ getElementDataType()->accept(visitor);
+ return true;
+ }
+
+private:
+ std::string _value;
+};
+
+class HLAStringData {
+public:
+ HLAStringData() :
+ _value(new HLAStringDataElement(0))
+ { }
+ HLAStringData(const std::string& value) :
+ _value(new HLAStringDataElement(0))
+ { _value->setValue(value); }
+
+ operator const std::string&() const
+ { return _value->getValue(); }
+ HLAStringData& operator=(const std::string& value)
+ { _value->setValue(value); return *this; }
+
+ const std::string& getValue() const
+ { return _value->getValue(); }
+ void setValue(const std::string& value)
+ { _value->setValue(value); }
+
+ const HLAStringDataElement* getDataElement() const
+ { return _value.get(); }
+ HLAStringDataElement* getDataElement()
+ { return _value.get(); }
+
+ const HLAArrayDataType* getDataType() const
+ { return _value->getDataType(); }
+ void setDataType(const HLAArrayDataType* dataType)
+ { _value->setDataType(dataType); }
+
+private:
+ SGSharedPtr<HLAStringDataElement> _value;
+};
+
+template<typename T>
+class HLAVec2DataElement : public HLAAbstractArrayDataElement {
+public:
+ HLAVec2DataElement(const HLAArrayDataType* dataType = 0) :
+ HLAAbstractArrayDataElement(dataType),
+ _value(SGVec2<T>::zeros())
+ {}
+ HLAVec2DataElement(const HLAArrayDataType* dataType, const SGVec2<T>& value) :
+ HLAAbstractArrayDataElement(dataType),
+ _value(value)
+ {}
+ const SGVec2<T>& getValue() const
+ { return _value; }
+ void setValue(const SGVec2<T>& value)
+ { _value = value; }
+
+ virtual bool setNumElements(unsigned count)
+ {
+ for (unsigned i = 2; i < count; ++i)
+ _value[i] = 0;
+ return true;
+ }
+ virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
+ {
+ if (i < 2) {
+ HLATemplateDecodeVisitor<typename SGVec2<T>::value_type> visitor(stream);
+ getElementDataType()->accept(visitor);
+ _value[i] = visitor.getValue();
+ } else {
+ HLADataTypeDecodeVisitor visitor(stream);
+ getElementDataType()->accept(visitor);
+ }
+ return true;
+ }
+
+ virtual unsigned getNumElements() const
+ {
+ return 2;
+ }
+ virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
+ {
+ if (i < 2) {
+ HLATemplateEncodeVisitor<typename SGVec2<T>::value_type> visitor(stream, _value[i]);
+ getElementDataType()->accept(visitor);
+ } else {
+ HLADataTypeEncodeVisitor visitor(stream);
+ getElementDataType()->accept(visitor);
+ }
+ return true;
+ }
+
+private:
+ SGVec2<T> _value;
+};
+
+template<typename T>
+class HLAVec3DataElement : public HLAAbstractArrayDataElement {
+public:
+ HLAVec3DataElement(const HLAArrayDataType* dataType = 0) :
+ HLAAbstractArrayDataElement(dataType),
+ _value(SGVec3<T>::zeros())
+ {}
+ HLAVec3DataElement(const HLAArrayDataType* dataType, const SGVec3<T>& value) :
+ HLAAbstractArrayDataElement(dataType),
+ _value(value)
+ {}
+ const SGVec3<T>& getValue() const
+ { return _value; }
+ void setValue(const SGVec3<T>& value)
+ { _value = value; }
+
+ virtual bool setNumElements(unsigned count)
+ {
+ for (unsigned i = 3; i < count; ++i)
+ _value[i] = 0;
+ return true;
+ }
+ virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
+ {
+ if (i < 3) {
+ HLATemplateDecodeVisitor<typename SGVec3<T>::value_type> visitor(stream);
+ getElementDataType()->accept(visitor);
+ _value[i] = visitor.getValue();
+ } else {
+ HLADataTypeDecodeVisitor visitor(stream);
+ getElementDataType()->accept(visitor);
+ }
+ return true;
+ }
+
+ virtual unsigned getNumElements() const
+ {
+ return 3;
+ }
+ virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
+ {
+ if (i < 3) {
+ HLATemplateEncodeVisitor<typename SGVec3<T>::value_type> visitor(stream, _value[i]);
+ getElementDataType()->accept(visitor);
+ } else {
+ HLADataTypeEncodeVisitor visitor(stream);
+ getElementDataType()->accept(visitor);
+ }
+ return true;
+ }
+
+private:
+ SGVec3<T> _value;
+};
+
+template<typename T>
+class HLAVec4DataElement : public HLAAbstractArrayDataElement {
+public:
+ HLAVec4DataElement(const HLAArrayDataType* dataType = 0) :
+ HLAAbstractArrayDataElement(dataType),
+ _value(SGVec4<T>::zeros())
+ {}
+ HLAVec4DataElement(const HLAArrayDataType* dataType, const SGVec4<T>& value) :
+ HLAAbstractArrayDataElement(dataType),
+ _value(value)
+ {}
+ const SGVec4<T>& getValue() const
+ { return _value; }
+ void setValue(const SGVec4<T>& value)
+ { _value = value; }
+
+ virtual bool setNumElements(unsigned count)
+ {
+ for (unsigned i = 4; i < count; ++i)
+ _value[i] = 0;
+ return true;
+ }
+ virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
+ {
+ if (i < 4) {
+ HLATemplateDecodeVisitor<typename SGVec4<T>::value_type> visitor(stream);
+ getElementDataType()->accept(visitor);
+ _value[i] = visitor.getValue();
+ } else {
+ HLADataTypeDecodeVisitor visitor(stream);
+ getElementDataType()->accept(visitor);
+ }
+ return true;
+ }
+
+ virtual unsigned getNumElements() const
+ {
+ return 4;
+ }
+ virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
+ {
+ if (i < 4) {
+ HLATemplateEncodeVisitor<typename SGVec4<T>::value_type> visitor(stream, _value[i]);
+ getElementDataType()->accept(visitor);
+ } else {
+ HLADataTypeEncodeVisitor visitor(stream);
+ getElementDataType()->accept(visitor);
+ }
+ return true;
+ }
+
+private:
+ SGVec4<T> _value;
+};
+
+template<typename T>
+class HLAQuatDataElement : public HLAAbstractArrayDataElement {
+public:
+ HLAQuatDataElement(const HLAArrayDataType* dataType = 0) :
+ HLAAbstractArrayDataElement(dataType),
+ _value(SGQuat<T>::zeros())
+ {}
+ HLAQuatDataElement(const HLAArrayDataType* dataType, const SGQuat<T>& value) :
+ HLAAbstractArrayDataElement(dataType),
+ _value(value)
+ {}
+ const SGQuat<T>& getValue() const
+ { return _value; }
+ void setValue(const SGQuat<T>& value)
+ { _value = value; }
+
+ virtual bool setNumElements(unsigned count)
+ {
+ for (unsigned i = 4; i < count; ++i)
+ _value[i] = 0;
+ return true;
+ }
+ virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
+ {
+ if (i < 4) {
+ HLATemplateDecodeVisitor<typename SGQuat<T>::value_type> visitor(stream);
+ getElementDataType()->accept(visitor);
+ _value[i] = visitor.getValue();
+ } else {
+ HLADataTypeDecodeVisitor visitor(stream);
+ getElementDataType()->accept(visitor);
+ }
+ return true;
+ }
+
+ virtual unsigned getNumElements() const
+ {
+ return 4;
+ }
+ virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
+ {
+ if (i < 4) {
+ HLATemplateEncodeVisitor<typename SGQuat<T>::value_type> visitor(stream, _value[i]);
+ getElementDataType()->accept(visitor);
+ } else {
+ HLADataTypeEncodeVisitor visitor(stream);
+ getElementDataType()->accept(visitor);
+ }
+ return true;
+ }
+
+private:
+ SGQuat<T> _value;
+};
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "HLAArrayDataType.hxx"
+
+#include "HLAArrayDataElement.hxx"
+
+namespace simgear {
+
+HLAArrayDataType::HLAArrayDataType(const std::string& name) :
+ HLADataType(name)
+{
+}
+
+HLAArrayDataType::~HLAArrayDataType()
+{
+}
+
+void
+HLAArrayDataType::accept(HLADataTypeVisitor& visitor) const
+{
+ visitor.apply(*this);
+}
+
+const HLAArrayDataType*
+HLAArrayDataType::toArrayDataType() const
+{
+ return this;
+}
+
+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;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+
+HLAFixedArrayDataType::HLAFixedArrayDataType(const std::string& name) :
+ HLAArrayDataType(name)
+{
+}
+
+HLAFixedArrayDataType::~HLAFixedArrayDataType()
+{
+}
+
+void
+HLAFixedArrayDataType::accept(HLADataTypeVisitor& visitor) const
+{
+ visitor.apply(*this);
+}
+
+bool
+HLAFixedArrayDataType::decode(HLADecodeStream& stream, HLAAbstractArrayDataElement& value) const
+{
+ stream.alignOffsetForSize(getAlignment());
+ unsigned numElements = getNumElements();
+ if (!value.setNumElements(numElements))
+ return false;
+ for (unsigned i = 0; i < numElements; ++i)
+ if (!value.decodeElement(stream, i))
+ return false;
+ return true;
+}
+
+bool
+HLAFixedArrayDataType::encode(HLAEncodeStream& stream, const HLAAbstractArrayDataElement& value) const
+{
+ stream.alignOffsetForSize(getAlignment());
+ unsigned numElementsType = getNumElements();
+ unsigned numElementsValue = value.getNumElements();
+ unsigned numElements = SGMisc<unsigned>::min(numElementsType, numElementsValue);
+ unsigned i = 0;
+ for (; i < numElements; ++i)
+ if (!value.encodeElement(stream, i))
+ return false;
+ for (; i < numElementsType; ++i) {
+ HLADataTypeEncodeVisitor visitor(stream);
+ getElementDataType()->accept(visitor);
+ }
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+
+HLAVariableArrayDataType::HLAVariableArrayDataType(const std::string& name) :
+ HLAArrayDataType(name)
+{
+ setSizeDataType(new HLAUInt32BEDataType);
+}
+
+HLAVariableArrayDataType::~HLAVariableArrayDataType()
+{
+}
+
+void
+HLAVariableArrayDataType::accept(HLADataTypeVisitor& visitor) const
+{
+ visitor.apply(*this);
+}
+
+bool
+HLAVariableArrayDataType::decode(HLADecodeStream& stream, HLAAbstractArrayDataElement& value) const
+{
+ stream.alignOffsetForSize(getAlignment());
+ HLATemplateDecodeVisitor<unsigned> numElementsVisitor(stream);
+ getSizeDataType()->accept(numElementsVisitor);
+ unsigned numElements = numElementsVisitor.getValue();
+ if (!value.setNumElements(numElements))
+ return false;
+ for (unsigned i = 0; i < numElements; ++i)
+ if (!value.decodeElement(stream, i))
+ return false;
+ return true;
+}
+
+bool
+HLAVariableArrayDataType::encode(HLAEncodeStream& stream, const HLAAbstractArrayDataElement& value) const
+{
+ stream.alignOffsetForSize(getAlignment());
+ unsigned numElements = value.getNumElements();
+ HLATemplateEncodeVisitor<unsigned> numElementsVisitor(stream, numElements);
+ getSizeDataType()->accept(numElementsVisitor);
+ for (unsigned i = 0; i < numElements; ++i)
+ if (!value.encodeElement(stream, i))
+ return false;
+ return true;
+}
+
+void
+HLAVariableArrayDataType::setSizeDataType(const HLADataType* 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());
+}
+
+} // namespace simgear
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLAArrayDataType_hxx
+#define HLAArrayDataType_hxx
+
+#include <string>
+#include <simgear/structure/SGSharedPtr.hxx>
+#include "HLADataType.hxx"
+
+namespace simgear {
+
+class HLAAbstractArrayDataElement;
+
+class HLAArrayDataType : public HLADataType {
+public:
+ HLAArrayDataType(const std::string& name = "HLAArrayDataType");
+ virtual ~HLAArrayDataType();
+
+ virtual void accept(HLADataTypeVisitor& visitor) const;
+
+ virtual const HLAArrayDataType* toArrayDataType() const;
+
+ virtual bool decode(HLADecodeStream& stream, HLAAbstractArrayDataElement& value) const = 0;
+ virtual bool encode(HLAEncodeStream& stream, const HLAAbstractArrayDataElement& value) const = 0;
+
+ void setElementDataType(const HLADataType* elementDataType);
+ const HLADataType* getElementDataType() const
+ { return _elementDataType.get(); }
+
+private:
+ SGSharedPtr<const HLADataType> _elementDataType;
+};
+
+class HLAFixedArrayDataType : public HLAArrayDataType {
+public:
+ HLAFixedArrayDataType(const std::string& name = "HLAFixedArrayDataType");
+ virtual ~HLAFixedArrayDataType();
+
+ virtual void accept(HLADataTypeVisitor& visitor) const;
+
+ virtual bool decode(HLADecodeStream& stream, HLAAbstractArrayDataElement& value) const;
+ virtual bool encode(HLAEncodeStream& stream, const HLAAbstractArrayDataElement& value) const;
+
+ void setNumElements(unsigned numElements)
+ { _numElements = numElements; }
+ unsigned getNumElements() const
+ { return _numElements; }
+
+private:
+ unsigned _numElements;
+};
+
+class HLAVariableArrayDataType : public HLAArrayDataType {
+public:
+ HLAVariableArrayDataType(const std::string& name = "HLAVariableArrayDataType");
+ virtual ~HLAVariableArrayDataType();
+
+ virtual void accept(HLADataTypeVisitor& visitor) const;
+
+ 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
+ { return _sizeDataType.get(); }
+
+private:
+ SGSharedPtr<const HLADataType> _sizeDataType;
+};
+
+} // namespace simgear
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "HLABasicDataElement.hxx"
+
+#include "HLADataTypeVisitor.hxx"
+
+namespace simgear {
+
+HLABasicDataElement::HLABasicDataElement(const HLABasicDataType* dataType) :
+ _dataType(dataType)
+{
+}
+
+HLABasicDataElement::~HLABasicDataElement()
+{
+}
+
+const HLABasicDataType*
+HLABasicDataElement::getDataType() const
+{
+ return _dataType.get();
+}
+
+bool
+HLABasicDataElement::setDataType(const HLADataType* dataType)
+{
+ const HLABasicDataType* scalarDataType = dynamic_cast<const HLABasicDataType*>(dataType);
+ if (!scalarDataType) {
+ SG_LOG(SG_NETWORK, SG_WARN, "HLABasicDataType: unable to set data type!");
+ return false;
+ }
+ setDataType(scalarDataType);
+ return true;
+}
+
+void
+HLABasicDataElement::setDataType(const HLABasicDataType* dataType)
+{
+ _dataType = dataType;
+}
+
+#define IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(type, ctype) \
+HLAAbstract##type##DataElement::HLAAbstract##type##DataElement(const HLABasicDataType* dataType) :\
+ HLABasicDataElement(dataType) \
+{ \
+} \
+ \
+HLAAbstract##type##DataElement::~HLAAbstract##type##DataElement() \
+{ \
+} \
+ \
+bool \
+HLAAbstract##type##DataElement::encode(HLAEncodeStream& stream) const \
+{ \
+ if (!_dataType.valid()) \
+ return false; \
+ HLATemplateEncodeVisitor<ctype> visitor(stream, getValue()); \
+ _dataType->accept(visitor); \
+ return true; \
+} \
+ \
+bool \
+HLAAbstract##type##DataElement::decode(HLADecodeStream& stream) \
+{ \
+ if (!_dataType.valid()) \
+ return false; \
+ HLATemplateDecodeVisitor<ctype> visitor(stream); \
+ _dataType->accept(visitor); \
+ setValue(visitor.getValue()); \
+ return true; \
+} \
+ \
+HLA##type##DataElement::HLA##type##DataElement(const HLABasicDataType* dataType) : \
+ HLAAbstract##type##DataElement(dataType), \
+ _value(0) \
+{ \
+} \
+ \
+HLA##type##DataElement::HLA##type##DataElement(const HLABasicDataType* dataType, \
+ const ctype& value) : \
+ HLAAbstract##type##DataElement(dataType), \
+ _value(value) \
+{ \
+} \
+ \
+HLA##type##DataElement::~HLA##type##DataElement() \
+{ \
+} \
+ \
+ctype \
+HLA##type##DataElement::getValue() const \
+{ \
+ return _value; \
+} \
+ \
+void \
+HLA##type##DataElement::setValue(ctype value) \
+{ \
+ _value = value; \
+}
+
+IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(Char, char);
+IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(WChar, wchar_t);
+IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(SChar, signed char);
+IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(UChar, unsigned char);
+IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(Short, short);
+IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(UShort, unsigned short);
+IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(Int, int);
+IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(UInt, unsigned int);
+IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(Long, long);
+IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(ULong, unsigned long);
+IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(Float, float);
+IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(Double, double);
+
+#undef IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT
+
+}
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLABasicDataElement_hxx
+#define HLABasicDataElement_hxx
+
+#include "HLABasicDataType.hxx"
+#include "HLADataElement.hxx"
+
+namespace simgear {
+
+class HLABasicDataElement : public HLADataElement {
+public:
+ HLABasicDataElement(const HLABasicDataType* dataType);
+ virtual ~HLABasicDataElement();
+
+ virtual const HLABasicDataType* getDataType() const;
+ virtual bool setDataType(const HLADataType* dataType);
+ void setDataType(const HLABasicDataType* dataType);
+
+protected:
+ SGSharedPtr<const HLABasicDataType> _dataType;
+};
+
+#define TYPED_HLA_BASIC_DATA_ELEMENT(type, ctype) \
+class HLAAbstract##type##DataElement : public HLABasicDataElement { \
+public: \
+ HLAAbstract##type##DataElement(const HLABasicDataType* dataType = 0); \
+ virtual ~HLAAbstract##type##DataElement(); \
+ virtual bool encode(HLAEncodeStream& stream) const; \
+ virtual bool decode(HLADecodeStream& stream); \
+ \
+ virtual ctype getValue() const = 0; \
+ virtual void setValue(ctype) = 0; \
+}; \
+class HLA##type##DataElement : public HLAAbstract##type##DataElement { \
+public: \
+ HLA##type##DataElement(const HLABasicDataType* dataType = 0); \
+ HLA##type##DataElement(const HLABasicDataType* dataType, \
+ const ctype& value); \
+ virtual ~HLA##type##DataElement(); \
+ virtual ctype getValue() const; \
+ virtual void setValue(ctype value); \
+private: \
+ ctype _value; \
+}; \
+class HLA##type##Data { \
+public: \
+ HLA##type##Data() : \
+ _value(new HLA##type##DataElement(0)) \
+ { } \
+ HLA##type##Data(const ctype& value) : \
+ _value(new HLA##type##DataElement(0, value)) \
+ { } \
+ operator ctype() const \
+ { return _value->getValue(); } \
+ HLA##type##Data& operator=(const ctype& value) \
+ { _value->setValue(value); return *this; } \
+ ctype getValue() const \
+ { return _value->getValue(); } \
+ void setValue(const ctype& value) \
+ { _value->setValue(value); } \
+ const HLA##type##DataElement* getDataElement() const \
+ { return _value.get(); } \
+ HLA##type##DataElement* getDataElement() \
+ { return _value.get(); } \
+ const HLABasicDataType* getDataType() const \
+ { return _value->getDataType(); } \
+ void setDataType(const HLABasicDataType* dataType) \
+ { _value->setDataType(dataType); } \
+ \
+private: \
+ SGSharedPtr<HLA##type##DataElement> _value; \
+};
+
+
+TYPED_HLA_BASIC_DATA_ELEMENT(Char, char);
+TYPED_HLA_BASIC_DATA_ELEMENT(WChar, wchar_t);
+TYPED_HLA_BASIC_DATA_ELEMENT(SChar, signed char);
+TYPED_HLA_BASIC_DATA_ELEMENT(UChar, unsigned char);
+TYPED_HLA_BASIC_DATA_ELEMENT(Short, short);
+TYPED_HLA_BASIC_DATA_ELEMENT(UShort, unsigned short);
+TYPED_HLA_BASIC_DATA_ELEMENT(Int, int);
+TYPED_HLA_BASIC_DATA_ELEMENT(UInt, unsigned int);
+TYPED_HLA_BASIC_DATA_ELEMENT(Long, long);
+TYPED_HLA_BASIC_DATA_ELEMENT(ULong, unsigned long);
+TYPED_HLA_BASIC_DATA_ELEMENT(Float, float);
+TYPED_HLA_BASIC_DATA_ELEMENT(Double, double);
+
+#undef TYPED_HLA_BASIC_DATA_ELEMENT
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "HLABasicDataType.hxx"
+
+#include "HLADataType.hxx"
+#include "HLADataTypeVisitor.hxx"
+
+namespace simgear {
+
+HLABasicDataType::HLABasicDataType(const std::string& name) :
+ HLADataType(name)
+{
+}
+
+HLABasicDataType::~HLABasicDataType()
+{
+}
+
+void
+HLABasicDataType::accept(HLADataTypeVisitor& visitor) const
+{
+ visitor.apply(*this);
+}
+
+const HLABasicDataType*
+HLABasicDataType::toBasicDataType() const
+{
+ return this;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+HLAInt8DataType::HLAInt8DataType(const std::string& name) :
+ HLABasicDataType(name)
+{
+ setAlignment(sizeof(int8_t));
+}
+
+HLAInt8DataType::~HLAInt8DataType()
+{
+}
+
+void
+HLAInt8DataType::accept(HLADataTypeVisitor& visitor) const
+{
+ visitor.apply(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+HLAUInt8DataType::HLAUInt8DataType(const std::string& name) :
+ HLABasicDataType(name)
+{
+ setAlignment(sizeof(uint8_t));
+}
+
+HLAUInt8DataType::~HLAUInt8DataType()
+{
+}
+
+void
+HLAUInt8DataType::accept(HLADataTypeVisitor& visitor) const
+{
+ visitor.apply(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+#define BASIC_DATATYPE_IMPLEMENTATION(type, name) \
+HLA##name##DataType::HLA##name##DataType(const std::string& name) : \
+ HLABasicDataType(name) \
+{ \
+ setAlignment(sizeof(type)); \
+} \
+ \
+HLA##name##DataType::~HLA##name##DataType() \
+{ \
+} \
+ \
+void \
+HLA##name##DataType::accept(HLADataTypeVisitor& visitor) const \
+{ \
+ visitor.apply(*this); \
+} \
+ \
+ \
+ \
+HLA##name##LEDataType::HLA##name##LEDataType(const std::string& name) : \
+ HLA##name##DataType(name) \
+{ \
+} \
+ \
+HLA##name##LEDataType::~HLA##name##LEDataType() \
+{ \
+} \
+ \
+bool \
+HLA##name##LEDataType::decode(HLADecodeStream& stream, \
+ type& value) const \
+{ \
+ if (!stream.alignOffsetForSize(getAlignment())) \
+ return false; \
+ return stream.decode##name##LE(value); \
+} \
+ \
+bool \
+HLA##name##LEDataType::encode(HLAEncodeStream& stream, \
+ const type& value) const \
+{ \
+ if (!stream.alignOffsetForSize(getAlignment())) \
+ return false; \
+ return stream.encode##name##LE(value); \
+} \
+ \
+ \
+ \
+HLA##name##BEDataType::HLA##name##BEDataType(const std::string& name) : \
+ HLA##name##DataType(name) \
+{ \
+} \
+ \
+HLA##name##BEDataType::~HLA##name##BEDataType() \
+{ \
+} \
+ \
+bool \
+HLA##name##BEDataType::decode(HLADecodeStream& stream, \
+ type& value) const \
+{ \
+ if (!stream.alignOffsetForSize(getAlignment())) \
+ return false; \
+ return stream.decode##name##BE(value); \
+} \
+ \
+bool \
+HLA##name##BEDataType::encode(HLAEncodeStream& stream, \
+ const type& value) const \
+{ \
+ if (!stream.alignOffsetForSize(getAlignment())) \
+ return false; \
+ return stream.encode##name##BE(value); \
+}
+
+BASIC_DATATYPE_IMPLEMENTATION(int16_t, Int16)
+BASIC_DATATYPE_IMPLEMENTATION(uint16_t, UInt16)
+BASIC_DATATYPE_IMPLEMENTATION(int32_t, Int32)
+BASIC_DATATYPE_IMPLEMENTATION(uint32_t, UInt32)
+BASIC_DATATYPE_IMPLEMENTATION(int64_t, Int64)
+BASIC_DATATYPE_IMPLEMENTATION(uint64_t, UInt64)
+BASIC_DATATYPE_IMPLEMENTATION(float, Float32)
+BASIC_DATATYPE_IMPLEMENTATION(double, Float64)
+
+#undef BASIC_DATATYPE_IMPLEMENTATION
+
+} // namespace simgear
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLABasicDataType_hxx
+#define HLABasicDataType_hxx
+
+#include <string>
+#include "HLADataType.hxx"
+
+namespace simgear {
+
+class HLABasicDataType : public HLADataType {
+public:
+ virtual ~HLABasicDataType();
+ virtual void accept(HLADataTypeVisitor& visitor) const;
+
+ virtual const HLABasicDataType* toBasicDataType() const;
+
+protected:
+ HLABasicDataType(const std::string& name);
+};
+
+class HLAInt8DataType : public HLABasicDataType {
+public:
+ HLAInt8DataType(const std::string& name = "HLAInt8DataType");
+ virtual ~HLAInt8DataType();
+
+ virtual void accept(HLADataTypeVisitor& visitor) const;
+
+ bool skip(HLADecodeStream& stream) const
+ {
+ if (!stream.alignOffsetForSize(getAlignment()))
+ return false;
+ return stream.skip(1);
+ }
+ bool skip(HLAEncodeStream& stream) const
+ {
+ if (!stream.alignOffsetForSize(getAlignment()))
+ return false;
+ return stream.skip(1);
+ }
+ bool decode(HLADecodeStream& stream, int8_t& value) const
+ {
+ if (!stream.alignOffsetForSize(getAlignment()))
+ return false;
+ return stream.decodeInt8(value);
+ }
+ bool encode(HLAEncodeStream& stream, const int8_t& value) const
+ {
+ if (!stream.alignOffsetForSize(getAlignment()))
+ return false;
+ return stream.encodeInt8(value);
+ }
+};
+
+class HLAUInt8DataType : public HLABasicDataType {
+public:
+ HLAUInt8DataType(const std::string& name = "HLAUInt8DataType");
+ virtual ~HLAUInt8DataType();
+
+ virtual void accept(HLADataTypeVisitor& visitor) const;
+
+ bool skip(HLADecodeStream& stream) const
+ {
+ if (!stream.alignOffsetForSize(getAlignment()))
+ return false;
+ return stream.skip(1);
+ }
+ bool skip(HLAEncodeStream& stream) const
+ {
+ if (!stream.alignOffsetForSize(getAlignment()))
+ return false;
+ return stream.skip(1);
+ }
+ bool decode(HLADecodeStream& stream, uint8_t& value) const
+ {
+ if (!stream.alignOffsetForSize(getAlignment()))
+ return false;
+ return stream.decodeUInt8(value);
+ }
+ bool encode(HLAEncodeStream& stream, const uint8_t& value) const
+ {
+ if (!stream.alignOffsetForSize(getAlignment()))
+ return false;
+ return stream.encodeUInt8(value);
+ }
+};
+
+#define BASIC_DATATYPE_IMPLEMENTATION(type, name) \
+class HLA##name##DataType : public HLABasicDataType { \
+public: \
+ virtual ~HLA##name##DataType(); \
+ \
+ virtual void accept(HLADataTypeVisitor& visitor) const; \
+ \
+ bool skip(HLADecodeStream& stream) const \
+ { \
+ if (!stream.alignOffsetForSize(getAlignment())) \
+ return false; \
+ return stream.skip(sizeof(type)); \
+ } \
+ bool skip(HLAEncodeStream& stream) const \
+ { \
+ if (!stream.alignOffsetForSize(getAlignment())) \
+ return false; \
+ return stream.skip(sizeof(type)); \
+ } \
+ virtual bool decode(HLADecodeStream& stream, type& value) const = 0; \
+ virtual bool encode(HLAEncodeStream& stream, const type& value) const = 0;\
+protected: \
+ HLA##name##DataType(const std::string& name); \
+}; \
+class HLA##name##LEDataType : public HLA##name##DataType { \
+public: \
+ HLA##name##LEDataType(const std::string& name = "HLA" #name "LEDataType");\
+ virtual ~HLA##name##LEDataType(); \
+ virtual bool decode(HLADecodeStream& stream, type& value) const; \
+ virtual bool encode(HLAEncodeStream& stream, const type& value) const; \
+}; \
+class HLA##name##BEDataType : public HLA##name##DataType { \
+public: \
+ HLA##name##BEDataType(const std::string& name = "HLA" #name "BEDataType");\
+ virtual ~HLA##name##BEDataType(); \
+ virtual bool decode(HLADecodeStream& stream, type& value) const; \
+ virtual bool encode(HLAEncodeStream& stream, const type& value) const; \
+};
+
+BASIC_DATATYPE_IMPLEMENTATION(int16_t, Int16)
+BASIC_DATATYPE_IMPLEMENTATION(uint16_t, UInt16)
+BASIC_DATATYPE_IMPLEMENTATION(int32_t, Int32)
+BASIC_DATATYPE_IMPLEMENTATION(uint32_t, UInt32)
+BASIC_DATATYPE_IMPLEMENTATION(int64_t, Int64)
+BASIC_DATATYPE_IMPLEMENTATION(uint64_t, UInt64)
+BASIC_DATATYPE_IMPLEMENTATION(float, Float32)
+BASIC_DATATYPE_IMPLEMENTATION(double, Float64)
+
+#undef BASIC_DATATYPE_IMPLEMENTATION
+
+} // namespace simgear
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "HLADataElement.hxx"
+
+#include <simgear/debug/logstream.hxx>
+
+namespace simgear {
+
+HLADataElement::PathElement::Data::~Data()
+{
+}
+
+const HLADataElement::PathElement::FieldData*
+HLADataElement::PathElement::Data::toFieldData() const
+{
+ return 0;
+}
+
+const HLADataElement::PathElement::IndexData*
+HLADataElement::PathElement::Data::toIndexData() const
+{
+ return 0;
+}
+
+HLADataElement::PathElement::FieldData::FieldData(const std::string& name) :
+ _name(name)
+{
+}
+
+HLADataElement::PathElement::FieldData::~FieldData()
+{
+}
+
+const HLADataElement::PathElement::FieldData*
+HLADataElement::PathElement::FieldData::toFieldData() const
+{
+ return this;
+}
+
+bool
+HLADataElement::PathElement::FieldData::less(const Data* data) const
+{
+ const FieldData* fieldData = data->toFieldData();
+ // IndexData is allways smaller than FieldData
+ if (!fieldData)
+ return false;
+ return _name < fieldData->_name;
+}
+
+bool
+HLADataElement::PathElement::FieldData::equal(const Data* data) const
+{
+ const FieldData* fieldData = data->toFieldData();
+ // IndexData is allways smaller than FieldData
+ if (!fieldData)
+ return false;
+ return _name == fieldData->_name;
+}
+
+void
+HLADataElement::PathElement::FieldData::append(std::string& s) const
+{
+ s.append(1, std::string::value_type('.'));
+ s.append(_name);
+}
+
+HLADataElement::PathElement::IndexData::IndexData(unsigned index) :
+ _index(index)
+{
+}
+
+HLADataElement::PathElement::IndexData::~IndexData()
+{
+}
+
+const HLADataElement::PathElement::IndexData*
+HLADataElement::PathElement::IndexData::toIndexData() const
+{
+ return this;
+}
+
+bool
+HLADataElement::PathElement::IndexData::less(const Data* data) const
+{
+ const IndexData* indexData = data->toIndexData();
+ // IndexData is allways smaller than FieldData
+ if (!indexData)
+ return true;
+ return _index < indexData->_index;
+}
+
+bool
+HLADataElement::PathElement::IndexData::equal(const Data* data) const
+{
+ const IndexData* indexData = data->toIndexData();
+ // IndexData is allways smaller than FieldData
+ if (!indexData)
+ return false;
+ return _index == indexData->_index;
+}
+
+void
+HLADataElement::PathElement::IndexData::append(std::string& s) const
+{
+ s.append(1, std::string::value_type('['));
+ unsigned value = _index;
+ do {
+ s.append(1, std::string::value_type('0' + value % 10));
+ } while (value /= 10);
+ s.append(1, std::string::value_type(']'));
+}
+
+HLADataElement::~HLADataElement()
+{
+}
+
+std::string
+HLADataElement::toString(const Path& path)
+{
+ std::string s;
+ for (Path::const_iterator i = path.begin(); i != path.end(); ++i)
+ i->append(s);
+ return s;
+}
+
+HLADataElement::AttributePathPair
+HLADataElement::toAttributePathPair(const std::string& s)
+{
+ Path path;
+ // Skip the initial attribute name if given
+ std::string::size_type i = s.find_first_of("[.");
+ std::string attribute = s.substr(0, i);
+ while (i < s.size()) {
+ if (s[i] == '[') {
+ ++i;
+ unsigned index = 0;
+ while (i < s.size()) {
+ if (s[i] == ']')
+ break;
+ unsigned v = s[i] - '0';
+ // Error, no number
+ if (10 <= v) {
+ SG_LOG(SG_NETWORK, SG_WARN, "HLADataElement: invalid character in array subscript for \""
+ << s << "\" at \"" << attribute << toString(path) << "\"!");
+ return AttributePathPair();
+ }
+ index *= 10;
+ index += v;
+ ++i;
+ }
+ path.push_back(index);
+ ++i;
+ continue;
+ }
+ if (s[i] == '.') {
+ // Error, . cannot be last
+ if (s.size() <= ++i) {
+ SG_LOG(SG_NETWORK, SG_WARN, "HLADataElement: invalid terminating '.' for \""
+ << s << "\"!");
+ return AttributePathPair();
+ }
+ std::string::size_type e = s.find_first_of("[.", i);
+ path.push_back(s.substr(i, e - i));
+ i = e;
+ continue;
+ }
+ }
+
+ return AttributePathPair(attribute, path);
+}
+
+}
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLADataElement_hxx
+#define HLADataElement_hxx
+
+#include <list>
+#include <map>
+#include <simgear/structure/SGReferenced.hxx>
+#include <simgear/structure/SGSharedPtr.hxx>
+#include <simgear/timing/timestamp.hxx>
+#include "RTIData.hxx"
+#include "HLADataType.hxx"
+
+class SGTimeStamp;
+
+namespace simgear {
+
+class HLADataElement : public SGReferenced {
+public:
+ virtual ~HLADataElement();
+
+ virtual bool encode(HLAEncodeStream& stream) const = 0;
+ virtual bool decode(HLADecodeStream& stream) = 0;
+
+ virtual const HLADataType* getDataType() const = 0;
+ virtual bool setDataType(const HLADataType* dataType) = 0;
+
+ // Container for the timestamp the originating attribute was last updated for
+ // class TimeStamp : public SGReferenced {
+ // public:
+ // const SGTimeStamp& getTimeStamp() const
+ // { return _timeStamp; }
+ // void setTimeStamp(const SGTimeStamp& timeStamp)
+ // { _timeStamp = timeStamp; }
+ // private:
+ // SGTimeStamp _timeStamp;
+ // };
+
+ // const TimeStamp* getTimeStamp() const
+ // { return _timeStamp.get(); }
+ // void setTimeStamp(const TimeStamp* timeStamp)
+ // { _timeStamp = timeStamp; }
+
+ // struct ChangeCount : public SGReferenced {
+ // ChangeCount() : _value(0) {}
+ // unsigned _value;
+ // };
+ // SGSharedPtr<ChangeCount> _changeCount;
+ // unsigned getChangeCount() const
+ // {
+ // // If we don't have return allways the same
+ // if (!_changeCount.valid())
+ // return 0;
+ // return _changeCount->_value;
+ // }
+
+ /// HLADataElements could be identified by path
+ /// These paths are composed of structure field names and array indices in the
+ /// order they appear while walking to the data element.
+ /// So provide here some tool functions to access these elements
+ /// Note that these functions are relatively expensive in execution time.
+ /// So only use them once at object creation time and store direct references to the values
+
+ class PathElement {
+ public:
+ PathElement(unsigned index) : _data(new IndexData(index)) {}
+ PathElement(const std::string& name) : _data(new FieldData(name)) {}
+
+ bool isFieldValue() const
+ { return _data->toFieldData(); }
+ bool isIndexValue() const
+ { return _data->toIndexData(); }
+
+ unsigned getIndexValue() const
+ {
+ const IndexData* indexData = _data->toIndexData();
+ if (!indexData)
+ return ~unsigned(0);
+ return indexData->_index;
+ }
+
+ std::string getFieldValue() const
+ {
+ const FieldData* fieldData = _data->toFieldData();
+ if (!fieldData)
+ return std::string();
+ return fieldData->_name;
+ }
+
+ // Want to be able to use that in std::map and std::set
+ bool operator<(const PathElement& pathElement) const
+ { return _data->less(pathElement._data.get()); }
+ bool operator==(const PathElement& pathElement) const
+ { return _data->equal(pathElement._data.get()); }
+
+ void append(std::string& s) const
+ { _data->append(s); }
+
+ private:
+ struct FieldData;
+ struct IndexData;
+ struct Data : public SGReferenced {
+ virtual ~Data();
+ virtual const FieldData* toFieldData() const;
+ virtual const IndexData* toIndexData() const;
+ virtual bool less(const Data*) const = 0;
+ virtual bool equal(const Data*) const = 0;
+ virtual void append(std::string&) const = 0;
+ };
+ struct FieldData : public Data {
+ FieldData(const std::string& name);
+ virtual ~FieldData();
+ virtual const FieldData* toFieldData() const;
+ virtual bool less(const Data* data) const;
+ virtual bool equal(const Data* data) const;
+ virtual void append(std::string& s) const;
+ std::string _name;
+ };
+ struct IndexData : public Data {
+ IndexData(unsigned index);
+ virtual ~IndexData();
+ virtual const IndexData* toIndexData() const;
+ virtual bool less(const Data* data) const;
+ virtual bool equal(const Data* data) const;
+ virtual void append(std::string& s) const;
+ unsigned _index;
+ };
+
+ SGSharedPtr<Data> _data;
+ };
+ typedef std::list<PathElement> Path;
+ typedef std::pair<std::string, Path> AttributePathPair;
+ typedef std::pair<unsigned, Path> IndexPathPair;
+
+ static std::string toString(const Path& path);
+ static std::string toString(const AttributePathPair& path)
+ { return path.first + toString(path.second); }
+ static AttributePathPair toAttributePathPair(const std::string& s);
+ static Path toPath(const std::string& s)
+ { return toAttributePathPair(s).second; }
+
+private:
+ // SGSharedPtr<const TimeStamp> _timeStamp;
+};
+
+class HLADataElementProvider {
+public:
+ class AbstractProvider : public SGReferenced {
+ public:
+ virtual ~AbstractProvider() { }
+ virtual HLADataElement* getDataElement(const HLADataElement::Path& path) = 0;
+ // virtual HLADataElement* getDataElement(const HLADataElement::Path& path, const HLADataType* dataType)
+ // {
+ // SGSharedPtr<HLADataElement> dataElement = getDataElement(path);
+ // if (!dataElement.valid())
+ // return 0;
+ // if (!dataElement->setDataType(dataType))
+ // return 0;
+ // return dataElement.release();
+ // }
+ };
+
+ HLADataElementProvider()
+ { }
+ HLADataElementProvider(HLADataElement* dataElement) :
+ _provider(new ConcreteProvider(dataElement))
+ { }
+ HLADataElementProvider(const SGSharedPtr<HLADataElement>& dataElement) :
+ _provider(new ConcreteProvider(dataElement))
+ { }
+ HLADataElementProvider(AbstractProvider* provider) :
+ _provider(provider)
+ { }
+
+ HLADataElement* getDataElement(const HLADataElement::Path& path) const
+ {
+ if (!_provider.valid())
+ return 0;
+ return _provider->getDataElement(path);
+ }
+
+private:
+ class ConcreteProvider : public AbstractProvider {
+ public:
+ ConcreteProvider(const SGSharedPtr<HLADataElement>& dataElement) :
+ _dataElement(dataElement)
+ { }
+ virtual HLADataElement* getDataElement(const HLADataElement::Path&)
+ { return _dataElement.get(); }
+ private:
+ SGSharedPtr<HLADataElement> _dataElement;
+ };
+
+ SGSharedPtr<AbstractProvider> _provider;
+};
+
+typedef std::map<HLADataElement::Path, HLADataElementProvider> HLAPathElementMap;
+typedef std::map<unsigned, HLAPathElementMap> HLAAttributePathElementMap;
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "HLADataType.hxx"
+
+#include "HLADataElement.hxx"
+#include "HLADataTypeVisitor.hxx"
+
+namespace simgear {
+
+HLADataType::HLADataType(const std::string& name, unsigned alignment) :
+ _name(name),
+ _alignment(1)
+{
+ setAlignment(alignment);
+}
+
+HLADataType::~HLADataType()
+{
+}
+
+void
+HLADataType::accept(HLADataTypeVisitor& visitor) const
+{
+ visitor.apply(*this);
+}
+
+const HLADataTypeReference*
+HLADataType::toDataTypeReference() const
+{
+ return 0;
+}
+
+const HLABasicDataType*
+HLADataType::toBasicDataType() const
+{
+ return 0;
+}
+
+const HLAArrayDataType*
+HLADataType::toArrayDataType() const
+{
+ return 0;
+}
+
+const HLAEnumeratedDataType*
+HLADataType::toEnumeratedDataType() const
+{
+ return 0;
+}
+
+const HLAFixedRecordDataType*
+HLADataType::toFixedRecordDataType() const
+{
+ return 0;
+}
+
+const HLAVariantDataType*
+HLADataType::toVariantDataType() const
+{
+ return 0;
+}
+
+void
+HLADataType::setAlignment(unsigned alignment)
+{
+ /// FIXME: more checks
+ if (alignment == 0)
+ _alignment = 1;
+ else
+ _alignment = alignment;
+}
+
+HLADataTypeReference::~HLADataTypeReference()
+{
+}
+
+void
+HLADataTypeReference::accept(HLADataTypeVisitor& visitor) const
+{
+ visitor.apply(*this);
+}
+
+const HLADataTypeReference*
+HLADataTypeReference::toDataTypeReference() const
+{
+ return this;
+}
+
+}
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLADataType_hxx
+#define HLADataType_hxx
+
+#include <string>
+#include <simgear/structure/SGWeakPtr.hxx>
+#include <simgear/structure/SGWeakReferenced.hxx>
+#include "RTIData.hxx"
+
+namespace simgear {
+
+class HLADataTypeVisitor;
+
+class HLADataTypeReference;
+class HLABasicDataType;
+class HLAArrayDataType;
+class HLAEnumeratedDataType;
+class HLAFixedRecordDataType;
+class HLAVariantDataType;
+
+enum HLAUpdateType {
+ HLAStaticUpdate,
+ HLAPeriodicUpdate,
+ HLAConditionalUpdate,
+ HLAUndefinedUpdate
+};
+
+class HLADataType : public SGWeakReferenced {
+public:
+ virtual ~HLADataType();
+
+ const std::string& getName() const
+ { return _name; }
+
+ const std::string& getSemantics() const
+ { return _semantics; }
+ void setSemantics(const std::string& semantics)
+ { _semantics = semantics; }
+
+ unsigned getAlignment() const
+ { return _alignment; }
+
+ 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;
+ virtual const HLAFixedRecordDataType* toFixedRecordDataType() const;
+ virtual const HLAVariantDataType* toVariantDataType() const;
+
+protected:
+ HLADataType(const std::string& name, unsigned alignment = 1);
+ void setAlignment(unsigned alignment);
+
+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
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLADataTypeVisitor_hxx
+#define HLADataTypeVisitor_hxx
+
+#include <cassert>
+#include <string>
+#include <simgear/debug/logstream.hxx>
+#include <simgear/math/SGMath.hxx>
+#include "HLAArrayDataType.hxx"
+#include "HLABasicDataType.hxx"
+#include "HLADataTypeVisitor.hxx"
+#include "HLAEnumeratedDataType.hxx"
+#include "HLAFixedRecordDataType.hxx"
+#include "HLAVariantDataType.hxx"
+
+namespace simgear {
+
+class HLADataTypeVisitor {
+public:
+ virtual ~HLADataTypeVisitor() {}
+
+ 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)
+ { apply(static_cast<const HLABasicDataType&>(dataType)); }
+ virtual void apply(const HLAUInt8DataType& dataType)
+ { apply(static_cast<const HLABasicDataType&>(dataType)); }
+ virtual void apply(const HLAInt16DataType& dataType)
+ { apply(static_cast<const HLABasicDataType&>(dataType)); }
+ virtual void apply(const HLAUInt16DataType& dataType)
+ { apply(static_cast<const HLABasicDataType&>(dataType)); }
+ virtual void apply(const HLAInt32DataType& dataType)
+ { apply(static_cast<const HLABasicDataType&>(dataType)); }
+ virtual void apply(const HLAUInt32DataType& dataType)
+ { apply(static_cast<const HLABasicDataType&>(dataType)); }
+ virtual void apply(const HLAInt64DataType& dataType)
+ { apply(static_cast<const HLABasicDataType&>(dataType)); }
+ virtual void apply(const HLAUInt64DataType& dataType)
+ { apply(static_cast<const HLABasicDataType&>(dataType)); }
+ virtual void apply(const HLAFloat32DataType& dataType)
+ { apply(static_cast<const HLABasicDataType&>(dataType)); }
+ virtual void apply(const HLAFloat64DataType& dataType)
+ { apply(static_cast<const HLABasicDataType&>(dataType)); }
+
+ virtual void apply(const HLAArrayDataType& dataType)
+ { apply(static_cast<const HLADataType&>(dataType)); }
+ virtual void apply(const HLAFixedArrayDataType& dataType)
+ { apply(static_cast<const HLAArrayDataType&>(dataType)); }
+ virtual void apply(const HLAVariableArrayDataType& dataType)
+ { apply(static_cast<const HLAArrayDataType&>(dataType)); }
+
+ virtual void apply(const HLAEnumeratedDataType& dataType)
+ { apply(static_cast<const HLADataType&>(dataType)); }
+
+ virtual void apply(const HLAFixedRecordDataType& dataType)
+ { apply(static_cast<const HLADataType&>(dataType)); }
+
+ virtual void apply(const HLAVariantDataType& dataType)
+ { apply(static_cast<const HLADataType&>(dataType)); }
+};
+
+/// Walks the datatype tree and checks if it is completely defined
+class HLADataTypeCheckVisitor : public HLADataTypeVisitor {
+public:
+ HLADataTypeCheckVisitor() : _valid(true) {}
+
+ bool valid() const { return _valid; }
+
+ virtual void apply(const HLAInt8DataType& dataType) { }
+ virtual void apply(const HLAUInt8DataType& dataType) { }
+ virtual void apply(const HLAInt16DataType& dataType) { }
+ virtual void apply(const HLAUInt16DataType& dataType) { }
+ virtual void apply(const HLAInt32DataType& dataType) { }
+ virtual void apply(const HLAUInt32DataType& dataType) { }
+ virtual void apply(const HLAInt64DataType& dataType) { }
+ virtual void apply(const HLAUInt64DataType& dataType) { }
+ virtual void apply(const HLAFloat32DataType& dataType) { }
+ virtual void apply(const HLAFloat64DataType& dataType) { }
+
+ virtual void apply(const HLAFixedArrayDataType& dataType)
+ {
+ if (!dataType.getElementDataType())
+ _valid = false;
+ else
+ dataType.getElementDataType()->accept(*this);
+ }
+ virtual void apply(const HLAVariableArrayDataType& dataType)
+ {
+ if (!dataType.getElementDataType())
+ _valid = false;
+ else
+ dataType.getElementDataType()->accept(*this);
+
+ if (!dataType.getSizeDataType())
+ _valid = false;
+ else
+ dataType.getSizeDataType()->accept(*this);
+ }
+
+ virtual void apply(const HLAEnumeratedDataType& dataType)
+ {
+ if (!dataType.getRepresentation())
+ _valid = false;
+ else
+ dataType.getRepresentation()->accept(*this);
+ }
+
+ virtual void apply(const HLAFixedRecordDataType& dataType)
+ {
+ unsigned numFields = dataType.getNumFields();
+ for (unsigned i = 0; i < numFields; ++i) {
+ if (!dataType.getFieldDataType(i))
+ _valid = false;
+ else
+ dataType.getFieldDataType(i)->accept(*this);
+ }
+ }
+
+ virtual void apply(const HLAVariantDataType& dataType)
+ { assert(0); }
+
+protected:
+ bool _valid;
+};
+
+class HLADataTypeDecodeVisitor : public HLADataTypeVisitor {
+public:
+ HLADataTypeDecodeVisitor(HLADecodeStream& stream) : _stream(stream) {}
+ virtual ~HLADataTypeDecodeVisitor() {}
+
+ virtual void apply(const HLAInt8DataType& dataType) { dataType.skip(_stream); }
+ virtual void apply(const HLAUInt8DataType& dataType) { dataType.skip(_stream); }
+ virtual void apply(const HLAInt16DataType& dataType) { dataType.skip(_stream); }
+ virtual void apply(const HLAUInt16DataType& dataType) { dataType.skip(_stream); }
+ virtual void apply(const HLAInt32DataType& dataType) { dataType.skip(_stream); }
+ virtual void apply(const HLAUInt32DataType& dataType) { dataType.skip(_stream); }
+ virtual void apply(const HLAInt64DataType& dataType) { dataType.skip(_stream); }
+ virtual void apply(const HLAUInt64DataType& dataType) { dataType.skip(_stream); }
+ virtual void apply(const HLAFloat32DataType& dataType) { dataType.skip(_stream); }
+ virtual void apply(const HLAFloat64DataType& dataType) { dataType.skip(_stream); }
+
+ virtual void apply(const HLAFixedArrayDataType& dataType)
+ {
+ unsigned numElements = dataType.getNumElements();
+ for (unsigned i = 0; i < numElements; ++i)
+ dataType.getElementDataType()->accept(*this);
+ }
+ virtual void apply(const HLAVariableArrayDataType& dataType);
+
+ virtual void apply(const HLAEnumeratedDataType& dataType)
+ {
+ dataType.getRepresentation()->accept(*this);
+ }
+
+ virtual void apply(const HLAFixedRecordDataType& dataType)
+ {
+ unsigned numFields = dataType.getNumFields();
+ for (unsigned i = 0; i < numFields; ++i)
+ dataType.getFieldDataType(i)->accept(*this);
+ }
+
+ virtual void apply(const HLAVariantDataType& dataType) { assert(0); }
+
+protected:
+ HLADecodeStream& _stream;
+};
+
+class HLADataTypeEncodeVisitor : public HLADataTypeVisitor {
+public:
+ HLADataTypeEncodeVisitor(HLAEncodeStream& stream) : _stream(stream) {}
+ virtual ~HLADataTypeEncodeVisitor() {}
+
+ virtual void apply(const HLAInt8DataType& dataType) { dataType.skip(_stream); }
+ virtual void apply(const HLAUInt8DataType& dataType) { dataType.skip(_stream); }
+ virtual void apply(const HLAInt16DataType& dataType) { dataType.skip(_stream); }
+ virtual void apply(const HLAUInt16DataType& dataType) { dataType.skip(_stream); }
+ virtual void apply(const HLAInt32DataType& dataType) { dataType.skip(_stream); }
+ virtual void apply(const HLAUInt32DataType& dataType) { dataType.skip(_stream); }
+ virtual void apply(const HLAInt64DataType& dataType) { dataType.skip(_stream); }
+ virtual void apply(const HLAUInt64DataType& dataType) { dataType.skip(_stream); }
+ virtual void apply(const HLAFloat32DataType& dataType) { dataType.skip(_stream); }
+ virtual void apply(const HLAFloat64DataType& dataType) { dataType.skip(_stream); }
+
+ virtual void apply(const HLAFixedArrayDataType& dataType)
+ {
+ /// FIXME, might vanish in this sense ...
+ // dataType.encode(_stream, *this);
+ unsigned numElements = dataType.getNumElements();
+ for (unsigned i = 0; i < numElements; ++i)
+ dataType.getElementDataType()->accept(*this);
+ }
+ virtual void apply(const HLAVariableArrayDataType& dataType);
+
+ virtual void apply(const HLAEnumeratedDataType& dataType)
+ {
+ dataType.getRepresentation()->accept(*this);
+ }
+
+ virtual void apply(const HLAFixedRecordDataType& dataType)
+ {
+ unsigned numFields = dataType.getNumFields();
+ for (unsigned i = 0; i < numFields; ++i)
+ dataType.getFieldDataType(i)->accept(*this);
+ }
+
+ virtual void apply(const HLAVariantDataType& dataType) { assert(0); }
+
+protected:
+ HLAEncodeStream& _stream;
+};
+
+/// Begin implementation of some get/set visitors
+
+class HLAScalarDecodeVisitor : public HLADataTypeDecodeVisitor {
+public:
+ HLAScalarDecodeVisitor(HLADecodeStream& stream) :
+ HLADataTypeDecodeVisitor(stream)
+ {}
+
+ virtual void apply(const HLAFixedArrayDataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
+ HLADataTypeDecodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAVariableArrayDataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
+ HLADataTypeDecodeVisitor::apply(dataType);
+ }
+
+ virtual void apply(const HLAEnumeratedDataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
+ HLADataTypeDecodeVisitor::apply(dataType);
+ }
+
+ virtual void apply(const HLAFixedRecordDataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
+ HLADataTypeDecodeVisitor::apply(dataType);
+ }
+
+ virtual void apply(const HLAVariantDataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
+ HLADataTypeDecodeVisitor::apply(dataType);
+ }
+};
+
+class HLAScalarEncodeVisitor : public HLADataTypeEncodeVisitor {
+public:
+ HLAScalarEncodeVisitor(HLAEncodeStream& stream) :
+ HLADataTypeEncodeVisitor(stream)
+ {}
+
+ virtual void apply(const HLAFixedArrayDataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
+ HLADataTypeEncodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAVariableArrayDataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
+ HLADataTypeEncodeVisitor::apply(dataType);
+ }
+
+ virtual void apply(const HLAEnumeratedDataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
+ HLADataTypeEncodeVisitor::apply(dataType);
+ }
+
+ virtual void apply(const HLAFixedRecordDataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
+ HLADataTypeEncodeVisitor::apply(dataType);
+ }
+
+ virtual void apply(const HLAVariantDataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
+ HLADataTypeEncodeVisitor::apply(dataType);
+ }
+};
+
+class HLAFixedRecordDecodeVisitor : public HLADataTypeDecodeVisitor {
+public:
+ HLAFixedRecordDecodeVisitor(HLADecodeStream& stream) :
+ HLADataTypeDecodeVisitor(stream)
+ { }
+
+ virtual void apply(const HLAInt8DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
+ HLADataTypeDecodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAUInt8DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
+ HLADataTypeDecodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAInt16DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
+ HLADataTypeDecodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAUInt16DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
+ HLADataTypeDecodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAInt32DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
+ HLADataTypeDecodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAUInt32DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
+ HLADataTypeDecodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAInt64DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
+ HLADataTypeDecodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAUInt64DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
+ HLADataTypeDecodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAFloat32DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
+ HLADataTypeDecodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAFloat64DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
+ HLADataTypeDecodeVisitor::apply(dataType);
+ }
+
+ virtual void apply(const HLAFixedArrayDataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
+ HLADataTypeDecodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAVariableArrayDataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
+ HLADataTypeDecodeVisitor::apply(dataType);
+ }
+
+ virtual void apply(const HLAEnumeratedDataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
+ HLADataTypeDecodeVisitor::apply(dataType);
+ }
+
+ virtual void apply(const HLAVariantDataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
+ HLADataTypeDecodeVisitor::apply(dataType);
+ }
+};
+
+class HLAFixedRecordEncodeVisitor : public HLADataTypeEncodeVisitor {
+public:
+ HLAFixedRecordEncodeVisitor(HLAEncodeStream& stream) :
+ HLADataTypeEncodeVisitor(stream)
+ { }
+
+ virtual void apply(const HLAInt8DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
+ HLADataTypeEncodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAUInt8DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
+ HLADataTypeEncodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAInt16DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
+ HLADataTypeEncodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAUInt16DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
+ HLADataTypeEncodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAInt32DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
+ HLADataTypeEncodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAUInt32DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
+ HLADataTypeEncodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAInt64DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
+ HLADataTypeEncodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAUInt64DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
+ HLADataTypeEncodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAFloat32DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
+ HLADataTypeEncodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAFloat64DataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
+ HLADataTypeEncodeVisitor::apply(dataType);
+ }
+
+ virtual void apply(const HLAFixedArrayDataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
+ HLADataTypeEncodeVisitor::apply(dataType);
+ }
+ virtual void apply(const HLAVariableArrayDataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
+ HLADataTypeEncodeVisitor::apply(dataType);
+ }
+
+ virtual void apply(const HLAEnumeratedDataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
+ HLADataTypeEncodeVisitor::apply(dataType);
+ }
+
+ virtual void apply(const HLAVariantDataType& dataType)
+ {
+ SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
+ HLADataTypeEncodeVisitor::apply(dataType);
+ }
+};
+
+template<typename T>
+class HLATemplateDecodeVisitor : public HLAScalarDecodeVisitor {
+public:
+ typedef T value_type;
+
+ HLATemplateDecodeVisitor(HLADecodeStream& stream, const value_type& value = value_type()) :
+ HLAScalarDecodeVisitor(stream),
+ _value(value)
+ {}
+
+ void setValue(const value_type& value)
+ { _value = value; }
+ const value_type& getValue() const
+ { return _value; }
+
+ virtual void apply(const HLAInt8DataType& dataType)
+ {
+ int8_t value = 0;
+ dataType.decode(_stream, value);
+ _value = value_type(value);
+ }
+ virtual void apply(const HLAUInt8DataType& dataType)
+ {
+ uint8_t value = 0;
+ dataType.decode(_stream, value);
+ _value = value_type(value);
+ }
+ virtual void apply(const HLAInt16DataType& dataType)
+ {
+ int16_t value = 0;
+ dataType.decode(_stream, value);
+ _value = value_type(value);
+ }
+ virtual void apply(const HLAUInt16DataType& dataType)
+ {
+ uint16_t value = 0;
+ dataType.decode(_stream, value);
+ _value = value_type(value);
+ }
+ virtual void apply(const HLAInt32DataType& dataType)
+ {
+ int32_t value = 0;
+ dataType.decode(_stream, value);
+ _value = value_type(value);
+ }
+ virtual void apply(const HLAUInt32DataType& dataType)
+ {
+ uint32_t value = 0;
+ dataType.decode(_stream, value);
+ _value = value_type(value);
+ }
+ virtual void apply(const HLAInt64DataType& dataType)
+ {
+ int64_t value = 0;
+ dataType.decode(_stream, value);
+ _value = value_type(value);
+ }
+ virtual void apply(const HLAUInt64DataType& dataType)
+ {
+ uint64_t value = 0;
+ dataType.decode(_stream, value);
+ _value = value_type(value);
+ }
+ virtual void apply(const HLAFloat32DataType& dataType)
+ {
+ float value = 0;
+ dataType.decode(_stream, value);
+ _value = value_type(value);
+ }
+ virtual void apply(const HLAFloat64DataType& dataType)
+ {
+ double value = 0;
+ dataType.decode(_stream, value);
+ _value = value_type(value);
+ }
+
+private:
+ value_type _value;
+};
+
+template<typename T>
+class HLATemplateEncodeVisitor : public HLAScalarEncodeVisitor {
+public:
+ typedef T value_type;
+
+ HLATemplateEncodeVisitor(HLAEncodeStream& stream, const value_type& value = value_type()) :
+ HLAScalarEncodeVisitor(stream),
+ _value(value)
+ {}
+
+ void setValue(const value_type& value)
+ { _value = value; }
+ const value_type& getValue() const
+ { return _value; }
+
+ virtual void apply(const HLAInt8DataType& dataType)
+ {
+ dataType.encode(_stream, _value);
+ }
+ virtual void apply(const HLAUInt8DataType& dataType)
+ {
+ dataType.encode(_stream, _value);
+ }
+ virtual void apply(const HLAInt16DataType& dataType)
+ {
+ dataType.encode(_stream, _value);
+ }
+ virtual void apply(const HLAUInt16DataType& dataType)
+ {
+ dataType.encode(_stream, _value);
+ }
+ virtual void apply(const HLAInt32DataType& dataType)
+ {
+ dataType.encode(_stream, _value);
+ }
+ virtual void apply(const HLAUInt32DataType& dataType)
+ {
+ dataType.encode(_stream, _value);
+ }
+ virtual void apply(const HLAInt64DataType& dataType)
+ {
+ dataType.encode(_stream, _value);
+ }
+ virtual void apply(const HLAUInt64DataType& dataType)
+ {
+ dataType.encode(_stream, _value);
+ }
+ virtual void apply(const HLAFloat32DataType& dataType)
+ {
+ dataType.encode(_stream, _value);
+ }
+ virtual void apply(const HLAFloat64DataType& dataType)
+ {
+ dataType.encode(_stream, _value);
+ }
+
+private:
+ value_type _value;
+};
+
+inline void HLADataTypeDecodeVisitor::apply(const HLAVariableArrayDataType& dataType)
+{
+ HLATemplateDecodeVisitor<unsigned> numElementsVisitor(_stream);
+ dataType.getSizeDataType()->accept(numElementsVisitor);
+ unsigned numElements = numElementsVisitor.getValue();
+ for (unsigned i = 0; i < numElements; ++i)
+ dataType.getElementDataType()->accept(*this);
+}
+
+inline void HLADataTypeEncodeVisitor::apply(const HLAVariableArrayDataType& dataType)
+{
+ HLATemplateEncodeVisitor<unsigned> numElementsVisitor(_stream, 0);
+ dataType.getSizeDataType()->accept(numElementsVisitor);
+}
+
+} // namespace simgear
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "HLAEnumeratedDataElement.hxx"
+
+#include <simgear/debug/logstream.hxx>
+
+namespace simgear {
+
+HLAAbstractEnumeratedDataElement::HLAAbstractEnumeratedDataElement(const HLAEnumeratedDataType* dataType) :
+ _dataType(dataType)
+{
+}
+
+HLAAbstractEnumeratedDataElement::~HLAAbstractEnumeratedDataElement()
+{
+}
+
+bool
+HLAAbstractEnumeratedDataElement::decode(HLADecodeStream& stream)
+{
+ if (!_dataType.valid())
+ return false;
+ unsigned index;
+ if (!_dataType->decode(stream, index))
+ return false;
+ setEnumeratorIndex(index);
+ return true;
+}
+
+bool
+HLAAbstractEnumeratedDataElement::encode(HLAEncodeStream& stream) const
+{
+ if (!_dataType.valid())
+ return false;
+ return _dataType->encode(stream, getEnumeratorIndex());
+}
+
+const HLAEnumeratedDataType*
+HLAAbstractEnumeratedDataElement::getDataType() const
+{
+ return _dataType.get();
+}
+
+bool
+HLAAbstractEnumeratedDataElement::setDataType(const HLADataType* dataType)
+{
+ const HLAEnumeratedDataType* enumeratedDataType = dataType->toEnumeratedDataType();
+ if (!enumeratedDataType) {
+ SG_LOG(SG_NETWORK, SG_WARN, "HLAEnumeratedDataType: unable to set data type!");
+ return false;
+ }
+ setDataType(enumeratedDataType);
+ return true;
+}
+
+void
+HLAAbstractEnumeratedDataElement::setDataType(const HLAEnumeratedDataType* dataType)
+{
+ _dataType = dataType;
+}
+
+const HLABasicDataType*
+HLAAbstractEnumeratedDataElement::getRepresentationDataType() const
+{
+ if (!_dataType.valid())
+ return 0;
+ return _dataType->getRepresentation();
+}
+
+std::string
+HLAAbstractEnumeratedDataElement::getStringRepresentation() const
+{
+ if (!_dataType.valid())
+ return std::string();
+ return _dataType->getString(getEnumeratorIndex());
+}
+
+bool
+HLAAbstractEnumeratedDataElement::setStringRepresentation(const std::string& name)
+{
+ if (!_dataType.valid())
+ return false;
+ unsigned index = _dataType->getIndex(name);
+ if (_dataType->getNumEnumerators() <= index)
+ return false;
+ setEnumeratorIndex(index);
+ return true;
+}
+
+
+HLAEnumeratedDataElement::HLAEnumeratedDataElement(const HLAEnumeratedDataType* dataType) :
+ HLAAbstractEnumeratedDataElement(dataType),
+ _enumeratorIndex(~unsigned(0))
+{
+}
+
+HLAEnumeratedDataElement::~HLAEnumeratedDataElement()
+{
+}
+
+unsigned
+HLAEnumeratedDataElement::getEnumeratorIndex() const
+{
+ return _enumeratorIndex;
+}
+
+void
+HLAEnumeratedDataElement::setEnumeratorIndex(unsigned index)
+{
+ _enumeratorIndex = index;
+}
+
+}
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLAEnumeratedDataElement_hxx
+#define HLAEnumeratedDataElement_hxx
+
+#include "HLADataElement.hxx"
+#include "HLAEnumeratedDataType.hxx"
+
+namespace simgear {
+
+class HLAAbstractEnumeratedDataElement : public HLADataElement {
+public:
+ HLAAbstractEnumeratedDataElement(const HLAEnumeratedDataType* dataType);
+ virtual ~HLAAbstractEnumeratedDataElement();
+
+ virtual bool decode(HLADecodeStream& stream);
+ virtual bool encode(HLAEncodeStream& stream) const;
+
+ virtual const HLAEnumeratedDataType* getDataType() const;
+ virtual bool setDataType(const HLADataType* dataType);
+ void setDataType(const HLAEnumeratedDataType* dataType);
+
+ const HLABasicDataType* getRepresentationDataType() const;
+
+ std::string getStringRepresentation() const;
+ bool setStringRepresentation(const std::string& name);
+
+ virtual unsigned getEnumeratorIndex() const = 0;
+ virtual void setEnumeratorIndex(unsigned index) = 0;
+
+private:
+ SGSharedPtr<const HLAEnumeratedDataType> _dataType;
+};
+
+class HLAEnumeratedDataElement : public HLAAbstractEnumeratedDataElement {
+public:
+ HLAEnumeratedDataElement(const HLAEnumeratedDataType* dataType);
+ virtual ~HLAEnumeratedDataElement();
+
+ virtual unsigned getEnumeratorIndex() const;
+ virtual void setEnumeratorIndex(unsigned index);
+
+private:
+ unsigned _enumeratorIndex;
+};
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "HLAEnumeratedDataType.hxx"
+
+#include <map>
+#include <sstream>
+#include <vector>
+#include "HLAEnumeratedDataType.hxx"
+#include "HLADataTypeVisitor.hxx"
+
+namespace simgear {
+
+template<typename DataType, typename T>
+class HLAEnumeratedDataType::Map : public HLAEnumeratedDataType::AbstractMap {
+public:
+ typedef typename std::pair<std::string,T> RepresentationPair;
+ typedef typename std::map<T, unsigned> RepresentationIndexMap;
+ typedef typename std::vector<RepresentationPair> IndexRepresentationMap;
+ typedef typename std::map<std::string, unsigned> StringIndexMap;
+
+ Map(const DataType* dataType) :
+ _dataType(dataType)
+ { }
+ virtual bool encode(HLAEncodeStream& stream, unsigned index) const
+ {
+ T value = _otherRepresentation;
+ if (index < _indexRepresentationMap.size())
+ value = _indexRepresentationMap[index].second;
+ if (!_dataType->encode(stream, value))
+ return false;
+ return true;
+ }
+ virtual bool decode(HLADecodeStream& stream, unsigned& index) const
+ {
+ T value;
+ if (!_dataType->decode(stream, value))
+ return false;
+ typename RepresentationIndexMap::const_iterator i;
+ i = _representationIndexMap.find(value);
+ if (i == _representationIndexMap.end())
+ index = _indexRepresentationMap.size();
+ else
+ index = i->second;
+ return true;
+ }
+ virtual const HLABasicDataType* getDataType() const
+ { return _dataType.get(); }
+
+ virtual bool add(const std::string& name, const std::string& number)
+ {
+ std::stringstream ss(number);
+ T value;
+ ss >> value;
+ if (ss.fail())
+ return false;
+ if (_representationIndexMap.find(value) != _representationIndexMap.end())
+ return false;
+ if (_stringIndexMap.find(name) != _stringIndexMap.end())
+ return false;
+ _stringIndexMap[name] = _indexRepresentationMap.size();
+ _representationIndexMap[value] = _indexRepresentationMap.size();
+ _indexRepresentationMap.push_back(RepresentationPair(name, value));
+ return true;
+ }
+ virtual std::string getString(unsigned index) const
+ {
+ if (_indexRepresentationMap.size() <= index)
+ return std::string();
+ return _indexRepresentationMap[index].first;
+ }
+ virtual unsigned getIndex(const std::string& name) const
+ {
+ typename StringIndexMap::const_iterator i = _stringIndexMap.find(name);
+ if (i == _stringIndexMap.end())
+ return ~unsigned(0);
+ return i->second;
+ }
+ virtual unsigned getNumEnumerators() const
+ { return _indexRepresentationMap.size(); }
+
+private:
+ IndexRepresentationMap _indexRepresentationMap;
+ StringIndexMap _stringIndexMap;
+ RepresentationIndexMap _representationIndexMap;
+
+ T _otherRepresentation;
+ SGSharedPtr<const DataType> _dataType;
+};
+
+class HLAEnumeratedDataType::RepresentationVisitor : public HLADataTypeVisitor {
+public:
+ virtual void apply(const HLAInt8DataType& dataType)
+ { _map = new Map<HLAInt8DataType, int8_t>(&dataType); }
+ virtual void apply(const HLAUInt8DataType& dataType)
+ { _map = new Map<HLAUInt8DataType, uint8_t>(&dataType); }
+ virtual void apply(const HLAInt16DataType& dataType)
+ { _map = new Map<HLAInt16DataType, int16_t>(&dataType); }
+ virtual void apply(const HLAUInt16DataType& dataType)
+ { _map = new Map<HLAUInt16DataType, uint16_t>(&dataType); }
+ virtual void apply(const HLAInt32DataType& dataType)
+ { _map = new Map<HLAInt32DataType, int32_t>(&dataType); }
+ virtual void apply(const HLAUInt32DataType& dataType)
+ { _map = new Map<HLAUInt32DataType, uint32_t>(&dataType); }
+ virtual void apply(const HLAInt64DataType& dataType)
+ { _map = new Map<HLAInt64DataType, int64_t>(&dataType); }
+ virtual void apply(const HLAUInt64DataType& dataType)
+ { _map = new Map<HLAUInt64DataType, uint64_t>(&dataType); }
+
+ SGSharedPtr<AbstractMap> _map;
+};
+
+HLAEnumeratedDataType::HLAEnumeratedDataType(const std::string& name) :
+ HLADataType(name)
+{
+}
+
+HLAEnumeratedDataType::~HLAEnumeratedDataType()
+{
+}
+
+void
+HLAEnumeratedDataType::accept(HLADataTypeVisitor& visitor) const
+{
+ visitor.apply(*this);
+}
+
+const HLAEnumeratedDataType*
+HLAEnumeratedDataType::toEnumeratedDataType() const
+{
+ return this;
+}
+
+bool
+HLAEnumeratedDataType::decode(HLADecodeStream& stream, unsigned& index) const
+{
+ if (!_map.valid())
+ return false;
+
+ if (!_map->decode(stream, index))
+ return false;
+ return true;
+}
+
+bool
+HLAEnumeratedDataType::encode(HLAEncodeStream& stream, unsigned index) const
+{
+ if (!_map.valid())
+ return false;
+
+ return _map->encode(stream, index);
+}
+
+void
+HLAEnumeratedDataType::setRepresentation(HLABasicDataType* representation)
+{
+ if (!representation)
+ return;
+
+ RepresentationVisitor representationVisitor;
+ representation->accept(representationVisitor);
+ _map.swap(representationVisitor._map);
+}
+
+} // namespace simgear
+
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLAEnumeratedDataType_hxx
+#define HLAEnumeratedDataType_hxx
+
+#include <string>
+#include <simgear/structure/SGSharedPtr.hxx>
+#include "HLADataType.hxx"
+
+namespace simgear {
+
+class HLAEnumeratedDataType : public HLADataType {
+public:
+ HLAEnumeratedDataType(const std::string& name = "HLAEnumeratedDataType");
+ virtual ~HLAEnumeratedDataType();
+
+ virtual void accept(HLADataTypeVisitor& visitor) const;
+
+ virtual const HLAEnumeratedDataType* toEnumeratedDataType() const;
+
+ virtual bool decode(HLADecodeStream& stream, unsigned& index) const;
+ virtual bool encode(HLAEncodeStream& stream, unsigned index) const;
+
+ std::string getString(unsigned index) const
+ {
+ if (!_map.valid())
+ return std::string();
+ return _map->getString(index);
+ }
+ unsigned getIndex(const std::string& name) const
+ {
+ if (!_map.valid())
+ return ~unsigned(0);
+ return _map->getIndex(name);
+ }
+ unsigned getNumEnumerators() const
+ {
+ if (!_map.valid())
+ return 0;
+ return _map->getNumEnumerators();
+ }
+
+ bool addEnumerator(const std::string& name, const std::string& number)
+ {
+ if (!_map.valid())
+ return false;
+ return _map->add(name, number);
+ }
+
+ void setRepresentation(HLABasicDataType* representation);
+ const HLABasicDataType* getRepresentation() const
+ {
+ if (!_map.valid())
+ return 0;
+ return _map->getDataType();
+ }
+
+private:
+ class AbstractMap : public SGReferenced {
+ public:
+ virtual ~AbstractMap() {}
+ virtual bool encode(HLAEncodeStream& stream, unsigned index) const = 0;
+ virtual bool decode(HLADecodeStream& stream, unsigned& index) const = 0;
+ virtual const HLABasicDataType* getDataType() const = 0;
+ virtual bool add(const std::string& name, const std::string& number) = 0;
+ virtual std::string getString(unsigned index) const = 0;
+ virtual unsigned getIndex(const std::string& name) const = 0;
+ virtual unsigned getNumEnumerators() const = 0;
+ };
+
+ template<typename DataType, typename T>
+ class Map;
+ class RepresentationVisitor;
+
+ SGSharedPtr<AbstractMap> _map;
+};
+
+} // namespace simgear
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "HLAFederate.hxx"
+
+#include "RTIFederate.hxx"
+#include "RTIInteractionClass.hxx"
+#include "RTIObjectClass.hxx"
+#include "HLADataElement.hxx"
+#include "HLADataType.hxx"
+#include "HLAOMTXmlVisitor.hxx"
+
+namespace simgear {
+
+HLAFederate::HLAFederate(const SGSharedPtr<RTIFederate>& rtiFederate) :
+ _rtiFederate(rtiFederate)
+{
+}
+
+HLAFederate::~HLAFederate()
+{
+}
+
+const std::string&
+HLAFederate::getFederateType() const
+{
+ return _rtiFederate->getFederateType();
+}
+
+const std::string&
+HLAFederate::getFederationName() const
+{
+ return _rtiFederate->getFederationName();
+}
+
+bool
+HLAFederate::createFederationExecution(const std::string& federation, const std::string& objectModel)
+{
+ return _rtiFederate->createFederationExecution(federation, objectModel);
+}
+
+bool
+HLAFederate::destroyFederationExecution(const std::string& federation)
+{
+ return _rtiFederate->destroyFederationExecution(federation);
+}
+
+bool
+HLAFederate::join(const std::string& federateType, const std::string& federation)
+{
+ return _rtiFederate->join(federateType, federation);
+}
+
+bool
+HLAFederate::resign()
+{
+ return _rtiFederate->resign();
+}
+
+bool
+HLAFederate::enableTimeConstrained()
+{
+ return _rtiFederate->enableTimeConstrained();
+}
+
+bool
+HLAFederate::disableTimeConstrained()
+{
+ return _rtiFederate->disableTimeConstrained();
+}
+
+bool
+HLAFederate::enableTimeRegulation(const SGTimeStamp& lookahead)
+{
+ return _rtiFederate->enableTimeRegulation(lookahead);
+}
+
+bool
+HLAFederate::disableTimeRegulation()
+{
+ return _rtiFederate->disableTimeRegulation();
+}
+
+bool
+HLAFederate::timeAdvanceRequestBy(const SGTimeStamp& dt)
+{
+ return _rtiFederate->timeAdvanceRequestBy(dt);
+}
+
+bool
+HLAFederate::timeAdvanceRequest(const SGTimeStamp& dt)
+{
+ return _rtiFederate->timeAdvanceRequest(dt);
+}
+
+bool
+HLAFederate::tick()
+{
+ return _rtiFederate->tick();
+}
+
+bool
+HLAFederate::tick(const double& minimum, const double& maximum)
+{
+ return _rtiFederate->tick(minimum, maximum);
+}
+
+bool
+HLAFederate::readObjectModelTemplate(const std::string& objectModel,
+ HLAFederate::ObjectModelFactory& objectModelFactory)
+{
+ if (!_rtiFederate.valid()) {
+ SG_LOG(SG_IO, SG_ALERT, "Could not process HLA XML object model file: "
+ "No rti federate available!");
+ return false;
+ }
+
+ // 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;
+ }
+
+ unsigned numObjectClasses = omtXmlVisitor.getNumObjectClasses();
+ for (unsigned i = 0; i < numObjectClasses; ++i) {
+ const HLAOMTXmlVisitor::ObjectClass* objectClass = omtXmlVisitor.getObjectClass(i);
+ std::string objectClassName = objectClass->getName();
+
+ SGSharedPtr<HLAObjectClass> hlaObjectClass = objectModelFactory.createObjectClass(objectClassName, *this);
+ if (!hlaObjectClass.valid()) {
+ SG_LOG(SG_IO, SG_INFO, "Ignoring object class \"" << objectClassName << "\".");
+ continue;
+ }
+
+ 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);
+
+ 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);
+ 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);
+
+ if (subscribe && objectModelFactory.subscribeAttribute(objectClassName, attributeName, attribute->_sharing))
+ subscriptions.insert(index);
+ if (publish && objectModelFactory.publishAttribute(objectClassName, attributeName, attribute->_sharing))
+ publications.insert(index);
+ }
+
+ if (publish)
+ hlaObjectClass->publish(publications);
+ if (subscribe)
+ hlaObjectClass->subscribe(subscriptions, true);
+
+ _objectClassMap[objectClassName] = hlaObjectClass;
+ }
+
+ return true;
+}
+
+HLAObjectClass*
+HLAFederate::getObjectClass(const std::string& name)
+{
+ ObjectClassMap::const_iterator i = _objectClassMap.find(name);
+ if (i == _objectClassMap.end())
+ return 0;
+ return i->second.get();
+}
+
+const HLAObjectClass*
+HLAFederate::getObjectClass(const std::string& name) const
+{
+ ObjectClassMap::const_iterator i = _objectClassMap.find(name);
+ if (i == _objectClassMap.end())
+ return 0;
+ return i->second.get();
+}
+
+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();
+}
+
+} // namespace simgear
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLAFederate_hxx
+#define HLAFederate_hxx
+
+#include <map>
+
+#include "HLAObjectInstance.hxx"
+#include "HLAObjectClass.hxx"
+#include "HLAInteractionClass.hxx"
+
+class SGTimeStamp;
+
+namespace simgear {
+
+class RTIFederate;
+
+class HLAFederate : public SGWeakReferenced {
+public:
+ virtual ~HLAFederate();
+
+ /// Get the name of the joined federate/federation
+ const std::string& getFederateType() const;
+ const std::string& getFederationName() const;
+
+ /// Create a federation execution
+ /// Semantically this methods should be static,
+ /// but the nonstatic case could reuse the connection to the server
+ /// FIXME: cannot determine from the return value if we created the execution
+ bool createFederationExecution(const std::string& federation, const std::string& objectModel);
+ bool destroyFederationExecution(const std::string& federation);
+
+ /// Join with federateType the federation execution
+ bool join(const std::string& federateType, const std::string& federation);
+ bool resign();
+
+ bool enableTimeConstrained();
+ bool disableTimeConstrained();
+
+ bool enableTimeRegulation(const SGTimeStamp& lookahead);
+ bool disableTimeRegulation();
+
+ bool timeAdvanceRequestBy(const SGTimeStamp& dt);
+ bool timeAdvanceRequest(const SGTimeStamp& dt);
+
+ /// Process messages
+ bool tick();
+ bool tick(const double& minimum, const double& maximum);
+
+ class ObjectModelFactory {
+ public:
+ virtual ~ObjectModelFactory()
+ { }
+
+ virtual HLAObjectClass* createObjectClass(const std::string& name, HLAFederate& federate)
+ { return new HLAObjectClass(name, federate); }
+ virtual bool subscribeObjectClass(const std::string& objectClassName, const std::string& sharing)
+ { return sharing.find("Subscribe") != std::string::npos; }
+ virtual bool publishObjectClass(const std::string& objectClassName, const std::string& sharing)
+ { return sharing.find("Publish") != std::string::npos; }
+ virtual bool subscribeAttribute(const std::string& objectClassName, const std::string& attributeName, const std::string& sharing)
+ { return sharing.find("Subscribe") != std::string::npos; }
+ virtual bool publishAttribute(const std::string& objectClassName, const std::string& attributeName, const std::string& sharing)
+ { return sharing.find("Publish") != std::string::npos; }
+
+ };
+
+ /// Read an omt xml file
+ bool readObjectModelTemplate(const std::string& objectModel,
+ ObjectModelFactory& objectModelFactory);
+
+ HLAObjectClass* getObjectClass(const std::string& name);
+ const HLAObjectClass* getObjectClass(const std::string& name) const;
+
+ HLAInteractionClass* getInteractionClass(const std::string& name);
+ const HLAInteractionClass* getInteractionClass(const std::string& name) const;
+
+protected:
+ HLAFederate(const SGSharedPtr<RTIFederate>& rtiFederate);
+
+private:
+ SGSharedPtr<RTIFederate> _rtiFederate;
+
+ typedef std::map<std::string, SGSharedPtr<HLAObjectClass> > ObjectClassMap;
+ ObjectClassMap _objectClassMap;
+
+ typedef std::map<std::string, SGSharedPtr<HLAInteractionClass> > InteractionClassMap;
+ InteractionClassMap _interactionClassMap;
+
+ friend class HLAInteractionClass;
+ friend class HLAObjectClass;
+};
+
+} // namespace simgear
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "HLAFixedRecordDataElement.hxx"
+
+#include <string>
+#include <vector>
+#include <simgear/debug/logstream.hxx>
+#include "HLADataTypeVisitor.hxx"
+
+namespace simgear {
+
+HLAAbstractFixedRecordDataElement::HLAAbstractFixedRecordDataElement(const HLAFixedRecordDataType* dataType) :
+ _dataType(dataType)
+{
+}
+
+HLAAbstractFixedRecordDataElement::~HLAAbstractFixedRecordDataElement()
+{
+}
+
+bool
+HLAAbstractFixedRecordDataElement::decode(HLADecodeStream& stream)
+{
+ if (!_dataType.valid())
+ return false;
+ return _dataType->decode(stream, *this);
+}
+
+bool
+HLAAbstractFixedRecordDataElement::encode(HLAEncodeStream& stream) const
+{
+ if (!_dataType.valid())
+ return false;
+ return _dataType->encode(stream, *this);
+}
+
+const HLAFixedRecordDataType*
+HLAAbstractFixedRecordDataElement::getDataType() const
+{
+ return _dataType.get();
+}
+
+bool
+HLAAbstractFixedRecordDataElement::setDataType(const HLADataType* dataType)
+{
+ const HLAFixedRecordDataType* fixedRecordDataType = dataType->toFixedRecordDataType();
+ if (!fixedRecordDataType) {
+ SG_LOG(SG_NETWORK, SG_WARN, "HLAFixedRecordDataType: unable to set data type!");
+ return false;
+ }
+ setDataType(fixedRecordDataType);
+ return true;
+}
+
+void
+HLAAbstractFixedRecordDataElement::setDataType(const HLAFixedRecordDataType* dataType)
+{
+ _dataType = dataType;
+}
+
+unsigned
+HLAAbstractFixedRecordDataElement::getNumFields() const
+{
+ return _dataType->getNumFields();
+}
+
+unsigned
+HLAAbstractFixedRecordDataElement::getFieldNumber(const std::string& name) const
+{
+ return _dataType->getFieldNumber(name);
+}
+
+const HLADataType*
+HLAAbstractFixedRecordDataElement::getFieldDataType(unsigned i) const
+{
+ return _dataType->getFieldDataType(i);
+}
+
+const HLADataType*
+HLAAbstractFixedRecordDataElement::getFieldDataType(const std::string& name) const
+{
+ return getFieldDataType(getFieldNumber(name));
+}
+
+
+HLAFixedRecordDataElement::HLAFixedRecordDataElement(const HLAFixedRecordDataType* dataType) :
+ HLAAbstractFixedRecordDataElement(dataType)
+{
+ _fieldVector.resize(getNumFields());
+}
+
+HLAFixedRecordDataElement::~HLAFixedRecordDataElement()
+{
+}
+
+bool
+HLAFixedRecordDataElement::decodeField(HLADecodeStream& stream, unsigned i)
+{
+ HLADataElement* dataElement = getField(i);
+ if (dataElement) {
+ return dataElement->decode(stream);
+ } else {
+ HLADataTypeDecodeVisitor visitor(stream);
+ getDataType()->getFieldDataType(i)->accept(visitor);
+ return true;
+ }
+}
+
+bool
+HLAFixedRecordDataElement::encodeField(HLAEncodeStream& stream, unsigned i) const
+{
+ const HLADataElement* dataElement = getField(i);
+ if (dataElement) {
+ return dataElement->encode(stream);
+ } else {
+ HLADataTypeEncodeVisitor visitor(stream);
+ getDataType()->getFieldDataType(i)->accept(visitor);
+ return true;
+ }
+}
+
+HLADataElement*
+HLAFixedRecordDataElement::getField(const std::string& name)
+{
+ return getField(getFieldNumber(name));
+}
+
+const HLADataElement*
+HLAFixedRecordDataElement::getField(const std::string& name) const
+{
+ return getField(getFieldNumber(name));
+}
+
+HLADataElement*
+HLAFixedRecordDataElement::getField(unsigned i)
+{
+ if (_fieldVector.size() <= i)
+ return 0;
+ return _fieldVector[i].get();
+}
+
+const HLADataElement*
+HLAFixedRecordDataElement::getField(unsigned i) const
+{
+ if (_fieldVector.size() <= i)
+ return 0;
+ return _fieldVector[i].get();
+}
+
+void
+HLAFixedRecordDataElement::setField(unsigned index, HLADataElement* value)
+{
+ if (getNumFields() <= index)
+ return;
+ _fieldVector[index] = value;
+}
+
+void
+HLAFixedRecordDataElement::setField(const std::string& name, HLADataElement* value)
+{
+ setField(getFieldNumber(name), value);
+}
+
+}
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLAFixedRecordDataElement_hxx
+#define HLAFixedRecordDataElement_hxx
+
+#include <string>
+#include <vector>
+#include "HLADataElement.hxx"
+#include "HLAFixedRecordDataType.hxx"
+
+namespace simgear {
+
+class HLAAbstractFixedRecordDataElement : public HLADataElement {
+public:
+ HLAAbstractFixedRecordDataElement(const HLAFixedRecordDataType* dataType);
+ virtual ~HLAAbstractFixedRecordDataElement();
+
+ virtual bool decode(HLADecodeStream& stream);
+ virtual bool encode(HLAEncodeStream& stream) const;
+
+ virtual const HLAFixedRecordDataType* getDataType() const;
+ virtual bool setDataType(const HLADataType* dataType);
+ void setDataType(const HLAFixedRecordDataType* dataType);
+
+ unsigned getNumFields() const;
+ unsigned getFieldNumber(const std::string& name) const;
+
+ const HLADataType* getFieldDataType(unsigned i) const;
+ const HLADataType* getFieldDataType(const std::string& name) const;
+
+ virtual bool decodeField(HLADecodeStream& stream, unsigned i) = 0;
+ virtual bool encodeField(HLAEncodeStream& stream, unsigned i) const = 0;
+
+private:
+ SGSharedPtr<const HLAFixedRecordDataType> _dataType;
+};
+
+class HLAFixedRecordDataElement : public HLAAbstractFixedRecordDataElement {
+public:
+ HLAFixedRecordDataElement(const HLAFixedRecordDataType* dataType);
+ virtual ~HLAFixedRecordDataElement();
+
+ virtual bool decodeField(HLADecodeStream& stream, unsigned i);
+ virtual bool encodeField(HLAEncodeStream& stream, unsigned i) const;
+
+ HLADataElement* getField(const std::string& name);
+ const HLADataElement* getField(const std::string& name) const;
+
+ HLADataElement* getField(unsigned i);
+ const HLADataElement* getField(unsigned i) const;
+
+ void setField(unsigned index, HLADataElement* value);
+ void setField(const std::string& name, HLADataElement* value);
+
+private:
+ typedef std::vector<SGSharedPtr<HLADataElement> > FieldVector;
+ FieldVector _fieldVector;
+};
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "HLAFixedRecordDataType.hxx"
+
+#include "HLADataTypeVisitor.hxx"
+#include "HLAFixedRecordDataElement.hxx"
+
+namespace simgear {
+
+HLAFixedRecordDataType::HLAFixedRecordDataType(const std::string& name) :
+ HLADataType(name)
+{
+}
+
+HLAFixedRecordDataType::~HLAFixedRecordDataType()
+{
+}
+
+void
+HLAFixedRecordDataType::accept(HLADataTypeVisitor& visitor) const
+{
+ visitor.apply(*this);
+}
+
+const HLAFixedRecordDataType*
+HLAFixedRecordDataType::toFixedRecordDataType() const
+{
+ return this;
+}
+
+bool
+HLAFixedRecordDataType::decode(HLADecodeStream& stream, HLAAbstractFixedRecordDataElement& value) const
+{
+ stream.alignOffsetForSize(getAlignment());
+ unsigned numFields = getNumFields();
+ for (unsigned i = 0; i < numFields; ++i)
+ if (!value.decodeField(stream, i))
+ return false;
+ return true;
+}
+
+bool
+HLAFixedRecordDataType::encode(HLAEncodeStream& stream, const HLAAbstractFixedRecordDataElement& value) const
+{
+ stream.alignOffsetForSize(getAlignment());
+ unsigned numFields = getNumFields();
+ for (unsigned i = 0; i < numFields; ++i)
+ if (!value.encodeField(stream, i))
+ return false;
+ return true;
+}
+
+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));
+}
+
+} // namespace simgear
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLAFixedRecordDataType_hxx
+#define HLAFixedRecordDataType_hxx
+
+#include <string>
+#include <vector>
+#include <simgear/structure/SGSharedPtr.hxx>
+#include "HLADataType.hxx"
+
+namespace simgear {
+
+class HLAAbstractFixedRecordDataElement;
+
+class HLAFixedRecordDataType : public HLADataType {
+public:
+ HLAFixedRecordDataType(const std::string& name = "HLAFixedRecordDataType");
+ virtual ~HLAFixedRecordDataType();
+
+ virtual void accept(HLADataTypeVisitor& visitor) const;
+
+ virtual const HLAFixedRecordDataType* toFixedRecordDataType() const;
+
+ virtual bool decode(HLADecodeStream& stream, HLAAbstractFixedRecordDataElement& value) const;
+ virtual bool encode(HLAEncodeStream& stream, const HLAAbstractFixedRecordDataElement& value) const;
+
+ unsigned getNumFields() const
+ { return _fieldList.size(); }
+
+ std::string getFieldName(unsigned i) const
+ {
+ if (_fieldList.size() <= i)
+ return std::string();
+ return _fieldList[i].getName();
+ }
+ const HLADataType* getFieldDataType(unsigned i) const
+ {
+ if (_fieldList.size() <= i)
+ return 0;
+ return _fieldList[i].getDataType();
+ }
+
+ unsigned getFieldNumber(const std::string& name) const
+ {
+ for (unsigned i = 0; i < _fieldList.size(); ++i) {
+ if (_fieldList[i].getName() != name)
+ continue;
+ return i;
+ }
+ return ~0u;
+ }
+
+ void addField(const std::string& name, const HLADataType* dataType);
+
+private:
+ struct Field {
+ Field(const std::string& name, const HLADataType* dataType) :
+ _name(name), _dataType(dataType) {}
+ const std::string& getName() const
+ { return _name; }
+
+ const HLADataType* getDataType() const
+ { return _dataType.get(); }
+
+ private:
+ std::string _name;
+ SGSharedPtr<const HLADataType> _dataType;
+ };
+
+ typedef std::vector<Field> FieldList;
+ FieldList _fieldList;
+};
+
+} // namespace simgear
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLAInteractionClass_hxx
+#define HLAInteractionClass_hxx
+
+namespace simgear {
+
+class RTIInteractionClass;
+
+class HLAInteractionClass : public SGWeakReferenced {
+public:
+ virtual ~HLAInteractionClass() {}
+};
+
+} // namespace simgear
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLALocation_hxx
+#define HLALocation_hxx
+
+#include "HLABasicDataElement.hxx"
+
+namespace simgear {
+
+class HLAAbstractLocation : public SGReferenced {
+public:
+ virtual ~HLAAbstractLocation() {}
+
+ virtual SGVec3d getCartPosition() const = 0;
+ virtual void setCartPosition(const SGVec3d&) = 0;
+
+ virtual SGQuatd getCartOrientation() const = 0;
+ virtual void setCartOrientation(const SGQuatd&) = 0;
+
+ virtual SGVec3d getAngularBodyVelocity() const = 0;
+ virtual void setAngularBodyVelocity(const SGVec3d& angular) = 0;
+
+ virtual SGVec3d getLinearBodyVelocity() const = 0;
+ virtual void setLinearBodyVelocity(const SGVec3d& linear) = 0;
+};
+
+class HLACartesianLocation : public HLAAbstractLocation {
+public:
+ HLACartesianLocation() :
+ _position(SGVec3d::zeros()),
+ _imag(SGVec3d::zeros()),
+ _angularVelocity(SGVec3d::zeros()),
+ _linearVelocity(SGVec3d::zeros())
+ { }
+
+ virtual SGVec3d getCartPosition() const
+ { return _position; }
+ virtual void setCartPosition(const SGVec3d& position)
+ { _position = position; }
+
+ virtual SGQuatd getCartOrientation() const
+ { return SGQuatd::fromPositiveRealImag(_imag); }
+ virtual void setCartOrientation(const SGQuatd& orientation)
+ { _imag = orientation.getPositiveRealImag(); }
+
+ virtual SGVec3d getAngularBodyVelocity() const
+ { return _angularVelocity; }
+ virtual void setAngularBodyVelocity(const SGVec3d& angularVelocity)
+ { _angularVelocity = angularVelocity; }
+
+ virtual SGVec3d getLinearBodyVelocity() const
+ { return _linearVelocity; }
+ virtual void setLinearBodyVelocity(const SGVec3d& linearVelocity)
+ { _linearVelocity = linearVelocity; }
+
+ HLADataElementProvider getPositionDataElement(unsigned i)
+ {
+ if (3 <= i)
+ return HLADataElementProvider();
+ return new PositionDataElement(this, i);
+ }
+ HLADataElementProvider getOrientationDataElement(unsigned i)
+ {
+ if (3 <= i)
+ return HLADataElementProvider();
+ return new OrientationDataElement(this, i);
+ }
+
+ HLADataElementProvider getAngularVelocityDataElement(unsigned i)
+ {
+ if (3 <= i)
+ return HLADataElementProvider();
+ return new AngularVelocityDataElement(this, i);
+ }
+ HLADataElementProvider getLinearVelocityDataElement(unsigned i)
+ {
+ if (3 <= i)
+ return HLADataElementProvider();
+ return new LinearVelocityDataElement(this, i);
+ }
+
+private:
+ class PositionDataElement : public HLAAbstractDoubleDataElement {
+ public:
+ PositionDataElement(HLACartesianLocation* data, unsigned index) :
+ _data(data), _index(index)
+ { }
+ virtual double getValue() const
+ { return _data->_position[_index]; }
+ virtual void setValue(double value)
+ { _data->_position[_index] = value; }
+
+ private:
+ SGSharedPtr<HLACartesianLocation> _data;
+ unsigned _index;
+ };
+
+ class OrientationDataElement : public HLAAbstractDoubleDataElement {
+ public:
+ OrientationDataElement(HLACartesianLocation* data, unsigned index) :
+ _data(data), _index(index)
+ { }
+ virtual double getValue() const
+ { return _data->_imag[_index]; }
+ virtual void setValue(double value)
+ { _data->_imag[_index] = value; }
+
+ private:
+ SGSharedPtr<HLACartesianLocation> _data;
+ unsigned _index;
+ };
+
+ class AngularVelocityDataElement : public HLAAbstractDoubleDataElement {
+ public:
+ AngularVelocityDataElement(HLACartesianLocation* data, unsigned index) :
+ _data(data), _index(index)
+ { }
+ virtual double getValue() const
+ { return _data->_angularVelocity[_index]; }
+ virtual void setValue(double value)
+ { _data->_angularVelocity[_index] = value; }
+
+ private:
+ SGSharedPtr<HLACartesianLocation> _data;
+ unsigned _index;
+ };
+
+ class LinearVelocityDataElement : public HLAAbstractDoubleDataElement {
+ public:
+ LinearVelocityDataElement(HLACartesianLocation* data, unsigned index) :
+ _data(data), _index(index)
+ { }
+ virtual double getValue() const
+ { return _data->_linearVelocity[_index]; }
+ virtual void setValue(double value)
+ { _data->_linearVelocity[_index] = value; }
+
+ private:
+ SGSharedPtr<HLACartesianLocation> _data;
+ unsigned _index;
+ };
+
+ SGVec3d _position;
+ SGVec3d _imag;
+
+ SGVec3d _angularVelocity;
+ SGVec3d _linearVelocity;
+};
+
+class HLALocationFactory : public SGReferenced {
+public:
+ virtual ~HLALocationFactory() {}
+ virtual HLAAbstractLocation* createLocation(HLAAttributePathElementMap&) const = 0;
+};
+
+class HLACartesianLocationFactory : public HLALocationFactory {
+public:
+ virtual HLAAbstractLocation* createLocation(HLAAttributePathElementMap& attributePathElementMap) const
+ {
+ HLACartesianLocation* location = new HLACartesianLocation;
+ for (unsigned i = 0; i < 3; ++i) {
+ const HLADataElement::IndexPathPair& indexPathPair = _positonIndexPathPair[i];
+ attributePathElementMap[indexPathPair.first][indexPathPair.second] = location->getPositionDataElement(i);
+ }
+ for (unsigned i = 0; i < 3; ++i) {
+ const HLADataElement::IndexPathPair& indexPathPair = _orientationIndexPathPair[i];
+ attributePathElementMap[indexPathPair.first][indexPathPair.second] = location->getOrientationDataElement(i);
+ }
+ for (unsigned i = 0; i < 3; ++i) {
+ const HLADataElement::IndexPathPair& indexPathPair = _angularVelocityIndexPathPair[i];
+ attributePathElementMap[indexPathPair.first][indexPathPair.second] = location->getAngularVelocityDataElement(i);
+ }
+ for (unsigned i = 0; i < 3; ++i) {
+ const HLADataElement::IndexPathPair& indexPathPair = _linearVelocityIndexPathPair[i];
+ attributePathElementMap[indexPathPair.first][indexPathPair.second] = location->getLinearVelocityDataElement(i);
+ }
+ return location;
+ }
+
+ void setPositionIndexPathPair(unsigned index, const HLADataElement::IndexPathPair& indexPathPair)
+ {
+ if (3 <= index)
+ return;
+ _positonIndexPathPair[index] = indexPathPair;
+ }
+ void setOrientationIndexPathPair(unsigned index, const HLADataElement::IndexPathPair& indexPathPair)
+ {
+ if (3 <= index)
+ return;
+ _orientationIndexPathPair[index] = indexPathPair;
+ }
+
+ void setAngularVelocityIndexPathPair(unsigned index, const HLADataElement::IndexPathPair& indexPathPair)
+ {
+ if (3 <= index)
+ return;
+ _angularVelocityIndexPathPair[index] = indexPathPair;
+ }
+ void setLinearVelocityIndexPathPair(unsigned index, const HLADataElement::IndexPathPair& indexPathPair)
+ {
+ if (3 <= index)
+ return;
+ _linearVelocityIndexPathPair[index] = indexPathPair;
+ }
+
+private:
+ HLADataElement::IndexPathPair _positonIndexPathPair[3];
+ HLADataElement::IndexPathPair _orientationIndexPathPair[3];
+
+ HLADataElement::IndexPathPair _angularVelocityIndexPathPair[3];
+ HLADataElement::IndexPathPair _linearVelocityIndexPathPair[3];
+};
+
+class HLAGeodeticLocation : public HLAAbstractLocation {
+public:
+ HLAGeodeticLocation() :
+ _dirty(true),
+ _cartPosition(SGVec3d::zeros()),
+ _cartOrientation(SGQuatd::unit()),
+ _cartBodyVelocity(SGVec3d::zeros()),
+ _geodPosition(),
+ _geodEulerRad(SGVec3d::zeros()),
+ _groundTrackRad(0),
+ _groundSpeedMPerSec(0),
+ _verticalSpeedMPerSec(0)
+ {
+ updateCartesianFromGeodetic();
+ }
+
+ virtual SGVec3d getCartPosition() const
+ { updateCartesianFromGeodetic(); return _cartPosition; }
+ virtual void setCartPosition(const SGVec3d& position)
+ { _cartPosition = position; _dirty = true; }
+
+ virtual SGQuatd getCartOrientation() const
+ { updateCartesianFromGeodetic(); return _cartOrientation; }
+ virtual void setCartOrientation(const SGQuatd& orientation)
+ { _cartOrientation = orientation; _dirty = true; }
+
+ virtual SGVec3d getAngularBodyVelocity() const
+ { return SGVec3d::zeros(); }
+ virtual void setAngularBodyVelocity(const SGVec3d& angular)
+ { }
+
+ virtual SGVec3d getLinearBodyVelocity() const
+ { updateCartesianFromGeodetic(); return _cartBodyVelocity; }
+ virtual void setLinearBodyVelocity(const SGVec3d& linear)
+ { _cartBodyVelocity = linear; _dirty = true; }
+
+ void setLatitudeDeg(double value)
+ { _geodPosition.setLatitudeDeg(value); _dirty = true; }
+ double getLatitudeDeg() const
+ { updateGeodeticFromCartesian(); return _geodPosition.getLatitudeDeg(); }
+ void setLatitudeRad(double value)
+ { _geodPosition.setLatitudeRad(value); _dirty = true; }
+ double getLatitudeRad() const
+ { updateGeodeticFromCartesian(); return _geodPosition.getLatitudeRad(); }
+ void setLongitudeDeg(double value)
+ { _geodPosition.setLongitudeDeg(value); _dirty = true; }
+ double getLongitudeDeg() const
+ { updateGeodeticFromCartesian(); return _geodPosition.getLongitudeDeg(); }
+ void setLongitudeRad(double value)
+ { _geodPosition.setLongitudeRad(value); _dirty = true; }
+ double getLongitudeRad() const
+ { updateGeodeticFromCartesian(); return _geodPosition.getLongitudeRad(); }
+ void setElevationFt(double value)
+ { _geodPosition.setElevationFt(value); _dirty = true; }
+ double getElevationFt() const
+ { updateGeodeticFromCartesian(); return _geodPosition.getElevationFt(); }
+ void setElevationM(double value)
+ { _geodPosition.setElevationM(value); _dirty = true; }
+ double getElevationM() const
+ { updateGeodeticFromCartesian(); return _geodPosition.getElevationM(); }
+
+ void setHeadingRad(double value)
+ { _geodEulerRad[2] = value; _dirty = true; }
+ double getHeadingRad() const
+ { updateGeodeticFromCartesian(); return _geodEulerRad[2]; }
+ void setHeadingDeg(double value)
+ { setHeadingRad(SGMiscd::deg2rad(value)); }
+ double getHeadingDeg() const
+ { return SGMiscd::rad2deg(getHeadingRad()); }
+ void setPitchRad(double value)
+ { _geodEulerRad[1] = value; _dirty = true; }
+ double getPitchRad() const
+ { updateGeodeticFromCartesian(); return _geodEulerRad[1]; }
+ void setPitchDeg(double value)
+ { setPitchRad(SGMiscd::deg2rad(value)); }
+ double getPitchDeg() const
+ { return SGMiscd::rad2deg(getPitchRad()); }
+ void setRollRad(double value)
+ { _geodEulerRad[0] = value; _dirty = true; }
+ double getRollRad() const
+ { updateGeodeticFromCartesian(); return _geodEulerRad[0]; }
+ void setRollDeg(double value)
+ { setRollRad(SGMiscd::deg2rad(value)); }
+ double getRollDeg() const
+ { return SGMiscd::rad2deg(getRollRad()); }
+
+ void setGroundTrackRad(double value)
+ { _groundTrackRad = value; _dirty = true; }
+ double getGroundTrackRad() const
+ { updateGeodeticFromCartesian(); return _groundTrackRad; }
+ void setGroundTrackDeg(double value)
+ { setGroundTrackRad(SGMiscd::deg2rad(value)); }
+ double getGroundTrackDeg() const
+ { return SGMiscd::rad2deg(getGroundTrackRad()); }
+
+
+ void setGroundSpeedMPerSec(double value)
+ { _groundSpeedMPerSec = value; _dirty = true; }
+ double getGroundSpeedMPerSec() const
+ { updateGeodeticFromCartesian(); return _groundSpeedMPerSec; }
+ void setGroundSpeedFtPerSec(double value)
+ { setGroundSpeedMPerSec(SG_FEET_TO_METER*value); }
+ double getGroundSpeedFtPerSec() const
+ { return SG_METER_TO_FEET*getGroundSpeedMPerSec(); }
+ void setGroundSpeedKnots(double value)
+ { setGroundSpeedMPerSec(SG_KT_TO_MPS*value); }
+ double getGroundSpeedKnots() const
+ { return SG_MPS_TO_KT*getGroundSpeedMPerSec(); }
+
+ void setVerticalSpeedMPerSec(double value)
+ { _verticalSpeedMPerSec = value; _dirty = true; }
+ double getVerticalSpeedMPerSec() const
+ { updateGeodeticFromCartesian(); return _verticalSpeedMPerSec; }
+ void setVerticalSpeedFtPerSec(double value)
+ { setVerticalSpeedMPerSec(SG_FEET_TO_METER*value); }
+ double getVerticalSpeedFtPerSec() const
+ { return SG_METER_TO_FEET*getVerticalSpeedMPerSec(); }
+ void setVerticalSpeedFtPerMin(double value)
+ { setVerticalSpeedFtPerSec(value/60); }
+ double getVerticalSpeedFtPerMin() const
+ { return 60*getVerticalSpeedFtPerSec(); }
+
+#define DATA_ELEMENT(name) \
+ HLADataElementProvider get## name ## DataElement() \
+ { return new DataElement<&HLAGeodeticLocation::get## name, &HLAGeodeticLocation::set ## name>(this); }
+
+ DATA_ELEMENT(LatitudeDeg)
+ DATA_ELEMENT(LatitudeRad)
+ DATA_ELEMENT(LongitudeDeg)
+ DATA_ELEMENT(LongitudeRad)
+ DATA_ELEMENT(ElevationFt)
+ DATA_ELEMENT(ElevationM)
+ DATA_ELEMENT(HeadingDeg)
+ DATA_ELEMENT(HeadingRad)
+ DATA_ELEMENT(PitchDeg)
+ DATA_ELEMENT(PitchRad)
+ DATA_ELEMENT(RollDeg)
+ DATA_ELEMENT(RollRad)
+
+ DATA_ELEMENT(GroundTrackDeg)
+ DATA_ELEMENT(GroundTrackRad)
+ DATA_ELEMENT(GroundSpeedMPerSec)
+ DATA_ELEMENT(GroundSpeedFtPerSec)
+ DATA_ELEMENT(GroundSpeedKnots)
+ DATA_ELEMENT(VerticalSpeedMPerSec)
+ DATA_ELEMENT(VerticalSpeedFtPerSec)
+ DATA_ELEMENT(VerticalSpeedFtPerMin)
+
+#undef DATA_ELEMENT
+
+private:
+ template<double (HLAGeodeticLocation::*getter)() const,
+ void (HLAGeodeticLocation::*setter)(double)>
+ class DataElement : public HLAAbstractDoubleDataElement {
+ public:
+ DataElement(HLAGeodeticLocation* data) :
+ _data(data)
+ { }
+ virtual double getValue() const
+ { return (_data->*getter)(); }
+ virtual void setValue(double value)
+ { (_data->*setter)(value); }
+
+ private:
+ SGSharedPtr<HLAGeodeticLocation> _data;
+ };
+
+ void updateGeodeticFromCartesian() const
+ {
+ if (!_dirty)
+ return;
+ _geodPosition = SGGeod::fromCart(_cartPosition);
+ SGQuatd geodOrientation = inverse(SGQuatd::fromLonLat(_geodPosition))*_cartOrientation;
+ geodOrientation.getEulerRad(_geodEulerRad[2], _geodEulerRad[1], _geodEulerRad[0]);
+ SGVec3d nedVel = geodOrientation.backTransform(_cartBodyVelocity);
+ if (SGLimitsd::min() < SGMiscd::max(fabs(nedVel[0]), fabs(nedVel[1])))
+ _groundTrackRad = atan2(nedVel[1], nedVel[0]);
+ else
+ _groundTrackRad = 0;
+ _groundSpeedMPerSec = sqrt(nedVel[0]*nedVel[0] + nedVel[1]*nedVel[1]);
+ _verticalSpeedMPerSec = -nedVel[2];
+ _dirty = false;
+ }
+ void updateCartesianFromGeodetic() const
+ {
+ if (!_dirty)
+ return;
+ _cartPosition = SGVec3d::fromGeod(_geodPosition);
+ SGQuatd geodOrientation = SGQuatd::fromEulerRad(_geodEulerRad[2], _geodEulerRad[1], _geodEulerRad[0]);
+ _cartOrientation = SGQuatd::fromLonLat(_geodPosition)*geodOrientation;
+ SGVec3d nedVel(cos(_groundTrackRad)*_groundSpeedMPerSec,
+ sin(_groundTrackRad)*_groundSpeedMPerSec,
+ -_verticalSpeedMPerSec);
+ _cartBodyVelocity = geodOrientation.transform(nedVel);
+ _dirty = false;
+ }
+
+ mutable bool _dirty;
+
+ // the cartesian values
+ mutable SGVec3d _cartPosition;
+ mutable SGQuatd _cartOrientation;
+ mutable SGVec3d _cartBodyVelocity;
+
+ // The geodetic values
+ mutable SGGeod _geodPosition;
+ mutable SGVec3d _geodEulerRad;
+ mutable double _groundTrackRad;
+ mutable double _groundSpeedMPerSec;
+ mutable double _verticalSpeedMPerSec;
+};
+
+class HLAGeodeticLocationFactory : public HLALocationFactory {
+public:
+ enum Semantic {
+ LatitudeDeg,
+ LatitudeRad,
+ LongitudeDeg,
+ LongitudeRad,
+ ElevationM,
+ ElevationFt,
+ HeadingDeg,
+ HeadingRad,
+ PitchDeg,
+ PitchRad,
+ RollDeg,
+ RollRad,
+ GroundTrackDeg,
+ GroundTrackRad,
+ GroundSpeedKnots,
+ GroundSpeedFtPerSec,
+ GroundSpeedMPerSec,
+ VerticalSpeedFtPerSec,
+ VerticalSpeedFtPerMin,
+ VerticalSpeedMPerSec
+ };
+
+ virtual HLAGeodeticLocation* createLocation(HLAAttributePathElementMap& attributePathElementMap) const
+ {
+ HLAGeodeticLocation* location = new HLAGeodeticLocation;
+
+ for (IndexPathPairSemanticMap::const_iterator i = _indexPathPairSemanticMap.begin();
+ i != _indexPathPairSemanticMap.end(); ++i) {
+ switch (i->second) {
+ case LatitudeDeg:
+ attributePathElementMap[i->first.first][i->first.second] = location->getLatitudeDegDataElement();
+ break;
+ case LatitudeRad:
+ attributePathElementMap[i->first.first][i->first.second] = location->getLatitudeRadDataElement();
+ break;
+ case LongitudeDeg:
+ attributePathElementMap[i->first.first][i->first.second] = location->getLongitudeDegDataElement();
+ break;
+ case LongitudeRad:
+ attributePathElementMap[i->first.first][i->first.second] = location->getLongitudeRadDataElement();
+ break;
+ case ElevationM:
+ attributePathElementMap[i->first.first][i->first.second] = location->getElevationMDataElement();
+ break;
+ case ElevationFt:
+ attributePathElementMap[i->first.first][i->first.second] = location->getElevationFtDataElement();
+ break;
+ case HeadingDeg:
+ attributePathElementMap[i->first.first][i->first.second] = location->getHeadingDegDataElement();
+ break;
+ case HeadingRad:
+ attributePathElementMap[i->first.first][i->first.second] = location->getHeadingRadDataElement();
+ break;
+ case PitchDeg:
+ attributePathElementMap[i->first.first][i->first.second] = location->getPitchDegDataElement();
+ break;
+ case PitchRad:
+ attributePathElementMap[i->first.first][i->first.second] = location->getPitchRadDataElement();
+ break;
+ case RollDeg:
+ attributePathElementMap[i->first.first][i->first.second] = location->getRollDegDataElement();
+ break;
+ case RollRad:
+ attributePathElementMap[i->first.first][i->first.second] = location->getRollRadDataElement();
+ break;
+ case GroundTrackDeg:
+ attributePathElementMap[i->first.first][i->first.second] = location->getGroundTrackDegDataElement();
+ break;
+ case GroundTrackRad:
+ attributePathElementMap[i->first.first][i->first.second] = location->getGroundTrackRadDataElement();
+ break;
+ case GroundSpeedKnots:
+ attributePathElementMap[i->first.first][i->first.second] = location->getGroundSpeedKnotsDataElement();
+ break;
+ case GroundSpeedFtPerSec:
+ attributePathElementMap[i->first.first][i->first.second] = location->getGroundSpeedFtPerSecDataElement();
+ break;
+ case GroundSpeedMPerSec:
+ attributePathElementMap[i->first.first][i->first.second] = location->getGroundSpeedMPerSecDataElement();
+ break;
+ case VerticalSpeedFtPerSec:
+ attributePathElementMap[i->first.first][i->first.second] = location->getVerticalSpeedFtPerSecDataElement();
+ break;
+ case VerticalSpeedFtPerMin:
+ attributePathElementMap[i->first.first][i->first.second] = location->getVerticalSpeedFtPerMinDataElement();
+ break;
+ case VerticalSpeedMPerSec:
+ attributePathElementMap[i->first.first][i->first.second] = location->getVerticalSpeedMPerSecDataElement();
+ break;
+ }
+ }
+
+ return location;
+ }
+
+ void setIndexPathPair(Semantic semantic, const HLADataElement::IndexPathPair& indexPathPair)
+ { _indexPathPairSemanticMap[indexPathPair] = semantic; }
+
+private:
+ typedef std::map<HLADataElement::IndexPathPair, Semantic> IndexPathPairSemanticMap;
+ IndexPathPairSemanticMap _indexPathPairSemanticMap;
+};
+
+} // namespace simgear
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "HLAOMTXmlVisitor.hxx"
+
+#include <map>
+#include <string>
+#include <sstream>
+
+#include <simgear/structure/exception.hxx>
+#include <simgear/xml/easyxml.hxx>
+#include "HLAArrayDataType.hxx"
+#include "HLABasicDataType.hxx"
+#include "HLADataTypeVisitor.hxx"
+#include "HLAEnumeratedDataType.hxx"
+#include "HLAFixedRecordDataType.hxx"
+#include "HLAVariantDataType.hxx"
+
+namespace simgear {
+
+HLAOMTXmlVisitor::ObjectClass::ObjectClass(const std::string& name, const std::string& sharing) :
+ _name(name),
+ _sharing(sharing)
+{
+}
+
+HLAOMTXmlVisitor::ObjectClass::~ObjectClass()
+{
+}
+
+const std::string&
+HLAOMTXmlVisitor::ObjectClass::getName() const
+{
+ return _name;
+}
+
+const std::string&
+HLAOMTXmlVisitor::ObjectClass::getSharing() const
+{
+ return _sharing;
+}
+
+unsigned
+HLAOMTXmlVisitor::ObjectClass::getNumAttributes() const
+{
+ return _attributes.size();
+}
+
+const HLAOMTXmlVisitor::Attribute*
+HLAOMTXmlVisitor::ObjectClass::getAttribute(unsigned index) const
+{
+ if (_attributes.size() <= index)
+ return 0;
+ 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 _parentObjectClass.get();
+}
+
+HLAOMTXmlVisitor::InteractionClass::InteractionClass(const std::string& name) :
+ _name(name)
+{
+}
+
+HLAOMTXmlVisitor::InteractionClass::~InteractionClass()
+{
+}
+
+const std::string&
+HLAOMTXmlVisitor::InteractionClass::getName() const
+{
+ return _name;
+}
+
+const std::string&
+HLAOMTXmlVisitor::InteractionClass::getDimensions() const
+{
+ return _dimensions;
+}
+
+const std::string&
+HLAOMTXmlVisitor::InteractionClass::getTransportation() const
+{
+ return _transportation;
+}
+
+const std::string&
+HLAOMTXmlVisitor::InteractionClass::getOrder() const
+{
+ return _order;
+}
+
+unsigned
+HLAOMTXmlVisitor::InteractionClass::getNumParameters() const
+{
+ return _parameters.size();
+}
+
+const HLAOMTXmlVisitor::Parameter*
+HLAOMTXmlVisitor::InteractionClass::getParameter(unsigned index) const
+{
+ if (_parameters.size() <= index)
+ return 0;
+ 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
+{
+ return _parentInteractionClass.get();
+}
+
+HLAOMTXmlVisitor::HLAOMTXmlVisitor()
+{
+}
+
+HLAOMTXmlVisitor::~HLAOMTXmlVisitor()
+{
+}
+
+unsigned
+HLAOMTXmlVisitor::getNumObjectClasses() const
+{
+ return _objectClassList.size();
+}
+
+const HLAOMTXmlVisitor::ObjectClass*
+HLAOMTXmlVisitor::getObjectClass(unsigned i) const
+{
+ if (_objectClassList.size() <= i)
+ return 0;
+ return _objectClassList[i];
+}
+
+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)
+ continue;
+ return i->get();
+ }
+ 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
+{
+ const ObjectClass* objectClass = getObjectClass(objectClassName);
+ if (!objectClass)
+ return 0;
+ return objectClass->getAttribute(attributeName);
+}
+
+HLADataType*
+HLAOMTXmlVisitor::getAttributeDataType(const std::string& objectClassName, const std::string& attributeName) const
+{
+ const Attribute* attribute = getAttribute(objectClassName, attributeName);
+ if (!attribute)
+ return 0;
+ return getDataType(attribute->_dataType);
+}
+
+unsigned
+HLAOMTXmlVisitor::getNumInteractionClasses() const
+{
+ return _interactionClassList.size();
+}
+
+const HLAOMTXmlVisitor::InteractionClass*
+HLAOMTXmlVisitor::getInteractionClass(unsigned i) const
+{
+ if (_interactionClassList.size() <= i)
+ return 0;
+ 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
+{
+ StringDataTypeMap::const_iterator i = dataTypeMap.find(dataTypeName);
+ if (i != dataTypeMap.end())
+ return new HLADataTypeReference(i->second);
+
+ SGSharedPtr<HLADataType> dataType;
+ dataType = getBasicDataType(dataTypeName);
+ if (dataType.valid())
+ return dataType;
+
+ dataType = getSimpleDataType(dataTypeName);
+ if (dataType.valid())
+ return dataType;
+
+ dataType = getEnumeratedDataType(dataTypeName);
+ if (dataType.valid())
+ return dataType;
+
+ dataType = getArrayDataType(dataTypeName, dataTypeMap);
+ if (dataType.valid())
+ return dataType;
+
+ dataType = getFixedRecordDataType(dataTypeName, dataTypeMap);
+ if (dataType.valid())
+ return dataType;
+
+ dataType = getVariantDataType(dataTypeName, dataTypeMap);
+ if (dataType.valid())
+ return dataType;
+
+ SG_LOG(SG_IO, SG_WARN, "Could not resolve dataType \"" << dataTypeName << "\".");
+ return 0;
+}
+
+SGSharedPtr<HLABasicDataType>
+HLAOMTXmlVisitor::getBasicDataType(const std::string& dataTypeName) const
+{
+ BasicDataMap::const_iterator i = _basicDataMap.find(dataTypeName);
+ if (i == _basicDataMap.end())
+ return 0;
+ if (i->second._size == "8") {
+ return new HLAUInt8DataType(dataTypeName);
+ } else if (i->second._size == "16") {
+ if (i->first.find("Unsigned") != std::string::npos) {
+ if (i->second._endian == "Little") {
+ return new HLAUInt16LEDataType(dataTypeName);
+ } else {
+ return new HLAUInt16BEDataType(dataTypeName);
+ }
+ } else if (i->first.find("octetPair") != std::string::npos) {
+ if (i->second._endian == "Little") {
+ return new HLAUInt16LEDataType(dataTypeName);
+ } else {
+ return new HLAUInt16BEDataType(dataTypeName);
+ }
+ } else {
+ if (i->second._endian == "Little") {
+ return new HLAInt16LEDataType(dataTypeName);
+ } else {
+ return new HLAInt16BEDataType(dataTypeName);
+ }
+ }
+ } else if (i->second._size == "32") {
+ if (i->first.find("Unsigned") != std::string::npos) {
+ if (i->second._endian == "Little") {
+ return new HLAUInt32LEDataType(dataTypeName);
+ } else {
+ return new HLAUInt32BEDataType(dataTypeName);
+ }
+ } else if (i->first.find("float") != std::string::npos) {
+ if (i->second._endian == "Little") {
+ return new HLAFloat32LEDataType(dataTypeName);
+ } else {
+ return new HLAFloat32BEDataType(dataTypeName);
+ }
+ } else {
+ if (i->second._endian == "Little") {
+ return new HLAInt32LEDataType(dataTypeName);
+ } else {
+ return new HLAInt32BEDataType(dataTypeName);
+ }
+ }
+ } else if (i->second._size == "64") {
+ if (i->first.find("Unsigned") != std::string::npos) {
+ if (i->second._endian == "Little") {
+ return new HLAUInt64LEDataType(dataTypeName);
+ } else {
+ return new HLAUInt64BEDataType(dataTypeName);
+ }
+ } else if (i->first.find("float") != std::string::npos) {
+ if (i->second._endian == "Little") {
+ return new HLAFloat64LEDataType(dataTypeName);
+ } else {
+ return new HLAFloat64BEDataType(dataTypeName);
+ }
+ } else {
+ if (i->second._endian == "Little") {
+ return new HLAInt64LEDataType(dataTypeName);
+ } else {
+ return new HLAInt64BEDataType(dataTypeName);
+ }
+ }
+ }
+
+ return 0;
+}
+
+SGSharedPtr<HLADataType>
+HLAOMTXmlVisitor::getSimpleDataType(const std::string& dataTypeName) const
+{
+ SimpleDataMap::const_iterator i = _simpleDataMap.find(dataTypeName);
+ if (i == _simpleDataMap.end())
+ return 0;
+ return getDataType(i->second._representation);
+}
+
+SGSharedPtr<HLAEnumeratedDataType>
+HLAOMTXmlVisitor::getEnumeratedDataType(const std::string& dataTypeName) const
+{
+ EnumeratedDataMap::const_iterator i = _enumeratedDataMap.find(dataTypeName);
+ if (i == _enumeratedDataMap.end())
+ return 0;
+
+ SGSharedPtr<HLAEnumeratedDataType> enumeratedDataType = new HLAEnumeratedDataType(dataTypeName);
+ enumeratedDataType->setRepresentation(getBasicDataType(i->second._representation));
+
+ for (EnumeratorList::const_iterator j = i->second._enumeratorList.begin();
+ j != i->second._enumeratorList.end(); ++j) {
+ if (!enumeratedDataType->addEnumerator(j->_name, j->_values)) {
+ SG_LOG(SG_IO, SG_ALERT, "Could not add enumerator \"" << j->_name
+ << "\" to find enumerated data type \"" << dataTypeName << "\".");
+ return 0;
+ }
+ }
+
+ return enumeratedDataType;
+}
+
+SGSharedPtr<HLADataType>
+HLAOMTXmlVisitor::getArrayDataType(const std::string& dataTypeName, HLAOMTXmlVisitor::StringDataTypeMap& dataTypeMap) const
+{
+ ArrayDataMap::const_iterator i = _arrayDataMap.find(dataTypeName);
+ if (i == _arrayDataMap.end())
+ return 0;
+ SGSharedPtr<HLAArrayDataType> arrayDataType;
+ if (i->second._encoding == "HLAvariableArray") {
+ arrayDataType = new HLAVariableArrayDataType(dataTypeName);
+ } else if (i->second._encoding == "HLAfixedArray") {
+ std::stringstream ss(i->second._cardinality);
+ unsigned cardinality;
+ ss >> cardinality;
+ if (ss.fail()) {
+ SG_LOG(SG_IO, SG_ALERT, "Could not interpret cardinality \""
+ << i->second._cardinality << "\" for dataType \""
+ << dataTypeName << "\".");
+ return 0;
+ }
+ SGSharedPtr<HLAFixedArrayDataType> dataType = new HLAFixedArrayDataType(dataTypeName);
+ dataType->setNumElements(cardinality);
+ arrayDataType = dataType;
+ } else {
+ SG_LOG(SG_IO, SG_ALERT, "Can not interpret encoding \""
+ << i->second._encoding << "\" for dataType \""
+ << dataTypeName << "\".");
+ return 0;
+ }
+
+ dataTypeMap[dataTypeName] = arrayDataType;
+ SGSharedPtr<HLADataType> elementDataType = getDataType(i->second._dataType, dataTypeMap);
+ if (!elementDataType.valid()) {
+ SG_LOG(SG_IO, SG_ALERT, "Could not interpret dataType \""
+ << i->second._dataType << "\" for array data type \""
+ << dataTypeName << "\".");
+ dataTypeMap.erase(dataTypeName);
+ return 0;
+ }
+ arrayDataType->setElementDataType(elementDataType.get());
+
+ return arrayDataType;
+}
+
+SGSharedPtr<HLAFixedRecordDataType>
+HLAOMTXmlVisitor::getFixedRecordDataType(const std::string& dataTypeName, HLAOMTXmlVisitor::StringDataTypeMap& dataTypeMap) const
+{
+ FixedRecordDataMap::const_iterator i = _fixedRecordDataMap.find(dataTypeName);
+ if (i == _fixedRecordDataMap.end())
+ return 0;
+
+ SGSharedPtr<HLAFixedRecordDataType> dataType = new HLAFixedRecordDataType(dataTypeName);
+ 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);
+ 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);
+ return 0;
+ }
+ dataType->addField(i->second._fieldList[j]._name, fieldDataType.get());
+ }
+ return dataType;
+}
+
+SGSharedPtr<HLAVariantDataType>
+HLAOMTXmlVisitor::getVariantDataType(const std::string& dataTypeName, HLAOMTXmlVisitor::StringDataTypeMap& dataTypeMap) const
+{
+ VariantRecordDataMap::const_iterator i = _variantRecordDataMap.find(dataTypeName);
+ if (i == _variantRecordDataMap.end())
+ return 0;
+ SGSharedPtr<HLAVariantDataType> dataType = new HLAVariantDataType(dataTypeName);
+ dataTypeMap[dataTypeName] = dataType;
+
+ SGSharedPtr<HLAEnumeratedDataType> enumeratedDataType = getEnumeratedDataType(i->second._dataType);
+ if (!enumeratedDataType.valid()) {
+ SG_LOG(SG_IO, SG_ALERT, "Could not find enumerted data type \"" << i->second._dataType
+ << "\" for variant data type \"" << dataTypeName << "\".");
+ return 0;
+ }
+ dataType->setEnumeratedDataType(enumeratedDataType);
+
+ for (AlternativeList::const_iterator j = i->second._alternativeList.begin();
+ j != i->second._alternativeList.end(); ++j) {
+ SGSharedPtr<HLADataType> alternativeDataType = getDataType(j->_dataType, dataTypeMap);
+ if (!alternativeDataType.valid()) {
+ SG_LOG(SG_IO, SG_ALERT, "Could not resolve alternative dataType \"" << j->_dataType
+ << "\" for alternative \"" << j->_name << "\".");
+ dataTypeMap.erase(dataTypeName);
+ return 0;
+ }
+ if (!dataType->addAlternative(j->_name, j->_enumerator, alternativeDataType.get(), j->_semantics)) {
+ SG_LOG(SG_IO, SG_ALERT, "Could not add alternative \"" << j->_name << "\".");
+ return 0;
+ }
+ }
+ return dataType;
+}
+
+HLAOMTXmlVisitor::Mode
+HLAOMTXmlVisitor::getCurrentMode()
+{
+ if (_modeStack.empty())
+ return UnknownMode;
+ return _modeStack.back();
+}
+
+void
+HLAOMTXmlVisitor::pushMode(HLAOMTXmlVisitor::Mode mode)
+{
+ _modeStack.push_back(mode);
+}
+
+void
+HLAOMTXmlVisitor::popMode()
+{
+ _modeStack.pop_back();
+}
+
+void
+HLAOMTXmlVisitor::startXML()
+{
+ _modeStack.clear();
+}
+
+void
+HLAOMTXmlVisitor::endXML()
+{
+ if (!_modeStack.empty())
+ throw sg_exception("Internal parse error!");
+
+ // propagate parent attributes to the derived classes
+ for (ObjectClassList::const_iterator i = _objectClassList.begin(); i != _objectClassList.end(); ++i) {
+ SGSharedPtr<const ObjectClass> objectClass = (*i)->_parentObjectClass;
+ while (objectClass) {
+ for (AttributeList::const_reverse_iterator j = objectClass->_attributes.rbegin();
+ j != objectClass->_attributes.rend(); ++j) {
+ (*i)->_attributes.insert((*i)->_attributes.begin(), *j);
+ }
+ objectClass = objectClass->_parentObjectClass;
+ }
+ }
+
+ // propagate parent parameter to the derived interactions
+ for (InteractionClassList::const_iterator i = _interactionClassList.begin(); i != _interactionClassList.end(); ++i) {
+ SGSharedPtr<const InteractionClass> interactionClass = (*i)->_parentInteractionClass;
+ while (interactionClass) {
+ for (ParameterList::const_reverse_iterator j = interactionClass->_parameters.rbegin();
+ j != interactionClass->_parameters.rend(); ++j) {
+ (*i)->_parameters.insert((*i)->_parameters.begin(), *j);
+ }
+ interactionClass = interactionClass->_parentInteractionClass;
+ }
+ }
+}
+
+void
+HLAOMTXmlVisitor::startElement(const char* name, const XMLAttributes& atts)
+{
+ if (strcmp(name, "attribute") == 0) {
+ if (getCurrentMode() != ObjectClassMode)
+ throw sg_exception("attribute tag outside objectClass!");
+ pushMode(AttributeMode);
+
+ if (_objectClassList.empty())
+ throw sg_exception("attribute tag outside of an objectClass");
+
+ std::string name = getAttribute("name", atts);
+ if (name.empty())
+ throw sg_exception("attribute tag without name attribute");
+
+ SGSharedPtr<Attribute> attribute = new Attribute(name);
+
+ attribute->_dataType = getAttribute("dataType", atts);
+ attribute->_updateType = getAttribute("updateType", atts);
+ attribute->_updateCondition = getAttribute("updateCondition", atts);
+ attribute->_ownership = getAttribute("ownership", atts);
+ attribute->_sharing = getAttribute("sharing", atts);
+ attribute->_dimensions = getAttribute("dimensions", atts);
+ attribute->_transportation = getAttribute("transportation", atts);
+ attribute->_order = getAttribute("order", atts);
+
+ _objectClassStack.back()->_attributes.push_back(attribute);
+
+ } else if (strcmp(name, "objectClass") == 0) {
+ if (getCurrentMode() != ObjectsMode && getCurrentMode() != ObjectClassMode)
+ throw sg_exception("objectClass tag outside objectClass or objects!");
+ pushMode(ObjectClassMode);
+
+ std::string name = getAttribute("name", atts);
+ if (name.empty())
+ throw sg_exception("objectClass tag without name attribute");
+
+ std::string sharing = getAttribute("sharing", atts);
+
+ // The new ObjectClass
+ ObjectClass* objectClass = new ObjectClass(name, sharing);
+
+ // Inherit all previous attributes
+ if (!_objectClassStack.empty())
+ objectClass->_parentObjectClass = _objectClassStack.back();
+
+ _objectClassStack.push_back(objectClass);
+ _objectClassList.push_back(objectClass);
+
+ } else if (strcmp(name, "objects") == 0) {
+ if (getCurrentMode() != ObjectModelMode)
+ throw sg_exception("objects tag outside objectModel!");
+ pushMode(ObjectsMode);
+
+ } else if (strcmp(name, "parameter") == 0) {
+ if (getCurrentMode() != InteractionClassMode)
+ throw sg_exception("parameter tag outside interactionClass!");
+ pushMode(ParameterMode);
+
+ if (_interactionClassList.empty())
+ throw sg_exception("parameter tag outside of an interactionClass");
+
+ std::string name = getAttribute("name", atts);
+ if (name.empty())
+ throw sg_exception("parameter tag without name parameter");
+
+ SGSharedPtr<Parameter> parameter = new Parameter(name);
+ parameter->_dataType = getAttribute("dataType", atts);
+
+ _interactionClassStack.back()->_parameters.push_back(parameter);
+
+ } else if (strcmp(name, "interactionClass") == 0) {
+ if (getCurrentMode() != InteractionsMode && getCurrentMode() != InteractionClassMode)
+ throw sg_exception("interactionClass tag outside interactions or interactionClass!");
+ pushMode(InteractionClassMode);
+
+ std::string name = getAttribute("name", atts);
+ if (name.empty())
+ throw sg_exception("interactionClass tag without name attribute");
+
+ // The new ObjectClass
+ InteractionClass* interactionClass = new InteractionClass(name);
+ interactionClass->_dimensions = getAttribute("dimensions", atts);
+ interactionClass->_transportation = getAttribute("transportation", atts);
+ interactionClass->_order = getAttribute("order", atts);
+
+ // Inherit all previous attributes
+ if (!_interactionClassStack.empty())
+ interactionClass->_parentInteractionClass = _interactionClassStack.back();
+
+ _interactionClassStack.push_back(interactionClass);
+ _interactionClassList.push_back(interactionClass);
+
+ } else if (strcmp(name, "interactions") == 0) {
+ if (getCurrentMode() != ObjectModelMode)
+ throw sg_exception("interactions tag outside objectModel!");
+ pushMode(InteractionsMode);
+
+ } else if (strcmp(name, "basicData") == 0) {
+ if (getCurrentMode() != BasicDataRepresentationsMode)
+ throw sg_exception("basicData tag outside basicDataRepresentations!");
+ pushMode(BasicDataMode);
+
+ std::string name = getAttribute("name", atts);
+ if (name.empty())
+ throw sg_exception("basicData tag without name attribute");
+
+ _basicDataMap[name]._size = getAttribute("size", atts);
+ _basicDataMap[name]._endian = getAttribute("endian", atts);
+
+ } else if (strcmp(name, "basicDataRepresentations") == 0) {
+ if (getCurrentMode() != DataTypesMode)
+ throw sg_exception("basicDataRepresentations tag outside dataTypes!");
+ pushMode(BasicDataRepresentationsMode);
+
+ } else if (strcmp(name, "simpleData") == 0) {
+ if (getCurrentMode() != SimpleDataTypesMode)
+ throw sg_exception("simpleData tag outside simpleDataTypes!");
+ pushMode(SimpleDataMode);
+
+ std::string name = getAttribute("name", atts);
+ if (name.empty())
+ throw sg_exception("simpleData tag without name attribute");
+
+ _simpleDataMap[name]._representation = getAttribute("representation", atts);
+ _simpleDataMap[name]._units = getAttribute("units", atts);
+ _simpleDataMap[name]._resolution = getAttribute("resolution", atts);
+ _simpleDataMap[name]._accuracy = getAttribute("accuracy", atts);
+
+ } else if (strcmp(name, "simpleDataTypes") == 0) {
+ if (getCurrentMode() != DataTypesMode)
+ throw sg_exception("simpleDataTypes tag outside dataTypes!");
+ pushMode(SimpleDataTypesMode);
+
+ } else if (strcmp(name, "enumerator") == 0) {
+ if (getCurrentMode() != EnumeratedDataMode)
+ throw sg_exception("enumerator tag outside enumeratedData!");
+ pushMode(EnumeratorMode);
+
+ std::string name = getAttribute("name", atts);
+ if (name.empty())
+ throw sg_exception("enumerator tag without name attribute");
+
+ Enumerator enumerator;
+ enumerator._name = name;
+ enumerator._values = getAttribute("values", atts);
+ _enumeratedDataMap[_enumeratedDataName]._enumeratorList.push_back(enumerator);
+
+ } else if (strcmp(name, "enumeratedData") == 0) {
+ if (getCurrentMode() != EnumeratedDataTypesMode)
+ throw sg_exception("enumeratedData tag outside enumeratedDataTypes!");
+ pushMode(EnumeratedDataMode);
+
+ std::string name = getAttribute("name", atts);
+ if (name.empty())
+ throw sg_exception("enumeratedData tag without name attribute");
+
+ _enumeratedDataName = name;
+ _enumeratedDataMap[_enumeratedDataName]._representation = getAttribute("representation", atts);
+
+ } else if (strcmp(name, "enumeratedDataTypes") == 0) {
+ if (getCurrentMode() != DataTypesMode)
+ throw sg_exception("enumeratedDataTypes tag outside dataTypes!");
+ pushMode(EnumeratedDataTypesMode);
+
+ Enumerator enumerator;
+ enumerator._name = getAttribute("name", atts);
+ enumerator._values = getAttribute("values", atts);
+ _enumeratedDataMap[_enumeratedDataName]._enumeratorList.push_back(enumerator);
+
+ } else if (strcmp(name, "arrayData") == 0) {
+ if (getCurrentMode() != ArrayDataTypesMode)
+ throw sg_exception("arrayData tag outside arrayDataTypes!");
+ pushMode(ArrayDataMode);
+
+ std::string name = getAttribute("name", atts);
+ if (name.empty())
+ throw sg_exception("arrayData tag without name attribute");
+
+ _arrayDataMap[name]._dataType = getAttribute("dataType", atts);
+ _arrayDataMap[name]._cardinality = getAttribute("cardinality", atts);
+ _arrayDataMap[name]._encoding = getAttribute("encoding", atts);
+
+ } else if (strcmp(name, "arrayDataTypes") == 0) {
+ if (getCurrentMode() != DataTypesMode)
+ throw sg_exception("arrayDataTypes tag outside dataTypes!");
+ pushMode(ArrayDataTypesMode);
+
+ } else if (strcmp(name, "field") == 0) {
+ if (getCurrentMode() != FixedRecordDataMode)
+ throw sg_exception("field tag outside fixedRecordData!");
+ pushMode(FieldMode);
+
+ std::string name = getAttribute("name", atts);
+ if (name.empty())
+ throw sg_exception("field tag without name attribute");
+
+ Field field;
+ field._name = name;
+ field._dataType = getAttribute("dataType", atts);
+ _fixedRecordDataMap[_fixedRecordDataName]._fieldList.push_back(field);
+
+ } else if (strcmp(name, "fixedRecordData") == 0) {
+ if (getCurrentMode() != FixedRecordDataTypesMode)
+ throw sg_exception("fixedRecordData tag outside fixedRecordDataTypes!");
+ pushMode(FixedRecordDataMode);
+
+ std::string name = getAttribute("name", atts);
+ if (name.empty())
+ throw sg_exception("fixedRecordData tag without name attribute");
+
+ _fixedRecordDataName = name;
+ _fixedRecordDataMap[name]._encoding = getAttribute("encoding", atts);
+
+ } else if (strcmp(name, "fixedRecordDataTypes") == 0) {
+ if (getCurrentMode() != DataTypesMode)
+ throw sg_exception("fixedRecordDataTypes tag outside dataTypes!");
+ pushMode(FixedRecordDataTypesMode);
+
+ } else if (strcmp(name, "alternative") == 0) {
+
+ if (getCurrentMode() != VariantRecordDataMode)
+ throw sg_exception("alternative tag outside variantRecordData!");
+ pushMode(AlternativeDataMode);
+
+ std::string name = getAttribute("name", atts);
+ if (name.empty())
+ throw sg_exception("alternative tag without name attribute");
+
+ Alternative alternative;
+ alternative._name = name;
+ alternative._dataType = getAttribute("dataType", atts);
+ alternative._semantics = getAttribute("semantics", atts);
+ alternative._enumerator = getAttribute("enumerator", atts);
+ _variantRecordDataMap[_variantRecordDataName]._alternativeList.push_back(alternative);
+
+ } else if (strcmp(name, "variantRecordData") == 0) {
+ if (getCurrentMode() != VariantRecordDataTypesMode)
+ throw sg_exception("variantRecordData tag outside variantRecordDataTypes!");
+ pushMode(VariantRecordDataMode);
+
+ std::string name = getAttribute("name", atts);
+ if (name.empty())
+ throw sg_exception("fixedRecordData tag without name attribute");
+
+ _variantRecordDataName = name;
+ _variantRecordDataMap[name]._encoding = getAttribute("encoding", atts);
+ _variantRecordDataMap[name]._dataType = getAttribute("dataType", atts);
+ _variantRecordDataMap[name]._semantics = getAttribute("semantics", atts);
+ _variantRecordDataMap[name]._discriminant = getAttribute("discriminant", atts);
+
+ } else if (strcmp(name, "variantRecordDataTypes") == 0) {
+ if (getCurrentMode() != DataTypesMode)
+ throw sg_exception("variantRecordDataTypes tag outside dataTypes!");
+ pushMode(VariantRecordDataTypesMode);
+
+ } else if (strcmp(name, "dataTypes") == 0) {
+ if (getCurrentMode() != ObjectModelMode)
+ throw sg_exception("dataTypes tag outside objectModel!");
+ pushMode(DataTypesMode);
+
+ } else if (strcmp(name, "objectModel") == 0) {
+ if (!_modeStack.empty())
+ throw sg_exception("objectModel tag not at top level!");
+ pushMode(ObjectModelMode);
+
+ } else {
+ _modeStack.push_back(UnknownMode);
+ }
+}
+
+void
+HLAOMTXmlVisitor::endElement(const char* name)
+{
+ if (strcmp(name, "objectClass") == 0) {
+ _objectClassStack.pop_back();
+ } else if (strcmp(name, "interactionClass") == 0) {
+ _interactionClassStack.pop_back();
+ } else if (strcmp(name, "enumeratedData") == 0) {
+ _enumeratedDataName.clear();
+ } else if (strcmp(name, "fixedRecordData") == 0) {
+ _fixedRecordDataName.clear();
+ } else if (strcmp(name, "variantRecordData") == 0) {
+ _variantRecordDataName.clear();
+ }
+
+ _modeStack.pop_back();
+}
+
+std::string
+HLAOMTXmlVisitor::getAttribute(const char* name, const XMLAttributes& atts)
+{
+ int index = atts.findAttribute(name);
+ if (index < 0 || atts.size() <= index)
+ return std::string();
+ return std::string(atts.getValue(index));
+}
+
+std::string
+HLAOMTXmlVisitor::getAttribute(const std::string& name, const XMLAttributes& atts)
+{
+ int index = atts.findAttribute(name.c_str());
+ if (index < 0 || atts.size() <= index)
+ return std::string();
+ return std::string(atts.getValue(index));
+}
+
+} // namespace simgear
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLAOMTXmlVisitor_hxx
+#define HLAOMTXmlVisitor_hxx
+
+#include <map>
+#include <string>
+
+#include <simgear/structure/exception.hxx>
+#include <simgear/structure/SGSharedPtr.hxx>
+#include <simgear/xml/easyxml.hxx>
+#include "HLADataType.hxx"
+
+namespace simgear {
+
+class HLAOMTXmlVisitor : public XMLVisitor {
+public:
+ /// structures representing the federate object model data
+ struct Attribute : public SGReferenced {
+ Attribute(const std::string& name) :
+ _name(name)
+ { }
+ const std::string& getName() const
+ { return _name; }
+ const std::string& getDimensions() const
+ { return _dimensions; }
+ const std::string& getTransportation() const
+ { return _transportation; }
+ const std::string& getOrder() const
+ { return _order; }
+
+ std::string _name;
+ std::string _dataType;
+ std::string _updateType;
+ std::string _updateCondition;
+ std::string _ownership;
+ std::string _sharing;
+ std::string _dimensions;
+ std::string _transportation;
+ std::string _order;
+ friend class HLAOMTXmlVisitor;
+ };
+ typedef std::vector<SGSharedPtr<Attribute> > AttributeList;
+
+ struct ObjectClass : public SGReferenced {
+ ObjectClass(const std::string& name, const std::string& sharing);
+ ~ObjectClass();
+
+ const std::string& getName() const;
+ const std::string& getSharing() const;
+
+ unsigned getNumAttributes() const;
+ const Attribute* getAttribute(unsigned index) const;
+ const Attribute* getAttribute(const std::string& name) const;
+
+ const ObjectClass* getParentObjectClass() const;
+
+ private:
+ friend class HLAOMTXmlVisitor;
+ std::string _name;
+ std::string _sharing;
+ AttributeList _attributes;
+ SGSharedPtr<ObjectClass> _parentObjectClass;
+ };
+ typedef std::vector<SGSharedPtr<ObjectClass> > ObjectClassList;
+
+ struct Parameter : public SGReferenced {
+ Parameter(const std::string& name) :
+ _name(name)
+ { }
+ const std::string& getName() const
+ { return _name; }
+ const std::string& getDataType() const
+ { return _dataType; }
+
+ private:
+ std::string _name;
+ std::string _dataType;
+ friend class HLAOMTXmlVisitor;
+ };
+ typedef std::vector<SGSharedPtr<Parameter> > ParameterList;
+
+ struct InteractionClass : public SGReferenced {
+ InteractionClass(const std::string& name);
+ ~InteractionClass();
+
+ const std::string& getName() const;
+ const std::string& getDimensions() const;
+ const std::string& getTransportation() const;
+ const std::string& getOrder() const;
+
+ unsigned getNumParameters() const;
+ const Parameter* getParameter(unsigned index) const;
+ const Parameter* getParameter(const std::string& name) const;
+
+ const InteractionClass* getParentInteractionClass() const;
+
+ private:
+ friend class HLAOMTXmlVisitor;
+ std::string _name;
+ std::string _dimensions;
+ std::string _transportation;
+ std::string _order;
+ ParameterList _parameters;
+ SGSharedPtr<InteractionClass> _parentInteractionClass;
+ };
+ typedef std::vector<SGSharedPtr<InteractionClass> > InteractionClassList;
+
+ HLAOMTXmlVisitor();
+ ~HLAOMTXmlVisitor();
+
+ 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<HLAVariantDataType> getVariantDataType(const std::string& dataTypeName, StringDataTypeMap& dataTypeMap) const;
+
+ enum Mode {
+ UnknownMode,
+
+ ObjectModelMode,
+
+ ObjectsMode,
+ ObjectClassMode,
+ AttributeMode,
+
+ InteractionsMode,
+ InteractionClassMode,
+ ParameterMode,
+
+ DataTypesMode,
+ BasicDataRepresentationsMode,
+ BasicDataMode,
+ SimpleDataTypesMode,
+ SimpleDataMode,
+ EnumeratedDataTypesMode,
+ EnumeratedDataMode,
+ EnumeratorMode,
+ ArrayDataTypesMode,
+ ArrayDataMode,
+ FixedRecordDataTypesMode,
+ FixedRecordDataMode,
+ FieldMode,
+ VariantRecordDataTypesMode,
+ VariantRecordDataMode,
+ AlternativeDataMode
+ };
+
+ Mode getCurrentMode();
+ void pushMode(Mode mode);
+ void popMode();
+
+ virtual void startXML();
+ virtual void endXML ();
+ 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);
+
+ struct BasicData {
+ // std::string _name;
+ std::string _size;
+ std::string _endian;
+ };
+ typedef std::map<std::string, BasicData> BasicDataMap;
+
+ struct SimpleData {
+ // std::string _name;
+ std::string _representation;
+ std::string _units;
+ std::string _resolution;
+ std::string _accuracy;
+ };
+ typedef std::map<std::string, SimpleData> SimpleDataMap;
+
+ struct Enumerator {
+ std::string _name;
+ std::string _values;
+ };
+ typedef std::vector<Enumerator> EnumeratorList;
+
+ struct EnumeratedData {
+ // std::string _name;
+ std::string _representation;
+ EnumeratorList _enumeratorList;
+ };
+ typedef std::map<std::string, EnumeratedData> EnumeratedDataMap;
+
+ struct ArrayData {
+ // std::string _name;
+ std::string _dataType;
+ std::string _cardinality;
+ std::string _encoding;
+ };
+ typedef std::map<std::string, ArrayData> ArrayDataMap;
+
+ struct Field {
+ std::string _name;
+ std::string _dataType;
+ };
+ typedef std::vector<Field> FieldList;
+
+ struct FixedRecordData {
+ // std::string _name;
+ std::string _encoding;
+ FieldList _fieldList;
+ };
+ typedef std::map<std::string, FixedRecordData> FixedRecordDataMap;
+
+ struct Alternative {
+ std::string _name;
+ std::string _dataType;
+ std::string _semantics;
+ std::string _enumerator;
+ };
+ typedef std::vector<Alternative> AlternativeList;
+
+ struct VariantRecordData {
+ // std::string _name;
+ std::string _encoding;
+ std::string _dataType;
+ std::string _discriminant;
+ std::string _semantics;
+ AlternativeList _alternativeList;
+ };
+ typedef std::map<std::string, VariantRecordData> VariantRecordDataMap;
+
+ std::vector<Mode> _modeStack;
+
+ /// The total list of object classes
+ ObjectClassList _objectClassList;
+ ObjectClassList _objectClassStack;
+
+ /// The total list of interaction classes
+ InteractionClassList _interactionClassList;
+ InteractionClassList _interactionClassStack;
+
+ /// DataType definitions
+ BasicDataMap _basicDataMap;
+ SimpleDataMap _simpleDataMap;
+ std::string _enumeratedDataName;
+ EnumeratedDataMap _enumeratedDataMap;
+ ArrayDataMap _arrayDataMap;
+ std::string _fixedRecordDataName;
+ FixedRecordDataMap _fixedRecordDataMap;
+ std::string _variantRecordDataName;
+ VariantRecordDataMap _variantRecordDataMap;
+};
+
+} // namespace simgear
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "HLAObjectClass.hxx"
+
+#include "RTIFederate.hxx"
+#include "RTIObjectClass.hxx"
+#include "RTIObjectInstance.hxx"
+#include "HLADataType.hxx"
+#include "HLAFederate.hxx"
+#include "HLAObjectInstance.hxx"
+
+namespace simgear {
+
+HLAObjectClass::InstanceCallback::~InstanceCallback()
+{
+}
+
+void
+HLAObjectClass::InstanceCallback::discoverInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance, const RTIData& tag)
+{
+}
+
+void
+HLAObjectClass::InstanceCallback::removeInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance, const RTIData& tag)
+{
+}
+
+void
+HLAObjectClass::InstanceCallback::registerInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance)
+{
+}
+
+void
+HLAObjectClass::InstanceCallback::deleteInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance)
+{
+}
+
+HLAObjectClass::RegistrationCallback::~RegistrationCallback()
+{
+}
+
+HLAObjectClass::HLAObjectClass(const std::string& name, HLAFederate& 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 << "\"!");
+}
+
+HLAObjectClass::~HLAObjectClass()
+{
+}
+
+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();
+}
+
+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() << "\"!");
+ return ~0u;
+ }
+ return _rtiObjectClass->getOrCreateAttributeIndex(name);
+}
+
+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);
+}
+
+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() << "\"!");
+ return 0;
+ }
+ return _rtiObjectClass->getAttributeDataType(index);
+}
+
+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() << "\"!");
+ return;
+ }
+ _rtiObjectClass->setAttributeDataType(index, 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() << "\"!");
+ return HLAUndefinedUpdate;
+ }
+ return _rtiObjectClass->getAttributeUpdateType(index);
+}
+
+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() << "\"!");
+ return;
+ }
+ _rtiObjectClass->setAttributeUpdateType(index, updateType);
+}
+
+HLADataElement::IndexPathPair
+HLAObjectClass::getIndexPathPair(const HLADataElement::AttributePathPair& attributePathPair) const
+{
+ unsigned index = getAttributeIndex(attributePathPair.first);
+ if (getNumAttributes() <= index) {
+ SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass::getIndexPathPair(\""
+ << HLADataElement::toString(attributePathPair)
+ << "\"): Could not resolve attribute \"" << attributePathPair.first
+ << "\" for object class \"" << getName() << "\"!");
+ }
+ return HLADataElement::IndexPathPair(index, attributePathPair.second);
+}
+
+HLADataElement::IndexPathPair
+HLAObjectClass::getIndexPathPair(const std::string& path) const
+{
+ return getIndexPathPair(HLADataElement::toAttributePathPair(path));
+}
+
+bool
+HLAObjectClass::subscribe(const std::set<unsigned>& indexSet, bool active)
+{
+ if (!_rtiObjectClass.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::subscribe(): No RTIObject class for object class \"" << getName() << "\"!");
+ return false;
+ }
+ return _rtiObjectClass->subscribe(indexSet, active);
+}
+
+bool
+HLAObjectClass::unsubscribe()
+{
+ if (!_rtiObjectClass.valid()) {
+ 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)
+{
+ if (!_rtiObjectClass.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::publish(): No RTIObject class for object class \"" << getName() << "\"!");
+ return false;
+ }
+ return _rtiObjectClass->publish(indexSet);
+}
+
+bool
+HLAObjectClass::unpublish()
+{
+ if (!_rtiObjectClass.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::unpublish(): No RTIObject class for object class \"" << getName() << "\"!");
+ return false;
+ }
+ return _rtiObjectClass->unpublish();
+}
+
+void
+HLAObjectClass::startRegistration() const
+{
+}
+
+void
+HLAObjectClass::stopRegistration() const
+{
+}
+
+HLAObjectInstance*
+HLAObjectClass::createObjectInstance(RTIObjectInstance* rtiObjectInstance)
+{
+ return new HLAObjectInstance(this, rtiObjectInstance);
+}
+
+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();
+ }
+}
+
+void
+HLAObjectClass::removeInstance(HLAObjectInstance& hlaObjectInstance, const RTIData& tag)
+{
+ SG_LOG(SG_NETWORK, SG_INFO, "RTI: remove object instance \"" << hlaObjectInstance.getName() << "\"");
+ removeInstanceCallback(hlaObjectInstance, tag);
+ _objectInstanceSet.erase(&hlaObjectInstance);
+}
+
+void
+HLAObjectClass::registerInstance(HLAObjectInstance& objectInstance)
+{
+ _objectInstanceSet.insert(&objectInstance);
+ registerInstanceCallback(objectInstance);
+}
+
+void
+HLAObjectClass::deleteInstance(HLAObjectInstance& objectInstance)
+{
+ deleteInstanceCallback(objectInstance);
+ _objectInstanceSet.erase(&objectInstance);
+}
+
+void
+HLAObjectClass::discoverInstanceCallback(HLAObjectInstance& objectInstance, const RTIData& tag) const
+{
+ if (!_instanceCallback.valid())
+ return;
+ _instanceCallback->discoverInstance(*this, objectInstance, tag);
+}
+
+void
+HLAObjectClass::removeInstanceCallback(HLAObjectInstance& objectInstance, const RTIData& tag) const
+{
+ if (!_instanceCallback.valid())
+ return;
+ _instanceCallback->removeInstance(*this, objectInstance, tag);
+}
+
+void
+HLAObjectClass::registerInstanceCallback(HLAObjectInstance& objectInstance) const
+{
+ if (!_instanceCallback.valid())
+ return;
+ _instanceCallback->registerInstance(*this, objectInstance);
+}
+
+void
+HLAObjectClass::deleteInstanceCallback(HLAObjectInstance& objectInstance) const
+{
+ if (!_instanceCallback.valid())
+ return;
+ _instanceCallback->deleteInstance(*this, objectInstance);
+}
+
+void
+HLAObjectClass::startRegistrationCallback()
+{
+ if (_registrationCallback.valid())
+ _registrationCallback->startRegistration(*this);
+ else
+ startRegistration();
+}
+
+void
+HLAObjectClass::stopRegistrationCallback()
+{
+ if (_registrationCallback.valid())
+ _registrationCallback->stopRegistration(*this);
+ else
+ stopRegistration();
+}
+
+} // namespace simgear
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLAObjectClass_hxx
+#define HLAObjectClass_hxx
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "HLADataType.hxx"
+#include "HLAObjectInstance.hxx"
+
+namespace simgear {
+
+class RTIObjectClass;
+class HLAFederate;
+
+class HLAObjectClass : public SGWeakReferenced {
+public:
+ HLAObjectClass(const std::string& name, HLAFederate& federate);
+ virtual ~HLAObjectClass();
+
+ const std::string& getName() const
+ { return _name; }
+
+ unsigned getNumAttributes() const;
+ unsigned getAttributeIndex(const std::string& name) const;
+ std::string getAttributeName(unsigned index) const;
+
+ const HLADataType* getAttributeDataType(unsigned index) const;
+ void setAttributeDataType(unsigned index, const HLADataType*);
+
+ HLAUpdateType getAttributeUpdateType(unsigned index) const;
+ void setAttributeUpdateType(unsigned index, HLAUpdateType updateType);
+
+ HLADataElement::IndexPathPair getIndexPathPair(const HLADataElement::AttributePathPair&) const;
+ HLADataElement::IndexPathPair getIndexPathPair(const std::string& path) const;
+
+ bool subscribe(const std::set<unsigned>& indexSet, bool active);
+ bool unsubscribe();
+
+ bool publish(const std::set<unsigned>& indexSet);
+ bool unpublish();
+
+ // Object instance creation and destruction
+ class InstanceCallback : public SGReferenced {
+ public:
+ virtual ~InstanceCallback();
+
+ virtual void discoverInstance(const HLAObjectClass& objectClass, HLAObjectInstance& objectInstance, const RTIData& tag);
+ virtual void removeInstance(const HLAObjectClass& objectClass, HLAObjectInstance& objectInstance, const RTIData& tag);
+
+ virtual void registerInstance(const HLAObjectClass& objectClass, HLAObjectInstance& objectInstance);
+ virtual void deleteInstance(const HLAObjectClass& objectClass, HLAObjectInstance& objectInstance);
+ };
+
+ void setInstanceCallback(const SGSharedPtr<InstanceCallback>& instanceCallback)
+ { _instanceCallback = instanceCallback; }
+ const SGSharedPtr<InstanceCallback>& getInstanceCallback() const
+ { return _instanceCallback; }
+
+ // Handles startRegistrationForObjectClass and stopRegistrationForObjectClass events
+ class RegistrationCallback : public SGReferenced {
+ public:
+ virtual ~RegistrationCallback();
+ virtual void startRegistration(HLAObjectClass& objectClass) = 0;
+ virtual void stopRegistration(HLAObjectClass& objectClass) = 0;
+ };
+
+ void setRegistrationCallback(const SGSharedPtr<RegistrationCallback>& registrationCallback)
+ { _registrationCallback = registrationCallback; }
+ 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);
+
+private:
+ // 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();
+ friend class HLAObjectInstance;
+ friend class RTIObjectClass;
+
+ // The object class name
+ std::string _name;
+
+ // The underlying rti dispatcher class
+ SGSharedPtr<RTIObjectClass> _rtiObjectClass;
+
+ // Callback classes
+ SGSharedPtr<InstanceCallback> _instanceCallback;
+ SGSharedPtr<RegistrationCallback> _registrationCallback;
+
+ // The set of active objects
+ typedef std::set<SGSharedPtr<HLAObjectInstance> > ObjectInstanceSet;
+ ObjectInstanceSet _objectInstanceSet;
+};
+
+} // namespace simgear
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "HLAObjectInstance.hxx"
+
+#include <algorithm>
+#include "HLAArrayDataElement.hxx"
+#include "HLABasicDataElement.hxx"
+#include "HLADataElement.hxx"
+#include "HLAEnumeratedDataElement.hxx"
+#include "HLAFixedRecordDataElement.hxx"
+#include "HLAObjectClass.hxx"
+#include "HLAVariantDataElement.hxx"
+#include "RTIObjectClass.hxx"
+#include "RTIObjectInstance.hxx"
+
+namespace simgear {
+
+HLAObjectInstance::HLAObjectInstance(HLAObjectClass* objectClass) :
+ _objectClass(objectClass)
+{
+}
+
+HLAObjectInstance::HLAObjectInstance(HLAObjectClass* objectClass, RTIObjectInstance* rtiObjectInstance) :
+ _objectClass(objectClass),
+ _rtiObjectInstance(rtiObjectInstance)
+{
+ _rtiObjectInstance->_hlaObjectInstance = this;
+ _name = _rtiObjectInstance->getName();
+}
+
+HLAObjectInstance::~HLAObjectInstance()
+{
+}
+
+SGSharedPtr<HLAObjectClass>
+HLAObjectInstance::getObjectClass() const
+{
+ return _objectClass.lock();
+}
+
+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();
+}
+
+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);
+}
+
+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);
+}
+
+const HLADataType*
+HLAObjectInstance::getAttributeDataType(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);
+}
+
+void
+HLAObjectInstance::setAttributeDataElement(unsigned index, SGSharedPtr<HLADataElement> dataElement)
+{
+ if (!_rtiObjectInstance.valid()) {
+ SG_LOG(SG_IO, SG_ALERT, "Trying to set data element for inactive object!");
+ return;
+ }
+ _rtiObjectInstance->setDataElement(index, dataElement);
+}
+
+HLADataElement*
+HLAObjectInstance::getAttributeDataElement(unsigned index)
+{
+ if (!_rtiObjectInstance.valid()) {
+ SG_LOG(SG_IO, SG_ALERT, "Trying to set data element for inactive object!");
+ return 0;
+ }
+ return _rtiObjectInstance->getDataElement(index);
+}
+
+const HLADataElement*
+HLAObjectInstance::getAttributeDataElement(unsigned index) const
+{
+ if (!_rtiObjectInstance.valid()) {
+ SG_LOG(SG_IO, SG_ALERT, "Trying to set data element for inactive object!");
+ return 0;
+ }
+ return _rtiObjectInstance->getDataElement(index);
+}
+
+class HLAObjectInstance::DataElementFactoryVisitor : public HLADataTypeVisitor {
+public:
+ DataElementFactoryVisitor(const HLAPathElementMap& pathElementMap) :
+ _pathElementMap(pathElementMap)
+ { }
+ DataElementFactoryVisitor(const HLADataElement::Path& path, const HLAPathElementMap& pathElementMap) :
+ _pathElementMap(pathElementMap),
+ _path(path)
+ { }
+ virtual ~DataElementFactoryVisitor() {}
+
+ virtual void apply(const HLADataType& dataType)
+ {
+ _dataElement = createDataElement(_path, dataType);
+ if (_dataElement.valid())
+ return;
+
+ SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Can not find a suitable data element for data type \""
+ << dataType.getName() << "\"");
+ }
+
+ virtual void apply(const HLAInt8DataType& dataType)
+ {
+ _dataElement = createDataElement(_path, dataType);
+ if (_dataElement.valid())
+ return;
+
+ _dataElement = new HLASCharDataElement(&dataType);
+ }
+ virtual void apply(const HLAUInt8DataType& dataType)
+ {
+ _dataElement = createDataElement(_path, dataType);
+ if (_dataElement.valid())
+ return;
+
+ _dataElement = new HLAUCharDataElement(&dataType);
+ }
+ virtual void apply(const HLAInt16DataType& dataType)
+ {
+ _dataElement = createDataElement(_path, dataType);
+ if (_dataElement.valid())
+ return;
+
+ _dataElement = new HLAShortDataElement(&dataType);
+ }
+ virtual void apply(const HLAUInt16DataType& dataType)
+ {
+ _dataElement = createDataElement(_path, dataType);
+ if (_dataElement.valid())
+ return;
+
+ _dataElement = new HLAUShortDataElement(&dataType);
+ }
+ virtual void apply(const HLAInt32DataType& dataType)
+ {
+ _dataElement = createDataElement(_path, dataType);
+ if (_dataElement.valid())
+ return;
+
+ _dataElement = new HLAIntDataElement(&dataType);
+ }
+ virtual void apply(const HLAUInt32DataType& dataType)
+ {
+ _dataElement = createDataElement(_path, dataType);
+ if (_dataElement.valid())
+ return;
+
+ _dataElement = new HLAUIntDataElement(&dataType);
+ }
+ virtual void apply(const HLAInt64DataType& dataType)
+ {
+ _dataElement = createDataElement(_path, dataType);
+ if (_dataElement.valid())
+ return;
+
+ _dataElement = new HLALongDataElement(&dataType);
+ }
+ virtual void apply(const HLAUInt64DataType& dataType)
+ {
+ _dataElement = createDataElement(_path, dataType);
+ if (_dataElement.valid())
+ return;
+
+ _dataElement = new HLAULongDataElement(&dataType);
+ }
+ virtual void apply(const HLAFloat32DataType& dataType)
+ {
+ _dataElement = createDataElement(_path, dataType);
+ if (_dataElement.valid())
+ return;
+
+ _dataElement = new HLAFloatDataElement(&dataType);
+ }
+ virtual void apply(const HLAFloat64DataType& dataType)
+ {
+ _dataElement = createDataElement(_path, dataType);
+ if (_dataElement.valid())
+ return;
+
+ _dataElement = new HLADoubleDataElement(&dataType);
+ }
+
+ class ArrayDataElementFactory : public HLAArrayDataElement::DataElementFactory {
+ public:
+ ArrayDataElementFactory(const HLADataElement::Path& path, const HLAPathElementMap& pathElementMap) :
+ _path(path)
+ {
+ for (HLAPathElementMap::const_iterator i = pathElementMap.lower_bound(path);
+ i != pathElementMap.end(); ++i) {
+ if (i->first.begin() != std::search(i->first.begin(), i->first.end(),
+ path.begin(), path.end()))
+ break;
+ _pathElementMap.insert(*i);
+ }
+ }
+ virtual HLADataElement* createElement(const HLAArrayDataElement& element, unsigned index)
+ {
+ const HLADataType* dataType = element.getElementDataType();
+ if (!dataType)
+ return 0;
+ HLADataElement::Path path = _path;
+ path.push_back(HLADataElement::PathElement(index));
+ DataElementFactoryVisitor visitor(path, _pathElementMap);
+ dataType->accept(visitor);
+ return visitor._dataElement.release();
+ }
+ private:
+ HLADataElement::Path _path;
+ HLAPathElementMap _pathElementMap;
+ };
+
+ virtual void apply(const HLAFixedArrayDataType& dataType)
+ {
+ _dataElement = createDataElement(_path, dataType);
+ if (_dataElement.valid())
+ return;
+
+ SGSharedPtr<HLAArrayDataElement> arrayDataElement;
+ arrayDataElement = new HLAArrayDataElement(&dataType);
+ arrayDataElement->setDataElementFactory(new ArrayDataElementFactory(_path, _pathElementMap));
+ arrayDataElement->setNumElements(dataType.getNumElements());
+
+ _dataElement = arrayDataElement;
+ }
+
+ virtual void apply(const HLAVariableArrayDataType& dataType)
+ {
+ _dataElement = createDataElement(_path, dataType);
+ if (_dataElement.valid())
+ return;
+
+ SGSharedPtr<HLAArrayDataElement> arrayDataElement;
+ arrayDataElement = new HLAArrayDataElement(&dataType);
+ arrayDataElement->setDataElementFactory(new ArrayDataElementFactory(_path, _pathElementMap));
+
+ _dataElement = arrayDataElement;
+ }
+
+ virtual void apply(const HLAEnumeratedDataType& dataType)
+ {
+ _dataElement = createDataElement(_path, dataType);
+ if (_dataElement.valid())
+ return;
+
+ _dataElement = new HLAEnumeratedDataElement(&dataType);
+ }
+
+ virtual void apply(const HLAFixedRecordDataType& dataType)
+ {
+ _dataElement = createDataElement(_path, dataType);
+ if (_dataElement.valid())
+ return;
+
+ SGSharedPtr<HLAFixedRecordDataElement> recordDataElement;
+ recordDataElement = new HLAFixedRecordDataElement(&dataType);
+
+ unsigned numFields = dataType.getNumFields();
+ for (unsigned i = 0; i < numFields; ++i) {
+
+ _path.push_back(HLADataElement::PathElement(dataType.getFieldName(i)));
+
+ dataType.getFieldDataType(i)->accept(*this);
+ recordDataElement->setField(i, _dataElement.release());
+
+ _path.pop_back();
+ }
+ _dataElement = recordDataElement;
+ }
+
+ class VariantDataElementFactory : public HLAVariantDataElement::DataElementFactory {
+ public:
+ VariantDataElementFactory(const HLADataElement::Path& path, const HLAPathElementMap& pathElementMap) :
+ _path(path)
+ {
+ for (HLAPathElementMap::const_iterator i = pathElementMap.lower_bound(path);
+ i != pathElementMap.end(); ++i) {
+ if (i->first.begin() != std::search(i->first.begin(), i->first.end(),
+ path.begin(), path.end()))
+ break;
+ _pathElementMap.insert(*i);
+ }
+ }
+ virtual HLADataElement* createElement(const HLAVariantDataElement& element, unsigned index)
+ {
+ const HLAVariantDataType* dataType = element.getDataType();
+ if (!dataType)
+ return 0;
+ const HLADataType* alternativeDataType = element.getAlternativeDataType();
+ if (!alternativeDataType)
+ return 0;
+ HLADataElement::Path path = _path;
+ path.push_back(HLADataElement::PathElement(dataType->getAlternativeName(index)));
+ DataElementFactoryVisitor visitor(path, _pathElementMap);
+ alternativeDataType->accept(visitor);
+ return visitor._dataElement.release();
+ }
+ private:
+ HLADataElement::Path _path;
+ HLAPathElementMap _pathElementMap;
+ };
+
+ virtual void apply(const HLAVariantDataType& dataType)
+ {
+ _dataElement = createDataElement(_path, dataType);
+ if (_dataElement.valid())
+ return;
+
+ SGSharedPtr<HLAVariantDataElement> variantDataElement;
+ variantDataElement = new HLAVariantDataElement(&dataType);
+ variantDataElement->setDataElementFactory(new VariantDataElementFactory(_path, _pathElementMap));
+
+ _dataElement = variantDataElement;
+ }
+
+ const SGSharedPtr<HLADataElement>& getDataElement() const
+ { return _dataElement; }
+
+private:
+ SGSharedPtr<HLADataElement> createDataElement(const HLADataElement::Path& path, const HLADataType& dataType)
+ {
+ HLAPathElementMap::const_iterator i = _pathElementMap.find(path);
+ if (i == _pathElementMap.end()) {
+ SG_LOG(SG_IO, SG_WARN, "No dataElement provided for \""
+ << HLADataElement::toString(path) << "\".");
+
+ return 0;
+ }
+ SGSharedPtr<HLADataElement> dataElement = i->second.getDataElement(path);
+ if (!dataElement->setDataType(&dataType)) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot set data type for data element at \""
+ << HLADataElement::toString(path) << "\"!");
+ return 0;
+ }
+ SG_LOG(SG_IO, SG_DEBUG, "Using provided dataElement for \""
+ << HLADataElement::toString(path) << "\".");
+ return dataElement;
+ }
+
+ SGSharedPtr<HLADataElement> _dataElement;
+ const HLAPathElementMap& _pathElementMap;
+ HLADataElement::Path _path;
+};
+
+void
+HLAObjectInstance::setAttribute(unsigned index, const HLAPathElementMap& pathElementMap)
+{
+ const HLADataType* dataType = getAttributeDataType(index);
+ if (!dataType) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot get attribute data type for setting attribute at index "
+ << index << "!");
+ return;
+ }
+
+ SG_LOG(SG_IO, SG_DEBUG, "Setting DataElement for attribute \""
+ << getAttributeName(index) << "\".");
+
+ DataElementFactoryVisitor visitor(pathElementMap);
+ dataType->accept(visitor);
+ setAttributeDataElement(index, visitor.getDataElement());
+}
+
+void
+HLAObjectInstance::setAttributes(const HLAAttributePathElementMap& attributePathElementMap)
+{
+ for (HLAAttributePathElementMap::const_iterator i = attributePathElementMap.begin();
+ i != attributePathElementMap.end(); ++i) {
+ setAttribute(i->first, i->second);
+ }
+}
+
+void
+HLAObjectInstance::requestAttributeUpdate(unsigned index)
+{
+ if (!_rtiObjectInstance.valid()) {
+ SG_LOG(SG_IO, SG_ALERT, "Trying to request attribute update for inactive object!");
+ return;
+ }
+ _rtiObjectInstance->setRequestAttributeUpdate(index, true);
+}
+
+void
+HLAObjectInstance::requestAttributeUpdate()
+{
+ if (!_rtiObjectInstance.valid()) {
+ SG_LOG(SG_IO, SG_ALERT, "Trying to request attribute update for inactive object!");
+ return;
+ }
+ _rtiObjectInstance->setRequestAttributeUpdate(true);
+}
+
+void
+HLAObjectInstance::registerInstance()
+{
+ if (_rtiObjectInstance.valid()) {
+ 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()) {
+ 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())
+ return;
+ _rtiObjectInstance = 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);
+}
+
+void
+HLAObjectInstance::deleteInstance(const RTIData& tag)
+{
+ if (!_rtiObjectInstance.valid()) {
+ SG_LOG(SG_IO, SG_ALERT, "Trying to delete inactive object!");
+ return;
+ }
+ SGSharedPtr<HLAObjectClass> objectClass = _objectClass.lock();
+ if (!objectClass.valid())
+ return;
+ objectClass->deleteInstance(*this);
+ _rtiObjectInstance->deleteObjectInstance(tag);
+}
+
+void
+HLAObjectInstance::localDeleteInstance()
+{
+ if (!_rtiObjectInstance.valid()) {
+ SG_LOG(SG_IO, SG_ALERT, "Trying to delete inactive object!");
+ return;
+ }
+ _rtiObjectInstance->localDeleteObjectInstance();
+}
+
+void
+HLAObjectInstance::updateAttributeValues(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)
+{
+ 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::reflectQueuedAttributeValues(const SGTimeStamp& timeStamp)
+{
+ if (!_rtiObjectInstance.valid()) {
+ SG_LOG(SG_IO, SG_INFO, "Not updating inactive object!");
+ return;
+ }
+ _rtiObjectInstance->reflectQueuedAttributeValues(timeStamp);
+}
+
+void
+HLAObjectInstance::removeInstance(const RTIData& tag)
+{
+ SGSharedPtr<HLAObjectClass> objectClass = _objectClass.lock();
+ if (!objectClass.valid())
+ return;
+ objectClass->removeInstanceCallback(*this, tag);
+}
+
+void
+HLAObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const RTIData& tag)
+{
+ if (!_attributeCallback.valid())
+ return;
+ _attributeCallback->reflectAttributeValues(*this, dataPairList, tag);
+}
+
+void
+HLAObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList,
+ const SGTimeStamp& timeStamp, const RTIData& tag)
+{
+ if (!_attributeCallback.valid())
+ return;
+ _attributeCallback->reflectAttributeValues(*this, dataPairList, timeStamp, tag);
+}
+
+} // namespace simgear
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLAObjectInstance_hxx
+#define HLAObjectInstance_hxx
+
+#include <simgear/structure/SGWeakPtr.hxx>
+
+#include "HLADataElement.hxx"
+
+class SGTimeStamp;
+
+namespace simgear {
+
+class RTIObjectInstance;
+class HLAObjectClass;
+
+class HLAObjectInstance : public SGWeakReferenced {
+public:
+ HLAObjectInstance(HLAObjectClass* objectClass);
+ HLAObjectInstance(HLAObjectClass* objectClass, RTIObjectInstance* rtiObjectInstance);
+ virtual ~HLAObjectInstance();
+
+ const std::string& getName() const
+ { return _name; }
+
+ SGSharedPtr<HLAObjectClass> getObjectClass() const;
+
+ unsigned getNumAttributes() const;
+ unsigned getAttributeIndex(const std::string& name) const;
+ std::string getAttributeName(unsigned index) const;
+
+ const HLADataType* getAttributeDataType(unsigned index) const;
+
+ void setAttributeDataElement(unsigned index, SGSharedPtr<HLADataElement> dataElement);
+ HLADataElement* getAttributeDataElement(unsigned index);
+ const HLADataElement* getAttributeDataElement(unsigned index) const;
+ void setAttribute(unsigned index, const HLAPathElementMap& pathElementMap);
+ void setAttributes(const HLAAttributePathElementMap& attributePathElementMap);
+
+ // Ask the rti to provide the attribute at index
+ void requestAttributeUpdate(unsigned index);
+ void requestAttributeUpdate();
+
+ void registerInstance();
+ void deleteInstance(const RTIData& tag);
+ void localDeleteInstance();
+
+ 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)
+ { }
+ virtual void reflectAttributeValues(HLAObjectInstance& objectInstance, const RTIIndexDataPairList& dataPairList,
+ const SGTimeStamp& timeStamp, const RTIData& tag)
+ { reflectAttributeValues(objectInstance, dataPairList, tag); }
+ };
+
+ void setAttributeCallback(const SGSharedPtr<AttributeCallback>& attributeCallback)
+ { _attributeCallback = attributeCallback; }
+ 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);
+
+ // Retrieve queued up updates up to and including timestamp,
+ // Note that this only applies to timestamped updates.
+ // The unordered updates are reflected as they arrive
+ void reflectQueuedAttributeValues(const SGTimeStamp& timeStamp);
+
+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;
+
+ class DataElementFactoryVisitor;
+
+ std::string _name;
+
+ SGWeakPtr<HLAObjectClass> _objectClass;
+ SGSharedPtr<RTIObjectInstance> _rtiObjectInstance;
+ SGSharedPtr<AttributeCallback> _attributeCallback;
+};
+
+} // namespace simgear
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "HLAPropertyDataElement.hxx"
+
+#include "HLADataTypeVisitor.hxx"
+
+namespace simgear {
+
+class HLAPropertyDataElement::DecodeVisitor : public HLADataTypeDecodeVisitor {
+public:
+ DecodeVisitor(HLADecodeStream& stream, HLAPropertyReference& propertyReference) :
+ HLADataTypeDecodeVisitor(stream),
+ _propertyReference(propertyReference)
+ { }
+
+ virtual void apply(const HLAInt8DataType& dataType)
+ {
+ int8_t value = 0;
+ dataType.decode(_stream, value);
+ _propertyReference.setIntValue(value);
+ }
+ virtual void apply(const HLAUInt8DataType& dataType)
+ {
+ uint8_t value = 0;
+ dataType.decode(_stream, value);
+ _propertyReference.setIntValue(value);
+ }
+ virtual void apply(const HLAInt16DataType& dataType)
+ {
+ int16_t value = 0;
+ dataType.decode(_stream, value);
+ _propertyReference.setIntValue(value);
+ }
+ virtual void apply(const HLAUInt16DataType& dataType)
+ {
+ uint16_t value = 0;
+ dataType.decode(_stream, value);
+ _propertyReference.setIntValue(value);
+ }
+ virtual void apply(const HLAInt32DataType& dataType)
+ {
+ int32_t value = 0;
+ dataType.decode(_stream, value);
+ _propertyReference.setIntValue(value);
+ }
+ virtual void apply(const HLAUInt32DataType& dataType)
+ {
+ uint32_t value = 0;
+ dataType.decode(_stream, value);
+ _propertyReference.setIntValue(value);
+ }
+ virtual void apply(const HLAInt64DataType& dataType)
+ {
+ int64_t value = 0;
+ dataType.decode(_stream, value);
+ _propertyReference.setLongValue(value);
+ }
+ virtual void apply(const HLAUInt64DataType& dataType)
+ {
+ uint64_t value = 0;
+ dataType.decode(_stream, value);
+ _propertyReference.setLongValue(value);
+ }
+ virtual void apply(const HLAFloat32DataType& dataType)
+ {
+ float value = 0;
+ dataType.decode(_stream, value);
+ _propertyReference.setFloatValue(value);
+ }
+ virtual void apply(const HLAFloat64DataType& dataType)
+ {
+ double value = 0;
+ dataType.decode(_stream, value);
+ _propertyReference.setDoubleValue(value);
+ }
+
+ virtual void apply(const HLAFixedArrayDataType& dataType)
+ {
+ unsigned numElements = dataType.getNumElements();
+ std::string value;
+ value.reserve(numElements);
+ for (unsigned i = 0; i < numElements; ++i) {
+ HLATemplateDecodeVisitor<char> visitor(_stream);
+ dataType.getElementDataType()->accept(visitor);
+ value.push_back(visitor.getValue());
+ }
+ _propertyReference.setStringValue(value);
+ }
+ virtual void apply(const HLAVariableArrayDataType& dataType)
+ {
+ HLATemplateDecodeVisitor<unsigned> numElementsVisitor(_stream);
+ dataType.getSizeDataType()->accept(numElementsVisitor);
+ unsigned numElements = numElementsVisitor.getValue();
+ std::string value;
+ value.reserve(numElements);
+ for (unsigned i = 0; i < numElements; ++i) {
+ HLATemplateDecodeVisitor<char> visitor(_stream);
+ dataType.getElementDataType()->accept(visitor);
+ value.push_back(visitor.getValue());
+ }
+ _propertyReference.setStringValue(value);
+ }
+
+protected:
+ HLAPropertyReference& _propertyReference;
+};
+
+class HLAPropertyDataElement::EncodeVisitor : public HLADataTypeEncodeVisitor {
+public:
+ EncodeVisitor(HLAEncodeStream& stream, const HLAPropertyReference& propertyReference) :
+ HLADataTypeEncodeVisitor(stream),
+ _propertyReference(propertyReference)
+ { }
+
+ virtual void apply(const HLAInt8DataType& dataType)
+ {
+ dataType.encode(_stream, _propertyReference.getIntValue());
+ }
+ virtual void apply(const HLAUInt8DataType& dataType)
+ {
+ dataType.encode(_stream, _propertyReference.getIntValue());
+ }
+ virtual void apply(const HLAInt16DataType& dataType)
+ {
+ dataType.encode(_stream, _propertyReference.getIntValue());
+ }
+ virtual void apply(const HLAUInt16DataType& dataType)
+ {
+ dataType.encode(_stream, _propertyReference.getIntValue());
+ }
+ virtual void apply(const HLAInt32DataType& dataType)
+ {
+ dataType.encode(_stream, _propertyReference.getIntValue());
+ }
+ virtual void apply(const HLAUInt32DataType& dataType)
+ {
+ dataType.encode(_stream, _propertyReference.getIntValue());
+ }
+ virtual void apply(const HLAInt64DataType& dataType)
+ {
+ dataType.encode(_stream, _propertyReference.getLongValue());
+ }
+ virtual void apply(const HLAUInt64DataType& dataType)
+ {
+ dataType.encode(_stream, _propertyReference.getLongValue());
+ }
+ virtual void apply(const HLAFloat32DataType& dataType)
+ {
+ dataType.encode(_stream, _propertyReference.getFloatValue());
+ }
+ virtual void apply(const HLAFloat64DataType& dataType)
+ {
+ dataType.encode(_stream, _propertyReference.getDoubleValue());
+ }
+
+ virtual void apply(const HLAFixedArrayDataType& dataType)
+ {
+ unsigned numElements = dataType.getNumElements();
+ std::string value = _propertyReference.getStringValue();
+ for (unsigned i = 0; i < numElements; ++i) {
+ if (i < value.size()) {
+ HLATemplateEncodeVisitor<char> visitor(_stream, value[i]);
+ dataType.getElementDataType()->accept(visitor);
+ } else {
+ HLADataTypeEncodeVisitor visitor(_stream);
+ dataType.getElementDataType()->accept(visitor);
+ }
+ }
+ }
+
+ virtual void apply(const HLAVariableArrayDataType& dataType)
+ {
+ std::string value = _propertyReference.getStringValue();
+ HLATemplateEncodeVisitor<std::string::size_type> numElementsVisitor(_stream, value.size());
+ dataType.getSizeDataType()->accept(numElementsVisitor);
+ for (unsigned i = 0; i < value.size(); ++i) {
+ HLATemplateEncodeVisitor<char> visitor(_stream, value[i]);
+ dataType.getElementDataType()->accept(visitor);
+ }
+ }
+
+protected:
+ const HLAPropertyReference& _propertyReference;
+};
+
+HLAPropertyDataElement::HLAPropertyDataElement(HLAPropertyReference* propertyReference) :
+ _propertyReference(propertyReference)
+{
+}
+
+HLAPropertyDataElement::HLAPropertyDataElement(const simgear::HLADataType* dataType, HLAPropertyReference* propertyReference) :
+ _dataType(dataType),
+ _propertyReference(propertyReference)
+{
+}
+
+HLAPropertyDataElement::~HLAPropertyDataElement()
+{
+}
+
+bool
+HLAPropertyDataElement::encode(HLAEncodeStream& stream) const
+{
+ if (!_dataType.valid())
+ return false;
+ if (_propertyReference.valid()) {
+ EncodeVisitor visitor(stream, *_propertyReference);
+ _dataType->accept(visitor);
+ } else {
+ HLADataTypeEncodeVisitor visitor(stream);
+ _dataType->accept(visitor);
+ }
+ return true;
+}
+
+bool
+HLAPropertyDataElement::decode(HLADecodeStream& stream)
+{
+ if (!_dataType.valid())
+ return false;
+ if (_propertyReference.valid()) {
+ DecodeVisitor visitor(stream, *_propertyReference);
+ _dataType->accept(visitor);
+ } else {
+ HLADataTypeDecodeVisitor visitor(stream);
+ _dataType->accept(visitor);
+ }
+ return true;
+}
+
+const HLADataType*
+HLAPropertyDataElement::getDataType() const
+{
+ return _dataType.get();
+}
+
+bool
+HLAPropertyDataElement::setDataType(const HLADataType* dataType)
+{
+ if (dataType->toBasicDataType()) {
+ _dataType = dataType;
+ return true;
+ } else {
+ const HLAArrayDataType* arrayDataType = dataType->toArrayDataType();
+ if (arrayDataType && arrayDataType->getElementDataType() &&
+ arrayDataType->getElementDataType()->toBasicDataType()) {
+ _dataType = dataType;
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace simgear
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLAPropertyDataElement_hxx
+#define HLAPropertyDataElement_hxx
+
+#include <set>
+#include <simgear/props/props.hxx>
+#include "HLADataElement.hxx"
+
+namespace simgear {
+
+class HLAPropertyReference : public SGReferenced {
+public:
+ HLAPropertyReference()
+ { }
+ HLAPropertyReference(const std::string& relativePath) :
+ _relativePath(relativePath)
+ { }
+
+ void setIntValue(int value)
+ {
+ if (!_propertyNode.valid())
+ return;
+ _propertyNode->setIntValue(value);
+ }
+ int getIntValue() const
+ {
+ if (!_propertyNode.valid())
+ return 0;
+ return _propertyNode->getIntValue();
+ }
+
+ void setLongValue(long value)
+ {
+ if (!_propertyNode.valid())
+ return;
+ _propertyNode->setLongValue(value);
+ }
+ long getLongValue() const
+ {
+ if (!_propertyNode.valid())
+ return 0;
+ return _propertyNode->getLongValue();
+ }
+
+ void setFloatValue(float value)
+ {
+ if (!_propertyNode.valid())
+ return;
+ _propertyNode->setFloatValue(value);
+ }
+ float getFloatValue() const
+ {
+ if (!_propertyNode.valid())
+ return 0;
+ return _propertyNode->getFloatValue();
+ }
+
+ void setDoubleValue(double value)
+ {
+ if (!_propertyNode.valid())
+ return;
+ _propertyNode->setDoubleValue(value);
+ }
+ double getDoubleValue() const
+ {
+ if (!_propertyNode.valid())
+ return 0;
+ return _propertyNode->getDoubleValue();
+ }
+
+ void setStringValue(const std::string& value)
+ {
+ if (!_propertyNode.valid())
+ return;
+ _propertyNode->setStringValue(value);
+ }
+ std::string getStringValue() const
+ {
+ if (!_propertyNode.valid())
+ return std::string();
+ return _propertyNode->getStringValue();
+ }
+
+ SGPropertyNode* getPropertyNode()
+ { return _propertyNode.get(); }
+
+ void setRootNode(SGPropertyNode* rootNode)
+ {
+ if (!rootNode)
+ _propertyNode.clear();
+ else
+ _propertyNode = rootNode->getNode(_relativePath, true);
+ }
+
+private:
+ std::string _relativePath;
+ SGSharedPtr<SGPropertyNode> _propertyNode;
+};
+
+class HLAPropertyReferenceSet : public SGReferenced {
+public:
+ void insert(const SGSharedPtr<HLAPropertyReference>& propertyReference)
+ {
+ _propertyReferenceSet.insert(propertyReference);
+ propertyReference->setRootNode(_rootNode.get());
+ }
+ void remove(const SGSharedPtr<HLAPropertyReference>& propertyReference)
+ {
+ PropertyReferenceSet::iterator i = _propertyReferenceSet.find(propertyReference);
+ if (i == _propertyReferenceSet.end())
+ return;
+ _propertyReferenceSet.erase(i);
+ propertyReference->setRootNode(0);
+ }
+
+ void setRootNode(SGPropertyNode* rootNode)
+ {
+ _rootNode = rootNode;
+ for (PropertyReferenceSet::iterator i = _propertyReferenceSet.begin();
+ i != _propertyReferenceSet.end(); ++i) {
+ (*i)->setRootNode(_rootNode.get());
+ }
+ }
+ SGPropertyNode* getRootNode()
+ { return _rootNode.get(); }
+
+private:
+ SGSharedPtr<SGPropertyNode> _rootNode;
+
+ typedef std::set<SGSharedPtr<HLAPropertyReference> > PropertyReferenceSet;
+ PropertyReferenceSet _propertyReferenceSet;
+};
+
+class HLAPropertyDataElement : public HLADataElement {
+public:
+ HLAPropertyDataElement(HLAPropertyReference* propertyReference);
+ HLAPropertyDataElement(const simgear::HLADataType* dataType, HLAPropertyReference* propertyReference);
+ ~HLAPropertyDataElement();
+
+ virtual bool encode(HLAEncodeStream& stream) const;
+ virtual bool decode(HLADecodeStream& stream);
+
+ virtual const HLADataType* getDataType() const;
+ virtual bool setDataType(const HLADataType* dataType);
+
+private:
+ class DecodeVisitor;
+ class EncodeVisitor;
+
+ SGSharedPtr<const HLADataType> _dataType;
+ SGSharedPtr<HLAPropertyReference> _propertyReference;
+};
+
+} // namespace simgear
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "HLARawDataElement.hxx"
+
+namespace simgear {
+
+HLARawDataElement::HLARawDataElement(const HLADataType* dataType) :
+ _dataType(dataType)
+{
+}
+
+HLARawDataElement::~HLARawDataElement()
+{
+}
+
+bool
+HLARawDataElement::encode(HLAEncodeStream& stream) const
+{
+ stream.setData(_rtiData);
+ stream.skip(_rtiData.size());
+ return true;
+}
+
+bool
+HLARawDataElement::decode(HLADecodeStream& stream)
+{
+ _rtiData = stream.getData();
+ stream.skip(_rtiData.size());
+ return true;
+}
+
+const HLADataType*
+HLARawDataElement::getDataType() const
+{
+ return _dataType.get();
+}
+
+bool
+HLARawDataElement::setDataType(const HLADataType* dataType)
+{
+ _dataType = dataType;
+ return true;
+}
+
+}
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLARawDataElement_hxx
+#define HLARawDataElement_hxx
+
+#include "RTIData.hxx"
+#include "HLADataElement.hxx"
+#include "HLADataType.hxx"
+
+namespace simgear {
+
+class HLARawDataElement : public HLADataElement {
+public:
+ HLARawDataElement(const HLADataType* dataType);
+ virtual ~HLARawDataElement();
+
+ virtual bool encode(HLAEncodeStream& stream) const;
+ virtual bool decode(HLADecodeStream& stream);
+
+ virtual const HLADataType* getDataType() const;
+ virtual bool setDataType(const HLADataType* dataType);
+
+ const RTIData& getData() const
+ { return _rtiData; }
+ RTIData& getData()
+ { return _rtiData; }
+ void setData(const RTIData& rtiData)
+ { _rtiData = rtiData; }
+
+protected:
+ SGSharedPtr<const HLADataType> _dataType;
+ RTIData _rtiData;
+};
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "HLAVariantDataElement.hxx"
+
+#include <simgear/debug/logstream.hxx>
+
+namespace simgear {
+
+HLAAbstractVariantDataElement::HLAAbstractVariantDataElement(const HLAVariantDataType* dataType) :
+ _dataType(dataType)
+{
+}
+
+HLAAbstractVariantDataElement::~HLAAbstractVariantDataElement()
+{
+}
+
+bool
+HLAAbstractVariantDataElement::decode(HLADecodeStream& stream)
+{
+ if (!_dataType.valid())
+ return false;
+ return _dataType->decode(stream, *this);
+}
+
+bool
+HLAAbstractVariantDataElement::encode(HLAEncodeStream& stream) const
+{
+ if (!_dataType.valid())
+ return false;
+ return _dataType->encode(stream, *this);
+}
+
+const HLAVariantDataType*
+HLAAbstractVariantDataElement::getDataType() const
+{
+ return _dataType.get();
+}
+
+bool
+HLAAbstractVariantDataElement::setDataType(const HLADataType* dataType)
+{
+ const HLAVariantDataType* variantDataType = dataType->toVariantDataType();
+ if (!variantDataType) {
+ SG_LOG(SG_NETWORK, SG_WARN, "HLAVariantDataType: unable to set data type!");
+ return false;
+ }
+ setDataType(variantDataType);
+ return true;
+}
+
+void
+HLAAbstractVariantDataElement::setDataType(const HLAVariantDataType* dataType)
+{
+ _dataType = dataType;
+}
+
+std::string
+HLAAbstractVariantDataElement::getAlternativeName() const
+{
+ if (!_dataType.valid())
+ return std::string();
+ return _dataType->getAlternativeName(getAlternativeIndex());
+}
+
+const HLADataType*
+HLAAbstractVariantDataElement::getAlternativeDataType() const
+{
+ if (!_dataType.valid())
+ return 0;
+ return _dataType->getAlternativeDataType(getAlternativeIndex());
+}
+
+
+HLAVariantDataElement::DataElementFactory::~DataElementFactory()
+{
+}
+
+HLAVariantDataElement::HLAVariantDataElement(const HLAVariantDataType* dataType) :
+ HLAAbstractVariantDataElement(dataType),
+ _alternativeIndex(~0u)
+{
+}
+
+HLAVariantDataElement::~HLAVariantDataElement()
+{
+}
+
+bool
+HLAVariantDataElement::setAlternativeIndex(unsigned index)
+{
+ if (_alternativeIndex == index)
+ return true;
+ SGSharedPtr<HLADataElement> dataElement = newElement(index);
+ if (!dataElement.valid())
+ return false;
+ _dataElement.swap(dataElement);
+ _alternativeIndex = index;
+ return true;
+}
+
+bool
+HLAVariantDataElement::decodeAlternative(HLADecodeStream& stream)
+{
+ return _dataElement->decode(stream);
+}
+
+unsigned
+HLAVariantDataElement::getAlternativeIndex() const
+{
+ return _alternativeIndex;
+}
+
+bool
+HLAVariantDataElement::encodeAlternative(HLAEncodeStream& stream) const
+{
+ return _dataElement->encode(stream);
+}
+
+void
+HLAVariantDataElement::setDataElementFactory(HLAVariantDataElement::DataElementFactory* dataElementFactory)
+{
+ _dataElementFactory = dataElementFactory;
+}
+
+HLAVariantDataElement::DataElementFactory*
+HLAVariantDataElement::getDataElementFactory()
+{
+ return _dataElementFactory;
+}
+
+HLADataElement*
+HLAVariantDataElement::newElement(unsigned index)
+{
+ if (!_dataElementFactory.valid())
+ return 0;
+ return _dataElementFactory->createElement(*this, index);
+}
+
+}
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLAVariantDataElement_hxx
+#define HLAVariantDataElement_hxx
+
+#include <string>
+#include <simgear/structure/SGSharedPtr.hxx>
+#include "HLADataElement.hxx"
+#include "HLAVariantDataType.hxx"
+
+namespace simgear {
+
+class HLAAbstractVariantDataElement : public HLADataElement {
+public:
+ HLAAbstractVariantDataElement(const HLAVariantDataType* dataType);
+ virtual ~HLAAbstractVariantDataElement();
+
+ virtual bool decode(HLADecodeStream& stream);
+ virtual bool encode(HLAEncodeStream& stream) const;
+
+ virtual const HLAVariantDataType* getDataType() const;
+ virtual bool setDataType(const HLADataType* dataType);
+ void setDataType(const HLAVariantDataType* dataType);
+
+ std::string getAlternativeName() const;
+ const HLADataType* getAlternativeDataType() const;
+
+ virtual bool setAlternativeIndex(unsigned index) = 0;
+ virtual bool decodeAlternative(HLADecodeStream& stream) = 0;
+ virtual unsigned getAlternativeIndex() const = 0;
+ virtual bool encodeAlternative(HLAEncodeStream& stream) const = 0;
+
+private:
+ SGSharedPtr<const HLAVariantDataType> _dataType;
+};
+
+class HLAVariantDataElement : public HLAAbstractVariantDataElement {
+public:
+ HLAVariantDataElement(const HLAVariantDataType* dataType);
+ virtual ~HLAVariantDataElement();
+
+ virtual bool setAlternativeIndex(unsigned index);
+ virtual bool decodeAlternative(HLADecodeStream& stream);
+ virtual unsigned getAlternativeIndex() const;
+ virtual bool encodeAlternative(HLAEncodeStream& stream) const;
+
+ class DataElementFactory : public SGReferenced {
+ public:
+ virtual ~DataElementFactory();
+ virtual HLADataElement* createElement(const HLAVariantDataElement&, unsigned) = 0;
+ };
+
+ void setDataElementFactory(DataElementFactory* dataElementFactory);
+ DataElementFactory* getDataElementFactory();
+
+private:
+ HLADataElement* newElement(unsigned index);
+
+ SGSharedPtr<HLADataElement> _dataElement;
+ unsigned _alternativeIndex;
+
+ SGSharedPtr<DataElementFactory> _dataElementFactory;
+};
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "HLAVariantDataType.hxx"
+
+#include "HLADataTypeVisitor.hxx"
+#include "HLAVariantDataElement.hxx"
+
+namespace simgear {
+
+HLAVariantDataType::HLAVariantDataType(const std::string& name) :
+ HLADataType(name)
+{
+}
+
+HLAVariantDataType::~HLAVariantDataType()
+{
+}
+
+void
+HLAVariantDataType::accept(HLADataTypeVisitor& visitor) const
+{
+ visitor.apply(*this);
+}
+
+const HLAVariantDataType*
+HLAVariantDataType::toVariantDataType() const
+{
+ return this;
+}
+
+bool
+HLAVariantDataType::decode(HLADecodeStream& stream, HLAAbstractVariantDataElement& value) const
+{
+ if (!stream.alignOffsetForSize(getAlignment()))
+ return false;
+ if (!_enumeratedDataType.valid())
+ return false;
+ unsigned index = ~0u;
+ if (!_enumeratedDataType->decode(stream, index))
+ return false;
+ if (!value.setAlternativeIndex(index))
+ return false;
+ if (!value.decodeAlternative(stream))
+ return false;
+ return true;
+}
+
+bool
+HLAVariantDataType::encode(HLAEncodeStream& stream, const HLAAbstractVariantDataElement& value) const
+{
+ if (!stream.alignOffsetForSize(getAlignment()))
+ return false;
+ if (!_enumeratedDataType.valid())
+ return false;
+ unsigned index = value.getAlternativeIndex();
+ if (!_enumeratedDataType->encode(stream, index))
+ return false;
+ if (!value.encodeAlternative(stream))
+ return false;
+ return true;
+}
+
+void
+HLAVariantDataType::setEnumeratedDataType(HLAEnumeratedDataType* dataType)
+{
+ _enumeratedDataType = dataType;
+}
+
+bool
+HLAVariantDataType::addAlternative(const std::string& name, const std::string& enumerator,
+ const HLADataType* dataType, const std::string& semantics)
+{
+ if (!_enumeratedDataType.valid())
+ return false;
+ unsigned index = _enumeratedDataType->getIndex(enumerator);
+ if (_enumeratedDataType->getNumEnumerators() <= index)
+ return false;
+ _alternativeList.resize(_enumeratedDataType->getNumEnumerators());
+ _alternativeList[index]._name = name;
+ _alternativeList[index]._dataType = dataType;
+ _alternativeList[index]._semantics = semantics;
+ setAlignment(SGMisc<unsigned>::max(getAlignment(), dataType->getAlignment()));
+ return true;
+}
+
+} // namespace simgear
--- /dev/null
+// Copyright (C) 2009 - 2010 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 HLAVariantDataType_hxx
+#define HLAVariantDataType_hxx
+
+#include <string>
+#include <vector>
+#include "simgear/structure/SGSharedPtr.hxx"
+#include "HLADataType.hxx"
+#include "HLAEnumeratedDataType.hxx"
+
+namespace simgear {
+
+class HLAAbstractVariantDataElement;
+
+class HLAVariantDataType : public HLADataType {
+public:
+ HLAVariantDataType(const std::string& name = "HLAVariantDataType");
+ virtual ~HLAVariantDataType();
+
+ virtual void accept(HLADataTypeVisitor& visitor) const;
+
+ virtual const HLAVariantDataType* toVariantDataType() const;
+
+ virtual bool decode(HLADecodeStream& stream, HLAAbstractVariantDataElement& value) const;
+ virtual bool encode(HLAEncodeStream& stream, const HLAAbstractVariantDataElement& value) const;
+
+ const HLAEnumeratedDataType* getEnumeratedDataType() const
+ { return _enumeratedDataType.get(); }
+ void setEnumeratedDataType(HLAEnumeratedDataType* dataType);
+
+ bool addAlternative(const std::string& name, const std::string& enumerator,
+ const HLADataType* dataType, const std::string& semantics);
+
+ unsigned getNumAlternatives() const
+ { return _alternativeList.size(); }
+
+ unsigned getAlternativeIndex(const std::string& enumerator) const
+ {
+ if (!_enumeratedDataType.valid())
+ return ~unsigned(0);
+ return _enumeratedDataType->getIndex(enumerator);
+ }
+
+ const HLADataType* getAlternativeDataType(unsigned index) const
+ {
+ if (_alternativeList.size() <= index)
+ return 0;
+ return _alternativeList[index]._dataType.get();
+ }
+ const HLADataType* getAlternativeDataType(const std::string& enumerator) const
+ { return getAlternativeDataType(getAlternativeIndex(enumerator)); }
+
+ std::string getAlternativeName(unsigned index) const
+ {
+ if (_alternativeList.size() <= index)
+ return std::string();
+ return _alternativeList[index]._name;
+ }
+ std::string getAlternativeName(const std::string& enumerator) const
+ { return getAlternativeName(getAlternativeIndex(enumerator)); }
+
+ std::string getAlternativeSemantics(unsigned index) const
+ {
+ if (_alternativeList.size() <= index)
+ return std::string();
+ return _alternativeList[index]._semantics;
+ }
+ std::string getAlternativeSemantics(const std::string& enumerator) const
+ { return getAlternativeSemantics(getAlternativeIndex(enumerator)); }
+
+private:
+ SGSharedPtr<HLAEnumeratedDataType> _enumeratedDataType;
+
+ struct Alternative {
+ std::string _name;
+ SGSharedPtr<const HLADataType> _dataType;
+ std::string _semantics;
+ };
+
+ typedef std::vector<Alternative> AlternativeList;
+ AlternativeList _alternativeList;
+};
+
+} // namespace simgear
+
+#endif
-includedir = @includedir@/hla
-
INCLUDES = -I$(top_srcdir)
+
+lib_LIBRARIES = libsghla.a
+
+libsghla_adir = @includedir@/hla
+
+libsghla_a_HEADERS = \
+ RTIData.hxx \
+ HLAArrayDataElement.hxx \
+ HLAArrayDataType.hxx \
+ HLABasicDataElement.hxx \
+ HLABasicDataType.hxx \
+ HLADataElement.hxx \
+ HLADataType.hxx \
+ HLADataTypeVisitor.hxx \
+ HLAEnumeratedDataElement.hxx \
+ HLAEnumeratedDataType.hxx \
+ HLAFixedRecordDataElement.hxx \
+ HLAFixedRecordDataType.hxx \
+ HLAFederate.hxx \
+ HLAInteractionClass.hxx \
+ HLALocation.hxx \
+ HLAObjectClass.hxx \
+ HLAObjectInstance.hxx \
+ HLAOMTXmlVisitor.hxx \
+ HLAPropertyDataElement.hxx \
+ HLARawDataElement.hxx \
+ HLAVariantDataElement.hxx \
+ HLAVariantDataType.hxx
+
+libsghla_a_SOURCES = \
+ RTIObjectClass.cxx \
+ RTIObjectInstance.cxx \
+ RTIFederate.cxx \
+ HLAArrayDataElement.cxx \
+ HLAArrayDataType.cxx \
+ HLABasicDataElement.cxx \
+ HLABasicDataType.cxx \
+ HLADataElement.cxx \
+ HLADataType.cxx \
+ HLAEnumeratedDataElement.cxx \
+ HLAEnumeratedDataType.cxx \
+ HLAFederate.cxx \
+ HLAFixedRecordDataElement.cxx \
+ HLAFixedRecordDataType.cxx \
+ HLAObjectClass.cxx \
+ HLAObjectInstance.cxx \
+ HLAOMTXmlVisitor.cxx \
+ HLAPropertyDataElement.cxx \
+ HLARawDataElement.cxx \
+ HLAVariantDataElement.cxx \
+ HLAVariantDataType.cxx
+
+if ENABLE_HLA13
+
+lib_LIBRARIES += libsghla13.a
+
+libsghla13_adir = @includedir@/hla
+
+libsghla13_a_HEADERS = \
+ HLA13Federate.hxx
+
+libsghla13_a_SOURCES = \
+ RTI13ObjectClass.cxx \
+ RTI13ObjectInstance.cxx \
+ RTI13Federate.cxx \
+ HLA13Federate.cxx
+
+endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 RTIAmbassador_hxx
+#define RTIAmbassador_hxx
+
+#include <cstdlib>
+#include <list>
+#include <memory>
+#include <vector>
+#include <map>
+#include <set>
+
+#ifndef RTI_USES_STD_FSTREAM
+#define RTI_USES_STD_FSTREAM
+#endif
+
+#include <RTI.hh>
+#include <fedtime.hh>
+
+#include <simgear/debug/logstream.hxx>
+#include <simgear/structure/SGWeakReferenced.hxx>
+#include <simgear/structure/SGSharedPtr.hxx>
+#include <simgear/structure/SGWeakPtr.hxx>
+#include <simgear/timing/timestamp.hxx>
+
+#include "RTIObjectClass.hxx"
+#include "RTIData.hxx"
+#include "RTI13Federate.hxx"
+#include "RTI13ObjectInstance.hxx"
+
+namespace simgear {
+
+class RTI13Ambassador : public SGWeakReferenced {
+public:
+ RTI13Ambassador() :
+ _federateAmbassador(*this),
+ _timeRegulationEnabled(false),
+ _timeConstrainedEnabled(false),
+ _timeAdvancePending(false)
+ { }
+ virtual ~RTI13Ambassador()
+ { }
+
+ // processes the queues that filled up during the past
+ void processQueues()
+ {
+ while (!_queueCallbackList.empty()) {
+ (*_queueCallbackList.front())();
+ _queueCallbackList.pop_front();
+ }
+
+ while (!_objectInstancePendingCallbackList.empty()) {
+ (*_objectInstancePendingCallbackList.begin())->flushPendingRequests();
+ _objectInstancePendingCallbackList.erase(_objectInstancePendingCallbackList.begin());
+ }
+ }
+
+ bool getTimeRegulationEnabled() const
+ { return _timeRegulationEnabled; }
+ bool getTimeConstrainedEnabled() const
+ { return _timeConstrainedEnabled; }
+ bool getTimeAdvancePending() const
+ { return _timeAdvancePending; }
+ const SGTimeStamp& getCurrentLogicalTime() const
+ { return _federateTime; }
+
+ bool getFederationSynchronizationPointAnnounced(const std::string& label)
+ { return _pendingSyncLabels.find(label) != _pendingSyncLabels.end(); }
+ bool getFederationSynchronized(const std::string& label)
+ {
+ std::set<std::string>::iterator i = _syncronizedSyncLabels.find(label);
+ if (i == _syncronizedSyncLabels.end())
+ return false;
+ _syncronizedSyncLabels.erase(i);
+ return true;
+ }
+
+ void createFederationExecution(const std::string& name, const std::string& objectModel)
+ { _rtiAmbassador.createFederationExecution(name.c_str(), objectModel.c_str()); }
+ void destroyFederationExecution(const std::string& name)
+ { _rtiAmbassador.destroyFederationExecution(name.c_str()); }
+
+ RTI::FederateHandle joinFederationExecution(const std::string& federate, const std::string& federation)
+ { return _rtiAmbassador.joinFederationExecution(federate.c_str(), federation.c_str(), &_federateAmbassador); }
+ void resignFederationExecution()
+ { _rtiAmbassador.resignFederationExecution(RTI::DELETE_OBJECTS_AND_RELEASE_ATTRIBUTES); }
+
+ void registerFederationSynchronizationPoint(const std::string& label, const RTIData& tag)
+ { _rtiAmbassador.registerFederationSynchronizationPoint(label.c_str(), tag.data()); }
+ void synchronizationPointAchieved(const std::string& label)
+ { _rtiAmbassador.synchronizationPointAchieved(label.c_str()); }
+
+ void publishObjectClass(const RTI::ObjectClassHandle& handle, const RTI::AttributeHandleSet& attributeHandleSet)
+ { _rtiAmbassador.publishObjectClass(handle, attributeHandleSet); }
+ void unpublishObjectClass(const RTI::ObjectClassHandle& handle)
+ { _rtiAmbassador.unpublishObjectClass(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); }
+
+ RTI13ObjectInstance* registerObjectInstance(const RTI13ObjectClass* objectClass, HLAObjectInstance* hlaObjectInstance)
+ {
+ RTI::ObjectHandle objectHandle = _rtiAmbassador.registerObjectInstance(objectClass->getHandle());
+ RTI13ObjectInstance* objectInstance = new RTI13ObjectInstance(objectHandle, hlaObjectInstance, objectClass, this, true);
+ _objectInstanceMap[objectHandle] = objectInstance;
+ return objectInstance;
+ }
+ void updateAttributeValues(const RTI::ObjectHandle& objectHandle, const RTI::AttributeHandleValuePairSet& attributeValues,
+ const SGTimeStamp& timeStamp, const RTIData& tag)
+ { _rtiAmbassador.updateAttributeValues(objectHandle, attributeValues, toFedTime(timeStamp), tag.data()); }
+ void updateAttributeValues(const RTI::ObjectHandle& objectHandle, const RTI::AttributeHandleValuePairSet& attributeValues, const RTIData& tag)
+ { _rtiAmbassador.updateAttributeValues(objectHandle, attributeValues, tag.data()); }
+
+ // RTI::EventRetractionHandle sendInteraction(RTI::InteractionClassHandle interactionClassHandle, const RTI::ParameterHandleValuePairSet& parameters, const RTI::FedTime& fedTime, const RTIData& tag)
+ // { return _rtiAmbassador.sendInteraction(interactionClassHandle, parameters, fedTime, tag.data()); }
+ // void sendInteraction(RTI::InteractionClassHandle interactionClassHandle, const RTI::ParameterHandleValuePairSet& parameters, const RTIData& tag)
+ // { _rtiAmbassador.sendInteraction(interactionClassHandle, parameters, tag.data()); }
+
+ void deleteObjectInstance(const RTI::ObjectHandle& objectHandle, const SGTimeStamp& timeStamp, const RTIData& tag)
+ {
+ RTI::EventRetractionHandle h = _rtiAmbassador.deleteObjectInstance(objectHandle, toFedTime(timeStamp), tag.data());
+ ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle);
+ if (i == _objectInstanceMap.end()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: ObjectInstance not found.");
+ return;
+ }
+ _objectInstancePendingCallbackList.erase(i->second);
+ _objectInstanceMap.erase(i);
+ }
+ void deleteObjectInstance(const RTI::ObjectHandle& objectHandle, const RTIData& tag)
+ {
+ _rtiAmbassador.deleteObjectInstance(objectHandle, tag.data());
+ ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle);
+ if (i == _objectInstanceMap.end()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: ObjectInstance not found.");
+ return;
+ }
+ _objectInstancePendingCallbackList.erase(i->second);
+ _objectInstanceMap.erase(i);
+ }
+ void localDeleteObjectInstance(const RTI::ObjectHandle& objectHandle)
+ {
+ _rtiAmbassador.localDeleteObjectInstance(objectHandle);
+ ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle);
+ if (i == _objectInstanceMap.end()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: ObjectInstance not found.");
+ return;
+ }
+ _objectInstancePendingCallbackList.erase(i->second);
+ _objectInstanceMap.erase(i);
+ }
+
+ void requestObjectAttributeValueUpdate(const RTI::ObjectHandle& handle, const RTI::AttributeHandleSet& attributeHandleSet)
+ { _rtiAmbassador.requestObjectAttributeValueUpdate(handle, attributeHandleSet); }
+ void requestClassAttributeValueUpdate(const RTI::ObjectClassHandle& handle, const RTI::AttributeHandleSet& attributeHandleSet)
+ { _rtiAmbassador.requestClassAttributeValueUpdate(handle, attributeHandleSet); }
+
+ // Ownership Management -------------------
+
+ // bool unconditionalAttributeOwnershipDivestiture(const RTIHandle& objectHandle, const RTIHandleSet& attributeHandles)
+ // {
+ // try {
+ // std::auto_ptr<RTI::AttributeHandleSet> attributeHandleSet(RTI::AttributeHandleSetFactory::create(attributeHandles.size()));
+ // for (RTIHandleSet::const_iterator i = attributeHandles.begin(); i != attributeHandles.end(); ++i)
+ // attributeHandleSet->add(*i);
+ // _rtiAmbassador.unconditionalAttributeOwnershipDivestiture(objectHandle, *attributeHandleSet);
+ // return true;
+ // } catch (RTI::ObjectNotKnown& e) {
+ // } catch (RTI::AttributeNotDefined& e) {
+ // } catch (RTI::AttributeNotOwned& e) {
+ // } catch (RTI::FederateNotExecutionMember& e) {
+ // } catch (RTI::ConcurrentAccessAttempted& e) {
+ // } catch (RTI::SaveInProgress& e) {
+ // } catch (RTI::RestoreInProgress& e) {
+ // } catch (RTI::RTIinternalError& e) {
+ // }
+ // return false;
+ // }
+ // bool negotiatedAttributeOwnershipDivestiture(const RTIHandle& objectHandle, const RTIHandleSet& attributeHandles, const RTIData& tag)
+ // {
+ // try {
+ // std::auto_ptr<RTI::AttributeHandleSet> attributeHandleSet(RTI::AttributeHandleSetFactory::create(attributeHandles.size()));
+ // for (RTIHandleSet::const_iterator i = attributeHandles.begin(); i != attributeHandles.end(); ++i)
+ // attributeHandleSet->add(*i);
+ // _rtiAmbassador.negotiatedAttributeOwnershipDivestiture(objectHandle, *attributeHandleSet, tag.data());
+ // return true;
+ // } catch (RTI::ObjectNotKnown& e) {
+ // } catch (RTI::AttributeNotDefined& e) {
+ // } catch (RTI::AttributeNotOwned& e) {
+ // } catch (RTI::AttributeAlreadyBeingDivested& e) {
+ // } catch (RTI::FederateNotExecutionMember& e) {
+ // } catch (RTI::ConcurrentAccessAttempted& e) {
+ // } catch (RTI::SaveInProgress& e) {
+ // } catch (RTI::RestoreInProgress& e) {
+ // } catch (RTI::RTIinternalError& e) {
+ // }
+ // return false;
+ // }
+ // bool attributeOwnershipAcquisition(const RTIHandle& objectHandle, const RTIHandleSet& attributeHandles, const RTIData& tag)
+ // {
+ // try {
+ // std::auto_ptr<RTI::AttributeHandleSet> attributeHandleSet(RTI::AttributeHandleSetFactory::create(attributeHandles.size()));
+ // for (RTIHandleSet::const_iterator i = attributeHandles.begin(); i != attributeHandles.end(); ++i)
+ // attributeHandleSet->add(*i);
+ // _rtiAmbassador.attributeOwnershipAcquisition(objectHandle, *attributeHandleSet, tag.data());
+ // return true;
+ // } catch (RTI::ObjectNotKnown& e) {
+ // } catch (RTI::ObjectClassNotPublished& e) {
+ // } catch (RTI::AttributeNotDefined& e) {
+ // } catch (RTI::AttributeNotPublished& e) {
+ // } catch (RTI::FederateOwnsAttributes& e) {
+ // } catch (RTI::FederateNotExecutionMember& e) {
+ // } catch (RTI::ConcurrentAccessAttempted& e) {
+ // } catch (RTI::SaveInProgress& e) {
+ // } catch (RTI::RestoreInProgress& e) {
+ // } catch (RTI::RTIinternalError& e) {
+ // }
+ // return false;
+ // }
+ // bool attributeOwnershipAcquisitionIfAvailable(const RTIHandle& objectHandle, const RTIHandleSet& attributeHandles)
+ // {
+ // try {
+ // std::auto_ptr<RTI::AttributeHandleSet> attributeHandleSet(RTI::AttributeHandleSetFactory::create(attributeHandles.size()));
+ // for (RTIHandleSet::const_iterator i = attributeHandles.begin(); i != attributeHandles.end(); ++i)
+ // attributeHandleSet->add(*i);
+ // _rtiAmbassador.attributeOwnershipAcquisitionIfAvailable(objectHandle, *attributeHandleSet);
+ // return true;
+ // } catch (RTI::ObjectNotKnown& e) {
+ // } catch (RTI::ObjectClassNotPublished& e) {
+ // } catch (RTI::AttributeNotDefined& e) {
+ // } catch (RTI::AttributeNotPublished& e) {
+ // } catch (RTI::FederateOwnsAttributes& e) {
+ // } catch (RTI::AttributeAlreadyBeingAcquired& e) {
+ // } catch (RTI::FederateNotExecutionMember& e) {
+ // } catch (RTI::ConcurrentAccessAttempted& e) {
+ // } catch (RTI::SaveInProgress& e) {
+ // } catch (RTI::RestoreInProgress& e) {
+ // } catch (RTI::RTIinternalError& e) {
+ // }
+ // return false;
+ // }
+ // RTIHandleSet attributeOwnershipReleaseResponse(const RTIHandle& objectHandle, const RTIHandleSet& attributeHandles)
+ // {
+ // try {
+ // std::auto_ptr<RTI::AttributeHandleSet> attributeHandleSet(RTI::AttributeHandleSetFactory::create(attributeHandles.size()));
+ // for (RTIHandleSet::const_iterator i = attributeHandles.begin(); i != attributeHandles.end(); ++i)
+ // attributeHandleSet->add(*i);
+ // attributeHandleSet.reset(_rtiAmbassador.attributeOwnershipReleaseResponse(objectHandle, *attributeHandleSet));
+ // RTIHandleSet handleSet;
+ // RTI::ULong numAttribs = attributeHandleSet->size();
+ // for (RTI::ULong i = 0; i < numAttribs; ++i)
+ // handleSet.insert(attributeHandleSet->getHandle(i));
+ // return handleSet;
+ // } catch (RTI::ObjectNotKnown& e) {
+ // } catch (RTI::AttributeNotDefined& e) {
+ // } catch (RTI::AttributeNotOwned& e) {
+ // } catch (RTI::FederateWasNotAskedToReleaseAttribute& e) {
+ // } catch (RTI::FederateNotExecutionMember& e) {
+ // } catch (RTI::ConcurrentAccessAttempted& e) {
+ // } catch (RTI::SaveInProgress& e) {
+ // } catch (RTI::RestoreInProgress& e) {
+ // } catch (RTI::RTIinternalError& e) {
+ // }
+ // return RTIHandleSet();
+ // }
+ // bool cancelNegotiatedAttributeOwnershipDivestiture(const RTIHandle& objectHandle, const RTIHandleSet& attributeHandles)
+ // {
+ // try {
+ // std::auto_ptr<RTI::AttributeHandleSet> attributeHandleSet(RTI::AttributeHandleSetFactory::create(attributeHandles.size()));
+ // for (RTIHandleSet::const_iterator i = attributeHandles.begin(); i != attributeHandles.end(); ++i)
+ // attributeHandleSet->add(*i);
+ // _rtiAmbassador.cancelNegotiatedAttributeOwnershipDivestiture(objectHandle, *attributeHandleSet);
+ // return true;
+ // } catch (RTI::ObjectNotKnown& e) {
+ // } catch (RTI::AttributeNotDefined& e) {
+ // } catch (RTI::AttributeNotOwned& e) {
+ // } catch (RTI::AttributeDivestitureWasNotRequested& e) {
+ // } catch (RTI::FederateNotExecutionMember& e) {
+ // } catch (RTI::ConcurrentAccessAttempted& e) {
+ // } catch (RTI::SaveInProgress& e) {
+ // } catch (RTI::RestoreInProgress& e) {
+ // } catch (RTI::RTIinternalError& e) {
+ // }
+ // return false;
+ // }
+ // bool cancelAttributeOwnershipAcquisition(const RTIHandle& objectHandle, const RTIHandleSet& attributeHandles)
+ // {
+ // try {
+ // std::auto_ptr<RTI::AttributeHandleSet> attributeHandleSet(RTI::AttributeHandleSetFactory::create(attributeHandles.size()));
+ // for (RTIHandleSet::const_iterator i = attributeHandles.begin(); i != attributeHandles.end(); ++i)
+ // attributeHandleSet->add(*i);
+ // _rtiAmbassador.cancelAttributeOwnershipAcquisition(objectHandle, *attributeHandleSet);
+ // return true;
+ // } catch (RTI::ObjectNotKnown& e) {
+ // } catch (RTI::AttributeNotDefined& e) {
+ // } catch (RTI::AttributeAlreadyOwned& e) {
+ // } catch (RTI::AttributeAcquisitionWasNotRequested& e) {
+ // } catch (RTI::FederateNotExecutionMember& e) {
+ // } catch (RTI::ConcurrentAccessAttempted& e) {
+ // } catch (RTI::SaveInProgress& e) {
+ // } catch (RTI::RestoreInProgress& e) {
+ // } catch (RTI::RTIinternalError& e) {
+ // }
+ // return false;
+ // }
+ // bool queryAttributeOwnership(const RTIHandle& objectHandle, const RTIHandle& attributeHandle)
+ // {
+ // try {
+ // _rtiAmbassador.queryAttributeOwnership(objectHandle, attributeHandle);
+ // return true;
+ // } 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 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;
+ // }
+
+ /// Time Management
+
+ void enableTimeRegulation(const SGTimeStamp& federateTime, const SGTimeStamp& lookahead)
+ { _rtiAmbassador.enableTimeRegulation(toFedTime(federateTime), toFedTime(lookahead)); }
+ void disableTimeRegulation()
+ { _rtiAmbassador.disableTimeRegulation(); _timeRegulationEnabled = false; }
+
+ void enableTimeConstrained()
+ { _rtiAmbassador.enableTimeConstrained(); }
+ void disableTimeConstrained()
+ { _rtiAmbassador.disableTimeConstrained(); _timeConstrainedEnabled = false; }
+
+ void timeAdvanceRequest(const SGTimeStamp& time)
+ { _rtiAmbassador.timeAdvanceRequest(toFedTime(time)); _timeAdvancePending = true; }
+ void timeAdvanceRequestAvailable(const SGTimeStamp& time)
+ { _rtiAmbassador.timeAdvanceRequestAvailable(toFedTime(time)); _timeAdvancePending = true; }
+
+ // bool queryLBTS(double& time)
+ // {
+ // try {
+ // RTIfedTime fedTime;
+ // _rtiAmbassador.queryLBTS(fedTime);
+ // time = fedTime.getTime();
+ // return true;
+ // } catch (RTI::FederateNotExecutionMember& e) {
+ // } catch (RTI::ConcurrentAccessAttempted& e) {
+ // } catch (RTI::SaveInProgress& e) {
+ // } catch (RTI::RestoreInProgress& e) {
+ // } catch (RTI::RTIinternalError& e) {
+ // }
+ // return false;
+ // }
+ // bool queryFederateTime(double& time)
+ // {
+ // try {
+ // RTIfedTime fedTime;
+ // _rtiAmbassador.queryFederateTime(fedTime);
+ // time = fedTime.getTime();
+ // return true;
+ // } catch (RTI::FederateNotExecutionMember& e) {
+ // } catch (RTI::ConcurrentAccessAttempted& e) {
+ // } catch (RTI::SaveInProgress& e) {
+ // } catch (RTI::RestoreInProgress& e) {
+ // } catch (RTI::RTIinternalError& e) {
+ // }
+ // return false;
+ // }
+
+ // bool queryLookahead(double& time)
+ // {
+ // try {
+ // RTIfedTime fedTime;
+ // _rtiAmbassador.queryLookahead(fedTime);
+ // time = fedTime.getTime();
+ // return true;
+ // } catch (RTI::FederateNotExecutionMember& e) {
+ // } catch (RTI::ConcurrentAccessAttempted& e) {
+ // } catch (RTI::SaveInProgress& e) {
+ // } catch (RTI::RestoreInProgress& e) {
+ // } catch (RTI::RTIinternalError& e) {
+ // }
+ // return false;
+ // }
+
+ RTI13ObjectClass* createObjectClass(const std::string& name, HLAObjectClass* hlaObjectClass)
+ {
+ RTI::ObjectClassHandle objectClassHandle;
+ objectClassHandle = getObjectClassHandle(name);
+ if (_objectClassMap.find(objectClassHandle) != _objectClassMap.end()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not create object class, object class already exists!");
+ return 0;
+ }
+ RTI13ObjectClass* rtiObjectClass;
+ rtiObjectClass = new RTI13ObjectClass(hlaObjectClass, objectClassHandle, this);
+ _objectClassMap[objectClassHandle] = rtiObjectClass;
+ return rtiObjectClass;
+ }
+ RTI::ObjectClassHandle getObjectClassHandle(const std::string& name)
+ { return _rtiAmbassador.getObjectClassHandle(name.c_str()); }
+ std::string getObjectClassName(const RTI::ObjectClassHandle& handle)
+ { return rtiToStdString(_rtiAmbassador.getObjectClassName(handle)); }
+
+ RTI::AttributeHandle getAttributeHandle(const std::string& attributeName, const RTI::ObjectClassHandle& objectClassHandle)
+ { return _rtiAmbassador.getAttributeHandle(attributeName.c_str(), objectClassHandle); }
+ 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;
+ // }
+
+ // 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;
+ // }
+
+ RTI13ObjectInstance* getObjectInstance(const std::string& name)
+ {
+ RTI::ObjectHandle objectHandle;
+ objectHandle = getObjectInstanceHandle(name);
+ ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle);
+ if (i == _objectInstanceMap.end()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: ObjectInstance not found.");
+ return 0;
+ }
+ return i->second;
+ }
+ RTI::ObjectHandle getObjectInstanceHandle(const std::string& name)
+ { return _rtiAmbassador.getObjectInstanceHandle(name.c_str()); }
+ std::string getObjectInstanceName(const RTI::ObjectHandle& objectHandle)
+ { return rtiToStdString(_rtiAmbassador.getObjectInstanceName(objectHandle)); }
+
+ // RTIHandle getRoutingSpaceHandle(const std::string& routingSpaceName)
+ // {
+ // try {
+ // return _rtiAmbassador.getRoutingSpaceHandle(routingSpaceName.c_str());
+ // } catch (RTI::NameNotFound& e) {
+ // } catch (RTI::FederateNotExecutionMember& e) {
+ // } catch (RTI::ConcurrentAccessAttempted& e) {
+ // } catch (RTI::RTIinternalError& e) {
+ // }
+ // return RTIHandle(-1);
+ // }
+ // std::string getRoutingSpaceName(const RTIHandle& routingSpaceHandle)
+ // {
+ // std::string routingSpaceName;
+ // try {
+ // rtiToStdString(routingSpaceName, _rtiAmbassador.wgetRoutingSpaceName(routingSpaceHandle));
+ // } catch (RTI::SpaceNotDefined& e) {
+ // } catch (RTI::FederateNotExecutionMember& e) {
+ // } catch (RTI::ConcurrentAccessAttempted& e) {
+ // } catch (RTI::RTIinternalError& e) {
+ // }
+ // return routingSpaceName;
+ // }
+
+ void enableClassRelevanceAdvisorySwitch()
+ { _rtiAmbassador.enableClassRelevanceAdvisorySwitch(); }
+ void disableClassRelevanceAdvisorySwitch()
+ { _rtiAmbassador.disableClassRelevanceAdvisorySwitch(); }
+
+ void enableAttributeRelevanceAdvisorySwitch()
+ { _rtiAmbassador.enableAttributeRelevanceAdvisorySwitch(); }
+ void disableAttributeRelevanceAdvisorySwitch()
+ { _rtiAmbassador.disableAttributeRelevanceAdvisorySwitch(); }
+
+ void enableAttributeScopeAdvisorySwitch()
+ { _rtiAmbassador.enableAttributeScopeAdvisorySwitch(); }
+ void disableAttributeScopeAdvisorySwitch()
+ { _rtiAmbassador.disableAttributeScopeAdvisorySwitch(); }
+
+ void enableInteractionRelevanceAdvisorySwitch()
+ { _rtiAmbassador.enableInteractionRelevanceAdvisorySwitch(); }
+ void disableInteractionRelevanceAdvisorySwitch()
+ { _rtiAmbassador.disableInteractionRelevanceAdvisorySwitch(); }
+
+
+ bool tick()
+ { return _rtiAmbassador.tick(); }
+ bool tick(double minimum, double maximum)
+ { return _rtiAmbassador.tick(minimum, maximum); }
+
+ void addObjectInstanceForCallback(RTIObjectInstance* objectIntance)
+ { _objectInstancePendingCallbackList.insert(objectIntance); }
+
+private:
+ /// Generic callback to execute some notification on objects in a way that they are not prone to
+ /// ConcurrentAccess exceptions.
+ class QueueCallback : public SGReferenced {
+ public:
+ virtual ~QueueCallback() {}
+ virtual void operator()() = 0;
+ };
+
+ class RemoveObjectCallback : public QueueCallback {
+ public:
+ RemoveObjectCallback(SGSharedPtr<RTIObjectInstance> objectInstance, const RTIData& tag) :
+ _objectInstance(objectInstance),
+ _tag(tag)
+ { }
+ virtual void operator()()
+ {
+ _objectInstance->removeInstance(_tag);
+ }
+ private:
+ SGSharedPtr<RTIObjectInstance> _objectInstance;
+ RTIData _tag;
+ };
+
+ /// Just the interface class doing the callbacks into the parent class
+ struct FederateAmbassador : public RTI::FederateAmbassador {
+ FederateAmbassador(RTI13Ambassador& rtiAmbassador) :
+ _rtiAmbassador(rtiAmbassador)
+ {
+ }
+ virtual ~FederateAmbassador()
+ throw (RTI::FederateInternalError)
+ {
+ }
+
+ /// RTI federate ambassador callback functions.
+ virtual void synchronizationPointRegistrationSucceeded(const char* label)
+ throw (RTI::FederateInternalError)
+ {
+ }
+
+ virtual void synchronizationPointRegistrationFailed(const char* label)
+ throw (RTI::FederateInternalError)
+ {
+ }
+
+ virtual void announceSynchronizationPoint(const char* label, const char* tag)
+ throw (RTI::FederateInternalError)
+ {
+ _rtiAmbassador._pendingSyncLabels.insert(toStdString(label));
+ }
+
+ virtual void federationSynchronized(const char* label)
+ throw (RTI::FederateInternalError)
+ {
+ std::string s = toStdString(label);
+ _rtiAmbassador._pendingSyncLabels.erase(s);
+ _rtiAmbassador._syncronizedSyncLabels.insert(s);
+ }
+
+ virtual void initiateFederateSave(const char* label)
+ throw (RTI::UnableToPerformSave,
+ RTI::FederateInternalError)
+ {
+ }
+
+ virtual void federationSaved()
+ throw (RTI::FederateInternalError)
+ {
+ }
+
+ virtual void federationNotSaved()
+ throw (RTI::FederateInternalError)
+ {
+ }
+
+ virtual void requestFederationRestoreSucceeded(const char* label)
+ throw (RTI::FederateInternalError)
+ {
+ }
+
+ virtual void requestFederationRestoreFailed(const char* label, const char* reason)
+ throw (RTI::FederateInternalError)
+ {
+ }
+
+ virtual void federationRestoreBegun()
+ throw (RTI::FederateInternalError)
+ {
+ }
+
+ virtual void initiateFederateRestore(const char* label, RTI::FederateHandle federateHandle)
+ throw (RTI::SpecifiedSaveLabelDoesNotExist,
+ RTI::CouldNotRestore,
+ RTI::FederateInternalError)
+ {
+ }
+
+ virtual void federationRestored()
+ throw (RTI::FederateInternalError)
+ {
+ }
+
+ virtual void federationNotRestored()
+ throw (RTI::FederateInternalError)
+ {
+ }
+
+ // Declaration Management
+ virtual void startRegistrationForObjectClass(RTI::ObjectClassHandle objectClassHandle)
+ throw (RTI::ObjectClassNotPublished,
+ RTI::FederateInternalError)
+ {
+ ObjectClassMap::iterator i = _rtiAmbassador._objectClassMap.find(objectClassHandle);
+ if (i == _rtiAmbassador._objectClassMap.end())
+ return;
+ if (!i->second.valid())
+ return;
+ i->second->startRegistration();
+ }
+
+ virtual void stopRegistrationForObjectClass(RTI::ObjectClassHandle objectClassHandle)
+ throw (RTI::ObjectClassNotPublished,
+ RTI::FederateInternalError)
+ {
+ ObjectClassMap::iterator i = _rtiAmbassador._objectClassMap.find(objectClassHandle);
+ if (i == _rtiAmbassador._objectClassMap.end())
+ return;
+ if (!i->second.valid())
+ return;
+ i->second->stopRegistration();
+ }
+
+ virtual void turnInteractionsOn(RTI::InteractionClassHandle interactionClassHandle)
+ throw (RTI::InteractionClassNotPublished,
+ RTI::FederateInternalError)
+ {
+ }
+
+ virtual void turnInteractionsOff(RTI::InteractionClassHandle interactionClassHandle)
+ throw (RTI::InteractionClassNotPublished,
+ RTI::FederateInternalError)
+ {
+ }
+
+
+ // Object Management
+ virtual void discoverObjectInstance(RTI::ObjectHandle objectHandle, RTI::ObjectClassHandle objectClassHandle, const char* tag)
+ throw (RTI::CouldNotDiscover,
+ RTI::ObjectClassNotKnown,
+ RTI::FederateInternalError)
+ {
+ ObjectClassMap::iterator i = _rtiAmbassador._objectClassMap.find(objectClassHandle);
+ if (i == _rtiAmbassador._objectClassMap.end())
+ throw RTI::ObjectClassNotKnown("Federate: discoverObjectInstance()!");
+ if (!i->second.valid())
+ return;
+ SGSharedPtr<RTI13ObjectInstance> objectInstance = new RTI13ObjectInstance(objectHandle, 0, i->second, &_rtiAmbassador, false);
+ _rtiAmbassador._objectInstanceMap[objectHandle] = objectInstance;
+ _rtiAmbassador._objectInstancePendingCallbackList.insert(objectInstance);
+ i->second->discoverInstance(objectInstance.get(), tagToData(tag));
+ }
+
+ virtual void reflectAttributeValues(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleValuePairSet& attributeValuePairSet,
+ const RTI::FedTime& fedTime, const char* tag, RTI::EventRetractionHandle eventRetractionHandle)
+ throw (RTI::ObjectNotKnown,
+ RTI::AttributeNotKnown,
+ RTI::FederateOwnsAttributes,
+ RTI::InvalidFederationTime,
+ RTI::FederateInternalError)
+ {
+ ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
+ if (i == _rtiAmbassador._objectInstanceMap.end())
+ throw RTI::ObjectNotKnown("Reflect attributes for unknown object!");
+ if (!i->second.valid())
+ return;
+ i->second->reflectAttributeValues(attributeValuePairSet, toTimeStamp(fedTime), tagToData(tag));
+ }
+
+ virtual void reflectAttributeValues(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleValuePairSet& attributeValuePairSet,
+ const char* tag)
+ throw (RTI::ObjectNotKnown,
+ RTI::AttributeNotKnown,
+ RTI::FederateOwnsAttributes,
+ RTI::FederateInternalError)
+ {
+ ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
+ if (i == _rtiAmbassador._objectInstanceMap.end())
+ throw RTI::ObjectNotKnown("Reflect attributes for unknown object!");
+ if (!i->second.valid())
+ return;
+ i->second->reflectAttributeValues(attributeValuePairSet, tagToData(tag));
+ }
+
+ virtual void receiveInteraction(RTI::InteractionClassHandle interactionClassHandle, const RTI::ParameterHandleValuePairSet& parameters,
+ const RTI::FedTime& fedTime, const char* tag, RTI::EventRetractionHandle eventRetractionHandle)
+ throw (RTI::InteractionClassNotKnown,
+ RTI::InteractionParameterNotKnown,
+ RTI::InvalidFederationTime,
+ RTI::FederateInternalError)
+ {
+ }
+
+ virtual void receiveInteraction(RTI::InteractionClassHandle interactionClassHandle,
+ const RTI::ParameterHandleValuePairSet& parameters, const char* tag)
+ throw (RTI::InteractionClassNotKnown,
+ RTI::InteractionParameterNotKnown,
+ RTI::FederateInternalError)
+ {
+ }
+
+ virtual void removeObjectInstance(RTI::ObjectHandle objectHandle, const RTI::FedTime& fedTime,
+ const char* tag, RTI::EventRetractionHandle eventRetractionHandle)
+ throw (RTI::ObjectNotKnown,
+ RTI::InvalidFederationTime,
+ RTI::FederateInternalError)
+ {
+ ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
+ if (i == _rtiAmbassador._objectInstanceMap.end())
+ throw RTI::ObjectNotKnown("Federate: removeObjectInstance()!");
+ if (i->second.valid())
+ _rtiAmbassador._queueCallbackList.push_back(new RemoveObjectCallback(i->second, tagToData(tag)));
+ _rtiAmbassador._objectInstancePendingCallbackList.erase(i->second);
+ _rtiAmbassador._objectInstanceMap.erase(i);
+ }
+
+ virtual void removeObjectInstance(RTI::ObjectHandle objectHandle, const char* tag)
+ throw (RTI::ObjectNotKnown,
+ RTI::FederateInternalError)
+ {
+ ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
+ if (i == _rtiAmbassador._objectInstanceMap.end())
+ throw RTI::ObjectNotKnown("Federate: removeObjectInstance()!");
+ if (i->second.valid())
+ _rtiAmbassador._queueCallbackList.push_back(new RemoveObjectCallback(i->second, tagToData(tag)));
+ _rtiAmbassador._objectInstancePendingCallbackList.erase(i->second);
+ _rtiAmbassador._objectInstanceMap.erase(i);
+ }
+
+ virtual void attributesInScope(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes)
+ throw (RTI::ObjectNotKnown,
+ RTI::AttributeNotKnown,
+ RTI::FederateInternalError)
+ {
+ ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
+ if (i == _rtiAmbassador._objectInstanceMap.end())
+ throw RTI::ObjectNotKnown("Attributes in scope for unknown object!");
+ if (!i->second.valid())
+ return;
+ i->second->attributesInScope(attributes);
+ }
+
+ virtual void attributesOutOfScope(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes)
+ throw (RTI::ObjectNotKnown,
+ RTI::AttributeNotKnown,
+ RTI::FederateInternalError)
+ {
+ ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
+ if (i == _rtiAmbassador._objectInstanceMap.end())
+ throw RTI::ObjectNotKnown("Attributes in scope for unknown object!");
+ if (!i->second.valid())
+ return;
+ i->second->attributesOutOfScope(attributes);
+ }
+
+ virtual void provideAttributeValueUpdate(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes)
+ throw (RTI::ObjectNotKnown,
+ RTI::AttributeNotKnown,
+ RTI::AttributeNotOwned,
+ RTI::FederateInternalError)
+ {
+ ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
+ if (i == _rtiAmbassador._objectInstanceMap.end())
+ throw RTI::ObjectNotKnown("Reflect attributes for unknown object!");
+ if (!i->second.valid())
+ return;
+ i->second->provideAttributeValueUpdate(attributes);
+ }
+
+ virtual void turnUpdatesOnForObjectInstance(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes)
+ throw (RTI::ObjectNotKnown,
+ RTI::AttributeNotOwned,
+ RTI::FederateInternalError)
+ {
+ ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
+ if (i == _rtiAmbassador._objectInstanceMap.end())
+ throw RTI::ObjectNotKnown("Turn on attributes for unknown object!");
+ if (!i->second.valid())
+ return;
+ i->second->turnUpdatesOnForObjectInstance(attributes);
+ }
+
+ virtual void turnUpdatesOffForObjectInstance(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes)
+ throw (RTI::ObjectNotKnown,
+ RTI::AttributeNotOwned,
+ RTI::FederateInternalError)
+ {
+ ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
+ if (i == _rtiAmbassador._objectInstanceMap.end())
+ throw RTI::ObjectNotKnown("Turn off attributes for unknown object!");
+ if (!i->second.valid())
+ return;
+ i->second->turnUpdatesOffForObjectInstance(attributes);
+ }
+
+ // Ownership Management
+ virtual void requestAttributeOwnershipAssumption(RTI::ObjectHandle objectHandle,
+ const RTI::AttributeHandleSet& attributes, const char* tag)
+ throw (RTI::ObjectNotKnown,
+ RTI::AttributeNotKnown,
+ RTI::AttributeAlreadyOwned,
+ RTI::AttributeNotPublished,
+ RTI::FederateInternalError)
+ {
+ ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
+ if (i == _rtiAmbassador._objectInstanceMap.end())
+ throw RTI::ObjectNotKnown("requestAttributeOwnershipAssumption for unknown object!");
+ if (!i->second.valid())
+ return;
+ i->second->requestAttributeOwnershipAssumption(attributes, tagToData(tag));
+ }
+
+ virtual void attributeOwnershipDivestitureNotification(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes)
+ throw (RTI::ObjectNotKnown,
+ RTI::AttributeNotKnown,
+ RTI::AttributeNotOwned,
+ RTI::AttributeDivestitureWasNotRequested,
+ RTI::FederateInternalError)
+ {
+ ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
+ if (i == _rtiAmbassador._objectInstanceMap.end())
+ throw RTI::ObjectNotKnown("attributeOwnershipDivestitureNotification for unknown object!");
+ if (!i->second.valid())
+ return;
+ i->second->attributeOwnershipDivestitureNotification(attributes);
+ }
+
+ virtual void attributeOwnershipAcquisitionNotification(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes)
+ throw (RTI::ObjectNotKnown,
+ RTI::AttributeNotKnown,
+ RTI::AttributeAcquisitionWasNotRequested,
+ RTI::AttributeAlreadyOwned,
+ RTI::AttributeNotPublished,
+ RTI::FederateInternalError)
+ {
+ ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
+ if (i == _rtiAmbassador._objectInstanceMap.end())
+ throw RTI::ObjectNotKnown("attributeOwnershipAcquisitionNotification for unknown object!");
+ if (!i->second.valid())
+ return;
+ i->second->attributeOwnershipAcquisitionNotification(attributes);
+ }
+
+ virtual void attributeOwnershipUnavailable(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes)
+ throw (RTI::ObjectNotKnown,
+ RTI::AttributeNotKnown,
+ RTI::AttributeAlreadyOwned,
+ RTI::AttributeAcquisitionWasNotRequested,
+ RTI::FederateInternalError)
+ {
+ ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
+ if (i == _rtiAmbassador._objectInstanceMap.end())
+ throw RTI::ObjectNotKnown("attributeOwnershipUnavailable for unknown object!");
+ if (!i->second.valid())
+ return;
+ i->second->attributeOwnershipUnavailable(attributes);
+ }
+
+ virtual void requestAttributeOwnershipRelease(RTI::ObjectHandle objectHandle,
+ const RTI::AttributeHandleSet& attributes, const char* tag)
+ throw (RTI::ObjectNotKnown,
+ RTI::AttributeNotKnown,
+ RTI::AttributeNotOwned,
+ RTI::FederateInternalError)
+ {
+ ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
+ if (i == _rtiAmbassador._objectInstanceMap.end())
+ throw RTI::ObjectNotKnown("requestAttributeOwnershipRelease for unknown object!");
+ if (!i->second.valid())
+ return;
+ i->second->requestAttributeOwnershipRelease(attributes, tagToData(tag));
+ }
+
+ virtual void confirmAttributeOwnershipAcquisitionCancellation(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes)
+ throw (RTI::ObjectNotKnown,
+ RTI::AttributeNotKnown,
+ RTI::AttributeAlreadyOwned,
+ RTI::AttributeAcquisitionWasNotCanceled,
+ RTI::FederateInternalError)
+ {
+ ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
+ if (i == _rtiAmbassador._objectInstanceMap.end())
+ throw RTI::ObjectNotKnown("confirmAttributeOwnershipAcquisitionCancellation for unknown object!");
+ if (!i->second.valid())
+ return;
+ i->second->confirmAttributeOwnershipAcquisitionCancellation(attributes);
+ }
+
+ virtual void informAttributeOwnership(RTI::ObjectHandle objectHandle, RTI::AttributeHandle attributeHandle,
+ RTI::FederateHandle federateHandle)
+ throw (RTI::ObjectNotKnown,
+ RTI::AttributeNotKnown,
+ RTI::FederateInternalError)
+ {
+ ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
+ if (i == _rtiAmbassador._objectInstanceMap.end())
+ throw RTI::ObjectNotKnown("informAttributeOwnership for unknown object!");
+ if (!i->second.valid())
+ return;
+ i->second->informAttributeOwnership(attributeHandle, federateHandle);
+ }
+
+ virtual void attributeIsNotOwned(RTI::ObjectHandle objectHandle, RTI::AttributeHandle attributeHandle)
+ throw (RTI::ObjectNotKnown,
+ RTI::AttributeNotKnown,
+ RTI::FederateInternalError)
+ {
+ ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
+ if (i == _rtiAmbassador._objectInstanceMap.end())
+ throw RTI::ObjectNotKnown("attributeIsNotOwned for unknown object!");
+ if (!i->second.valid())
+ return;
+ i->second->attributeIsNotOwned(attributeHandle);
+ }
+
+ virtual void attributeOwnedByRTI(RTI::ObjectHandle objectHandle, RTI::AttributeHandle attributeHandle)
+ throw (RTI::ObjectNotKnown,
+ RTI::AttributeNotKnown,
+ RTI::FederateInternalError)
+ {
+ ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
+ if (i == _rtiAmbassador._objectInstanceMap.end())
+ throw RTI::ObjectNotKnown("attributeOwnedByRTI for unknown object!");
+ if (!i->second.valid())
+ return;
+ i->second->attributeOwnedByRTI(attributeHandle);
+ }
+
+ // Time Management
+ virtual void timeRegulationEnabled(const RTI::FedTime& fedTime)
+ throw (RTI::InvalidFederationTime,
+ RTI::EnableTimeRegulationWasNotPending,
+ RTI::FederateInternalError)
+ {
+ _rtiAmbassador._timeRegulationEnabled = true;
+ _rtiAmbassador._federateTime = toTimeStamp(fedTime);
+ SG_LOG(SG_NETWORK, SG_INFO, "RTI: timeRegulationEnabled: " << _rtiAmbassador._federateTime);
+ }
+
+ virtual void timeConstrainedEnabled(const RTI::FedTime& fedTime)
+ throw (RTI::InvalidFederationTime,
+ RTI::EnableTimeConstrainedWasNotPending,
+ RTI::FederateInternalError)
+ {
+ _rtiAmbassador._timeConstrainedEnabled = true;
+ _rtiAmbassador._federateTime = toTimeStamp(fedTime);
+ SG_LOG(SG_NETWORK, SG_INFO, "RTI: timeConstrainedEnabled: " << _rtiAmbassador._federateTime);
+ }
+
+ virtual void timeAdvanceGrant(const RTI::FedTime& fedTime)
+ throw (RTI::InvalidFederationTime,
+ RTI::TimeAdvanceWasNotInProgress,
+ RTI::FederateInternalError)
+ {
+ _rtiAmbassador._federateTime = toTimeStamp(fedTime);
+ _rtiAmbassador._timeAdvancePending = false;
+ SG_LOG(SG_NETWORK, SG_INFO, "RTI: timeAdvanceGrant: " << _rtiAmbassador._federateTime);
+ }
+
+ virtual void requestRetraction(RTI::EventRetractionHandle eventRetractionHandle)
+ throw (RTI::EventNotKnown,
+ RTI::FederateInternalError)
+ {
+ // No retraction concept yet
+ }
+
+ private:
+ const RTIData& tagToData(const char* tag)
+ {
+ if (tag)
+ _cachedTag.setData(tag, std::strlen(tag) + 1);
+ else
+ _cachedTag.setData("", 1);
+ return _cachedTag;
+ }
+ RTIData _cachedTag;
+
+ RTI13Ambassador& _rtiAmbassador;
+ };
+
+ static SGTimeStamp toTimeStamp(const RTI::FedTime& fedTime)
+ {
+ RTIfedTime referenceTime(fedTime);
+ return SGTimeStamp::fromSec(referenceTime.getTime() + 0.5e-9);
+ }
+
+ static RTIfedTime toFedTime(const SGTimeStamp& timeStamp)
+ {
+ RTIfedTime referenceTime;
+ referenceTime.setZero();
+ referenceTime += timeStamp.toSecs();
+ return referenceTime;
+ }
+
+ static std::string rtiToStdString(char* n)
+ {
+ if (!n)
+ return std::string();
+ std::string s;
+ s.assign(n);
+ delete[] n;
+ return s;
+ }
+
+ static std::string toStdString(const char* n)
+ {
+ if (!n)
+ return std::string();
+ return std::string(n);
+ }
+
+ // The connection class
+ RTI::RTIambassador _rtiAmbassador;
+
+ // The class with all the callbacks.
+ FederateAmbassador _federateAmbassador;
+
+ // All the sync labels we got an announcement for
+ std::set<std::string> _pendingSyncLabels;
+ std::set<std::string> _syncronizedSyncLabels;
+
+ // All that calls back into user code is just queued.
+ // That is to make sure we do not call recursively into the RTI
+ typedef std::list<SGSharedPtr<QueueCallback> > QueueCallbackList;
+ QueueCallbackList _queueCallbackList;
+ // All object instances that need to be called due to some event are noted here
+ // That is to make sure we do not call recursively into the RTI
+ typedef std::set<SGSharedPtr<RTIObjectInstance> > ObjectInstanceSet;
+ ObjectInstanceSet _objectInstancePendingCallbackList;
+
+ // Top level information for dispatching federate object attribute updates
+ typedef std::map<RTI::ObjectHandle, SGSharedPtr<RTI13ObjectInstance> > ObjectInstanceMap;
+ // Map of all available objects
+ ObjectInstanceMap _objectInstanceMap;
+
+ // Top level information for dispatching creation of federate objects
+ typedef std::map<RTI::ObjectClassHandle, SGSharedPtr<RTI13ObjectClass> > ObjectClassMap;
+ ObjectClassMap _objectClassMap;
+
+ bool _timeRegulationEnabled;
+ bool _timeConstrainedEnabled;
+ bool _timeAdvancePending;
+ SGTimeStamp _federateTime;
+};
+
+} // namespace simgear
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "RTI13Federate.hxx"
+
+#include "RTI13Ambassador.hxx"
+
+namespace simgear {
+
+RTI13Federate::RTI13Federate() :
+ _tickTimeout(10),
+ _ambassador(new RTI13Ambassador)
+{
+}
+
+RTI13Federate::~RTI13Federate()
+{
+}
+
+bool
+RTI13Federate::createFederationExecution(const std::string& federationName, const std::string& objectModel)
+{
+ try {
+ _ambassador->createFederationExecution(federationName, objectModel);
+ return true;
+ } catch (RTI::FederationExecutionAlreadyExists& e) {
+ return true;
+ } catch (RTI::CouldNotOpenFED& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not create federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ErrorReadingFED& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not create federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not create federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not create federation execution: " << e._name << " " << e._reason);
+ return false;
+ }
+}
+
+bool
+RTI13Federate::destroyFederationExecution(const std::string& federation)
+{
+ try {
+ _ambassador->destroyFederationExecution(federation);
+ return true;
+ } catch (RTI::FederatesCurrentlyJoined& e) {
+ return true;
+ } catch (RTI::FederationExecutionDoesNotExist& e) {
+ return true;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not destroy federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not destroy federation execution: " << e._name << " " << e._reason);
+ return false;
+ }
+}
+
+bool
+RTI13Federate::join(const std::string& federateType, const std::string& federationName)
+{
+ try {
+ _federateHandle = _ambassador->joinFederationExecution(federateType, federationName);
+ SG_LOG(SG_NETWORK, SG_INFO, "RTI: Joined federation \""
+ << federationName << "\" as \"" << federateType << "\"");
+ setFederateType(federateType);
+ setFederationName(federationName);
+ return true;
+ } catch (RTI::FederateAlreadyExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederationExecutionDoesNotExist& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::CouldNotOpenFED& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ErrorReadingFED& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason);
+ return false;
+ }
+}
+
+bool
+RTI13Federate::resign()
+{
+ try {
+ _ambassador->resignFederationExecution();
+ SG_LOG(SG_NETWORK, SG_INFO, "RTI: Resigned from federation.");
+ _federateHandle = -1;
+ return true;
+ } catch (RTI::FederateOwnsAttributes& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::InvalidResignAction& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ }
+}
+
+bool
+RTI13Federate::registerFederationSynchronizationPoint(const std::string& label, const RTIData& tag)
+{
+ try {
+ _ambassador->registerFederationSynchronizationPoint(label, tag);
+ SG_LOG(SG_NETWORK, SG_INFO, "RTI: registerFederationSynchronizationPoint(" << label << ", tag )");
+ return true;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register federation synchronization point: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register federation synchronization point: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register federation synchronization point: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register federation synchronization point: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register federation synchronization point: " << e._name << " " << e._reason);
+ return false;
+ }
+}
+
+bool
+RTI13Federate::waitForFederationSynchronizationPointAnnounced(const std::string& label)
+{
+ while (!_ambassador->getFederationSynchronizationPointAnnounced(label)) {
+ _ambassador->tick(_tickTimeout, 0);
+ _ambassador->processQueues();
+ }
+ return true;
+}
+
+bool
+RTI13Federate::synchronizationPointAchieved(const std::string& label)
+{
+ try {
+ _ambassador->synchronizationPointAchieved(label);
+ SG_LOG(SG_NETWORK, SG_INFO, "RTI: synchronizationPointAchieved(" << label << ")");
+ return true;
+ } catch (RTI::SynchronizationPointLabelWasNotAnnounced& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not signal synchronization point: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not signal synchronization point: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not signal synchronization point: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not signal synchronization point: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not signal synchronization point: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not signal synchronization point: " << e._name << " " << e._reason);
+ return false;
+ }
+}
+
+bool
+RTI13Federate::waitForFederationSynchronized(const std::string& label)
+{
+ while (!_ambassador->getFederationSynchronized(label)) {
+ _ambassador->tick(_tickTimeout, 0);
+ _ambassador->processQueues();
+ }
+ return true;
+}
+
+bool
+RTI13Federate::enableTimeConstrained()
+{
+ if (!_ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not enable time constrained at unconnected federate.");
+ return false;
+ }
+
+ if (_ambassador->getTimeConstrainedEnabled()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Time constrained is already enabled.");
+ return false;
+ }
+
+ try {
+ _ambassador->enableTimeConstrained();
+ } catch (RTI::TimeConstrainedAlreadyEnabled& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::EnableTimeConstrainedPending& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::TimeAdvanceAlreadyInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ }
+
+ while (!_ambassador->getTimeConstrainedEnabled()) {
+ _ambassador->tick(_tickTimeout, 0);
+ _ambassador->processQueues();
+ }
+
+ return true;
+}
+
+bool
+RTI13Federate::disableTimeConstrained()
+{
+ if (!_ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not disable time constrained at unconnected federate.");
+ return false;
+ }
+
+ if (!_ambassador->getTimeConstrainedEnabled()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Time constrained is not enabled.");
+ return false;
+ }
+
+ try {
+ _ambassador->disableTimeConstrained();
+ } catch (RTI::TimeConstrainedWasNotEnabled& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ }
+
+ return true;
+}
+
+bool
+RTI13Federate::enableTimeRegulation(const SGTimeStamp& lookahead)
+{
+ if (!_ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not enable time regulation at unconnected federate.");
+ return false;
+ }
+
+ if (_ambassador->getTimeRegulationEnabled()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Time regulation already enabled.");
+ return false;
+ }
+
+ try {
+ _ambassador->enableTimeRegulation(SGTimeStamp(), lookahead);
+ } catch (RTI::TimeRegulationAlreadyEnabled& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::EnableTimeRegulationPending& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::TimeAdvanceAlreadyInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::InvalidFederationTime& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::InvalidLookahead& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ }
+
+ while (!_ambassador->getTimeRegulationEnabled()) {
+ _ambassador->tick(_tickTimeout, 0);
+ _ambassador->processQueues();
+ }
+
+ return true;
+}
+
+bool
+RTI13Federate::disableTimeRegulation()
+{
+ if (!_ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not disable time regulation at unconnected federate.");
+ return false;
+ }
+
+ if (!_ambassador->getTimeRegulationEnabled()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Time regulation is not enabled.");
+ return false;
+ }
+
+ try {
+ _ambassador->disableTimeRegulation();
+ } catch (RTI::TimeRegulationWasNotEnabled& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ }
+
+ return true;
+}
+
+bool
+RTI13Federate::timeAdvanceRequestBy(const SGTimeStamp& dt)
+{
+ if (!_ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not disable time regulation at unconnected federate.");
+ return false;
+ }
+
+ SGTimeStamp fedTime = _ambassador->getCurrentLogicalTime() + dt;
+ return timeAdvanceRequest(fedTime);
+}
+
+bool
+RTI13Federate::timeAdvanceRequest(const SGTimeStamp& fedTime)
+{
+ if (!_ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not disable time regulation at unconnected federate.");
+ return false;
+ }
+
+ try {
+ _ambassador->timeAdvanceRequest(fedTime);
+ } catch (RTI::InvalidFederationTime& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederationTimeAlreadyPassed& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::TimeAdvanceAlreadyInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::EnableTimeRegulationPending& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::EnableTimeConstrainedPending& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
+ return false;
+ }
+
+ while (_ambassador->getTimeAdvancePending()) {
+ _ambassador->tick(_tickTimeout, 0);
+ _ambassador->processQueues();
+ }
+
+ return true;
+}
+
+bool
+RTI13Federate::tick()
+{
+ bool result = _ambassador->tick();
+ _ambassador->processQueues();
+ return result;
+}
+
+bool
+RTI13Federate::tick(const double& minimum, const double& maximum)
+{
+ bool result = _ambassador->tick(minimum, maximum);
+ _ambassador->processQueues();
+ return result;
+}
+
+RTI13ObjectClass*
+RTI13Federate::createObjectClass(const std::string& objectClassName, HLAObjectClass* hlaObjectClass)
+{
+ try {
+ return _ambassador->createObjectClass(objectClassName, hlaObjectClass);
+ } catch (RTI::NameNotFound& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: " << e._name << " " << e._reason);
+ return 0;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: " << e._name << " " << e._reason);
+ return 0;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: " << e._name << " " << e._reason);
+ return 0;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: " << e._name << " " << e._reason);
+ return 0;
+ }
+}
+
+RTI13ObjectInstance*
+RTI13Federate::getObjectInstance(const std::string& objectInstanceName)
+{
+ try {
+ return _ambassador->getObjectInstance(objectInstanceName);
+ } catch (RTI::ObjectNotKnown& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: " << e._name << " " << e._reason);
+ return 0;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: " << e._name << " " << e._reason);
+ return 0;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: " << e._name << " " << e._reason);
+ return 0;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: " << e._name << " " << e._reason);
+ return 0;
+ }
+}
+
+}
--- /dev/null
+// Copyright (C) 2009 - 2010 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 RTI13Federate_hxx
+#define RTI13Federate_hxx
+
+#ifndef RTI_USES_STD_FSTREAM
+#define RTI_USES_STD_FSTREAM
+#endif
+
+#include <RTI.hh>
+
+#include "RTIFederate.hxx"
+#include "RTI13ObjectClass.hxx"
+#include "RTI13ObjectInstance.hxx"
+
+namespace simgear {
+
+class RTI13Ambassador;
+
+class RTI13Federate : public RTIFederate {
+public:
+ RTI13Federate();
+ virtual ~RTI13Federate();
+
+ virtual bool createFederationExecution(const std::string& federation, const std::string& objectModel);
+ virtual bool destroyFederationExecution(const std::string& federation);
+
+ /// Join with federateName the federation execution federation
+ virtual bool join(const std::string& federateType, const std::string& federation);
+ virtual bool resign();
+
+ /// Synchronization Point handling
+ virtual bool registerFederationSynchronizationPoint(const std::string& label, const RTIData& tag);
+ virtual bool waitForFederationSynchronizationPointAnnounced(const std::string& label);
+ virtual bool synchronizationPointAchieved(const std::string& label);
+ virtual bool waitForFederationSynchronized(const std::string& label);
+
+ /// Time management
+ virtual bool enableTimeConstrained();
+ virtual bool disableTimeConstrained();
+
+ virtual bool enableTimeRegulation(const SGTimeStamp& lookahead);
+ virtual bool disableTimeRegulation();
+
+ virtual bool timeAdvanceRequestBy(const SGTimeStamp& dt);
+ virtual bool timeAdvanceRequest(const SGTimeStamp& fedTime);
+
+ /// Process messages
+ virtual bool tick();
+ virtual bool tick(const double& minimum, const double& maximum);
+
+ virtual RTI13ObjectClass* createObjectClass(const std::string& name, HLAObjectClass* hlaObjectClass);
+
+ virtual RTI13ObjectInstance* getObjectInstance(const std::string& name);
+
+private:
+ RTI13Federate(const RTI13Federate&);
+ RTI13Federate& operator=(const RTI13Federate&);
+
+ /// The federate handle
+ RTI::FederateHandle _federateHandle;
+
+ /// The timeout for the single callback tick function in
+ /// syncronous operations that need to wait for a callback
+ double _tickTimeout;
+
+ /// RTI connection
+ SGSharedPtr<RTI13Ambassador> _ambassador;
+};
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "RTI13ObjectClass.hxx"
+#include "RTI13Ambassador.hxx"
+
+namespace simgear {
+
+RTI13ObjectClass::RTI13ObjectClass(HLAObjectClass* hlaObjectClass, 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
+{
+ SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
+ 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
+{
+ SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
+ 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;
+ }
+}
+
+unsigned
+RTI13ObjectClass::getOrCreateAttributeIndex(const std::string& name)
+{
+ SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
+ 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;
+
+ unsigned index = _attributeHandleVector.size();
+ _attributeHandleIndexMap[attributeHandle] = index;
+ _attributeHandleVector.push_back(attributeHandle);
+ _attributeDataVector.push_back(name);
+
+ return index;
+
+ } 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;
+ }
+}
+
+// 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();
+// }
+// }
+
+bool
+RTI13ObjectClass::publish(const std::set<unsigned>& indexSet)
+{
+ SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
+ if (!ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
+ return false;
+ }
+
+ 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) {
+ if (_attributeHandleVector.size() <= *i) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI13ObjectClass::publish(): Invalid attribute index!");
+ continue;
+ }
+ attributeHandleSet->add(_attributeHandleVector[*i]);
+ }
+
+ 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);
+ return false;
+ } catch (RTI::AttributeNotDefined& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::OwnershipAcquisitionPending& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (...) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish object class.");
+ return false;
+ }
+}
+
+bool
+RTI13ObjectClass::unpublish()
+{
+ SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
+ if (!ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
+ return false;
+ }
+
+ 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);
+ return false;
+ } catch (RTI::ObjectClassNotPublished& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::OwnershipAcquisitionPending& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (...) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish object class.");
+ return false;
+ }
+}
+
+bool
+RTI13ObjectClass::subscribe(const std::set<unsigned>& indexSet, bool active)
+{
+ SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
+ if (!ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
+ return false;
+ }
+
+ 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) {
+ if (_attributeHandleVector.size() <= *i) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI13ObjectClass::subscribe(): Invalid attribute index!");
+ continue;
+ }
+ attributeHandleSet->add(_attributeHandleVector[*i]);
+ }
+
+ 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);
+ return false;
+ } catch (RTI::AttributeNotDefined& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (...) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe object class.");
+ return false;
+ }
+}
+
+bool
+RTI13ObjectClass::unsubscribe()
+{
+ SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
+ if (!ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
+ return 0;
+ }
+
+ 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);
+ return false;
+ } catch (RTI::ObjectClassNotSubscribed& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe object class: " << e._name << " " << e._reason);
+ return false;
+ } catch (...) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe object class.");
+ return false;
+ }
+}
+
+RTIObjectInstance*
+RTI13ObjectClass::registerObjectInstance(HLAObjectInstance* hlaObjectInstance)
+{
+ SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
+ if (!ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
+ return 0;
+ }
+
+ try {
+ return ambassador->registerObjectInstance(this, hlaObjectInstance);
+ } catch (RTI::ObjectClassNotDefined& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register object instance: " << e._name << " " << e._reason);
+ return 0;
+ } catch (RTI::ObjectClassNotPublished& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register object instance: " << e._name << " " << e._reason);
+ return 0;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register object instance: " << e._name << " " << e._reason);
+ return 0;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register object instance: " << e._name << " " << e._reason);
+ return 0;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register object instance: " << e._name << " " << e._reason);
+ return 0;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register object instance: " << e._name << " " << e._reason);
+ return 0;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register object instance: " << e._name << " " << e._reason);
+ return 0;
+ }
+}
+
+}
--- /dev/null
+// Copyright (C) 2009 - 2010 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 RTI13ObjectClass_hxx
+#define RTI13ObjectClass_hxx
+
+#include <map>
+
+#ifndef RTI_USES_STD_FSTREAM
+#define RTI_USES_STD_FSTREAM
+#endif
+
+#include <RTI.hh>
+
+#include <simgear/structure/SGWeakPtr.hxx>
+
+#include "RTIObjectClass.hxx"
+
+namespace simgear {
+
+class RTI13Ambassador;
+class RTIObjectInstance;
+
+class RTI13ObjectClass : public RTIObjectClass {
+public:
+ RTI13ObjectClass(HLAObjectClass* hlaObjectClass, RTI::ObjectClassHandle& handle, RTI13Ambassador* ambassador);
+ virtual ~RTI13ObjectClass();
+
+ const RTI::ObjectClassHandle& getHandle() const
+ { return _handle; }
+
+ virtual std::string getName() const;
+
+ 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
+ {
+ AttributeHandleIndexMap::const_iterator i = _attributeHandleIndexMap.find(handle);
+ if (i == _attributeHandleIndexMap.end())
+ return ~0u;
+ return i->second;
+ }
+ RTI::AttributeHandle getAttributeHandle(unsigned index) const
+ {
+ if (_attributeHandleVector.size() <= index)
+ return -1;
+ return _attributeHandleVector[index];
+ }
+
+ virtual bool publish(const std::set<unsigned>& indexSet);
+ virtual bool unpublish();
+
+ virtual bool subscribe(const std::set<unsigned>& indexSet, bool);
+ virtual bool unsubscribe();
+
+ virtual RTIObjectInstance* registerObjectInstance(HLAObjectInstance* hlaObjectInstance);
+
+private:
+ RTI::ObjectClassHandle _handle;
+ SGWeakPtr<RTI13Ambassador> _ambassador;
+
+ typedef std::map<RTI::AttributeHandle, unsigned> AttributeHandleIndexMap;
+ AttributeHandleIndexMap _attributeHandleIndexMap;
+
+ typedef std::vector<RTI::AttributeHandle> AttributeHandleVector;
+ AttributeHandleVector _attributeHandleVector;
+};
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "RTIObjectInstance.hxx"
+#include "RTI13Ambassador.hxx"
+
+namespace simgear {
+
+RTI13ObjectInstance::RTI13ObjectInstance(const RTI::ObjectHandle& handle, HLAObjectInstance* hlaObjectInstance,
+ const RTI13ObjectClass* objectClass, RTI13Ambassador* ambassador, bool owned) :
+ RTIObjectInstance(hlaObjectInstance),
+ _handle(handle),
+ _objectClass(objectClass),
+ _ambassador(ambassador),
+ _attributeValuePairSet(RTI::AttributeSetFactory::create(objectClass->getNumAttributes()))
+{
+ updateAttributesFromClass(owned);
+}
+
+RTI13ObjectInstance::~RTI13ObjectInstance()
+{
+}
+
+const RTIObjectClass*
+RTI13ObjectInstance::getObjectClass() const
+{
+ return _objectClass.get();
+}
+
+const RTI13ObjectClass*
+RTI13ObjectInstance::get13ObjectClass() const
+{
+ return _objectClass.get();
+}
+
+std::string
+RTI13ObjectInstance::getName() 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->getObjectInstanceName(_handle);
+ } catch (RTI::ObjectNotKnown& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object name: " << e._name << " " << e._reason);
+ return std::string();
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object name: " << e._name << " " << e._reason);
+ return std::string();
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object name: " << e._name << " " << e._reason);
+ return std::string();
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object name: " << e._name << " " << e._reason);
+ return std::string();
+ } catch (...) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object name.");
+ return std::string();
+ }
+}
+
+void
+RTI13ObjectInstance::addToRequestQueue()
+{
+ SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
+ if (!ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
+ return;
+ }
+
+ ambassador->addObjectInstanceForCallback(this);
+}
+
+void
+RTI13ObjectInstance::deleteObjectInstance(const RTIData& tag)
+{
+ SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
+ if (!ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
+ return;
+ }
+
+ try {
+ ambassador->deleteObjectInstance(_handle, tag);
+ } catch (RTI::ObjectNotKnown& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::DeletePrivilegeNotHeld& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ }
+}
+
+void
+RTI13ObjectInstance::deleteObjectInstance(const SGTimeStamp& timeStamp, const RTIData& tag)
+{
+ SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
+ if (!ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
+ return;
+ }
+
+ try {
+ ambassador->deleteObjectInstance(_handle, timeStamp, tag);
+ } catch (RTI::ObjectNotKnown& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::DeletePrivilegeNotHeld& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::InvalidFederationTime& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ }
+}
+
+void
+RTI13ObjectInstance::localDeleteObjectInstance()
+{
+ SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
+ if (!ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
+ return;
+ }
+
+ try {
+ ambassador->localDeleteObjectInstance(_handle);
+ } catch (RTI::ObjectNotKnown& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::FederateOwnsAttributes& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ }
+}
+
+void
+RTI13ObjectInstance::reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const RTIData& tag)
+{
+ // Retrieve an empty update struct from the memory pool
+ UpdateList updateList;
+ getUpdateFromPool(updateList);
+
+ RTI::ULong numAttribs = attributeValuePairSet.size();
+ for (RTI::ULong i = 0; i < numAttribs; ++i) {
+ unsigned index = getAttributeIndex(attributeValuePairSet.getHandle(i));
+ // Get a RTIData from the data pool
+ getDataFromPool(index, updateList.back()._indexDataPairList);
+ RTI::ULong length = attributeValuePairSet.getValueLength(i);
+ updateList.back()._indexDataPairList.back().second.resize(length);
+ attributeValuePairSet.getValue(i, updateList.back()._indexDataPairList.back().second.data(), length);
+ updateList.back()._tag = tag;
+ }
+
+ RTIObjectInstance::reflectAttributeValues(updateList.front()._indexDataPairList, tag);
+ // Return the update data back to the pool
+ putUpdateToPool(updateList);
+}
+
+void
+RTI13ObjectInstance::reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const SGTimeStamp& timeStamp, const RTIData& tag)
+{
+ // Retrieve an empty update struct from the memory pool
+ UpdateList updateList;
+ getUpdateFromPool(updateList);
+
+ RTI::ULong numAttribs = attributeValuePairSet.size();
+ for (RTI::ULong i = 0; i < numAttribs; ++i) {
+ unsigned index = getAttributeIndex(attributeValuePairSet.getHandle(i));
+ // Get a RTIData from the data pool
+ getDataFromPool(index, updateList.back()._indexDataPairList);
+ RTI::ULong length = attributeValuePairSet.getValueLength(i);
+ updateList.back()._indexDataPairList.back().second.resize(length);
+ attributeValuePairSet.getValue(i, updateList.back()._indexDataPairList.back().second.data(), length);
+ updateList.back()._tag = tag;
+ }
+
+ scheduleUpdates(timeStamp, updateList);
+}
+
+void
+RTI13ObjectInstance::requestObjectAttributeValueUpdate()
+{
+ SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
+ if (!ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
+ 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))
+ continue;
+ 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);
+ return;
+ } catch (RTI::AttributeNotDefined& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
+ return;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
+ return;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
+ return;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
+ return;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
+ return;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
+ return;
+ } catch (...) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance.");
+ return;
+ }
+}
+
+void
+RTI13ObjectInstance::provideAttributeValueUpdate(const RTI::AttributeHandleSet& attributes)
+{
+ // Called from the ambassador. Just marks some instance attributes dirty so that they are sent with the next update
+ RTI::ULong numAttribs = attributes.size();
+ for (RTI::ULong i = 0; i < numAttribs; ++i) {
+ unsigned index = getAttributeIndex(attributes.getHandle(i));
+ setAttributeForceUpdate(index);
+ }
+}
+
+void
+RTI13ObjectInstance::updateAttributeValues(const RTIData& tag)
+{
+ SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
+ if (!ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
+ return;
+ }
+
+ try {
+ // That means clear()
+ _attributeValuePairSet->empty();
+
+ unsigned numAttributes = getNumAttributes();
+ for (unsigned i = 0; i < numAttributes; ++i) {
+ if (!getAttributeEffectiveUpdateEnabled(i))
+ continue;
+ const HLADataElement* dataElement = getDataElement(i);
+ if (!dataElement)
+ continue;
+ // FIXME cache somewhere
+ RTIData data;
+ HLAEncodeStream stream(data);
+ dataElement->encode(stream);
+ _attributeValuePairSet->add(getAttributeHandle(i), data.data(), data.size());
+ }
+
+ if (!_attributeValuePairSet->size())
+ return;
+
+ ambassador->updateAttributeValues(_handle, *_attributeValuePairSet, tag);
+
+ for (unsigned i = 0; i < numAttributes; ++i) {
+ setAttributeUpdated(i);
+ }
+
+ } catch (RTI::ObjectNotKnown& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::AttributeNotDefined& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::AttributeNotOwned& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ }
+
+ // That means clear()
+ _attributeValuePairSet->empty();
+}
+
+void
+RTI13ObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag)
+{
+ SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
+ if (!ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
+ return;
+ }
+
+ try {
+ // That means clear()
+ _attributeValuePairSet->empty();
+
+ unsigned numAttributes = getNumAttributes();
+ for (unsigned i = 0; i < numAttributes; ++i) {
+ if (!getAttributeEffectiveUpdateEnabled(i))
+ continue;
+ const HLADataElement* dataElement = getDataElement(i);
+ if (!dataElement)
+ continue;
+ // FIXME cache somewhere
+ RTIData data;
+ HLAEncodeStream stream(data);
+ dataElement->encode(stream);
+ _attributeValuePairSet->add(getAttributeHandle(i), data.data(), data.size());
+ }
+
+ if (!_attributeValuePairSet->size())
+ return;
+
+ ambassador->updateAttributeValues(_handle, *_attributeValuePairSet, timeStamp, tag);
+
+ for (unsigned i = 0; i < numAttributes; ++i) {
+ setAttributeUpdated(i);
+ }
+
+ } catch (RTI::ObjectNotKnown& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::AttributeNotDefined& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::AttributeNotOwned& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::InvalidFederationTime& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
+ }
+
+ // That means clear()
+ _attributeValuePairSet->empty();
+}
+
+void
+RTI13ObjectInstance::attributesInScope(const RTI::AttributeHandleSet& attributeHandleSet)
+{
+ RTI::ULong numAttribs = attributeHandleSet.size();
+ for (RTI::ULong i = 0; i < numAttribs; ++i) {
+ RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
+ setAttributeInScope(getAttributeIndex(attributeHandle), true);
+ }
+}
+
+void
+RTI13ObjectInstance::attributesOutOfScope(const RTI::AttributeHandleSet& attributeHandleSet)
+{
+ RTI::ULong numAttribs = attributeHandleSet.size();
+ for (RTI::ULong i = 0; i < numAttribs; ++i) {
+ RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
+ setAttributeInScope(getAttributeIndex(attributeHandle), false);
+ }
+}
+
+void
+RTI13ObjectInstance::turnUpdatesOnForObjectInstance(const RTI::AttributeHandleSet& attributeHandleSet)
+{
+ RTI::ULong numAttribs = attributeHandleSet.size();
+ for (RTI::ULong i = 0; i < numAttribs; ++i) {
+ RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
+ setAttributeUpdateEnabled(getAttributeIndex(attributeHandle), true);
+ }
+}
+
+void
+RTI13ObjectInstance::turnUpdatesOffForObjectInstance(const RTI::AttributeHandleSet& attributeHandleSet)
+{
+ RTI::ULong numAttribs = attributeHandleSet.size();
+ for (RTI::ULong i = 0; i < numAttribs; ++i) {
+ RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
+ setAttributeUpdateEnabled(getAttributeIndex(attributeHandle), false);
+ }
+}
+
+void
+RTI13ObjectInstance::requestAttributeOwnershipAssumption(const RTI::AttributeHandleSet& attributes, const RTIData& tag)
+{
+}
+
+void
+RTI13ObjectInstance::attributeOwnershipDivestitureNotification(const RTI::AttributeHandleSet& attributes)
+{
+}
+
+void
+RTI13ObjectInstance::attributeOwnershipAcquisitionNotification(const RTI::AttributeHandleSet& attributes)
+{
+}
+
+void
+RTI13ObjectInstance::attributeOwnershipUnavailable(const RTI::AttributeHandleSet& attributes)
+{
+}
+
+void
+RTI13ObjectInstance::requestAttributeOwnershipRelease(const RTI::AttributeHandleSet& attributes, const RTIData& tag)
+{
+}
+
+void
+RTI13ObjectInstance::confirmAttributeOwnershipAcquisitionCancellation(const RTI::AttributeHandleSet& attributes)
+{
+}
+
+void
+RTI13ObjectInstance::informAttributeOwnership(RTI::AttributeHandle attributeHandle, RTI::FederateHandle federateHandle)
+{
+}
+
+void
+RTI13ObjectInstance::attributeIsNotOwned(RTI::AttributeHandle attributeHandle)
+{
+}
+
+void
+RTI13ObjectInstance::attributeOwnedByRTI(RTI::AttributeHandle attributeHandle)
+{
+}
+
+}
--- /dev/null
+// Copyright (C) 2009 - 2010 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 RTI13ObjectInstance_hxx
+#define RTI13ObjectInstance_hxx
+
+#include <map>
+#include <memory>
+
+#ifndef RTI_USES_STD_FSTREAM
+#define RTI_USES_STD_FSTREAM
+#endif
+
+#include <RTI.hh>
+
+#include <simgear/structure/SGWeakPtr.hxx>
+
+#include "RTIObjectInstance.hxx"
+#include "RTI13ObjectClass.hxx"
+
+namespace simgear {
+
+class RTI13Ambassador;
+class RTI13ObjectClass;
+
+class RTI13ObjectInstance : public RTIObjectInstance {
+public:
+ RTI13ObjectInstance(const RTI::ObjectHandle& handle, HLAObjectInstance* hlaObjectInstance, const RTI13ObjectClass* objectClass, RTI13Ambassador* ambassador, bool owned);
+ virtual ~RTI13ObjectInstance();
+
+ const RTI::ObjectHandle& getHandle() const
+ { return _handle; }
+ void setHandle(const RTI::ObjectHandle& handle)
+ { _handle = handle; }
+
+ virtual const RTIObjectClass* getObjectClass() const;
+ const RTI13ObjectClass* get13ObjectClass() 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
+ { return get13ObjectClass()->getAttributeHandle(index); }
+
+ virtual std::string getName() const;
+
+ virtual void addToRequestQueue();
+
+ virtual void deleteObjectInstance(const RTIData& tag);
+ virtual void deleteObjectInstance(const SGTimeStamp& timeStamp, const RTIData& tag);
+ virtual void localDeleteObjectInstance();
+
+ void reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const RTIData& tag);
+ void reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const SGTimeStamp& timeStamp, const RTIData& tag);
+ virtual void requestObjectAttributeValueUpdate();
+ void provideAttributeValueUpdate(const RTI::AttributeHandleSet& attributes);
+
+ virtual void updateAttributeValues(const RTIData& tag);
+ virtual void updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag);
+
+ void attributesInScope(const RTI::AttributeHandleSet& attributes);
+ void attributesOutOfScope(const RTI::AttributeHandleSet& attributes);
+
+ void turnUpdatesOnForObjectInstance(const RTI::AttributeHandleSet& attributes);
+ void turnUpdatesOffForObjectInstance(const RTI::AttributeHandleSet& attributes);
+
+ // Not yet sure what to do here. But the dispatch functions are already there
+ void requestAttributeOwnershipAssumption(const RTI::AttributeHandleSet& attributes, const RTIData& tag);
+ void attributeOwnershipDivestitureNotification(const RTI::AttributeHandleSet& attributes);
+ void attributeOwnershipAcquisitionNotification(const RTI::AttributeHandleSet& attributes);
+ void attributeOwnershipUnavailable(const RTI::AttributeHandleSet& attributes);
+ void requestAttributeOwnershipRelease(const RTI::AttributeHandleSet& attributes, const RTIData& tag);
+ void confirmAttributeOwnershipAcquisitionCancellation(const RTI::AttributeHandleSet& attributes);
+ void informAttributeOwnership(RTI::AttributeHandle attributeHandle, RTI::FederateHandle federateHandle);
+ void attributeIsNotOwned(RTI::AttributeHandle attributeHandle);
+ void attributeOwnedByRTI(RTI::AttributeHandle attributeHandle);
+
+private:
+ RTI::ObjectHandle _handle;
+ SGSharedPtr<const RTI13ObjectClass> _objectClass;
+ SGWeakPtr<RTI13Ambassador> _ambassador;
+
+ // cached storage for updates
+ std::auto_ptr<RTI::AttributeHandleValuePairSet> _attributeValuePairSet;
+};
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 RTIData_hxx
+#define RTIData_hxx
+
+#include <cstring>
+#include <list>
+#include <simgear/misc/stdint.hxx>
+
+namespace simgear {
+
+/// Sigh, this is std::vector<char>, except that
+/// you could feed that with external pointers without copying ...
+/// Note on alignment: the c++ standard garantees (5.3.4.10) that
+/// new (unsigned) char returns sufficiently aligned memory
+/// for all relevant cases
+class RTIData {
+public:
+ RTIData() :
+ _data(0),
+ _size(0),
+ _capacity(0)
+ { }
+ RTIData(unsigned size) :
+ _data(0),
+ _size(0),
+ _capacity(0)
+ { resize(size); }
+ RTIData(char* data, unsigned size) :
+ _data(data),
+ _size(size),
+ _capacity(0)
+ { }
+ RTIData(const char* data, unsigned size) :
+ _data(0),
+ _size(0),
+ _capacity(0)
+ { setData(data, size); }
+ RTIData(const char* data) :
+ _data(0),
+ _size(0),
+ _capacity(0)
+ { setData(data); }
+ RTIData(const RTIData& data) :
+ _data(0),
+ _size(0),
+ _capacity(0)
+ {
+ unsigned size = data.size();
+ if (size) {
+ resize(size);
+ memcpy(_data, data.data(), size);
+ }
+ }
+ ~RTIData()
+ {
+ if (_capacity)
+ delete [] _data;
+ _data = 0;
+ }
+
+ const char* data() const
+ { return _data; }
+ char* data()
+ { return _data; }
+
+ unsigned size() const
+ { return _size; }
+
+ bool empty() const
+ { return _size == 0; }
+
+ void clear()
+ {
+ if (_capacity == 0) {
+ _data = 0;
+ _size = 0;
+ } else
+ resize(0);
+ }
+
+ void resize(unsigned size)
+ {
+ if (size == _size)
+ return;
+ if (_capacity < size) {
+ unsigned capacity = 2*_capacity;
+ if (size < capacity)
+ ensureCapacity(capacity);
+ else
+ ensureCapacity(size);
+ }
+ _size = size;
+ }
+
+ void reserve(unsigned capacity)
+ {
+ if (capacity <= _capacity)
+ return;
+ ensureCapacity(capacity);
+ }
+
+ void setData(char* data, unsigned size)
+ {
+ if (_capacity)
+ delete [] _data;
+ _data = data;
+ _size = size;
+ _capacity = 0;
+ }
+ void setData(const char* data, unsigned size)
+ {
+ resize(size);
+ if (!size)
+ return;
+ memcpy(_data, data, size);
+ }
+ void setData(const char* data)
+ {
+ if (!data) {
+ setData("", 1);
+ } else {
+ size_t size = strlen(data) + 1;
+ setData(data, size);
+ }
+ }
+
+ RTIData& operator=(const RTIData& data)
+ {
+ unsigned size = data.size();
+ if (size) {
+ resize(size);
+ memcpy(_data, data.data(), size);
+ }
+ return *this;
+ }
+
+ void getData8(char data[1], unsigned offset = 0) const
+ {
+ data[0] = _data[offset];
+ }
+
+ void setData8(const char data[1], unsigned offset = 0)
+ {
+ _data[offset] = data[0];
+ }
+
+ void getData16LE(char data[2], unsigned offset = 0) const
+ {
+ if (hostIsLittleEndian()) {
+ data[0] = _data[offset];
+ data[1] = _data[offset+1];
+ } else {
+ data[1] = _data[offset];
+ data[0] = _data[offset+1];
+ }
+ }
+ void setData16LE(const char data[2], unsigned offset = 0)
+ {
+ if (hostIsLittleEndian()) {
+ _data[offset] = data[0];
+ _data[offset+1] = data[1];
+ } else {
+ _data[offset] = data[1];
+ _data[offset+1] = data[0];
+ }
+ }
+
+ void getData16BE(char data[2], unsigned offset = 0) const
+ {
+ if (hostIsLittleEndian()) {
+ data[1] = _data[offset];
+ data[0] = _data[offset+1];
+ } else {
+ data[0] = _data[offset];
+ data[1] = _data[offset+1];
+ }
+ }
+ void setData16BE(const char data[2], unsigned offset = 0)
+ {
+ if (hostIsLittleEndian()) {
+ _data[offset] = data[1];
+ _data[offset+1] = data[0];
+ } else {
+ _data[offset] = data[0];
+ _data[offset+1] = data[1];
+ }
+ }
+
+
+ void getData32LE(char data[4], unsigned offset = 0) const
+ {
+ if (hostIsLittleEndian()) {
+ data[0] = _data[offset];
+ data[1] = _data[offset+1];
+ data[2] = _data[offset+2];
+ data[3] = _data[offset+3];
+ } else {
+ data[3] = _data[offset];
+ data[2] = _data[offset+1];
+ data[1] = _data[offset+2];
+ data[0] = _data[offset+3];
+ }
+ }
+ void setData32LE(const char data[4], unsigned offset = 0)
+ {
+ if (hostIsLittleEndian()) {
+ _data[offset] = data[0];
+ _data[offset+1] = data[1];
+ _data[offset+2] = data[2];
+ _data[offset+3] = data[3];
+ } else {
+ _data[offset] = data[3];
+ _data[offset+1] = data[2];
+ _data[offset+2] = data[1];
+ _data[offset+3] = data[0];
+ }
+ }
+
+ void getData32BE(char data[4], unsigned offset = 0) const
+ {
+ if (hostIsLittleEndian()) {
+ data[3] = _data[offset];
+ data[2] = _data[offset+1];
+ data[1] = _data[offset+2];
+ data[0] = _data[offset+3];
+ } else {
+ data[0] = _data[offset];
+ data[1] = _data[offset+1];
+ data[2] = _data[offset+2];
+ data[3] = _data[offset+3];
+ }
+ }
+ void setData32BE(const char data[4], unsigned offset = 0)
+ {
+ if (hostIsLittleEndian()) {
+ _data[offset] = data[3];
+ _data[offset+1] = data[2];
+ _data[offset+2] = data[1];
+ _data[offset+3] = data[0];
+ } else {
+ _data[offset] = data[0];
+ _data[offset+1] = data[1];
+ _data[offset+2] = data[2];
+ _data[offset+3] = data[3];
+ }
+ }
+
+
+ void getData64LE(char data[8], unsigned offset = 0) const
+ {
+ if (hostIsLittleEndian()) {
+ data[0] = _data[offset];
+ data[1] = _data[offset+1];
+ data[2] = _data[offset+2];
+ data[3] = _data[offset+3];
+ data[4] = _data[offset+4];
+ data[5] = _data[offset+5];
+ data[6] = _data[offset+6];
+ data[7] = _data[offset+7];
+ } else {
+ data[7] = _data[offset];
+ data[6] = _data[offset+1];
+ data[5] = _data[offset+2];
+ data[4] = _data[offset+3];
+ data[3] = _data[offset+4];
+ data[2] = _data[offset+5];
+ data[1] = _data[offset+6];
+ data[0] = _data[offset+7];
+ }
+ }
+ void setData64LE(const char data[8], unsigned offset = 0)
+ {
+ if (hostIsLittleEndian()) {
+ _data[offset] = data[0];
+ _data[offset+1] = data[1];
+ _data[offset+2] = data[2];
+ _data[offset+3] = data[3];
+ _data[offset+4] = data[4];
+ _data[offset+5] = data[5];
+ _data[offset+6] = data[6];
+ _data[offset+7] = data[7];
+ } else {
+ _data[offset] = data[7];
+ _data[offset+1] = data[6];
+ _data[offset+2] = data[5];
+ _data[offset+3] = data[4];
+ _data[offset+4] = data[3];
+ _data[offset+5] = data[2];
+ _data[offset+6] = data[1];
+ _data[offset+7] = data[0];
+ }
+ }
+
+ void getData64BE(char data[8], unsigned offset = 0) const
+ {
+ if (hostIsLittleEndian()) {
+ data[7] = _data[offset];
+ data[6] = _data[offset+1];
+ data[5] = _data[offset+2];
+ data[4] = _data[offset+3];
+ data[3] = _data[offset+4];
+ data[2] = _data[offset+5];
+ data[1] = _data[offset+6];
+ data[0] = _data[offset+7];
+ } else {
+ data[0] = _data[offset];
+ data[1] = _data[offset+1];
+ data[2] = _data[offset+2];
+ data[3] = _data[offset+3];
+ data[4] = _data[offset+4];
+ data[5] = _data[offset+5];
+ data[6] = _data[offset+6];
+ data[7] = _data[offset+7];
+ }
+ }
+ void setData64BE(const char data[8], unsigned offset = 0)
+ {
+ if (hostIsLittleEndian()) {
+ _data[offset] = data[7];
+ _data[offset+1] = data[6];
+ _data[offset+2] = data[5];
+ _data[offset+3] = data[4];
+ _data[offset+4] = data[3];
+ _data[offset+5] = data[2];
+ _data[offset+6] = data[1];
+ _data[offset+7] = data[0];
+ } else {
+ _data[offset] = data[0];
+ _data[offset+1] = data[1];
+ _data[offset+2] = data[2];
+ _data[offset+3] = data[3];
+ _data[offset+4] = data[4];
+ _data[offset+5] = data[5];
+ _data[offset+6] = data[6];
+ _data[offset+7] = data[7];
+ }
+ }
+
+
+#define TYPED_GETSET_IMPLEMENTATION(type, base, suffix) \
+ type get##base##suffix(unsigned offset = 0) const \
+ { \
+ union { \
+ type t; \
+ char u8[sizeof(type)]; \
+ } u; \
+ getData##suffix(u.u8, offset); \
+ return u.t; \
+ } \
+ void set##base##suffix(type value, unsigned offset = 0) \
+ { \
+ union { \
+ type t; \
+ char u8[sizeof(type)]; \
+ } u; \
+ u.t = value; \
+ setData##suffix(u.u8, offset); \
+ }
+
+ TYPED_GETSET_IMPLEMENTATION(uint8_t, UInt, 8)
+ TYPED_GETSET_IMPLEMENTATION(int8_t, Int, 8)
+ TYPED_GETSET_IMPLEMENTATION(uint16_t, UInt, 16LE)
+ TYPED_GETSET_IMPLEMENTATION(uint16_t, UInt, 16BE)
+ TYPED_GETSET_IMPLEMENTATION(int16_t, Int, 16LE)
+ TYPED_GETSET_IMPLEMENTATION(int16_t, Int, 16BE)
+ TYPED_GETSET_IMPLEMENTATION(uint32_t, UInt, 32LE)
+ TYPED_GETSET_IMPLEMENTATION(uint32_t, UInt, 32BE)
+ TYPED_GETSET_IMPLEMENTATION(int32_t, Int, 32LE)
+ TYPED_GETSET_IMPLEMENTATION(int32_t, Int, 32BE)
+ TYPED_GETSET_IMPLEMENTATION(uint64_t, UInt, 64LE)
+ TYPED_GETSET_IMPLEMENTATION(uint64_t, UInt, 64BE)
+ TYPED_GETSET_IMPLEMENTATION(int64_t, Int, 64LE)
+ TYPED_GETSET_IMPLEMENTATION(int64_t, Int, 64BE)
+
+ TYPED_GETSET_IMPLEMENTATION(float, Float, 32LE)
+ TYPED_GETSET_IMPLEMENTATION(float, Float, 32BE)
+ TYPED_GETSET_IMPLEMENTATION(double, Float, 64LE)
+ TYPED_GETSET_IMPLEMENTATION(double, Float, 64BE)
+
+#undef TYPED_GETSET_IMPLEMENTATION
+
+private:
+ static inline bool hostIsLittleEndian()
+ {
+ union {
+ uint16_t u16;
+ uint8_t u8[2];
+ } u;
+ u.u16 = 1;
+ return u.u8[0] == 1;
+ }
+
+ void ensureCapacity(unsigned capacity)
+ {
+ if (capacity < 32)
+ capacity = 32;
+ char* data = new char[capacity];
+ if (_size)
+ memcpy(data, _data, _size);
+ if (_capacity)
+ delete [] _data;
+ _data = data;
+ _capacity = capacity;
+ }
+
+ char* _data;
+ unsigned _size;
+ unsigned _capacity;
+};
+
+// A single attribute/parameter update blob
+typedef std::pair<unsigned, RTIData> RTIIndexDataPair;
+
+// A complete set of updates we received in one reflect/receive call
+typedef std::list<RTIIndexDataPair> RTIIndexDataPairList;
+
+/// Gets an own header at some time
+
+class RTIBasicDataStream {
+public:
+ RTIBasicDataStream() : _offset(0) {}
+
+ /// Get aligned offset that aligns to a multiple of size
+ static inline unsigned getAlignedOffset(unsigned offset, unsigned size)
+ {
+ return ((offset + size - 1)/size) * size;
+ }
+
+protected:
+ unsigned _offset;
+};
+
+class HLADecodeStream : public RTIBasicDataStream {
+public:
+ HLADecodeStream(const RTIData& value) :
+ _value(value)
+ { }
+
+ bool alignOffsetForSize(unsigned size)
+ {
+ _offset = getAlignedOffset(_offset, size);
+ return _offset <= _value.size();
+ }
+
+ bool skip(unsigned size)
+ {
+ _offset += size;
+ return _offset <= _value.size();
+ }
+
+ bool eof() const
+ { return _value.size() <= _offset; }
+
+ const RTIData& getData() const
+ { return _value; }
+
+#define TYPED_READ_IMPLEMENTATION(type, base, suffix) \
+ bool decode##base##suffix(type& value) \
+ { \
+ if (_value.size() < _offset + sizeof(type)) \
+ return false; \
+ value = _value.get##base##suffix(_offset); \
+ _offset += sizeof(type); \
+ return true; \
+ }
+
+ TYPED_READ_IMPLEMENTATION(uint8_t, UInt, 8)
+ TYPED_READ_IMPLEMENTATION(int8_t, Int, 8)
+ TYPED_READ_IMPLEMENTATION(uint16_t, UInt, 16LE)
+ TYPED_READ_IMPLEMENTATION(uint16_t, UInt, 16BE)
+ TYPED_READ_IMPLEMENTATION(int16_t, Int, 16LE)
+ TYPED_READ_IMPLEMENTATION(int16_t, Int, 16BE)
+ TYPED_READ_IMPLEMENTATION(uint32_t, UInt, 32LE)
+ TYPED_READ_IMPLEMENTATION(uint32_t, UInt, 32BE)
+ TYPED_READ_IMPLEMENTATION(int32_t, Int, 32LE)
+ TYPED_READ_IMPLEMENTATION(int32_t, Int, 32BE)
+ TYPED_READ_IMPLEMENTATION(uint64_t, UInt, 64LE)
+ TYPED_READ_IMPLEMENTATION(uint64_t, UInt, 64BE)
+ TYPED_READ_IMPLEMENTATION(int64_t, Int, 64LE)
+ TYPED_READ_IMPLEMENTATION(int64_t, Int, 64BE)
+
+ TYPED_READ_IMPLEMENTATION(float, Float, 32LE)
+ TYPED_READ_IMPLEMENTATION(float, Float, 32BE)
+ TYPED_READ_IMPLEMENTATION(double, Float, 64LE)
+ TYPED_READ_IMPLEMENTATION(double, Float, 64BE)
+
+#undef TYPED_READ_IMPLEMENTATION
+
+private:
+ const RTIData& _value;
+};
+
+class HLAEncodeStream : public RTIBasicDataStream {
+public:
+ HLAEncodeStream(RTIData& value) :
+ _value(value)
+ { }
+
+ bool alignOffsetForSize(unsigned size)
+ {
+ _offset = getAlignedOffset(_offset, size);
+ _value.resize(_offset);
+ return true;
+ }
+
+ bool skip(unsigned size)
+ {
+ _offset += size;
+ _value.resize(_offset);
+ return true;
+ }
+
+ bool eof() const
+ { return _value.size() <= _offset; }
+
+ void setData(const RTIData& data)
+ { _value = data; }
+
+#define TYPED_WRITE_IMPLEMENTATION(type, base, suffix) \
+ bool encode##base##suffix(type value) \
+ { \
+ unsigned nextOffset = _offset + sizeof(type); \
+ _value.resize(nextOffset); \
+ _value.set##base##suffix(value, _offset); \
+ _offset = nextOffset; \
+ return true; \
+ }
+
+ TYPED_WRITE_IMPLEMENTATION(uint8_t, UInt, 8)
+ TYPED_WRITE_IMPLEMENTATION(int8_t, Int, 8)
+ TYPED_WRITE_IMPLEMENTATION(uint16_t, UInt, 16LE)
+ TYPED_WRITE_IMPLEMENTATION(uint16_t, UInt, 16BE)
+ TYPED_WRITE_IMPLEMENTATION(int16_t, Int, 16LE)
+ TYPED_WRITE_IMPLEMENTATION(int16_t, Int, 16BE)
+ TYPED_WRITE_IMPLEMENTATION(uint32_t, UInt, 32LE)
+ TYPED_WRITE_IMPLEMENTATION(uint32_t, UInt, 32BE)
+ TYPED_WRITE_IMPLEMENTATION(int32_t, Int, 32LE)
+ TYPED_WRITE_IMPLEMENTATION(int32_t, Int, 32BE)
+ TYPED_WRITE_IMPLEMENTATION(uint64_t, UInt, 64LE)
+ TYPED_WRITE_IMPLEMENTATION(uint64_t, UInt, 64BE)
+ TYPED_WRITE_IMPLEMENTATION(int64_t, Int, 64LE)
+ TYPED_WRITE_IMPLEMENTATION(int64_t, Int, 64BE)
+
+ TYPED_WRITE_IMPLEMENTATION(float, Float, 32LE)
+ TYPED_WRITE_IMPLEMENTATION(float, Float, 32BE)
+ TYPED_WRITE_IMPLEMENTATION(double, Float, 64LE)
+ TYPED_WRITE_IMPLEMENTATION(double, Float, 64BE)
+
+#undef TYPED_WRITE_IMPLEMENTATION
+
+private:
+ RTIData& _value;
+};
+
+} // namespace simgear
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "RTIFederate.hxx"
+
+namespace simgear {
+
+RTIFederate::RTIFederate()
+{
+}
+
+RTIFederate::~RTIFederate()
+{
+}
+
+}
--- /dev/null
+// Copyright (C) 2009 - 2010 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 RTIFederate_hxx
+#define RTIFederate_hxx
+
+#include <string>
+#include "simgear/structure/SGWeakReferenced.hxx"
+#include "RTIObjectClass.hxx"
+#include "RTIObjectInstance.hxx"
+
+class SGTimeStamp;
+
+namespace simgear {
+
+class RTIFederate : public SGWeakReferenced {
+public:
+ RTIFederate();
+ virtual ~RTIFederate();
+
+ /// Get the name of the joined federate/federation
+ const std::string& getFederateType() const
+ { return _federateType; }
+ const std::string& getFederationName() const
+ { return _federationName; }
+
+ /// Create a federation execution
+ /// Semantically this methods should be static,
+ /// but the nonstatic case could reuse the connection to the server
+ /// FIXME: cannot determine from the return value if we created the execution
+ virtual bool createFederationExecution(const std::string& federation, const std::string& objectModel) = 0;
+ virtual bool destroyFederationExecution(const std::string& federation) = 0;
+
+ /// Join with federateName the federation execution federation
+ virtual bool join(const std::string& federateType, const std::string& federation) = 0;
+ virtual bool resign() = 0;
+
+ /// Synchronization Point handling
+ virtual bool registerFederationSynchronizationPoint(const std::string& label, const RTIData& tag) = 0;
+ virtual bool waitForFederationSynchronizationPointAnnounced(const std::string& label) = 0;
+ virtual bool synchronizationPointAchieved(const std::string& label) = 0;
+ virtual bool waitForFederationSynchronized(const std::string& label) = 0;
+
+ /// Time management
+ virtual bool enableTimeConstrained() = 0;
+ virtual bool disableTimeConstrained() = 0;
+
+ virtual bool enableTimeRegulation(const SGTimeStamp& lookahead) = 0;
+ virtual bool disableTimeRegulation() = 0;
+
+ virtual bool timeAdvanceRequestBy(const SGTimeStamp& dt) = 0;
+ virtual bool timeAdvanceRequest(const SGTimeStamp& fedTime) = 0;
+
+ /// Process messages
+ virtual bool tick() = 0;
+ virtual bool tick(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 RTIObjectInstance* getObjectInstance(const std::string& name) = 0;
+
+protected:
+ void setFederateType(const std::string& federateType)
+ { _federateType = federateType; }
+ void setFederationName(const std::string& federationName)
+ { _federationName = federationName; }
+
+private:
+ RTIFederate(const RTIFederate&);
+ RTIFederate& operator=(const RTIFederate&);
+
+ /// The federates name
+ std::string _federateType;
+
+ /// The federation execution name
+ std::string _federationName;
+};
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 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 RTIInteractionClass : public SGReferenced {
+public:
+ RTIInteractionClass(const std::string& name);
+ 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 publish(const std::set<unsigned>& indexSet) = 0;
+ virtual bool unpublish() = 0;
+
+ virtual bool subscribe(const std::set<unsigned>& indexSet, 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() {}
+ };
+
+private:
+ std::string _name;
+};
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "RTIObjectClass.hxx"
+
+#include "RTIObjectInstance.hxx"
+
+namespace simgear {
+
+RTIObjectClass::RTIObjectClass(HLAObjectClass* hlaObjectClass) :
+ _hlaObjectClass(hlaObjectClass)
+{
+}
+
+RTIObjectClass::~RTIObjectClass()
+{
+}
+
+void
+RTIObjectClass::discoverInstance(RTIObjectInstance* objectInstance, const RTIData& tag) const
+{
+ SGSharedPtr<HLAObjectClass> hlaObjectClass = _hlaObjectClass.lock();
+ if (!hlaObjectClass.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Invalid hla object class pointer in RTIObjectClass::discoverInstance().");
+ return;
+ }
+ hlaObjectClass->discoverInstance(objectInstance, tag);
+}
+
+void
+RTIObjectClass::startRegistration() const
+{
+ SGSharedPtr<HLAObjectClass> hlaObjectClass = _hlaObjectClass.lock();
+ if (!hlaObjectClass.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Invalid hla object class pointer in RTIObjectClass::startRegstration().");
+ return;
+ }
+ hlaObjectClass->startRegistrationCallback();
+}
+
+void
+RTIObjectClass::stopRegistration() const
+{
+ SGSharedPtr<HLAObjectClass> hlaObjectClass = _hlaObjectClass.lock();
+ if (!hlaObjectClass.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Invalid hla object class pointer in RTIObjectClass::stopRegistration().");
+ return;
+ }
+ hlaObjectClass->stopRegistrationCallback();
+}
+
+}
--- /dev/null
+// Copyright (C) 2009 - 2010 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 RTIObjectClass_hxx
+#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 RTIObjectInstance;
+class HLAObjectClass;
+
+class RTIObjectClass : public SGReferenced {
+public:
+ RTIObjectClass(HLAObjectClass* hlaObjectClass);
+ virtual ~RTIObjectClass();
+
+ virtual std::string getName() const = 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 unpublish() = 0;
+
+ virtual bool subscribe(const std::set<unsigned>& indexSet, 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;
+
+ 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;
+};
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2010 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 "RTIObjectInstance.hxx"
+#include "RTIObjectClass.hxx"
+#include "HLAObjectInstance.hxx"
+
+namespace simgear {
+
+RTIObjectInstance::RTIObjectInstance(HLAObjectInstance* hlaObjectInstance) :
+ _hlaObjectInstance(hlaObjectInstance),
+ _pendingAttributeUpdateRequest(false)
+{
+}
+
+RTIObjectInstance::~RTIObjectInstance()
+{
+}
+
+unsigned
+RTIObjectInstance::getNumAttributes() const
+{
+ 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())
+ return;
+ hlaObjectInstance->removeInstance(tag);
+}
+
+void
+RTIObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList, 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())
+ return;
+ hlaObjectInstance->reflectAttributeValues(dataPairList, tag);
+}
+
+void
+RTIObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList,
+ 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())
+ return;
+ hlaObjectInstance->reflectAttributeValues(dataPairList, timeStamp, tag);
+}
+
+}
--- /dev/null
+// Copyright (C) 2009 - 2010 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 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"
+#include "HLADataElement.hxx"
+
+class SGTimeStamp;
+
+namespace simgear {
+
+class RTIObjectClass;
+class HLAObjectInstance;
+
+class RTIObjectInstance : public SGReferenced {
+public:
+ RTIObjectInstance(HLAObjectInstance* hlaObjectInstance);
+ virtual ~RTIObjectInstance();
+
+ 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;
+
+ // FIXME: factor out an ambassador base
+ virtual void addToRequestQueue() = 0;
+
+ 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 updateAttributeValues(const RTIData& tag) = 0;
+ virtual void updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag) = 0;
+
+ void removeInstance(const RTIData& tag);
+ // Call this if you want to roll up the queued timestamed updates
+ // and reflect that into the attached data elements.
+ void reflectQueuedAttributeValues(const SGTimeStamp& timeStamp)
+ {
+ // replay all updates up to the given timestamp
+ UpdateListMap::iterator last = _updateListMap.upper_bound(timeStamp);
+ for (UpdateListMap::iterator i = _updateListMap.begin(); i != last; ++i) {
+ for (UpdateList::iterator j = i->second.begin(); j != i->second.end(); ++j) {
+ // FIXME have a variant that takes the timestamp?
+ reflectAttributeValues(j->_indexDataPairList, j->_tag);
+ }
+ putUpdateToPool(i->second);
+ }
+ }
+ 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);
+ }
+
+ const HLADataType* getAttributeDataType(unsigned i) const
+ {
+ 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);
+ }
+
+ 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)
+ {
+ if (_attributeData.size() <= i)
+ return;
+ _attributeData[i]._dataElement = dataElement;
+ }
+
+ void updateAttributesFromClass(bool owned)
+ {
+ // 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);
+ }
+ }
+ _attributeData.resize(numAttributes);
+ for (; i < numAttributes; ++i) {
+ if (getAttributePublished(i)) {
+ _attributeData[i].setUpdateEnabled(true);
+ _attributeData[i].setOwned(owned);
+ } else {
+ _attributeData[i].setUpdateEnabled(false);
+ _attributeData[i].setOwned(false);
+ }
+ }
+ }
+
+ void setAttributeForceUpdate(unsigned i)
+ {
+ if (_attributeData.size() <= i)
+ return;
+ _attributeData[i].setForceUpdate(true);
+ }
+ void setAttributeInScope(unsigned i, bool inScope)
+ {
+ if (_attributeData.size() <= i)
+ return;
+ _attributeData[i].setInScope(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;
+ addToRequestQueue();
+ }
+ }
+ }
+ bool getRequestAttributeUpdate(unsigned i) const
+ {
+ if (_attributeData.size() <= i)
+ return false;
+ return _attributeData[i]._requestUpdate;
+ }
+
+ void flushPendingRequests()
+ {
+ if (_pendingAttributeUpdateRequest) {
+ requestObjectAttributeValueUpdate();
+ _pendingAttributeUpdateRequest = false;
+ }
+ }
+
+protected:
+ // The backward reference to the user visible object
+ SGWeakPtr<HLAObjectInstance> _hlaObjectInstance;
+
+ // Is true if we should emit a requestattr
+ bool _pendingAttributeUpdateRequest;
+
+ // Contains a full update as it came in from the RTI
+ struct Update {
+ RTIIndexDataPairList _indexDataPairList;
+ RTIData _tag;
+ };
+ // A bunch of updates for the same timestamp
+ typedef std::list<Update> UpdateList;
+ // The timestamp sorted list of updates
+ typedef std::map<SGTimeStamp, UpdateList> UpdateListMap;
+
+ // The timestamped updates sorted by timestamp
+ UpdateListMap _updateListMap;
+
+ // The pool of unused updates so that we do not need to malloc/free each time
+ UpdateList _updateList;
+
+ void getUpdateFromPool(UpdateList& updateList)
+ {
+ if (_updateList.empty())
+ updateList.push_back(Update());
+ else
+ updateList.splice(updateList.end(), _updateList, _updateList.begin());
+ }
+ void putUpdateToPool(UpdateList& updateList)
+ {
+ for (UpdateList::iterator i = updateList.begin(); i != updateList.end(); ++i)
+ putDataToPool(i->_indexDataPairList);
+ _updateList.splice(_updateList.end(), updateList);
+ }
+
+ // Appends the updates in the list to the given timestamps updates
+ void scheduleUpdates(const SGTimeStamp& timeStamp, UpdateList& updateList)
+ {
+ UpdateListMap::iterator i = _updateListMap.find(timeStamp);
+ if (i == _updateListMap.end())
+ i = _updateListMap.insert(UpdateListMap::value_type(timeStamp, UpdateList())).first;
+ i->second.splice(i->second.end(), updateList);
+ }
+
+ // This adds raw storage for attribute index i to the end of the dataPairList.
+ void getDataFromPool(unsigned i, RTIIndexDataPairList& dataPairList)
+ {
+ if (_attributeData.size() <= i) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Invalid object attribute index!");
+ return;
+ }
+
+ // Nothing left in the pool - so allocate something
+ if (_attributeData[i]._indexDataPairList.empty()) {
+ dataPairList.push_back(RTIIndexDataPairList::value_type());
+ dataPairList.back().first = i;
+ return;
+ }
+
+ // Take one from the pool
+ dataPairList.splice(dataPairList.end(),
+ _attributeData[i]._indexDataPairList,
+ _attributeData[i]._indexDataPairList.begin());
+ }
+
+ void putDataToPool(RTIIndexDataPairList& dataPairList)
+ {
+ while (!dataPairList.empty()) {
+ // Put back into the pool
+ unsigned i = dataPairList.front().first;
+ if (_attributeData.size() <= i) {
+ // should not happen!!!
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Invalid object attribute index!");
+ dataPairList.pop_front();
+ } else {
+ _attributeData[i]._indexDataPairList.splice(_attributeData[i]._indexDataPairList.begin(),
+ dataPairList, dataPairList.begin());
+ }
+ }
+ }
+
+ struct AttributeData {
+ AttributeData() : _owned(false), _inScope(true), _updateEnabled(true), _forceUpdate(false), _requestUpdate(false)
+ { }
+
+ // The hla level data element with tha actual local program
+ // accessible data.
+ SGSharedPtr<HLADataElement> _dataElement;
+ // SGSharedPtr<HLADataElement::TimeStamp> _timeStamp;
+
+ // Pool of already allocated raw data used for reflection of updates
+ RTIIndexDataPairList _indexDataPairList;
+
+ 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; }
+
+ bool _owned;
+ bool _inScope;
+ bool _updateEnabled;
+ bool _forceUpdate;
+ bool _requestUpdate;
+ };
+ std::vector<AttributeData> _attributeData;
+
+ friend class HLAObjectInstance;
+};
+
+}
+
+#endif