Merge branch 'next' of gitorious.org:fg/simgear into next
This commit is contained in:
@@ -32,6 +32,9 @@ AM_INIT_AUTOMAKE([dist-bzip2])
|
||||
AC_ARG_ENABLE(headless,
|
||||
AS_HELP_STRING([--enable-headless],[Enable only packages for headless build]))
|
||||
|
||||
AC_ARG_ENABLE(osgdebug,
|
||||
AS_HELP_STRING([--enable-osgdebug],[Enable debug OSG libraries]))
|
||||
|
||||
AC_MSG_CHECKING([for headless mode])
|
||||
AC_MSG_RESULT([$enable_headless])
|
||||
|
||||
@@ -437,6 +440,8 @@ AM_CONDITIONAL(EXTGL_NEEDED, test "x$ac_cv_header_windows_h" = "xyes")
|
||||
CXXCPP="g++ -E"
|
||||
AC_LANG_PUSH(C++)
|
||||
|
||||
LIBS="$base_LIBS"
|
||||
|
||||
# OpenSceneGraph
|
||||
case "${host}" in
|
||||
*-apple-darwin*)
|
||||
@@ -497,6 +502,10 @@ if test "x$ac_cv_header_osg_Version" != "xyes" -o "x$ac_cv_lib_OpenThreads_OpenT
|
||||
fi
|
||||
fi
|
||||
|
||||
osg_LIBS="$LIBS"
|
||||
AC_SUBST(osg_LIBS)
|
||||
LIBS="$base_LIBS"
|
||||
|
||||
AC_CHECK_HEADER(boost/version.hpp)
|
||||
if test "x$ac_cv_header_boost_version_hpp" != "xyes"; then
|
||||
echo
|
||||
|
||||
@@ -26,9 +26,6 @@ set(HLA_HEADERS
|
||||
)
|
||||
|
||||
set(HLA_SOURCES
|
||||
RTIObjectClass.cxx
|
||||
RTIObjectInstance.cxx
|
||||
RTIFederate.cxx
|
||||
HLAArrayDataElement.cxx
|
||||
HLAArrayDataType.cxx
|
||||
HLABasicDataElement.cxx
|
||||
@@ -51,15 +48,18 @@ set(HLA_SOURCES
|
||||
simgear_component(hla hla "${HLA_SOURCES}" "${HLA_HEADERS}")
|
||||
|
||||
if(RTI_FOUND)
|
||||
set(HLA13_HEADERS
|
||||
HLA13Federate.hxx
|
||||
)
|
||||
set(HLA13_SOURCES
|
||||
set(RTI13_SOURCES
|
||||
RTI13ObjectClass.cxx
|
||||
RTI13ObjectInstance.cxx
|
||||
RTI13Federate.cxx
|
||||
HLA13Federate.cxx
|
||||
)
|
||||
simgear_component(hla13 hla "${HLA13_SOURCES}" "${HLA13_HEADERS}")
|
||||
set_property(TARGET sghla13 APPEND PROPERTY COMPILE_FLAGS "-I${RTI_INCLUDE_DIR}")
|
||||
simgear_component(rti13 hla "${RTI13_SOURCES}" "")
|
||||
set_property(TARGET sgrti13 APPEND PROPERTY COMPILE_FLAGS "-I${RTI_INCLUDE_DIR}")
|
||||
endif()
|
||||
|
||||
set(RTI_SOURCES
|
||||
RTIObjectClass.cxx
|
||||
RTIObjectInstance.cxx
|
||||
RTIFederate.cxx
|
||||
)
|
||||
simgear_component(rti hla "${RTI_SOURCES}" "")
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
// 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
|
||||
@@ -1,33 +0,0 @@
|
||||
// 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
|
||||
@@ -248,6 +248,43 @@ private:
|
||||
SGVec2<T> _value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class HLAVec2Data {
|
||||
public:
|
||||
HLAVec2Data() :
|
||||
_value(new HLAVec2DataElement<T>(0))
|
||||
{ }
|
||||
HLAVec2Data(const SGVec2<T>& value) :
|
||||
_value(new HLAVec2DataElement<T>(0, value))
|
||||
{ }
|
||||
|
||||
operator const SGVec2<T>&() const
|
||||
{ return _value->getValue(); }
|
||||
HLAVec2Data& operator=(const SGVec2<T>& value)
|
||||
{ _value->setValue(value); return *this; }
|
||||
|
||||
const SGVec2<T>& getValue() const
|
||||
{ return _value->getValue(); }
|
||||
void setValue(const SGVec2<T>& value)
|
||||
{ _value->setValue(value); }
|
||||
|
||||
const HLAVec2DataElement<T>* getDataElement() const
|
||||
{ return _value.get(); }
|
||||
HLAVec2DataElement<T>* getDataElement()
|
||||
{ return _value.get(); }
|
||||
|
||||
const HLAArrayDataType* getDataType() const
|
||||
{ return _value->getDataType(); }
|
||||
void setDataType(const HLAArrayDataType* dataType)
|
||||
{ _value->setDataType(dataType); }
|
||||
|
||||
private:
|
||||
SGSharedPtr<HLAVec2DataElement<T> > _value;
|
||||
};
|
||||
|
||||
typedef HLAVec2Data<float> HLAVec2fData;
|
||||
typedef HLAVec2Data<double> HLAVec2dData;
|
||||
|
||||
template<typename T>
|
||||
class HLAVec3DataElement : public HLAAbstractArrayDataElement {
|
||||
public:
|
||||
@@ -303,6 +340,43 @@ private:
|
||||
SGVec3<T> _value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class HLAVec3Data {
|
||||
public:
|
||||
HLAVec3Data() :
|
||||
_value(new HLAVec3DataElement<T>(0))
|
||||
{ }
|
||||
HLAVec3Data(const SGVec3<T>& value) :
|
||||
_value(new HLAVec3DataElement<T>(0, value))
|
||||
{ }
|
||||
|
||||
operator const SGVec3<T>&() const
|
||||
{ return _value->getValue(); }
|
||||
HLAVec3Data& operator=(const SGVec3<T>& value)
|
||||
{ _value->setValue(value); return *this; }
|
||||
|
||||
const SGVec3<T>& getValue() const
|
||||
{ return _value->getValue(); }
|
||||
void setValue(const SGVec3<T>& value)
|
||||
{ _value->setValue(value); }
|
||||
|
||||
const HLAVec3DataElement<T>* getDataElement() const
|
||||
{ return _value.get(); }
|
||||
HLAVec3DataElement<T>* getDataElement()
|
||||
{ return _value.get(); }
|
||||
|
||||
const HLAArrayDataType* getDataType() const
|
||||
{ return _value->getDataType(); }
|
||||
void setDataType(const HLAArrayDataType* dataType)
|
||||
{ _value->setDataType(dataType); }
|
||||
|
||||
private:
|
||||
SGSharedPtr<HLAVec3DataElement<T> > _value;
|
||||
};
|
||||
|
||||
typedef HLAVec3Data<float> HLAVec3fData;
|
||||
typedef HLAVec3Data<double> HLAVec3dData;
|
||||
|
||||
template<typename T>
|
||||
class HLAVec4DataElement : public HLAAbstractArrayDataElement {
|
||||
public:
|
||||
@@ -358,6 +432,43 @@ private:
|
||||
SGVec4<T> _value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class HLAVec4Data {
|
||||
public:
|
||||
HLAVec4Data() :
|
||||
_value(new HLAVec4DataElement<T>(0))
|
||||
{ }
|
||||
HLAVec4Data(const SGVec4<T>& value) :
|
||||
_value(new HLAVec4DataElement<T>(0, value))
|
||||
{ }
|
||||
|
||||
operator const SGVec4<T>&() const
|
||||
{ return _value->getValue(); }
|
||||
HLAVec4Data& operator=(const SGVec4<T>& value)
|
||||
{ _value->setValue(value); return *this; }
|
||||
|
||||
const SGVec4<T>& getValue() const
|
||||
{ return _value->getValue(); }
|
||||
void setValue(const SGVec4<T>& value)
|
||||
{ _value->setValue(value); }
|
||||
|
||||
const HLAVec4DataElement<T>* getDataElement() const
|
||||
{ return _value.get(); }
|
||||
HLAVec4DataElement<T>* getDataElement()
|
||||
{ return _value.get(); }
|
||||
|
||||
const HLAArrayDataType* getDataType() const
|
||||
{ return _value->getDataType(); }
|
||||
void setDataType(const HLAArrayDataType* dataType)
|
||||
{ _value->setDataType(dataType); }
|
||||
|
||||
private:
|
||||
SGSharedPtr<HLAVec4DataElement<T> > _value;
|
||||
};
|
||||
|
||||
typedef HLAVec4Data<float> HLAVec4fData;
|
||||
typedef HLAVec4Data<double> HLAVec4dData;
|
||||
|
||||
template<typename T>
|
||||
class HLAQuatDataElement : public HLAAbstractArrayDataElement {
|
||||
public:
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "HLAFederate.hxx"
|
||||
|
||||
#include "RTI13Federate.hxx"
|
||||
#include "RTIFederate.hxx"
|
||||
#include "RTIInteractionClass.hxx"
|
||||
#include "RTIObjectClass.hxx"
|
||||
@@ -26,8 +27,7 @@
|
||||
|
||||
namespace simgear {
|
||||
|
||||
HLAFederate::HLAFederate(const SGSharedPtr<RTIFederate>& rtiFederate) :
|
||||
_rtiFederate(rtiFederate)
|
||||
HLAFederate::HLAFederate()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -35,99 +35,209 @@ HLAFederate::~HLAFederate()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string&
|
||||
std::string
|
||||
HLAFederate::getFederateType() const
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return std::string();
|
||||
}
|
||||
return _rtiFederate->getFederateType();
|
||||
}
|
||||
|
||||
const std::string&
|
||||
std::string
|
||||
HLAFederate::getFederationName() const
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return std::string();
|
||||
}
|
||||
return _rtiFederate->getFederationName();
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::connect(Version version, const std::list<std::string>& stringList)
|
||||
{
|
||||
if (_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Trying to connect to already connected federate!");
|
||||
return false;
|
||||
}
|
||||
switch (version) {
|
||||
case RTI13:
|
||||
_rtiFederate = new RTI13Federate(stringList);
|
||||
break;
|
||||
case RTI1516:
|
||||
SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516 not yet(!?) supported.");
|
||||
// _rtiFederate = new RTI1516Federate(stringList);
|
||||
break;
|
||||
case RTI1516E:
|
||||
SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516E not yet(!?) supported.");
|
||||
// _rtiFederate = new RTI1516eFederate(stringList);
|
||||
break;
|
||||
default:
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Unknown rti version in connect!");
|
||||
}
|
||||
return _rtiFederate.valid();
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::disconnect()
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
_rtiFederate = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::createFederationExecution(const std::string& federation, const std::string& objectModel)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->createFederationExecution(federation, objectModel);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::destroyFederationExecution(const std::string& federation)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->destroyFederationExecution(federation);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::join(const std::string& federateType, const std::string& federation)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->join(federateType, federation);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::resign()
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->resign();
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::enableTimeConstrained()
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->enableTimeConstrained();
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::disableTimeConstrained()
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->disableTimeConstrained();
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::enableTimeRegulation(const SGTimeStamp& lookahead)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->enableTimeRegulation(lookahead);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::disableTimeRegulation()
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->disableTimeRegulation();
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::timeAdvanceRequestBy(const SGTimeStamp& dt)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->timeAdvanceRequestBy(dt);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::timeAdvanceRequest(const SGTimeStamp& dt)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->timeAdvanceRequest(dt);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::queryFederateTime(SGTimeStamp& timeStamp)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->queryFederateTime(timeStamp);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::modifyLookahead(const SGTimeStamp& timeStamp)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->modifyLookahead(timeStamp);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::queryLookahead(SGTimeStamp& timeStamp)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->queryLookahead(timeStamp);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::tick()
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->tick();
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::tick(const double& minimum, const double& maximum)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->tick(minimum, maximum);
|
||||
}
|
||||
|
||||
@@ -136,8 +246,7 @@ 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!");
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,11 +32,22 @@ class RTIFederate;
|
||||
|
||||
class HLAFederate : public SGWeakReferenced {
|
||||
public:
|
||||
enum Version {
|
||||
RTI13,
|
||||
RTI1516,
|
||||
RTI1516E
|
||||
};
|
||||
|
||||
HLAFederate();
|
||||
virtual ~HLAFederate();
|
||||
|
||||
/// connect to an rti
|
||||
bool connect(Version version, const std::list<std::string>& stringList);
|
||||
bool disconnect();
|
||||
|
||||
/// Get the name of the joined federate/federation
|
||||
const std::string& getFederateType() const;
|
||||
const std::string& getFederationName() const;
|
||||
std::string getFederateType() const;
|
||||
std::string getFederationName() const;
|
||||
|
||||
/// Create a federation execution
|
||||
/// Semantically this methods should be static,
|
||||
@@ -59,6 +70,7 @@ public:
|
||||
bool timeAdvanceRequest(const SGTimeStamp& dt);
|
||||
|
||||
bool queryFederateTime(SGTimeStamp& timeStamp);
|
||||
bool modifyLookahead(const SGTimeStamp& timeStamp);
|
||||
bool queryLookahead(SGTimeStamp& timeStamp);
|
||||
|
||||
/// Process messages
|
||||
@@ -93,9 +105,6 @@ public:
|
||||
HLAInteractionClass* getInteractionClass(const std::string& name);
|
||||
const HLAInteractionClass* getInteractionClass(const std::string& name) const;
|
||||
|
||||
protected:
|
||||
HLAFederate(const SGSharedPtr<RTIFederate>& rtiFederate);
|
||||
|
||||
private:
|
||||
SGSharedPtr<RTIFederate> _rtiFederate;
|
||||
|
||||
|
||||
@@ -29,9 +29,6 @@ libsghla_a_HEADERS = \
|
||||
HLAVariantDataType.hxx
|
||||
|
||||
libsghla_a_SOURCES = \
|
||||
RTIObjectClass.cxx \
|
||||
RTIObjectInstance.cxx \
|
||||
RTIFederate.cxx \
|
||||
HLAArrayDataElement.cxx \
|
||||
HLAArrayDataType.cxx \
|
||||
HLABasicDataElement.cxx \
|
||||
@@ -53,17 +50,23 @@ libsghla_a_SOURCES = \
|
||||
|
||||
if ENABLE_HLA13
|
||||
|
||||
lib_LIBRARIES += libsghla13.a
|
||||
lib_LIBRARIES += libsgrti13.a
|
||||
|
||||
libsghla13_adir = @includedir@/hla
|
||||
libsgrti13_adir = @includedir@/hla
|
||||
|
||||
libsghla13_a_HEADERS = \
|
||||
HLA13Federate.hxx
|
||||
|
||||
libsghla13_a_SOURCES = \
|
||||
libsgrti13_a_SOURCES = \
|
||||
RTI13ObjectClass.cxx \
|
||||
RTI13ObjectInstance.cxx \
|
||||
RTI13Federate.cxx \
|
||||
HLA13Federate.cxx
|
||||
RTI13Federate.cxx
|
||||
|
||||
endif
|
||||
|
||||
lib_LIBRARIES += libsgrti.a
|
||||
|
||||
libsgrti_adir = @includedir@/hla
|
||||
|
||||
libsgrti_a_SOURCES = \
|
||||
RTIObjectClass.cxx \
|
||||
RTIObjectInstance.cxx \
|
||||
RTIFederate.cxx
|
||||
|
||||
|
||||
@@ -387,6 +387,8 @@ public:
|
||||
_rtiAmbassador.queryFederateTime(fedTime);
|
||||
timeStamp = toTimeStamp(fedTime);
|
||||
}
|
||||
void modifyLookahead(const SGTimeStamp& timeStamp)
|
||||
{ _rtiAmbassador.modifyLookahead(toFedTime(timeStamp)); }
|
||||
void queryLookahead(SGTimeStamp& timeStamp)
|
||||
{
|
||||
RTIfedTime fedTime;
|
||||
|
||||
@@ -21,10 +21,13 @@
|
||||
|
||||
namespace simgear {
|
||||
|
||||
RTI13Federate::RTI13Federate() :
|
||||
RTI13Federate::RTI13Federate(const std::list<std::string>& stringList) :
|
||||
_tickTimeout(10),
|
||||
_ambassador(new RTI13Ambassador)
|
||||
{
|
||||
if (stringList.empty()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Ignoring non empty connect arguments while connecting to an RTI13 federation!");
|
||||
}
|
||||
}
|
||||
|
||||
RTI13Federate::~RTI13Federate()
|
||||
@@ -480,6 +483,37 @@ RTI13Federate::queryFederateTime(SGTimeStamp& timeStamp)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RTI13Federate::modifyLookahead(const SGTimeStamp& timeStamp)
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead.");
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
_ambassador->modifyLookahead(timeStamp);
|
||||
} catch (RTI::InvalidLookahead& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::FederateNotExecutionMember& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::ConcurrentAccessAttempted& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::SaveInProgress& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::RestoreInProgress& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::RTIinternalError& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RTI13Federate::queryLookahead(SGTimeStamp& timeStamp)
|
||||
{
|
||||
|
||||
@@ -34,7 +34,7 @@ class RTI13Ambassador;
|
||||
|
||||
class RTI13Federate : public RTIFederate {
|
||||
public:
|
||||
RTI13Federate();
|
||||
RTI13Federate(const std::list<std::string>& stringList);
|
||||
virtual ~RTI13Federate();
|
||||
|
||||
virtual bool createFederationExecution(const std::string& federation, const std::string& objectModel);
|
||||
@@ -61,6 +61,7 @@ public:
|
||||
virtual bool timeAdvanceRequest(const SGTimeStamp& fedTime);
|
||||
|
||||
virtual bool queryFederateTime(SGTimeStamp& timeStamp);
|
||||
virtual bool modifyLookahead(const SGTimeStamp& timeStamp);
|
||||
virtual bool queryLookahead(SGTimeStamp& timeStamp);
|
||||
|
||||
/// Process messages
|
||||
|
||||
@@ -66,6 +66,7 @@ public:
|
||||
virtual bool timeAdvanceRequest(const SGTimeStamp& fedTime) = 0;
|
||||
|
||||
virtual bool queryFederateTime(SGTimeStamp& timeStamp) = 0;
|
||||
virtual bool modifyLookahead(const SGTimeStamp& timeStamp) = 0;
|
||||
virtual bool queryLookahead(SGTimeStamp& timeStamp) = 0;
|
||||
|
||||
/// Process messages
|
||||
|
||||
@@ -37,17 +37,19 @@ set(SOURCES
|
||||
simgear_component(io io "${SOURCES}" "${HEADERS}")
|
||||
|
||||
add_executable(test_sock socktest.cxx)
|
||||
target_link_libraries(test_sock sgio sgstructure sgdebug)
|
||||
target_link_libraries(test_sock sgio sgstructure sgdebug ${OPENTHREADS_LIBRARY})
|
||||
|
||||
add_executable(test_http test_HTTP.cxx)
|
||||
target_link_libraries(test_http
|
||||
sgio sgstructure sgtiming sgmisc sgdebug
|
||||
${RT_LIBRARY})
|
||||
${RT_LIBRARY}
|
||||
${OPENTHREADS_LIBRARY})
|
||||
|
||||
add_test(http ${EXECUTABLE_OUTPUT_PATH}/test_http)
|
||||
|
||||
add_executable(httpget httpget.cxx)
|
||||
target_link_libraries(httpget
|
||||
sgio sgstructure sgtiming sgmisc sgdebug
|
||||
${RT_LIBRARY})
|
||||
${RT_LIBRARY}
|
||||
${OPENTHREADS_LIBRARY})
|
||||
|
||||
@@ -46,6 +46,7 @@ tcp_server_LDADD = \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
-lz \
|
||||
$(network_LIBS) \
|
||||
$(osg_LIBS) \
|
||||
$(base_LIBS)
|
||||
|
||||
tcp_client_SOURCES = tcp_client.cxx
|
||||
@@ -58,6 +59,7 @@ tcp_client_LDADD = \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
-lz \
|
||||
$(network_LIBS) \
|
||||
$(osg_LIBS) \
|
||||
$(base_LIBS)
|
||||
|
||||
socktest_SOURCES = socktest.cxx
|
||||
@@ -70,6 +72,7 @@ socktest_LDADD = \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
-lz \
|
||||
$(network_LIBS) \
|
||||
$(osg_LIBS) \
|
||||
$(base_LIBS)
|
||||
|
||||
lowtest_SOURCES = lowtest.cxx
|
||||
@@ -80,7 +83,7 @@ lowtest_LDADD = \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/bucket/libsgbucket.a \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
$(base_LIBS) -lz
|
||||
$(base_LIBS) -lz $(osg_LIBS)
|
||||
|
||||
decode_binobj_SOURCES = decode_binobj.cxx
|
||||
|
||||
@@ -89,4 +92,4 @@ decode_binobj_LDADD = \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/bucket/libsgbucket.a \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
$(base_LIBS) -lz
|
||||
$(base_LIBS) -lz $(osg_LIBS)
|
||||
|
||||
@@ -57,9 +57,166 @@
|
||||
#define socklen_t int
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
|
||||
#include <OpenThreads/Thread>
|
||||
#include <OpenThreads/Mutex>
|
||||
#include <OpenThreads/Condition>
|
||||
|
||||
namespace {
|
||||
|
||||
class Resolver : public OpenThreads::Thread
|
||||
{
|
||||
public:
|
||||
static Resolver* instance()
|
||||
{
|
||||
if (!static_instance) {
|
||||
OpenThreads::Thread::Init();
|
||||
|
||||
static_instance = new Resolver;
|
||||
atexit(&Resolver::cleanup);
|
||||
static_instance->start();
|
||||
}
|
||||
|
||||
return static_instance;
|
||||
}
|
||||
|
||||
static void cleanup()
|
||||
{
|
||||
static_instance->cancel();
|
||||
}
|
||||
|
||||
Resolver()
|
||||
{
|
||||
// take the lock initially, thread will wait upon it once running
|
||||
_lock.lock();
|
||||
}
|
||||
|
||||
simgear::IPAddress* lookup(const string& host)
|
||||
{
|
||||
simgear::IPAddress* result = NULL;
|
||||
_lock.lock();
|
||||
AddressCache::iterator it = _cache.find(host);
|
||||
if (it == _cache.end()) {
|
||||
_cache[host] = NULL; // mark as needing looked up
|
||||
_wait.signal(); // if the thread was sleeping, poke it
|
||||
} else {
|
||||
result = it->second;
|
||||
}
|
||||
_lock.unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
simgear::IPAddress* lookupSync(const string& host)
|
||||
{
|
||||
simgear::IPAddress* result = NULL;
|
||||
_lock.lock();
|
||||
AddressCache::iterator it = _cache.find(host);
|
||||
if (it == _cache.end()) {
|
||||
_lock.unlock();
|
||||
result = new simgear::IPAddress;
|
||||
bool ok = lookupHost(host.c_str(), *result);
|
||||
_lock.lock();
|
||||
if (ok) {
|
||||
_cache[host] = result; // mark as needing looked up
|
||||
} else {
|
||||
delete result;
|
||||
result = NULL;
|
||||
}
|
||||
} else { // found in cache, easy
|
||||
result = it->second;
|
||||
}
|
||||
_lock.unlock();
|
||||
return result;
|
||||
}
|
||||
protected:
|
||||
/**
|
||||
* run method waits on a condition (_wait), and when awoken,
|
||||
* finds any unresolved entries in _cache, resolves them, and goes
|
||||
* back to sleep.
|
||||
*/
|
||||
virtual void run()
|
||||
{
|
||||
while (true) {
|
||||
_wait.wait(&_lock);
|
||||
AddressCache::iterator it;
|
||||
|
||||
for (it = _cache.begin(); it != _cache.end(); ++it) {
|
||||
if (it->second == NULL) {
|
||||
string h = it->first;
|
||||
|
||||
_lock.unlock();
|
||||
simgear::IPAddress* addr = new simgear::IPAddress;
|
||||
// may take seconds or even minutes!
|
||||
lookupHost(h.c_str(), *addr);
|
||||
_lock.lock();
|
||||
|
||||
// cahce may have changed while we had the lock released -
|
||||
// so iterators may be invalid: restart the traversal
|
||||
it = _cache.begin();
|
||||
_cache[h] = addr;
|
||||
} // of found un-resolved entry
|
||||
} // of un-resolved address iteration
|
||||
} // of thread run loop
|
||||
}
|
||||
private:
|
||||
static Resolver* static_instance;
|
||||
|
||||
/**
|
||||
* The actual synchronous, blocking host lookup function
|
||||
* do *not* call this with any locks (mutexs) held, since depending
|
||||
* on local system configuration / network availability, it
|
||||
* may block for seconds or minutes.
|
||||
*/
|
||||
bool lookupHost(const char* host, simgear::IPAddress& addr)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = AF_INET;
|
||||
bool ok = false;
|
||||
|
||||
struct addrinfo* result0 = NULL;
|
||||
int err = getaddrinfo(host, NULL, &hints, &result0);
|
||||
if (err) {
|
||||
SG_LOG(SG_IO, SG_WARN, "getaddrinfo failed for '" << host << "' : " << gai_strerror(err));
|
||||
return false;
|
||||
} else {
|
||||
struct addrinfo* result;
|
||||
for (result = result0; result != NULL; result = result->ai_next) {
|
||||
if (result->ai_family != AF_INET) { // only accept IP4 for the moment
|
||||
continue;
|
||||
}
|
||||
|
||||
if (result->ai_addrlen != addr.getAddrLen()) {
|
||||
SG_LOG(SG_IO, SG_ALERT, "mismatch in socket address sizes: got " <<
|
||||
result->ai_addrlen << ", expected " << addr.getAddrLen());
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(addr.getAddr(), result->ai_addr, result->ai_addrlen);
|
||||
ok = true;
|
||||
break;
|
||||
} // of getaddrinfo results iteration
|
||||
} // of getaddrinfo succeeded
|
||||
|
||||
freeaddrinfo(result0);
|
||||
return ok;
|
||||
}
|
||||
|
||||
OpenThreads::Mutex _lock;
|
||||
OpenThreads::Condition _wait;
|
||||
|
||||
typedef std::map<string, simgear::IPAddress*> AddressCache;
|
||||
AddressCache _cache;
|
||||
};
|
||||
|
||||
Resolver* Resolver::static_instance = NULL;
|
||||
|
||||
} // of anonymous namespace
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
|
||||
@@ -115,33 +272,12 @@ void IPAddress::set ( const char* host, int port )
|
||||
return;
|
||||
}
|
||||
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = AF_INET;
|
||||
// check the cache
|
||||
IPAddress* cached = Resolver::instance()->lookupSync(host);
|
||||
if (cached) {
|
||||
memcpy(addr, cached->getAddr(), cached->getAddrLen());
|
||||
}
|
||||
|
||||
struct addrinfo* result0 = NULL;
|
||||
int err = getaddrinfo(host, NULL, &hints, &result0);
|
||||
if (err) {
|
||||
SG_LOG(SG_IO, SG_WARN, "getaddrinfo failed for '" << host << "' : " << gai_strerror(err));
|
||||
} else {
|
||||
struct addrinfo* result;
|
||||
for (result = result0; result != NULL; result = result->ai_next) {
|
||||
if (result->ai_family != AF_INET) { // only accept IP4 for the moment
|
||||
continue;
|
||||
}
|
||||
|
||||
if (result->ai_addrlen != getAddrLen()) {
|
||||
SG_LOG(SG_IO, SG_ALERT, "mismatch in socket address sizes: got " <<
|
||||
result->ai_addrlen << ", expected " << getAddrLen());
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(addr, result->ai_addr, result->ai_addrlen);
|
||||
break;
|
||||
} // of getaddrinfo results iteration
|
||||
} // of getaddrinfo succeeded
|
||||
|
||||
freeaddrinfo(result0);
|
||||
addr->sin_port = htons (port); // fix up port after getaddrinfo
|
||||
}
|
||||
|
||||
@@ -152,6 +288,17 @@ IPAddress::~IPAddress()
|
||||
}
|
||||
}
|
||||
|
||||
bool IPAddress::lookupNonblocking(const char* host, IPAddress& addr)
|
||||
{
|
||||
IPAddress* cached = Resolver::instance()->lookup(host);
|
||||
if (!cached) {
|
||||
return false;
|
||||
}
|
||||
|
||||
addr = *cached;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Create a string object representing an IP address.
|
||||
This is always a string of the form 'dd.dd.dd.dd' (with variable
|
||||
size numbers). */
|
||||
@@ -176,6 +323,11 @@ unsigned int IPAddress::getPort() const
|
||||
return ntohs(addr->sin_port);
|
||||
}
|
||||
|
||||
void IPAddress::setPort(int port)
|
||||
{
|
||||
addr->sin_port = htons(port);
|
||||
}
|
||||
|
||||
unsigned int IPAddress::getFamily () const
|
||||
{
|
||||
return addr->sin_family;
|
||||
@@ -215,6 +367,11 @@ unsigned int IPAddress::getAddrLen() const
|
||||
|
||||
struct sockaddr* IPAddress::getAddr() const
|
||||
{
|
||||
if (addr == NULL) {
|
||||
addr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
|
||||
memset(addr, 0, sizeof(struct sockaddr_in));
|
||||
}
|
||||
|
||||
return (struct sockaddr*) addr;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,18 +40,22 @@ namespace simgear
|
||||
*/
|
||||
class IPAddress
|
||||
{
|
||||
struct sockaddr_in* addr;
|
||||
mutable struct sockaddr_in* addr;
|
||||
public:
|
||||
IPAddress () : addr(0) {}
|
||||
IPAddress ( const char* host, int port ) ;
|
||||
~IPAddress();
|
||||
|
||||
static bool lookupNonblocking(const char* host, IPAddress& addr);
|
||||
|
||||
IPAddress( const IPAddress& other );
|
||||
const IPAddress& operator=(const IPAddress& other);
|
||||
|
||||
void set ( const char* host, int port ) ;
|
||||
const char* getHost () const ;
|
||||
unsigned int getPort() const ;
|
||||
void setPort(int port);
|
||||
|
||||
unsigned int getIP () const ;
|
||||
unsigned int getFamily () const ;
|
||||
static const char* getLocalHost () ;
|
||||
@@ -69,7 +73,7 @@ public:
|
||||
class Socket
|
||||
{
|
||||
int handle ;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Socket () ;
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
|
||||
namespace simgear {
|
||||
|
||||
static NetChannel* channels = 0 ;
|
||||
@@ -46,6 +47,7 @@ NetChannel::NetChannel ()
|
||||
{
|
||||
closed = true ;
|
||||
connected = false ;
|
||||
resolving_host = false;
|
||||
accepting = false ;
|
||||
write_blocked = false ;
|
||||
should_delete = false ;
|
||||
@@ -83,7 +85,6 @@ NetChannel::setHandle (int handle, bool is_connected)
|
||||
close () ;
|
||||
Socket::setHandle ( handle ) ;
|
||||
connected = is_connected ;
|
||||
//if ( connected ) this->handleConnect();
|
||||
closed = false ;
|
||||
}
|
||||
|
||||
@@ -107,21 +108,12 @@ NetChannel::listen ( int backlog )
|
||||
}
|
||||
|
||||
int
|
||||
NetChannel::connect ( const char* host, int port )
|
||||
NetChannel::connect ( const char* h, int p )
|
||||
{
|
||||
int result = Socket::connect ( host, port ) ;
|
||||
if (result == 0) {
|
||||
connected = true ;
|
||||
//this->handleConnect();
|
||||
return 0;
|
||||
} else if (isNonBlockingError ()) {
|
||||
return 0;
|
||||
} else {
|
||||
// some other error condition
|
||||
this->handleError (result);
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
host = h;
|
||||
port = p;
|
||||
resolving_host = true;
|
||||
return handleResolve();
|
||||
}
|
||||
|
||||
int
|
||||
@@ -189,12 +181,10 @@ NetChannel::handleReadEvent (void)
|
||||
if (accepting) {
|
||||
if (!connected) {
|
||||
connected = true ;
|
||||
//this->handleConnect();
|
||||
}
|
||||
this->handleAccept();
|
||||
} else if (!connected) {
|
||||
connected = true ;
|
||||
//this->handleConnect();
|
||||
this->handleRead();
|
||||
} else {
|
||||
this->handleRead();
|
||||
@@ -206,12 +196,35 @@ NetChannel::handleWriteEvent (void)
|
||||
{
|
||||
if (!connected) {
|
||||
connected = true ;
|
||||
//this->handleConnect();
|
||||
}
|
||||
write_blocked = false ;
|
||||
this->handleWrite();
|
||||
}
|
||||
|
||||
int
|
||||
NetChannel::handleResolve()
|
||||
{
|
||||
IPAddress addr;
|
||||
if (!IPAddress::lookupNonblocking(host.c_str(), addr)) {
|
||||
return 0; // not looked up yet, wait longer
|
||||
}
|
||||
|
||||
resolving_host = false;
|
||||
addr.setPort(port);
|
||||
int result = Socket::connect ( &addr ) ;
|
||||
if (result == 0) {
|
||||
connected = true ;
|
||||
return 0;
|
||||
} else if (isNonBlockingError ()) {
|
||||
return 0;
|
||||
} else {
|
||||
// some other error condition
|
||||
handleError (result);
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
NetChannel::poll (unsigned int timeout)
|
||||
{
|
||||
@@ -236,6 +249,12 @@ NetChannel::poll (unsigned int timeout)
|
||||
}
|
||||
else if ( ! ch -> closed )
|
||||
{
|
||||
if (ch -> resolving_host )
|
||||
{
|
||||
ch -> handleResolve();
|
||||
continue;
|
||||
}
|
||||
|
||||
nopen++ ;
|
||||
if (ch -> readable()) {
|
||||
assert(nreads<MAX_SOCKETS);
|
||||
|
||||
@@ -54,14 +54,17 @@
|
||||
#define SG_NET_CHANNEL_H
|
||||
|
||||
#include <simgear/io/raw_socket.hxx>
|
||||
#include <string>
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
|
||||
class NetChannel : public Socket
|
||||
{
|
||||
bool closed, connected, accepting, write_blocked, should_delete ;
|
||||
bool closed, connected, accepting, write_blocked, should_delete, resolving_host ;
|
||||
NetChannel* next_channel ;
|
||||
std::string host;
|
||||
int port;
|
||||
|
||||
friend bool netPoll (unsigned int timeout);
|
||||
|
||||
@@ -96,6 +99,7 @@ public:
|
||||
|
||||
void handleReadEvent (void);
|
||||
void handleWriteEvent (void);
|
||||
int handleResolve (void);
|
||||
|
||||
// These are meant to be overridden.
|
||||
virtual void handleClose (void) {
|
||||
|
||||
Reference in New Issue
Block a user