]> git.mxchange.org Git - simgear.git/commitdiff
Merge branch 'next' of gitorious.org:fg/simgear into next
authorStuart Buchanan <stuart_d_buchanan@yahoo.co.uk>
Thu, 1 Sep 2011 18:55:11 +0000 (19:55 +0100)
committerStuart Buchanan <stuart_d_buchanan@yahoo.co.uk>
Thu, 1 Sep 2011 18:55:11 +0000 (19:55 +0100)
18 files changed:
configure.ac
simgear/hla/CMakeLists.txt
simgear/hla/HLA13Federate.cxx [deleted file]
simgear/hla/HLA13Federate.hxx [deleted file]
simgear/hla/HLAArrayDataElement.hxx
simgear/hla/HLAFederate.cxx
simgear/hla/HLAFederate.hxx
simgear/hla/Makefile.am
simgear/hla/RTI13Ambassador.hxx
simgear/hla/RTI13Federate.cxx
simgear/hla/RTI13Federate.hxx
simgear/hla/RTIFederate.hxx
simgear/io/CMakeLists.txt
simgear/io/Makefile.am
simgear/io/raw_socket.cxx
simgear/io/raw_socket.hxx
simgear/io/sg_netChannel.cxx
simgear/io/sg_netChannel.hxx

index 28e846cd491bf215f9a35e98e562011d5cbd8c7f..81bae41ea605984b983ee0f84b22ba8eb5c42c8d 100644 (file)
@@ -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
index bae6eb7381107c349194b082d234913372477546..207210abb0500aaf3da5b2b32462a2fbdabf8dd7 100644 (file)
@@ -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}" "")
diff --git a/simgear/hla/HLA13Federate.cxx b/simgear/hla/HLA13Federate.cxx
deleted file mode 100644 (file)
index 4f78344..0000000
+++ /dev/null
@@ -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
diff --git a/simgear/hla/HLA13Federate.hxx b/simgear/hla/HLA13Federate.hxx
deleted file mode 100644 (file)
index dc3fa0b..0000000
+++ /dev/null
@@ -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
index f1acf8ef096a012dcdc4fcf370126e947609a1eb..b7c9c1e3dc46631eb0617225fa6486d112b540d5 100644 (file)
@@ -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:
index 96e31fc32ffe2f7fefcd57834b9a9535f46de234..59a5f4b0cd56b9afc4375d9178b6bf09ddd2b7b9 100644 (file)
@@ -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;
     }
 
index 241f60935a38f6905fc89c53eb82313f71ef5120..5af83396fe6c75cd0eb5ccbcb4a1daa56026063f 100644 (file)
@@ -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;
 
index e4af153109319ef5aeab332e9d3774008c62d7e8..67542ddb09722ab3a832959c7325556372a3bd4a 100644 (file)
@@ -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
-
-libsghla13_adir = @includedir@/hla
+lib_LIBRARIES += libsgrti13.a
 
-libsghla13_a_HEADERS = \
-       HLA13Federate.hxx
+libsgrti13_adir = @includedir@/hla
 
-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
+
index 502a39f72fc3ef04d35ecc7468eb2f97183941fd..5446f8583d4dded819cd2d793af3f6adfdd3164a 100644 (file)
@@ -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;
index d3f9eebc8694ddc0a14ef12a957ef34eb56f683d..a77fbaea8a8aded9c4650fc3dad3584428eda7fc 100644 (file)
 
 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)
 {
index acad0fceaf99347b09283b4ef472cc84f3002cca..839e7d508b743108284e4910d1f06fe3295636ba 100644 (file)
@@ -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
index bdb68faa4a330d8bca72d52cde6271013e127e02..c997704f36238723fca381321d19716f7cfebc40 100644 (file)
@@ -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
index a2638e1bee9ef61a42051cef156a9f8e620fbc6f..2cdb1d5a467428adaae35a845c7dcf06ce0e1968 100644 (file)
@@ -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})
     
\ No newline at end of file
index 760676a36dee8e12884029e097ddc245eec6f950..e0086d86624fdf1e9e20be6705b945b254167598 100644 (file)
@@ -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)
index d972c14531e4f5b292600cf0519bd901818ee0d8..b849bddc9b288d267a878e4fb6a8de95d87e1cb1 100644 (file)
 #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;
 }
 
index 2b5031f31df0a7bdec937def8772b5447c504dcc..9450e9eb8729cefe97caeefbfc445172e3a3513d 100644 (file)
@@ -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 () ;
index c3644b6c275d5d915d5844da112802f4efc6df6d..86839e71a707384661f9a5555cdd1f7d38e3e0d2 100644 (file)
@@ -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);
index 30af51226fe4d49832d7fe36bbd5e030cb8949e0..0ccc8607a7ba259ca03f968b2eeccc1eef2a107b 100644 (file)
 #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) {