Compare commits
7 Commits
version/2.
...
version/2.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe2fb8e6ae | ||
|
|
4793166abf | ||
|
|
4494eb061e | ||
|
|
8ed9e01c63 | ||
|
|
55fc86741b | ||
|
|
9c0cafb82c | ||
|
|
ede50bec49 |
16
.gitignore
vendored
16
.gitignore
vendored
@@ -1,9 +1,20 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
.deps
|
||||
autom4te.cache
|
||||
config.guess
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
missing
|
||||
aclocal.m4
|
||||
INSTALL
|
||||
SimGear.spec
|
||||
*.o
|
||||
lib*.a
|
||||
.*.swp
|
||||
cmake_install.cmake
|
||||
CMakeFiles
|
||||
CMakeCache.txt
|
||||
@@ -12,5 +23,4 @@ CPackSourceConfig.cmake
|
||||
cmake_uninstall.cmake
|
||||
CTestTestfile.cmake
|
||||
install_manifest.txt
|
||||
build
|
||||
Build
|
||||
|
||||
|
||||
135
CMakeLists.txt
135
CMakeLists.txt
@@ -1,8 +1,8 @@
|
||||
cmake_minimum_required (VERSION 2.6.4)
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
include (CheckFunctionExists)
|
||||
include (CheckIncludeFile)
|
||||
include (CheckCXXSourceCompiles)
|
||||
|
||||
include (CPack)
|
||||
|
||||
project(SimGear)
|
||||
|
||||
@@ -10,78 +10,19 @@ project(SimGear)
|
||||
file(READ version versionFile)
|
||||
string(STRIP ${versionFile} SIMGEAR_VERSION)
|
||||
|
||||
# use simgear version also as the SO version (if building SOs)
|
||||
SET(SIMGEAR_SOVERSION ${SIMGEAR_VERSION})
|
||||
|
||||
#packaging
|
||||
SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING")
|
||||
SET(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Simulation support libraries for FlightGear and related projects")
|
||||
SET(CPACK_PACKAGE_VENDOR "The FlightGear project")
|
||||
SET(CPACK_GENERATOR "TBZ2")
|
||||
SET(CPACK_INSTALL_CMAKE_PROJECTS ${CMAKE_CURRENT_BINARY_DIR};SimGear;ALL;/)
|
||||
|
||||
|
||||
# split version string into components, note CMAKE_MATCH_0 is the entire regexp match
|
||||
string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)" CPACK_PACKAGE_VERSION ${SIMGEAR_VERSION} )
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR ${CMAKE_MATCH_1})
|
||||
set(CPACK_PACKAGE_VERSION_MINOR ${CMAKE_MATCH_2})
|
||||
set(CPACK_PACKAGE_VERSION_PATCH ${CMAKE_MATCH_3})
|
||||
|
||||
message(STATUS "version is ${CPACK_PACKAGE_VERSION_MAJOR} dot ${CPACK_PACKAGE_VERSION_MINOR} dot ${CPACK_PACKAGE_VERSION_PATCH}")
|
||||
|
||||
set(CPACK_SOURCE_GENERATOR TBZ2)
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME "simgear-${SIMGEAR_VERSION}" CACHE INTERNAL "tarball basename")
|
||||
set(CPACK_SOURCE_IGNORE_FILES
|
||||
"^${PROJECT_SOURCE_DIR}/.git;\\\\.gitignore;Makefile.am;~$;${CPACK_SOURCE_IGNORE_FILES}")
|
||||
|
||||
message(STATUS "ignoring: ${CPACK_SOURCE_IGNORE_FILES}")
|
||||
|
||||
include (CPack)
|
||||
|
||||
# We have some custom .cmake scripts not in the official distribution.
|
||||
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules;${CMAKE_MODULE_PATH}")
|
||||
|
||||
# Change the default build type to something fast
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release CACHE STRING
|
||||
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
|
||||
FORCE)
|
||||
endif(NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
# Determine name of library installation directory, i.e. "lib" vs "lib64", which
|
||||
# differs between all Debian-based vs all other Linux distros.
|
||||
# See cmake bug #11964, http://cmake.org/gitweb?p=cmake.git;a=commit;h=126c993d
|
||||
# GNUInstallDirs requires CMake >= 2.8.5, use own file for older cmake
|
||||
if(${CMAKE_VERSION} VERSION_GREATER 2.8.4)
|
||||
include(GNUInstallDirs)
|
||||
else(${CMAKE_VERSION} VERSION_GREATER 2.8.4)
|
||||
include(OldGNUInstallDirs)
|
||||
endif(${CMAKE_VERSION} VERSION_GREATER 2.8.4)
|
||||
message(STATUS "Library installation directory: ${CMAKE_INSTALL_LIBDIR}")
|
||||
|
||||
option(SIMGEAR_SHARED "Set to ON to build SimGear as a shared library/framework" OFF)
|
||||
option(SIMGEAR_HEADLESS "Set to ON to build SimGear without GUI/graphics support" OFF)
|
||||
option(SIMGEAR_HEADLESS "Set to ON to build SimGear with GUI/graphics support" OFF)
|
||||
option(JPEG_FACTORY "Enable JPEG-factory support" OFF)
|
||||
option(ENABLE_LIBSVN "Set to ON to build SimGear with libsvnclient support" ON)
|
||||
option(ENABLE_RTI "Set to ON to build SimGear with RTI support" OFF)
|
||||
option(ENABLE_TESTS "Set to OFF to disable building SimGear's test applications" ON)
|
||||
|
||||
if (MSVC)
|
||||
GET_FILENAME_COMPONENT(PARENT_DIR ${PROJECT_SOURCE_DIR} PATH)
|
||||
if (CMAKE_CL_64)
|
||||
SET(TEST_3RDPARTY_DIR "${PARENT_DIR}/3rdparty.x64")
|
||||
else (CMAKE_CL_64)
|
||||
SET(TEST_3RDPARTY_DIR "${PARENT_DIR}/3rdparty")
|
||||
endif (CMAKE_CL_64)
|
||||
if (EXISTS ${TEST_3RDPARTY_DIR})
|
||||
set(MSVC_3RDPARTY_ROOT ${PARENT_DIR} CACHE PATH "Location where the third-party dependencies are extracted")
|
||||
else (EXISTS ${TEST_3RDPARTY_DIR})
|
||||
set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
|
||||
endif (EXISTS ${TEST_3RDPARTY_DIR})
|
||||
else (MSVC)
|
||||
set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
|
||||
endif (MSVC)
|
||||
set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
|
||||
|
||||
if (MSVC AND MSVC_3RDPARTY_ROOT)
|
||||
message(STATUS "3rdparty files located in ${MSVC_3RDPARTY_ROOT}")
|
||||
@@ -101,7 +42,6 @@ if (MSVC AND MSVC_3RDPARTY_ROOT)
|
||||
set (CMAKE_LIBRARY_PATH ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenScenegraph/lib )
|
||||
set (CMAKE_INCLUDE_PATH ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenScenegraph/include)
|
||||
set (BOOST_ROOT ${MSVC_3RDPARTY_ROOT}/boost_1_44_0)
|
||||
message(STATUS "BOOST_ROOT is ${BOOST_ROOT}")
|
||||
set (OPENAL_INCLUDE_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include)
|
||||
set (ALUT_INCLUDE_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include)
|
||||
set (OPENAL_LIBRARY_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib)
|
||||
@@ -113,21 +53,21 @@ set (BOOST_CXX_FLAGS "-DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DBOOST_BIMAP_DI
|
||||
find_package(ZLIB REQUIRED)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
if(SIMGEAR_HEADLESS)
|
||||
message(STATUS "headless mode")
|
||||
if (${SIMGEAR_HEADLESS})
|
||||
message(STATUS "headlesss mode")
|
||||
set(NO_OPENSCENEGRAPH_INTERFACE 1)
|
||||
else()
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(OpenAL REQUIRED)
|
||||
find_package(ALUT REQUIRED)
|
||||
find_package(OpenSceneGraph 3.0.0 REQUIRED osgText osgSim osgDB osgParticle osgUtil)
|
||||
endif(SIMGEAR_HEADLESS)
|
||||
find_package(OpenSceneGraph 2.8.1 REQUIRED osgText osgSim osgDB osgParticle osgUtil)
|
||||
endif()
|
||||
|
||||
if(JPEG_FACTORY)
|
||||
message(STATUS "JPEG-factory enabled")
|
||||
find_package(JPEG REQUIRED)
|
||||
include_directories(${JPEG_INCLUDE_DIR})
|
||||
endif(JPEG_FACTORY)
|
||||
endif()
|
||||
|
||||
if(ENABLE_LIBSVN)
|
||||
find_package(SvnClient)
|
||||
@@ -146,45 +86,18 @@ check_include_file(sys/timeb.h HAVE_SYS_TIMEB_H)
|
||||
check_include_file(unistd.h HAVE_UNISTD_H)
|
||||
check_include_file(windows.h HAVE_WINDOWS_H)
|
||||
|
||||
if(ENABLE_RTI)
|
||||
# See if we have any rti library variant installed
|
||||
find_package(RTI)
|
||||
endif(ENABLE_RTI)
|
||||
find_package(RTI)
|
||||
|
||||
check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)
|
||||
check_function_exists(ftime HAVE_FTIME)
|
||||
check_function_exists(timegm HAVE_TIMEGM)
|
||||
check_function_exists(rint HAVE_RINT)
|
||||
check_function_exists(mkdtemp HAVE_MKDTEMP)
|
||||
|
||||
if(HAVE_UNISTD_H)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_INCLUDE_PATH})
|
||||
check_cxx_source_compiles(
|
||||
"#include <unistd.h>
|
||||
#if !defined(_POSIX_TIMERS) || (0 >= _POSIX_TIMERS)
|
||||
#error clock_gettime is not supported
|
||||
#endif
|
||||
|
||||
int main() { return 0; }
|
||||
"
|
||||
HAVE_CLOCK_GETTIME)
|
||||
endif(HAVE_UNISTD_H)
|
||||
|
||||
set(RT_LIBRARY "")
|
||||
if(HAVE_CLOCK_GETTIME)
|
||||
check_function_exists(clock_gettime CLOCK_GETTIME_IN_LIBC)
|
||||
if(NOT CLOCK_GETTIME_IN_LIBC)
|
||||
check_library_exists(rt clock_gettime "" HAVE_RT)
|
||||
if(HAVE_RT)
|
||||
set(RT_LIBRARY rt)
|
||||
endif(HAVE_RT)
|
||||
endif(NOT CLOCK_GETTIME_IN_LIBC)
|
||||
endif(HAVE_CLOCK_GETTIME)
|
||||
|
||||
SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "add a postfix, usually 'd' on windows")
|
||||
SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "add a postfix, usually d on windows")
|
||||
SET(CMAKE_RELEASE_POSTFIX "" CACHE STRING "add a postfix, usually empty on windows")
|
||||
SET(CMAKE_RELWITHDEBINFO_POSTFIX "" CACHE STRING "add a postfix, usually empty on windows")
|
||||
SET(CMAKE_MINSIZEREL_POSTFIX "" CACHE STRING "add a postfix, usually empty on windows")
|
||||
SET(CMAKE_RELWITHDEBINFO_POSTFIX "rd" CACHE STRING "add a postfix, usually empty on windows")
|
||||
SET(CMAKE_MINSIZEREL_POSTFIX "s" CACHE STRING "add a postfix, usually empty on windows")
|
||||
|
||||
# isnan might not be real symbol, so can't check using function_exists
|
||||
check_cxx_source_compiles(
|
||||
@@ -194,13 +107,6 @@ check_cxx_source_compiles(
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(WARNING_FLAGS -Wall)
|
||||
|
||||
# certain GCC versions don't provide the atomic builds, and hence
|
||||
# require is to provide them in SGAtomic.cxx
|
||||
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_INCLUDE_PATH})
|
||||
check_cxx_source_compiles(
|
||||
"int main() { unsigned mValue; return __sync_add_and_fetch(&mValue, 1); }"
|
||||
GCC_ATOMIC_BUILTINS_FOUND)
|
||||
endif(CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
if(WIN32)
|
||||
@@ -211,14 +117,11 @@ if(WIN32)
|
||||
# SET(WARNING_FLAGS "${WARNING_FLAGS} /wd${warning}")
|
||||
# endforeach(warning)
|
||||
|
||||
set(MSVC_FLAGS "-DWIN32 -DNOMINMAX -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D__CRT_NONSTDC_NO_WARNINGS /wd4996")
|
||||
set(MSVC_FLAGS "-DWIN32 -DNOMINMAX -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D__CRT_NONSTDC_NO_WARNINGS")
|
||||
endif(MSVC)
|
||||
|
||||
# assumed on Windows
|
||||
set(HAVE_GETLOCALTIME 1)
|
||||
|
||||
set( WINSOCK_LIBRARY "ws2_32.lib" )
|
||||
set( RT_LIBRARY "winmm" )
|
||||
endif(WIN32)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} ${MSVC_FLAGS}")
|
||||
@@ -240,14 +143,7 @@ configure_file (
|
||||
"${PROJECT_SOURCE_DIR}/simgear/simgear_config_cmake.h.in"
|
||||
"${PROJECT_BINARY_DIR}/simgear/simgear_config.h"
|
||||
)
|
||||
|
||||
if(ENABLE_TESTS)
|
||||
# enable CTest / make test target
|
||||
|
||||
include (Dart)
|
||||
enable_testing()
|
||||
endif(ENABLE_TESTS)
|
||||
|
||||
|
||||
install (FILES ${PROJECT_BINARY_DIR}/simgear/simgear_config.h DESTINATION include/simgear/)
|
||||
add_subdirectory(simgear)
|
||||
|
||||
@@ -261,3 +157,4 @@ CONFIGURE_FILE(
|
||||
ADD_CUSTOM_TARGET(uninstall
|
||||
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
||||
|
||||
|
||||
|
||||
@@ -3,31 +3,6 @@
|
||||
|
||||
include (CheckFunctionExists)
|
||||
include (CheckIncludeFile)
|
||||
include (CheckLibraryExists)
|
||||
|
||||
macro(find_static_component comp libs)
|
||||
# account for alternative Windows svn distribution naming
|
||||
if(MSVC)
|
||||
set(compLib "lib${comp}")
|
||||
else(MSVC)
|
||||
set(compLib "${comp}")
|
||||
endif(MSVC)
|
||||
|
||||
string(TOUPPER "${comp}" compLibBase)
|
||||
set( compLibName ${compLibBase}_LIBRARY )
|
||||
|
||||
FIND_LIBRARY(${compLibName}
|
||||
NAMES ${compLib}
|
||||
HINTS $ENV{PLIBDIR}
|
||||
PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
|
||||
PATHS
|
||||
/usr/local
|
||||
/usr
|
||||
/opt
|
||||
)
|
||||
|
||||
list(APPEND ${libs} ${${compLibName}})
|
||||
endmacro()
|
||||
|
||||
find_program(HAVE_APR_CONFIG apr-1-config)
|
||||
if(HAVE_APR_CONFIG)
|
||||
@@ -41,13 +16,13 @@ if(HAVE_APR_CONFIG)
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
# clean up some vars, or other CMake pieces complain
|
||||
string(STRIP "${RAW_APR_LIBS}" APR_LIBS)
|
||||
string(STRIP ${RAW_APR_LIBS} APR_LIBS)
|
||||
|
||||
else(HAVE_APR_CONFIG)
|
||||
message(STATUS "apr-1-config not found, implement manual search for APR")
|
||||
endif(HAVE_APR_CONFIG)
|
||||
|
||||
if(HAVE_APR_CONFIG OR MSVC)
|
||||
if(HAVE_APR_CONFIG)
|
||||
find_path(LIBSVN_INCLUDE_DIR svn_client.h
|
||||
HINTS
|
||||
$ENV{LIBSVN_DIR}
|
||||
@@ -57,20 +32,20 @@ if(HAVE_APR_CONFIG OR MSVC)
|
||||
/usr
|
||||
/opt
|
||||
)
|
||||
|
||||
set(LIBSVN_LIBRARIES "")
|
||||
if (MSVC)
|
||||
find_static_component("apr-1" LIBSVN_LIBRARIES)
|
||||
else (MSVC)
|
||||
list(APPEND LIBSVN_LIBRARIES ${APR_LIBS})
|
||||
endif (MSVC)
|
||||
find_static_component("svn_client-1" LIBSVN_LIBRARIES)
|
||||
find_static_component("svn_subr-1" LIBSVN_LIBRARIES)
|
||||
find_static_component("svn_ra-1" LIBSVN_LIBRARIES)
|
||||
|
||||
check_library_exists(svn_client-1 svn_client_checkout "" HAVE_LIB_SVNCLIENT)
|
||||
check_library_exists(svn_subr-1 svn_cmdline_init "" HAVE_LIB_SVNSUBR)
|
||||
check_library_exists(svn_ra-1 svn_ra_initialize "" HAVE_LIB_SVNRA)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBSVN DEFAULT_MSG LIBSVN_LIBRARIES LIBSVN_INCLUDE_DIR)
|
||||
if(NOT LIBSVN_FOUND)
|
||||
set(LIBSVN_LIBRARIES "")
|
||||
endif(NOT LIBSVN_FOUND)
|
||||
endif(HAVE_APR_CONFIG OR MSVC)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBSVN DEFAULT_MSG
|
||||
HAVE_LIB_SVNSUBR
|
||||
HAVE_LIB_SVNCLIENT
|
||||
HAVE_LIB_SVNRA
|
||||
LIBSVN_INCLUDE_DIR)
|
||||
|
||||
if(LIBSVN_FOUND)
|
||||
set(LIBSVN_LIBRARIES "svn_client-1" "svn_subr-1" "svn_ra-1" ${APR_LIBS})
|
||||
endif(LIBSVN_FOUND)
|
||||
endif(HAVE_APR_CONFIG)
|
||||
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
# - Define GNU standard installation directories
|
||||
# Provides install directory variables as defined for GNU software:
|
||||
# http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
|
||||
# Inclusion of this module defines the following variables:
|
||||
# CMAKE_INSTALL_<dir> - destination for files of a given type
|
||||
# CMAKE_INSTALL_FULL_<dir> - corresponding absolute path
|
||||
# where <dir> is one of:
|
||||
# BINDIR - user executables (bin)
|
||||
# SBINDIR - system admin executables (sbin)
|
||||
# LIBEXECDIR - program executables (libexec)
|
||||
# SYSCONFDIR - read-only single-machine data (etc)
|
||||
# SHAREDSTATEDIR - modifiable architecture-independent data (com)
|
||||
# LOCALSTATEDIR - modifiable single-machine data (var)
|
||||
# LIBDIR - object code libraries (lib or lib64)
|
||||
# INCLUDEDIR - C header files (include)
|
||||
# OLDINCLUDEDIR - C header files for non-gcc (/usr/include)
|
||||
# DATAROOTDIR - read-only architecture-independent data root (share)
|
||||
# DATADIR - read-only architecture-independent data (DATAROOTDIR)
|
||||
# INFODIR - info documentation (DATAROOTDIR/info)
|
||||
# LOCALEDIR - locale-dependent data (DATAROOTDIR/locale)
|
||||
# MANDIR - man documentation (DATAROOTDIR/man)
|
||||
# DOCDIR - documentation root (DATAROOTDIR/doc/PROJECT_NAME)
|
||||
# Each CMAKE_INSTALL_<dir> value may be passed to the DESTINATION options of
|
||||
# install() commands for the corresponding file type. If the includer does
|
||||
# not define a value the above-shown default will be used and the value will
|
||||
# appear in the cache for editing by the user.
|
||||
# Each CMAKE_INSTALL_FULL_<dir> value contains an absolute path constructed
|
||||
# from the corresponding destination by prepending (if necessary) the value
|
||||
# of CMAKE_INSTALL_PREFIX.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2011 Nikita Krupen'ko <krnekit@gmail.com>
|
||||
# Copyright 2011 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
# Installation directories
|
||||
#
|
||||
if(NOT DEFINED CMAKE_INSTALL_BINDIR)
|
||||
set(CMAKE_INSTALL_BINDIR "bin" CACHE PATH "user executables (bin)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_SBINDIR)
|
||||
set(CMAKE_INSTALL_SBINDIR "sbin" CACHE PATH "system admin executables (sbin)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_LIBEXECDIR)
|
||||
set(CMAKE_INSTALL_LIBEXECDIR "libexec" CACHE PATH "program executables (libexec)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_SYSCONFDIR)
|
||||
set(CMAKE_INSTALL_SYSCONFDIR "etc" CACHE PATH "read-only single-machine data (etc)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_SHAREDSTATEDIR)
|
||||
set(CMAKE_INSTALL_SHAREDSTATEDIR "com" CACHE PATH "modifiable architecture-independent data (com)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_LOCALSTATEDIR)
|
||||
set(CMAKE_INSTALL_LOCALSTATEDIR "var" CACHE PATH "modifiable single-machine data (var)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
|
||||
set(_LIBDIR_DEFAULT "lib")
|
||||
# Override this default 'lib' with 'lib64' iff:
|
||||
# - we are on Linux system but NOT cross-compiling
|
||||
# - we are NOT on debian
|
||||
# - we are on a 64 bits system
|
||||
# reason is: amd64 ABI: http://www.x86-64.org/documentation/abi.pdf
|
||||
# Note that the future of multi-arch handling may be even
|
||||
# more complicated than that: http://wiki.debian.org/Multiarch
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux"
|
||||
AND NOT CMAKE_CROSSCOMPILING
|
||||
AND NOT EXISTS "/etc/debian_version")
|
||||
if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
|
||||
message(AUTHOR_WARNING
|
||||
"Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
|
||||
"Please enable at least one language before including GNUInstallDirs.")
|
||||
else()
|
||||
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
set(_LIBDIR_DEFAULT "lib64")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR)
|
||||
set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE PATH "C header files (include)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_OLDINCLUDEDIR)
|
||||
set(CMAKE_INSTALL_OLDINCLUDEDIR "/usr/include" CACHE PATH "C header files for non-gcc (/usr/include)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_DATAROOTDIR)
|
||||
set(CMAKE_INSTALL_DATAROOTDIR "share" CACHE PATH "read-only architecture-independent data root (share)")
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Values whose defaults are relative to DATAROOTDIR. Store empty values in
|
||||
# the cache and store the defaults in local variables if the cache values are
|
||||
# not set explicitly. This auto-updates the defaults as DATAROOTDIR changes.
|
||||
|
||||
if(NOT CMAKE_INSTALL_DATADIR)
|
||||
set(CMAKE_INSTALL_DATADIR "" CACHE PATH "read-only architecture-independent data (DATAROOTDIR)")
|
||||
set(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_INFODIR)
|
||||
set(CMAKE_INSTALL_INFODIR "" CACHE PATH "info documentation (DATAROOTDIR/info)")
|
||||
set(CMAKE_INSTALL_INFODIR "${CMAKE_INSTALL_DATAROOTDIR}/info")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_LOCALEDIR)
|
||||
set(CMAKE_INSTALL_LOCALEDIR "" CACHE PATH "locale-dependent data (DATAROOTDIR/locale)")
|
||||
set(CMAKE_INSTALL_LOCALEDIR "${CMAKE_INSTALL_DATAROOTDIR}/locale")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_MANDIR)
|
||||
set(CMAKE_INSTALL_MANDIR "" CACHE PATH "man documentation (DATAROOTDIR/man)")
|
||||
set(CMAKE_INSTALL_MANDIR "${CMAKE_INSTALL_DATAROOTDIR}/man")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_DOCDIR)
|
||||
set(CMAKE_INSTALL_DOCDIR "" CACHE PATH "documentation root (DATAROOTDIR/doc/PROJECT_NAME)")
|
||||
set(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}")
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
mark_as_advanced(
|
||||
CMAKE_INSTALL_BINDIR
|
||||
CMAKE_INSTALL_SBINDIR
|
||||
CMAKE_INSTALL_LIBEXECDIR
|
||||
CMAKE_INSTALL_SYSCONFDIR
|
||||
CMAKE_INSTALL_SHAREDSTATEDIR
|
||||
CMAKE_INSTALL_LOCALSTATEDIR
|
||||
CMAKE_INSTALL_LIBDIR
|
||||
CMAKE_INSTALL_INCLUDEDIR
|
||||
CMAKE_INSTALL_OLDINCLUDEDIR
|
||||
CMAKE_INSTALL_DATAROOTDIR
|
||||
CMAKE_INSTALL_DATADIR
|
||||
CMAKE_INSTALL_INFODIR
|
||||
CMAKE_INSTALL_LOCALEDIR
|
||||
CMAKE_INSTALL_MANDIR
|
||||
CMAKE_INSTALL_DOCDIR
|
||||
)
|
||||
|
||||
# Result directories
|
||||
#
|
||||
foreach(dir
|
||||
BINDIR
|
||||
SBINDIR
|
||||
LIBEXECDIR
|
||||
SYSCONFDIR
|
||||
SHAREDSTATEDIR
|
||||
LOCALSTATEDIR
|
||||
LIBDIR
|
||||
INCLUDEDIR
|
||||
OLDINCLUDEDIR
|
||||
DATAROOTDIR
|
||||
DATADIR
|
||||
INFODIR
|
||||
LOCALEDIR
|
||||
MANDIR
|
||||
DOCDIR
|
||||
)
|
||||
if(NOT IS_ABSOLUTE ${CMAKE_INSTALL_${dir}})
|
||||
set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}")
|
||||
else()
|
||||
set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_${dir}}")
|
||||
endif()
|
||||
endforeach()
|
||||
@@ -1,10 +1,10 @@
|
||||
|
||||
macro(simgear_component_common name includePath sourcesList sources headers)
|
||||
macro(simgear_component name includePath sources headers)
|
||||
|
||||
if (SIMGEAR_SHARED)
|
||||
|
||||
foreach(s ${sources})
|
||||
set_property(GLOBAL
|
||||
APPEND PROPERTY ${sourcesList} "${CMAKE_CURRENT_SOURCE_DIR}/${s}")
|
||||
APPEND PROPERTY ALL_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${s}")
|
||||
endforeach()
|
||||
|
||||
foreach(h ${headers})
|
||||
@@ -14,18 +14,10 @@ macro(simgear_component_common name includePath sourcesList sources headers)
|
||||
|
||||
else()
|
||||
set(libName "sg${name}")
|
||||
add_library(${libName} STATIC ${sources} ${headers})
|
||||
add_library(${libName} STATIC ${sources} )
|
||||
|
||||
install (TARGETS ${libName} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
install (TARGETS ${libName} ARCHIVE DESTINATION lib${LIB_SUFFIX})
|
||||
install (FILES ${headers} DESTINATION include/simgear/${includePath})
|
||||
endif()
|
||||
|
||||
install (FILES ${headers} DESTINATION include/simgear/${includePath})
|
||||
endmacro()
|
||||
|
||||
function(simgear_component name includePath sources headers)
|
||||
simgear_component_common(${name} ${includePath} CORE_SOURCES "${sources}" "${headers}")
|
||||
endfunction()
|
||||
|
||||
function(simgear_scene_component name includePath sources headers)
|
||||
simgear_component_common(${name} ${includePath} SCENE_SOURCES "${sources}" "${headers}")
|
||||
endfunction()
|
||||
|
||||
18
Makefile.am
Normal file
18
Makefile.am
Normal file
@@ -0,0 +1,18 @@
|
||||
EXTRA_DIST = \
|
||||
acinclude.m4 \
|
||||
autogen.sh \
|
||||
DoxygenMain.cxx \
|
||||
README.zlib \
|
||||
README.plib \
|
||||
README.OpenAL \
|
||||
README.OSG \
|
||||
projects
|
||||
|
||||
SUBDIRS = simgear
|
||||
|
||||
#
|
||||
# Rule to build RPM distribution package
|
||||
#
|
||||
rpm: dist
|
||||
rpm -ta $(PACKAGE)-$(VERSION).tar.gz
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
[This file is mirrored in both the FlightGear and SimGear packages.]
|
||||
|
||||
You *must* have OpenSceneGraph (OSG) installed to build this version of
|
||||
You *must* have OpenSceneGraph (OSG) installed to build this version of
|
||||
FlightGear.
|
||||
|
||||
Notice that FlightGear 2.6.0 requires at least version 3.0.0.
|
||||
Notice that FlightGear 1.9.0 requires at least version 2.7.8. Using earlier
|
||||
versions of OSG will yield serious rendering bugs.
|
||||
|
||||
You can get the latest version of OSG from:
|
||||
|
||||
@@ -21,6 +22,6 @@ ccmake .
|
||||
[ While running ccmake: press 'c' to configure, press 'c' once more, and
|
||||
then press 'g' to generate and exit ]
|
||||
|
||||
make
|
||||
make
|
||||
sudo make install
|
||||
|
||||
|
||||
706
acinclude.m4
Normal file
706
acinclude.m4
Normal file
@@ -0,0 +1,706 @@
|
||||
dnl
|
||||
dnl originally from ncftp 2.3.0
|
||||
dnl added wi_EXTRA_PDIR and wi_ANSI_C
|
||||
dnl $Id$
|
||||
dnl
|
||||
AC_DEFUN([wi_EXTRA_IDIR], [
|
||||
incdir="$1"
|
||||
if test -r $incdir ; then
|
||||
already=""
|
||||
for CPPflag in $CPPFLAGS ; do
|
||||
if test "_$CPPflag" = "_-I${incdir}" ; then
|
||||
already=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -n "$already" ; then
|
||||
echo " + already had -I$incdir" 1>&AS_MESSAGE_LOG_FD
|
||||
else
|
||||
if test "$CPPFLAGS" = "" ; then
|
||||
CPPFLAGS="-I$incdir"
|
||||
else
|
||||
CPPFLAGS="$CPPFLAGS -I$incdir"
|
||||
fi
|
||||
echo " + added -I$incdir" 1>&AS_MESSAGE_LOG_FD
|
||||
fi
|
||||
else
|
||||
echo " + IDIR is not accessible: '$myincdir'" 1>&AS_MESSAGE_LOG_FD
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN([wi_EXTRA_LDIR], [
|
||||
mylibdir="$1"
|
||||
if test -r $mylibdir ; then
|
||||
already=""
|
||||
for LDflag in $LDFLAGS ; do
|
||||
if test "_$LDflag" = "_-L${mylibdir}" ; then
|
||||
already=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -n "$already" ; then
|
||||
echo " + already had -L$mylibdir" 1>&AS_MESSAGE_LOG_FD
|
||||
else
|
||||
if test "$LDFLAGS" = "" ; then
|
||||
LDFLAGS="-L$mylibdir"
|
||||
else
|
||||
LDFLAGS="$LDFLAGS -L$mylibdir"
|
||||
fi
|
||||
echo " + added -L$mylibdir" 1>&AS_MESSAGE_LOG_FD
|
||||
fi
|
||||
else
|
||||
echo " + LDIR is not accessible: '$mylibdir'" 1>&AS_MESSAGE_LOG_FD
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl __FP__
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN([wi_EXTRA_PDIR], [
|
||||
progdir="$1"
|
||||
if test -r $progdir ; then
|
||||
case ":$PATH:" in
|
||||
*:${progdir}:*)
|
||||
echo " + already had $progdir in \$PATH" 1>&AS_MESSAGE_LOG_FD
|
||||
;;
|
||||
*)
|
||||
if test "$PATH" = "" ; then
|
||||
PATH="$progdir"
|
||||
else
|
||||
PATH="$PATH:$progdir"
|
||||
fi
|
||||
echo " + appended $progdir to \$PATH" 1>&AS_MESSAGE_LOG_FD
|
||||
;;
|
||||
esac
|
||||
else
|
||||
echo " + PDIR is not accessible: '$progdir'" 1>&AS_MESSAGE_LOG_FD
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl If you want to also look for include and lib subdirectories in the
|
||||
dnl $HOME tree, you supply "yes" as the first argument to this macro.
|
||||
dnl
|
||||
dnl If you want to look for subdirectories in include/lib directories,
|
||||
dnl you pass the names in argument 3, otherwise pass a dash.
|
||||
dnl
|
||||
AC_DEFUN([wi_EXTRA_DIRS], [echo "checking for extra include and lib directories..." 1>&6
|
||||
ifelse([$1], yes, [dnl
|
||||
b1=`cd .. ; pwd`
|
||||
b2=`cd ../.. ; pwd`
|
||||
exdirs="$HOME $j $b1 $b2 $prefix $2"
|
||||
],[dnl
|
||||
exdirs="$prefix $2"
|
||||
])
|
||||
subexdirs="$3"
|
||||
if test "$subexdirs" = "" ; then
|
||||
subexdirs="-"
|
||||
fi
|
||||
for subexdir in $subexdirs ; do
|
||||
if test "$subexdir" = "-" ; then
|
||||
subexdir=""
|
||||
else
|
||||
subexdir="/$subexdir"
|
||||
fi
|
||||
for exdir in $exdirs ; do
|
||||
if test "$exdir" != "/usr" || test "$subexdir" != ""; then
|
||||
incdir="${exdir}/include${subexdir}"
|
||||
wi_EXTRA_IDIR($incdir)
|
||||
|
||||
dnl On 64-bit machines, if lib64/ exists and is not identical to lib/
|
||||
dnl then it should be listed here, listed ahead of lib/.
|
||||
mylibdir64="${exdir}/lib64${subexdir}"
|
||||
mylibdir32="${exdir}/lib${subexdir}"
|
||||
|
||||
if test "x86_64" = $(uname -m) \
|
||||
-a ! ${mylibdir64} -ef ${mylibdir32} ; then
|
||||
wi_EXTRA_LDIR($mylibdir64)
|
||||
fi
|
||||
|
||||
wi_EXTRA_LDIR($mylibdir32)
|
||||
|
||||
progdir="${exdir}/bin${subexdir}"
|
||||
wi_EXTRA_PDIR($progdir)
|
||||
fi
|
||||
done
|
||||
done
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN([wi_HPUX_CFLAGS],
|
||||
[AC_MSG_CHECKING(if HP-UX ansi C compiler flags are needed)
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
os=`uname -s | tr '[A-Z]' '[a-z]'`
|
||||
ac_cv_hpux_flags=no
|
||||
if test "$os" = hp-ux ; then
|
||||
if test "$ac_cv_prog_gcc" = yes ; then
|
||||
if test "$CFLAGS" != "" ; then
|
||||
# Shouldn't be in there.
|
||||
CFLAGS=`echo "$CFLAGS" | sed 's/-Aa//g'`
|
||||
fi
|
||||
else
|
||||
# If you're not using gcc, then you better have a cc/c89
|
||||
# that is usable. If you have the barebones compiler, it
|
||||
# won't work. The good compiler uses -Aa for the ANSI
|
||||
# compatible stuff.
|
||||
x=`echo $CFLAGS | grep 'Aa' 2>/dev/null`
|
||||
if test "$x" = "" ; then
|
||||
CFLAGS="$CFLAGS -Aa"
|
||||
fi
|
||||
ac_cv_hpux_flags=yes
|
||||
fi
|
||||
# Also add _HPUX_SOURCE to get the extended namespace.
|
||||
x=`echo $CFLAGS | grep '_HPUX_SOURCE' 2>/dev/null`
|
||||
if test "$x" = "" ; then
|
||||
CFLAGS="$CFLAGS -D_HPUX_SOURCE"
|
||||
fi
|
||||
fi
|
||||
AC_MSG_RESULT($ac_cv_hpux_flags)
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN([wi_CFLAGS], [AC_REQUIRE([AC_PROG_CC])
|
||||
wi_HPUX_CFLAGS
|
||||
if test "$CFLAGS" = "" ; then
|
||||
CFLAGS="-O"
|
||||
elif test "$ac_cv_prog_gcc" = "yes" ; then
|
||||
case "$CFLAGS" in
|
||||
*"-g -O"*)
|
||||
#echo "using -g as default gcc CFLAGS" 1>&6
|
||||
CFLAGS=`echo $CFLAGS | sed 's/-g\ -O/-O/'`
|
||||
;;
|
||||
*"-O -g"*)
|
||||
# Leave the -g, but remove all -O options.
|
||||
#echo "using -g as default gcc CFLAGS" 1>&6
|
||||
CFLAGS=`echo $CFLAGS | sed 's/-O\ -g/-O/'`
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN([wi_PROTOTYPES], [
|
||||
AC_MSG_CHECKING(if the compiler supports function prototypes)
|
||||
AC_TRY_COMPILE(,[extern void exit(int status);],[wi_cv_prototypes=yes
|
||||
AC_DEFINE(PROTOTYPES)],wi_cv_prototypes=no)
|
||||
AC_MSG_RESULT($wi_cv_prototypes)
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN([wi_ANSI_C], [
|
||||
AC_MSG_CHECKING(ANSI-style function definitions)
|
||||
AC_TRY_COMPILE(,[int blubb(int x) { return 0; }],[wi_cv_ansi_funcs=yes
|
||||
AC_DEFINE(ANSI_FUNCS)],wi_cv_ansi_funcs=no)
|
||||
AC_MSG_RESULT($wi_cv_ansi_funcs)
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN([wi_HEADER_SYS_SELECT_H], [
|
||||
# See if <sys/select.h> is includable after <sys/time.h>
|
||||
if test "$ac_cv_header_sys_time_h" = no ; then
|
||||
AC_CHECK_HEADERS(sys/time.h sys/select.h)
|
||||
else
|
||||
AC_CHECK_HEADERS(sys/select.h)
|
||||
fi
|
||||
if test "$ac_cv_header_sys_select_h" = yes ; then
|
||||
AC_MSG_CHECKING([if <sys/select.h> is compatible with <sys/time.h>])
|
||||
selecth=yes
|
||||
if test "$ac_cv_header_sys_time_h" = yes ; then
|
||||
AC_TRY_COMPILE([#include <sys/time.h>
|
||||
#include <sys/select.h>],[
|
||||
fd_set a;
|
||||
struct timeval tmval;
|
||||
|
||||
tmval.tv_sec = 0;],selecth=yes,selecth=no)
|
||||
|
||||
if test "$selecth" = yes ; then
|
||||
AC_DEFINE(CAN_USE_SYS_SELECT_H)
|
||||
fi
|
||||
fi
|
||||
AC_MSG_RESULT($selecth)
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN([wi_LIB_RESOLV], [
|
||||
# See if we could access two well-known sites without help of any special
|
||||
# libraries, like resolv.
|
||||
|
||||
AC_TRY_RUN([
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
|
||||
main()
|
||||
{
|
||||
struct hostent *hp1, *hp2;
|
||||
int result;
|
||||
|
||||
hp1 = gethostbyname("gatekeeper.dec.com");
|
||||
hp2 = gethostbyname("ftp.ncsa.uiuc.edu");
|
||||
result = ((hp1 != (struct hostent *) 0) && (hp2 != (struct hostent *) 0));
|
||||
exit(! result);
|
||||
}],look_for_resolv=no,look_for_resolv=yes,look_for_resolv=yes)
|
||||
|
||||
AC_MSG_CHECKING([if we need to look for -lresolv])
|
||||
AC_MSG_RESULT($look_for_resolv)
|
||||
if test "$look_for_resolv" = yes ; then
|
||||
AC_CHECK_LIB(resolv,main)
|
||||
else
|
||||
ac_cv_lib_resolv=no
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
|
||||
AC_DEFUN([wi_LIB_NSL], [
|
||||
AC_MSG_CHECKING(if we can use -lnsl)
|
||||
ac_save_LIBS="$LIBS";
|
||||
LIBS="$LIBS -lnsl";
|
||||
AC_CACHE_VAL(r_cv_use_libnsl, [
|
||||
AC_TRY_RUN(
|
||||
main() { if (getpwuid(getuid())) exit(0); exit(-1); },
|
||||
nc_cv_use_libnsl=yes, nc_cv_use_libnsl=no, nc_cv_use_libnsl=no)
|
||||
])
|
||||
if test "$nc_cv_use_libnsl" = "no"; then LIBS="$ac_save_LIBS"; fi
|
||||
AC_MSG_RESULT($nc_cv_use_libnsl)
|
||||
])dnl
|
||||
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
|
||||
AC_DEFUN([nc_PATH_PROG_ZCAT], [
|
||||
AC_PATH_PROG(GZCAT,gzcat)
|
||||
AC_PATH_PROG(ZCAT,zcat)
|
||||
if test "x$GZCAT" = x ; then
|
||||
if test "x$ZCAT" != x ; then
|
||||
# See if zcat is really gzcat. gzcat has a --version option, regular
|
||||
# zcat does not.
|
||||
AC_MSG_CHECKING(if zcat is really gzcat in disguise)
|
||||
if $ZCAT --version 2> /dev/null ; then
|
||||
AC_DEFINE_UNQUOTED(GZCAT, "$ZCAT")
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
fi
|
||||
else
|
||||
AC_DEFINE_UNQUOTED(GZCAT, "$GZCAT")
|
||||
fi
|
||||
|
||||
if test "x$ZCAT" != x ; then
|
||||
AC_DEFINE_UNQUOTED(ZCAT, "$ZCAT")
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN([wi_SYSV_EXTRA_DIRS], [
|
||||
# Use System V because their curses extensions are required. This must
|
||||
# be done early so we use the -I and -L in the library checks also.
|
||||
# This is mostly a Solaris/SunOS hack. Note that doing this will also
|
||||
# use all of the other System V libraries and headers.
|
||||
|
||||
AC_MSG_CHECKING(for alternative System V libraries)
|
||||
if test -f /usr/5include/curses.h ; then
|
||||
CPPFLAGS="$CPPFLAGS -I/usr/5include"
|
||||
LDFLAGS="$LDFLAGS -L/usr/5lib"
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN([wi_DEFINE_UNAME], [
|
||||
# Get first 127 chars of all uname information. Some folks have
|
||||
# way too much stuff there, so grab only the first 127.
|
||||
unam=`uname -a 2>/dev/null | cut -c1-127`
|
||||
if test "$unam" != "" ; then
|
||||
AC_DEFINE_UNQUOTED(UNAME, "$unam")
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN([wi_READLINE_WITH_NCURSES], [
|
||||
# Readline and Ncurses could both define "backspace".
|
||||
# Warn about this if we have both things in our definitions list.
|
||||
|
||||
if test "$ac_cv_lib_readline" = yes && test "$ac_cv_lib_ncurses" = yes ; then
|
||||
|
||||
AC_MSG_CHECKING(if readline and ncurses will link together)
|
||||
j="$LIBS"
|
||||
LIBS="-lreadline -lncurses"
|
||||
AC_TRY_LINK(,[
|
||||
readline("prompt");
|
||||
endwin();
|
||||
],k=yes,k=no)
|
||||
if test "$k" = no ; then
|
||||
AC_MSG_RESULT(no)
|
||||
# Remove '-lreadline' from LIBS.
|
||||
LIBS=`echo $j | sed s/-lreadline//g`
|
||||
ac_cv_lib_readline=no
|
||||
AC_WARN([The versions of GNU readline and ncurses you have installed on this system
|
||||
can't be used together, because they use the same symbol, backspace. If
|
||||
possible, recompile one of the libraries with -Dbackspace=back_space, then
|
||||
re-run configure.])
|
||||
|
||||
else
|
||||
AC_MSG_RESULT(yes)
|
||||
LIBS="$j"
|
||||
fi
|
||||
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
|
||||
dnl AC_EXT_DAYLIGHT
|
||||
dnl Check for an external variable daylight. Stolen from w3c-libwww.
|
||||
AC_DEFUN([AC_EXT_DAYLIGHT],
|
||||
[ AC_MSG_CHECKING(int daylight variable)
|
||||
AC_TRY_COMPILE([#include <time.h>], [return daylight;],
|
||||
have_daylight=yes,
|
||||
have_daylight=no)
|
||||
AC_MSG_RESULT($have_daylight)
|
||||
])dnl
|
||||
|
||||
dnl AC_EXT_TIMEZONE
|
||||
dnl Check for an external variable timezone. Stolen from tcl-8.0.
|
||||
AC_DEFUN([AC_EXT_TIMEZONE],
|
||||
[
|
||||
#
|
||||
# Its important to include time.h in this check, as some systems (like convex)
|
||||
# have timezone functions, etc.
|
||||
#
|
||||
have_timezone=no
|
||||
AC_MSG_CHECKING([long timezone variable])
|
||||
AC_TRY_COMPILE([#include <time.h>],
|
||||
[extern long timezone;
|
||||
timezone += 1;
|
||||
exit (0);],
|
||||
[have_timezone=yes
|
||||
AC_MSG_RESULT(yes)],
|
||||
AC_MSG_RESULT(no))
|
||||
|
||||
#
|
||||
# On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
|
||||
#
|
||||
if test "$have_timezone" = no; then
|
||||
AC_MSG_CHECKING([time_t timezone variable])
|
||||
AC_TRY_COMPILE([#include <time.h>],
|
||||
[extern time_t timezone;
|
||||
timezone += 1;
|
||||
exit (0);],
|
||||
[have_timezone=yes
|
||||
AC_MSG_RESULT(yes)],
|
||||
AC_MSG_RESULT(no))
|
||||
fi
|
||||
])dnl
|
||||
|
||||
## AC_BZ_SET_COMPILER: Addition by Theodore Papadopoulo
|
||||
## Patch by Jim McKelvey: change sed -e 's/ /@/g' to sed -e 's/ /@/'
|
||||
AC_DEFUN([AC_SG_SET_COMPILER],
|
||||
[cxxwith=`echo $1 | sed -e 's/ /@/'`
|
||||
case "$cxxwith" in
|
||||
*:*@*) # Full initialization syntax
|
||||
CXX=`echo "$cxxwith" | sed -n -e 's/.*:\(.*\)@.*/\1/p'`
|
||||
CXXFLAGS=`echo "$cxxwith" | sed -n -e 's/.*:.*@\(.*\)/\1/p'`
|
||||
;;
|
||||
*:*) # Simple initialization syntax
|
||||
CXX=`echo "$cxxwith" | sed -n -e 's/.*:\(.*\)/\1/p'`
|
||||
CXXFLAGS=$3
|
||||
;;
|
||||
*) # Default values
|
||||
CXX=$2
|
||||
CXXFLAGS=$3
|
||||
CC="$2 --c"
|
||||
## CFLAGS=
|
||||
;;
|
||||
esac])
|
||||
|
||||
pushdef([AC_PROG_INSTALL],
|
||||
[
|
||||
dnl our own version, testing for a -p flag
|
||||
popdef([AC_PROG_INSTALL])
|
||||
dnl as AC_PROG_INSTALL works as it works we first have
|
||||
dnl to save if the user didn't specify INSTALL, as the
|
||||
dnl autoconf one overwrites INSTALL and we have no chance to find
|
||||
dnl out afterwards
|
||||
AC_PROG_INSTALL
|
||||
|
||||
# OK, user hasn't given any INSTALL, autoconf found one for us
|
||||
# now we test, if it supports the -p flag
|
||||
AC_MSG_CHECKING(for -p flag to install)
|
||||
rm -f confinst.$$.* > /dev/null 2>&1
|
||||
echo "Testtest" > confinst.$$.orig
|
||||
ac_res=no
|
||||
if ${INSTALL} -p confinst.$$.orig confinst.$$.new > /dev/null 2>&1 ; then
|
||||
if test -f confinst.$$.new ; then
|
||||
# OK, -p seems to do no harm to install
|
||||
INSTALL="${INSTALL} -p"
|
||||
ac_res=yes
|
||||
fi
|
||||
fi
|
||||
rm -f confinst.$$.*
|
||||
AC_MSG_RESULT($ac_res)
|
||||
dnl the following tries to resolve some signs and wonders coming up
|
||||
dnl with different autoconf/automake versions
|
||||
dnl e.g.:
|
||||
dnl *automake 1.4 install-strip sets A_M_INSTALL_PROGRAM_FLAGS to -s
|
||||
dnl and has INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(A_M_INSTALL_PROGRAM_FLAGS)
|
||||
dnl it header-vars.am, so there the actual INSTALL_PROGRAM gets the -s
|
||||
dnl *automake 1.4a (and above) use INSTALL_STRIP_FLAG and only has
|
||||
dnl INSTALL_PROGRAM = @INSTALL_PROGRAM@ there, but changes the
|
||||
dnl install-@DIR@PROGRAMS targets to explicitly use that flag
|
||||
dnl *autoconf 2.13 is dumb, and thinks it can use INSTALL_PROGRAM as
|
||||
dnl INSTALL_SCRIPT, which breaks with automake <= 1.4
|
||||
dnl *autoconf >2.13 (since 10.Apr 1999) has not that failure
|
||||
dnl to clean up that mess we:
|
||||
dnl +set INSTALL_PROGRAM to use INSTALL_STRIP_FLAG
|
||||
dnl which cleans KDE's program with automake > 1.4;
|
||||
dnl +set INSTALL_SCRIPT to only use INSTALL, to clean up autoconf's problems
|
||||
dnl with automake<=1.4
|
||||
dnl note that dues to this sometimes two '-s' flags are used
|
||||
INSTALL_PROGRAM='${INSTALL} $(INSTALL_STRIP_FLAG)'
|
||||
INSTALL_SCRIPT='${INSTALL}'
|
||||
])dnl
|
||||
|
||||
# ===========================================================================
|
||||
# http://autoconf-archive.cryp.to/ax_boost_base.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_BOOST_BASE([MINIMUM-VERSION])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Test for the Boost C++ libraries of a particular version (or newer)
|
||||
#
|
||||
# If no path to the installed boost library is given the macro searchs
|
||||
# under /usr, /usr/local, /opt and /opt/local and evaluates the
|
||||
# $BOOST_ROOT environment variable. Further documentation is available at
|
||||
# <http://randspringer.de/boost/index.html>.
|
||||
#
|
||||
# This macro calls:
|
||||
#
|
||||
# AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS)
|
||||
#
|
||||
# And sets:
|
||||
#
|
||||
# HAVE_BOOST
|
||||
#
|
||||
# LAST MODIFICATION
|
||||
#
|
||||
# 2008-04-12
|
||||
#
|
||||
# COPYLEFT
|
||||
#
|
||||
# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved.
|
||||
|
||||
AC_DEFUN([AX_BOOST_BASE],
|
||||
[
|
||||
AC_ARG_WITH([boost],
|
||||
AS_HELP_STRING([--with-boost@<:@=DIR@:>@], [use boost (default is yes) - it is possible to specify the root directory for boost (optional)]),
|
||||
[
|
||||
if test "$withval" = "no"; then
|
||||
want_boost="no"
|
||||
elif test "$withval" = "yes"; then
|
||||
want_boost="yes"
|
||||
ac_boost_path=""
|
||||
else
|
||||
want_boost="yes"
|
||||
ac_boost_path="$withval"
|
||||
fi
|
||||
],
|
||||
[want_boost="yes"])
|
||||
|
||||
|
||||
AC_ARG_WITH([boost-libdir],
|
||||
AS_HELP_STRING([--with-boost-libdir=LIB_DIR],
|
||||
[Force given directory for boost libraries. Note that this will overwrite library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]),
|
||||
[
|
||||
if test -d $withval
|
||||
then
|
||||
ac_boost_lib_path="$withval"
|
||||
else
|
||||
AC_MSG_ERROR(--with-boost-libdir expected directory name)
|
||||
fi
|
||||
],
|
||||
[ac_boost_lib_path=""]
|
||||
)
|
||||
|
||||
if test "x$want_boost" = "xyes"; then
|
||||
boost_lib_version_req=ifelse([$1], ,1.20.0,$1)
|
||||
boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'`
|
||||
boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'`
|
||||
boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'`
|
||||
boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
|
||||
if test "x$boost_lib_version_req_sub_minor" = "x" ; then
|
||||
boost_lib_version_req_sub_minor="0"
|
||||
fi
|
||||
WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor`
|
||||
AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req)
|
||||
succeeded=no
|
||||
|
||||
dnl first we check the system location for boost libraries
|
||||
dnl this location ist chosen if boost libraries are installed with the --layout=system option
|
||||
dnl or if you install boost with RPM
|
||||
if test "$ac_boost_path" != ""; then
|
||||
BOOST_LDFLAGS="-L$ac_boost_path/lib"
|
||||
BOOST_CPPFLAGS="-I$ac_boost_path/include"
|
||||
else
|
||||
for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do
|
||||
if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then
|
||||
BOOST_LDFLAGS="-L$ac_boost_path_tmp/lib"
|
||||
BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
dnl overwrite ld flags if we have required special directory with
|
||||
dnl --with-boost-libdir parameter
|
||||
if test "$ac_boost_lib_path" != ""; then
|
||||
BOOST_LDFLAGS="-L$ac_boost_lib_path"
|
||||
fi
|
||||
|
||||
CPPFLAGS_SAVED="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
|
||||
export CPPFLAGS
|
||||
|
||||
LDFLAGS_SAVED="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
|
||||
export LDFLAGS
|
||||
|
||||
AC_LANG_PUSH(C++)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
@%:@include <boost/version.hpp>
|
||||
]], [[
|
||||
#if BOOST_VERSION >= $WANT_BOOST_VERSION
|
||||
// Everything is okay
|
||||
#else
|
||||
# error Boost version is too old
|
||||
#endif
|
||||
]])],[
|
||||
AC_MSG_RESULT(yes)
|
||||
succeeded=yes
|
||||
found_system=yes
|
||||
],[
|
||||
])
|
||||
AC_LANG_POP([C++])
|
||||
|
||||
|
||||
|
||||
dnl if we found no boost with system layout we search for boost libraries
|
||||
dnl built and installed without the --layout=system option or for a staged(not installed) version
|
||||
if test "x$succeeded" != "xyes"; then
|
||||
_version=0
|
||||
if test "$ac_boost_path" != ""; then
|
||||
if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
|
||||
for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
|
||||
_version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
|
||||
V_CHECK=`expr $_version_tmp \> $_version`
|
||||
if test "$V_CHECK" = "1" ; then
|
||||
_version=$_version_tmp
|
||||
fi
|
||||
VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
|
||||
BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE"
|
||||
done
|
||||
fi
|
||||
else
|
||||
for ac_boost_path in /usr /usr/local /opt /opt/local ; do
|
||||
if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
|
||||
for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
|
||||
_version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
|
||||
V_CHECK=`expr $_version_tmp \> $_version`
|
||||
if test "$V_CHECK" = "1" ; then
|
||||
_version=$_version_tmp
|
||||
best_path=$ac_boost_path
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
|
||||
BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE"
|
||||
if test "$ac_boost_lib_path" = ""
|
||||
then
|
||||
BOOST_LDFLAGS="-L$best_path/lib"
|
||||
fi
|
||||
|
||||
if test "x$BOOST_ROOT" != "x"; then
|
||||
if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/lib" && test -r "$BOOST_ROOT/stage/lib"; then
|
||||
version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'`
|
||||
stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'`
|
||||
stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'`
|
||||
V_CHECK=`expr $stage_version_shorten \>\= $_version`
|
||||
if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then
|
||||
AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT)
|
||||
BOOST_CPPFLAGS="-I$BOOST_ROOT"
|
||||
BOOST_LDFLAGS="-L$BOOST_ROOT/stage/lib"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
|
||||
export CPPFLAGS
|
||||
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
|
||||
export LDFLAGS
|
||||
|
||||
AC_LANG_PUSH(C++)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
@%:@include <boost/version.hpp>
|
||||
]], [[
|
||||
#if BOOST_VERSION >= $WANT_BOOST_VERSION
|
||||
// Everything is okay
|
||||
#else
|
||||
# error Boost version is too old
|
||||
#endif
|
||||
]])],[
|
||||
AC_MSG_RESULT(yes)
|
||||
succeeded=yes
|
||||
found_system=yes
|
||||
],[
|
||||
])
|
||||
AC_LANG_POP([C++])
|
||||
fi
|
||||
|
||||
if test "$succeeded" != "yes" ; then
|
||||
if test "$_version" = "0" ; then
|
||||
AC_MSG_ERROR([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation.]])
|
||||
else
|
||||
AC_MSG_ERROR([Your boost libraries seems to old (version $_version).])
|
||||
fi
|
||||
else
|
||||
AC_SUBST(BOOST_CPPFLAGS)
|
||||
AC_SUBST(BOOST_LDFLAGS)
|
||||
AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available])
|
||||
fi
|
||||
|
||||
CPPFLAGS="$CPPFLAGS_SAVED"
|
||||
LDFLAGS="$LDFLAGS_SAVED"
|
||||
fi
|
||||
|
||||
])
|
||||
38
am2dsp.cfg
Normal file
38
am2dsp.cfg
Normal file
@@ -0,0 +1,38 @@
|
||||
type = StaticLibrary,Multithreaded,
|
||||
exclude_dir = threads
|
||||
|
||||
include_path = .
|
||||
include_path = ..
|
||||
include_path = .\SimGear
|
||||
include_path = ..\zlib-1.2.3
|
||||
include_path = "..\OpenAL 1.0 Software Development Kit\include"
|
||||
|
||||
define = _USE_MATH_DEFINES
|
||||
define = _CRT_SECURE_NO_DEPRECATE
|
||||
define = HAVE_CONFIG_H
|
||||
|
||||
# Rule to create simgear_config.h
|
||||
add_source_file = SOURCE=.\simgear\simgear_config.h.vc5\
|
||||
\
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"\
|
||||
\
|
||||
# Begin Custom Build - Creating config.h\
|
||||
InputPath=.\simgear\simgear_config.h.vc5\
|
||||
\
|
||||
".\simgear\simgear_config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\
|
||||
copy .\simgear\simgear_config.h.vc5 .\simgear\simgear_config.h\
|
||||
\
|
||||
# End Custom Build\
|
||||
\
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"\
|
||||
\
|
||||
# Begin Custom Build - Creating config.h\
|
||||
InputPath=.\simgear\simgear_config.h.vc5\
|
||||
\
|
||||
".\simgear\simgear_config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\
|
||||
copy .\simgear\simgear_config.h.vc5 .\simgear\simgear_config.h\
|
||||
\
|
||||
# End Custom Build\
|
||||
\
|
||||
!ENDIF\
|
||||
|
||||
52
autogen.sh
Executable file
52
autogen.sh
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/bin/sh
|
||||
|
||||
OSTYPE=`uname -s`
|
||||
MACHINE=`uname -m`
|
||||
AUTO_MAKE_VERSION=`automake --version | head -1 | awk '{print $4}' | sed -e 's/\.\([0-9]*\).*/\1/'`
|
||||
if test $AUTO_MAKE_VERSION -lt 15; then
|
||||
echo ""
|
||||
echo "You need to upgrade to automake version 1.5 or greater."
|
||||
echo "Most distributions have packages available to install or you can"
|
||||
echo "find the source for the most recent version at"
|
||||
echo "ftp://ftp.gnu.org/gnu/automake"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Host info: $OSTYPE $MACHINE"
|
||||
echo -n " automake: `automake --version | head -1 | awk '{print $4}'`"
|
||||
echo " ($AUTO_MAKE_VERSION)"
|
||||
echo ""
|
||||
|
||||
echo "Running aclocal"
|
||||
aclocal
|
||||
|
||||
echo "Running autoheader"
|
||||
autoheader
|
||||
if [ ! -e simgear/simgear_config.h.in ]; then
|
||||
echo "ERROR: autoheader didn't create simgear/simgear_config.h.in!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Running automake --add-missing"
|
||||
automake --add-missing
|
||||
|
||||
echo "Running autoconf"
|
||||
autoconf
|
||||
|
||||
if [ ! -e configure ]; then
|
||||
echo "ERROR: configure was not created!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "======================================"
|
||||
|
||||
if [ -f config.cache ]; then
|
||||
echo "config.cache exists. Removing the config.cache file will force"
|
||||
echo "the ./configure script to rerun all it's tests rather than using"
|
||||
echo "the previously cached values."
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo "Now you are ready to run './configure'"
|
||||
echo "======================================"
|
||||
670
configure.ac
Normal file
670
configure.ac
Normal file
@@ -0,0 +1,670 @@
|
||||
dnl Process this file with autogen.sh to produce a working configure
|
||||
dnl script.
|
||||
|
||||
AC_INIT(SimGear, m4_esyscmd([cat ./version | tr -d '\n']), [http://www.flightgear.org])
|
||||
|
||||
dnl Ensure touching the version causes autoconf to re-run
|
||||
AC_SUBST([CONFIGURE_DEPENDENCIES], ['$(top_srcdir)/version'])
|
||||
|
||||
AC_CONFIG_SRCDIR([simgear/bucket/newbucket.cxx])
|
||||
|
||||
dnl Require at least automake 2.52
|
||||
AC_PREREQ(2.52)
|
||||
|
||||
dnl Initialize the automake stuff
|
||||
dnl Specify KAI C++ compiler and flags.
|
||||
dnl Borrowed with slight modification from blitz distribution.
|
||||
AC_ARG_WITH(cxx,
|
||||
[ --with-cxx=COMPILER[:name-flags] set options for COMPILER (KCC)],
|
||||
[case "$withval" in
|
||||
KCC*) # KAI C++ http://www.kai.com/
|
||||
echo "Configuring for KAI C++"
|
||||
AC_SG_SET_COMPILER($withval,"KCC","--restrict --strict_warnings")
|
||||
CXX_OPTIMIZE_FLAGS=="+K3 -O3"
|
||||
CXX_DEBUG_FLAGS="-g +K0"
|
||||
;;
|
||||
esac
|
||||
])
|
||||
dnl set the $host variable based on local machine/os
|
||||
AC_CANONICAL_TARGET
|
||||
AM_INIT_AUTOMAKE([dist-bzip2])
|
||||
|
||||
AC_ARG_ENABLE(headless,
|
||||
AS_HELP_STRING([--enable-headless],[Enable only packages for headless build]))
|
||||
|
||||
AC_MSG_CHECKING([for headless mode])
|
||||
AC_MSG_RESULT([$enable_headless])
|
||||
|
||||
AM_CONDITIONAL(WANT_HEADLESS,[test "x$enable_headless" = "xyes"])
|
||||
|
||||
AC_MSG_CHECKING([CXX])
|
||||
AC_MSG_RESULT([$CXX])
|
||||
AC_MSG_CHECKING([CC])
|
||||
AC_MSG_RESULT([$CC])
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_CXX
|
||||
AC_PROG_CXXCPP
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AX_BOOST_BASE([1.37.0])
|
||||
|
||||
if test "x$BOOST_CPPFLAGS" != "x-I/usr/include" ; then
|
||||
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
|
||||
fi
|
||||
|
||||
dnl set the $host variable based on local machine/os
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
dnl Used on the Irix platform
|
||||
case "${host}" in
|
||||
*-*-irix*)
|
||||
if test "x$CXX" = "xCC" -o "x$CXX" = "xccache CC"; then
|
||||
AR="$CXX -ar"
|
||||
ARFLAGS="-o"
|
||||
CXXFLAGS="$CXXFLAGS -I$(top_srcdir)/simgear/compatibility/MIPSpro740"
|
||||
compatibility_DIR="compatibility"
|
||||
MIPSpro_DIRS="MIPSpro740"
|
||||
AC_MSG_CHECKING([for MIPSpro compiler version 7.4 or newer])
|
||||
AC_TRY_RUN([
|
||||
int main() {
|
||||
if ( _COMPILER_VERSION < 740 ) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
], AC_MSG_RESULT(yes),
|
||||
[ AC_MSG_RESULT(no)
|
||||
CXXFLAGS="$CXXFLAGS -I$(top_srcdir)/simgear/compatibility/MIPSpro721"
|
||||
MIPSpro_DIRS="$(MIPSpro_DIRS) MIPSpro721"
|
||||
AC_MSG_WARN([Using our own subset of the STL headers])
|
||||
], AC_MSG_RESULT(yes))
|
||||
AC_SUBST(MIPSpro_DIRS)
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
AR="ar"
|
||||
ARFLAGS="cru"
|
||||
compatibility_DIR=
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(AR)
|
||||
AC_SUBST(ARFLAGS)
|
||||
AC_SUBST(compatibility_DIR)
|
||||
|
||||
# Show all compiler warnings by default
|
||||
CXXFLAGS="$CXXFLAGS -Wall"
|
||||
CFLAGS="$CFLAGS -Wall"
|
||||
|
||||
if echo $includedir | egrep "simgear$" > /dev/null; then
|
||||
echo "includedir is" $includedir "libdir is" $libdir
|
||||
else
|
||||
includedir="${includedir}/simgear"
|
||||
echo "includedir changed to" $includedir "libdir is" $libdir
|
||||
fi
|
||||
|
||||
dnl set logging; default value of with_logging=yes
|
||||
AC_ARG_WITH(logging, [ --with-logging Include logging output (default)])
|
||||
if test "x$with_logging" = "xno" ; then
|
||||
AC_DEFINE([FG_NDEBUG], 1, [Define for no logging output])
|
||||
fi
|
||||
|
||||
# Specify if we want to build with Norman's jpeg image server support.
|
||||
# This requires libjpeg to be installed and available.
|
||||
# Default to with_jpeg_server=no
|
||||
JPEGLIB=''
|
||||
AC_ARG_WITH(jpeg_factory, [ --with-jpeg-factory Include Norman's jpeg image factory support code])
|
||||
if test "x$with_jpeg_factory" = "xyes" ; then
|
||||
echo "Building with Norman's jpeg image factory support"
|
||||
AC_CHECK_LIB(jpeg, jpeg_start_compress)
|
||||
if test "x$ac_cv_lib_jpeg_jpeg_start_compress" != "xyes" ; then
|
||||
echo
|
||||
echo "In order to build the jpeg factory code you need libjpeg installed."
|
||||
echo "otherwise please configure with the --with-jpeg-sever=no option"
|
||||
echo
|
||||
echo "libjpeg is available at :"
|
||||
echo " ftp://ftp.uu.net in the directory graphics/jpeg"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "Building without Norman's jpeg image server support"
|
||||
fi
|
||||
AM_CONDITIONAL(ENABLE_JPEG_SERVER, test "x$with_jpeg_factory" = "xyes")
|
||||
|
||||
# specify the osg location
|
||||
AC_ARG_WITH(osg, [ --with-osg=PREFIX Specify the prefix path to osg])
|
||||
|
||||
if test "x$with_osg" != "x" ; then
|
||||
echo "osg prefix is $with_osg"
|
||||
EXTRA_DIRS="${EXTRA_DIRS} $with_osg"
|
||||
fi
|
||||
|
||||
AC_ARG_WITH(osg_framework, [ --with-osg-framework=PREFIX Specify the prefix path to OSG.framework ])
|
||||
|
||||
if test "x$with_osg_framework" != "x"; then
|
||||
echo "osg framework prefix is $with_osg_framework"
|
||||
CPPFLAGS = "$CPPFLAGS -F$with-osg-framework"
|
||||
export DYLD_FRAMEWORK_PATH="$DYLD_FRAMEWORK_PATH:$with_osg_framework"
|
||||
fi
|
||||
|
||||
dnl specifying ALUT.framework (for user provided ALUT.framework)
|
||||
AC_ARG_WITH(alut_framework, [ --with-alut-framework=PREFIX Specify the prefix path to ALUT.framework ])
|
||||
|
||||
if test "x$with_alut_framework" != "x"; then
|
||||
echo "ALUT framework prefix is $with_alut_framework"
|
||||
fi
|
||||
|
||||
# specify the rti13 location
|
||||
AC_ARG_WITH(rti13, [ --with-rti13=PREFIX Specify the prefix path to a HLA13 rti])
|
||||
|
||||
if test "x$with_rti13" != "x" ; then
|
||||
echo "rti13 prefix is $with_rti13"
|
||||
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*)
|
||||
echo no EXTRA_DIRS for $host
|
||||
;;
|
||||
|
||||
*)
|
||||
if test -d /usr/X11R6 ; then
|
||||
EXTRA_DIR1="/usr/X11R6"
|
||||
fi
|
||||
if test -d /opt/X11R6 ; then
|
||||
EXTRA_DIR2="/opt/X11R6"
|
||||
fi
|
||||
EXTRA_DIRS="${EXTRA_DIRS} $EXTRA_DIR1 $EXTRA_DIR2"
|
||||
;;
|
||||
|
||||
esac
|
||||
wi_EXTRA_DIRS(no, ${EXTRA_DIRS})
|
||||
|
||||
|
||||
dnl Using AM_CONDITIONAL is a step out of the protected little
|
||||
dnl automake fold so it is potentially dangerous. But, we are
|
||||
dnl beginning to run into cases where the standard checks are not
|
||||
dnl enough. AM_CONDITIONALS are then referenced to conditionally
|
||||
dnl build a Makefile.in from a Makefile.am which lets us define custom
|
||||
dnl includes, compile alternative source files, etc.
|
||||
|
||||
dnl X11 might be installed on Mac OS X or cygwin/mingwin, we don't want
|
||||
dnl to use it if it is.
|
||||
case "${host}" in
|
||||
*-apple-darwin* | *-*-cygwin* | *-*-mingw32*)
|
||||
echo no fancy X11 check
|
||||
;;
|
||||
|
||||
*)
|
||||
AC_PATH_XTRA
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
dnl Checks for libraries.
|
||||
|
||||
dnl Thread related checks
|
||||
AC_CHECK_HEADER(pthread.h)
|
||||
AC_SEARCH_LIBS(pthread_exit, [pthread c_r])
|
||||
if test "x$ac_cv_header_pthread_h" = "xyes"; then
|
||||
CXXFLAGS="$CXXFLAGS -D_REENTRANT"
|
||||
CFLAGS="$CFLAGS -D_REENTRANT"
|
||||
|
||||
if test "x$ac_cv_search_pthread_exit" = "x-lc_r"; then
|
||||
CXXFLAGS="-pthread $CXXFLAGS"
|
||||
CFLAGS="-pthread $CFLAGS"
|
||||
fi
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(HAVE_THREADS, test "x$ac_cv_header_pthread_h" = "xyes")
|
||||
|
||||
thread_LIBS="$LIBS"
|
||||
LIBS=""
|
||||
|
||||
dnl search for network related libraries
|
||||
AC_SEARCH_LIBS(inet_addr, xnet)
|
||||
AC_SEARCH_LIBS(socket, socket)
|
||||
|
||||
network_LIBS="$LIBS"
|
||||
LIBS=""
|
||||
|
||||
dnl check for some default libraries
|
||||
AC_SEARCH_LIBS(cos, m)
|
||||
AC_SEARCH_LIBS(clock_gettime, rt)
|
||||
|
||||
base_LIBS="$LIBS"
|
||||
|
||||
dnl check for OpenGL related libraries
|
||||
case "${host}" in
|
||||
*-*-cygwin* | *-*-mingw32*)
|
||||
dnl CygWin under Windoze.
|
||||
|
||||
echo Win32 specific hacks...
|
||||
AC_DEFINE([WIN32], 1, [Define for Win32 platforms])
|
||||
AC_DEFINE([NOMINMAX], 1, [Define for Win32 platforms])
|
||||
|
||||
LIBS="$LIBS -lglu32 -lopengl32"
|
||||
LIBS="$LIBS -luser32 -lgdi32 -lwinmm"
|
||||
|
||||
dnl add -lwsock32 for mingwin
|
||||
case "${host}" in
|
||||
*-*-mingw32*)
|
||||
base_LIBS="$base_LIBS -lws2_32"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Will link apps with $LIBS"
|
||||
;;
|
||||
|
||||
*-apple-darwin*)
|
||||
dnl Mac OS X
|
||||
|
||||
LIBS="$LIBS -framework OpenGL -framework Carbon -lobjc"
|
||||
;;
|
||||
|
||||
*)
|
||||
dnl X-Windows based machines
|
||||
|
||||
AC_SEARCH_LIBS(XCreateWindow, X11)
|
||||
AC_SEARCH_LIBS(XShmCreateImage, Xext)
|
||||
AC_SEARCH_LIBS(XGetExtensionVersion, Xi)
|
||||
AC_SEARCH_LIBS(IceOpenConnection, ICE)
|
||||
AC_SEARCH_LIBS(SmcOpenConnection, SM)
|
||||
AC_SEARCH_LIBS(XtMalloc, Xt)
|
||||
AC_SEARCH_LIBS(XmuLookupStandardColormap, Xmu)
|
||||
|
||||
AC_SEARCH_LIBS(glNewList, [ GL GLcore MesaGL ])
|
||||
if test "x$ac_cv_search_glNewList" = "x-lGLcore"; then
|
||||
dnl if GLcore found, then also check for GL
|
||||
AC_SEARCH_LIBS(glXCreateContext, GL)
|
||||
fi
|
||||
|
||||
dnl if using mesa, check for xmesa.h
|
||||
if test "x$ac_cv_search_glNewList" = "x-lMesaGL"; then
|
||||
AC_CHECK_HEADER(GL/fxmesa.h)
|
||||
if test "x$ac_cv_header_GL_fxmesa_h" = "xyes"; then
|
||||
AC_DEFINE([XMESA], 1, [Define for fxmesa])
|
||||
AC_DEFINE([FX], 1, [Define for fxmesa])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SEARCH_LIBS(gluLookAt, [ GLU MesaGLU ])
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
opengl_LIBS="$LIBS"
|
||||
LIBS="$base_LIBS"
|
||||
|
||||
dnl check for OpenAL libraries
|
||||
OPENAL_OK="no"
|
||||
ALUT_OK="no"
|
||||
case "${host}" in
|
||||
*-*-cygwin* | *-*-mingw32*)
|
||||
dnl CygWin under Windoze.
|
||||
INCLUDES="$INCLUDES -I/usr/local/include/"
|
||||
LIBS="$LIBS -L/usr/local/lib"
|
||||
AC_SEARCH_LIBS(alGenBuffers, [ openal32 openal 'openal -ldsound -lwinmm' ] )
|
||||
AC_SEARCH_LIBS(alutInit, [ openal32 ALut alut ] )
|
||||
LIBS="$LIBS -lwinmm -ldsound -ldxguid -lole32"
|
||||
openal_LIBS="$LIBS"
|
||||
OPENAL_OK="$ac_cv_search_alGenBuffers"
|
||||
ALUT_OK="$ac_cv_search_alutInit"
|
||||
;;
|
||||
|
||||
*-apple-darwin*)
|
||||
dnl Mac OS X
|
||||
|
||||
LIBS="$LIBS -framework IOKit -framework OpenAL -framework ALUT"
|
||||
openal_LIBS="$LIBS"
|
||||
|
||||
if test "x$with_openal_lib" != "x"; then
|
||||
echo "libopenal is not supported on Mac OS platform."
|
||||
openal_LIBS=""
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS([OpenAL/al.h],[OPENAL_OK="yes"])
|
||||
# Looking for alut.h
|
||||
AC_CHECK_HEADERS([ALUT/alut.h],[ALUT_OK="yes"])
|
||||
|
||||
dnl Thank you Christian Bauer from SheepSaver
|
||||
dnl Modified by Tatsuhiro Nishioka for accepting a given framework path
|
||||
dnl AC_CHECK_FRAMEWORK($1=NAME, $2=INCLUDES, $3=FRAMEWORK_PATH, $4=ACTION_IF_TRUE) ; $3 is optional
|
||||
AC_DEFUN([AC_CHECK_FRAMEWORK], [
|
||||
AS_VAR_PUSHDEF([ac_Framework], [ac_cv_framework_$1])dnl
|
||||
AC_CACHE_CHECK([whether compiler supports framework $1],
|
||||
ac_Framework, [
|
||||
saved_LIBS="$LIBS"
|
||||
FRAMEWORKS="$FRAMEWORKS -framework $1"
|
||||
if test "$3" = ""; then
|
||||
FRAMEWORKS="$FRAMEWORKS $ADD2LD"
|
||||
elif test "`echo $FRAMEWORKS | grep -- -F$3`" = ""; then
|
||||
FRAMEWORKS="$FRAMEWORKS -F$3"
|
||||
CXXFLAGS="$CXXFLAGS -F$3"
|
||||
CPPFLAGS="$CPPFLAGS -F$3"
|
||||
CCFLAGS="$CCFLAGS -F$3"
|
||||
dnl This is needed for AC_TRY_LINK when a framework path is specified
|
||||
export DYLD_FRAMEWORK_PATH="${DYLD_FRAMEWORK_PATH}:$3"
|
||||
fi
|
||||
AC_TRY_LINK(
|
||||
[$2], [],
|
||||
[AS_VAR_SET(ac_Framework, yes)], [AS_VAR_SET(ac_Framework, no); LIBS="$saved_LIBS"]
|
||||
)
|
||||
])
|
||||
AS_IF([test AS_VAR_GET(ac_Framework) = yes],
|
||||
[AC_DEFINE(AS_TR_CPP(HAVE_FRAMEWORK_$1), 1, [Define if framework $1 is available.])]
|
||||
)
|
||||
AS_IF([test AS_VAR_GET(ac_Framework) = yes], $4)
|
||||
|
||||
AS_VAR_POPDEF([ac_Framework])dnl
|
||||
])
|
||||
|
||||
dnl Check for ALUT.framework when --with-alut-framework is specified
|
||||
if test "x$with_alut_framework" != "x"; then
|
||||
AC_CHECK_FRAMEWORK(ALUT, [#include <ALUT/alut.h>], $with_alut_framework, [ALUT_OK="yes"])
|
||||
fi
|
||||
|
||||
;;
|
||||
|
||||
*)
|
||||
dnl default unix style machines
|
||||
|
||||
save_LIBS=$LIBS
|
||||
LIBS="$LIBS $thread_LIBS"
|
||||
AC_SEARCH_LIBS(alGenBuffers, openal)
|
||||
AC_SEARCH_LIBS(alutInit, [ alut openal ] )
|
||||
OPENAL_OK="$ac_cv_search_alGenBuffers"
|
||||
ALUT_OK="$ac_cv_search_alutInit"
|
||||
openal_LIBS="$LIBS"
|
||||
LIBS=$save_LIBS
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
if test "$OPENAL_OK" == "no" -a "x$enable_headless" != "xyes"; then
|
||||
echo
|
||||
echo "You *must* have the openal library installed on your system to build"
|
||||
echo "SimGear!"
|
||||
echo
|
||||
echo "Please see README.OpenAL for more details."
|
||||
echo
|
||||
echo "configure aborted."
|
||||
exit
|
||||
fi
|
||||
|
||||
if test "$ALUT_OK" == "no" -a "x$enable_headless" != "xyes"; then
|
||||
echo
|
||||
echo "You *must* have the alut library installed on your system to build"
|
||||
echo "SimGear!"
|
||||
echo
|
||||
echo "Please see README.OpenAL for more details."
|
||||
echo
|
||||
echo "configure aborted."
|
||||
exit
|
||||
fi
|
||||
|
||||
|
||||
|
||||
LIBS="$base_LIBS"
|
||||
|
||||
AC_SUBST(base_LIBS)
|
||||
AC_SUBST(openal_LIBS)
|
||||
AC_SUBST(opengl_LIBS)
|
||||
AC_SUBST(thread_LIBS)
|
||||
AC_SUBST(network_LIBS)
|
||||
|
||||
dnl Check for MS Windows environment
|
||||
AC_CHECK_HEADER(windows.h)
|
||||
AM_CONDITIONAL(EXTGL_NEEDED, test "x$ac_cv_header_windows_h" = "xyes")
|
||||
|
||||
# The following are C++ items that need to be tested for with the c++
|
||||
# compiler
|
||||
|
||||
CXXCPP="g++ -E"
|
||||
AC_LANG_PUSH(C++)
|
||||
|
||||
# OpenSceneGraph
|
||||
case "${host}" in
|
||||
*-apple-darwin*)
|
||||
if test "x$with_osg_framework" != "x"; then
|
||||
# AC_CHECK_FRAMEWORK(osgViewer, [#include <osgViewer/Version>], $with_osg_framework)
|
||||
# AC_CHECK_FRAMEWORK(osgGA, [#include <osgGA/Version>], $with_osg_framework)
|
||||
# AC_CHECK_FRAMEWORK(osgText, [#include <osgText/Version>], $with_osg_framework)
|
||||
# AC_CHECK_FRAMEWORK(osgFX, [#include <osgFX/AnisotropicLighting>], $with_osg_framework)
|
||||
# AC_CHECK_FRAMEWORK(osgUtil, [#include <osgUtil/Version>], $with_osg_framework)
|
||||
# AC_CHECK_FRAMEWORK(osgDB, [#include <osgDB/Version>], $with_osg_framework)
|
||||
# AC_CHECK_FRAMEWORK(osgSim, [#include <osgSim/Version>], $with_osg_framework)
|
||||
# AC_CHECK_FRAMEWORK(osgParticle, [#include <osgParticle/Version>], $with_osg_framework)
|
||||
AC_CHECK_FRAMEWORK(osg, [#include <osg/Version>], $with_osg_framework)
|
||||
# osg_FRAMEWORKS="$FRAMEWORKS"
|
||||
# FRAMEWORKS=""
|
||||
# AC_SUBST(osg_FRAMEWORKS)
|
||||
AC_CHECK_FRAMEWORK(OpenThreads, [#include <OpenThreads/Version>], $with_osg_framework)
|
||||
openthreads_FRAMEWORK="$FRAMEWORKS"
|
||||
FRAMEWORKS=""
|
||||
AC_SUBST(openthreads_FRAMEWORK)
|
||||
else
|
||||
dnl
|
||||
dnl This is needed when osg dynamic libs are specified
|
||||
dnl instead of OSG frameworks on Mac OS X
|
||||
dnl
|
||||
AC_CHECK_LIB(OpenThreads,OpenThreadsGetVersion)
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
if test "x$enable_osgdebug" = "xyes"; then
|
||||
AC_CHECK_LIB(OpenThreadsd,OpenThreadsGetVersion)
|
||||
else
|
||||
AC_CHECK_LIB(OpenThreads,OpenThreadsGetVersion)
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
AM_CONDITIONAL(HAVE_FRAMEWORK_OSG, test "x$ac_cv_framework_osg" != "x")
|
||||
|
||||
AC_CHECK_HEADER(osg/Version)
|
||||
|
||||
if test "x$ac_cv_header_osg_Version" != "xyes" -o "x$ac_cv_lib_OpenThreads_OpenThreadsGetVersion" != "xyes"; then
|
||||
if test "x$ac_cv_framework_osg" != "xyes"; then
|
||||
echo
|
||||
echo "You *must* have the OpenThreads library installed on your system"
|
||||
echo "to build this version of SimGear!"
|
||||
echo " Maybe you need to specify --with-osg=DIR."
|
||||
echo " Maybe you need to specify some LDFLAGS to help the linker."
|
||||
echo
|
||||
echo " LIBS: '$LIBS'"
|
||||
echo " LDFLAGS: '$LDFLAGS'"
|
||||
echo " CPPFLAGS: '$CPPFLAGS'"
|
||||
echo
|
||||
echo "Please see README.OSG for more details."
|
||||
echo
|
||||
echo "configure aborted."
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADER(boost/version.hpp)
|
||||
if test "x$ac_cv_header_boost_version_hpp" != "xyes"; then
|
||||
echo
|
||||
echo "You *must* have the Boost library installed on your system"
|
||||
echo "to build this version of SimGear!"
|
||||
echo
|
||||
echo " LIBS: '$LIBS'"
|
||||
echo " LDFLAGS: '$LDFLAGS'"
|
||||
echo " CPPFLAGS: '$CPPFLAGS'"
|
||||
echo
|
||||
echo "configure aborted."
|
||||
exit
|
||||
fi
|
||||
|
||||
dnl Check for a HLA13 rti.
|
||||
dnl This is really tricky because of the ancient iostream stuff in RTI13
|
||||
saved_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS -DRTI_USES_STD_FSTREAM"
|
||||
AC_CHECK_HEADER(RTI.hh)
|
||||
CPPFLAGS="${saved_CPPFLAGS}"
|
||||
|
||||
dnl Up to now only RTI13
|
||||
AM_CONDITIONAL(ENABLE_HLA, test "x$ac_cv_header_RTI_hh" = "xyes")
|
||||
AM_CONDITIONAL(ENABLE_HLA13, test "x$ac_cv_header_RTI_hh" = "xyes")
|
||||
|
||||
AC_LANG_POP
|
||||
|
||||
dnl Check for system installed zlib
|
||||
AC_CHECK_HEADER(zlib.h)
|
||||
if test "x$ac_cv_header_zlib_h" != "xyes"; then
|
||||
echo
|
||||
echo "zlib library not found."
|
||||
echo
|
||||
echo "If your OS does not provide an installable package for zlib"
|
||||
echo "you will have to compile and install it first yourself. A copy"
|
||||
echo "of zlib-1.1.4.tar.gz is included with SimGear. You will"
|
||||
echo "have to untar this source code, and follow its included instructions"
|
||||
echo "to compile and install on your system."
|
||||
echo
|
||||
echo "configure aborted."
|
||||
echo
|
||||
fi
|
||||
|
||||
dnl Check for Subversion library support
|
||||
# libsvn support defaults to yes
|
||||
save_LIBS=$LIBS
|
||||
save_CPPFLAGS=$CPPFLAGS
|
||||
AC_ARG_WITH(libsvn, [ --without-libsvn Do not use built-in subversion (libsvn) for simgear [default=no]], [], [with_libsvn=yes])
|
||||
if test "x$with_libsvn" = "xyes"; then
|
||||
LIBS="`apr-1-config --link-ld`"
|
||||
CPPFLAGS="-I/usr/include/subversion-1 `apr-1-config --includes --cppflags`"
|
||||
AC_CHECK_HEADERS([svn_client.h])
|
||||
if test "x$ac_cv_header_svn_client_h" = "xyes"; then
|
||||
echo "Using built-in subversion (libsvn) for scenery downloads."
|
||||
AC_SEARCH_LIBS(svn_client_checkout, svn_client-1,
|
||||
[AC_DEFINE([HAVE_LIBSVN_CLIENT_1], [1], [Define to 1 if you have libsvn_client-1])],
|
||||
[AC_MSG_ERROR(svn_client-1 library not found.)],)
|
||||
AC_SEARCH_LIBS(svn_cmdline_init, svn_subr-1, , [AC_MSG_ERROR(svn_subr-1 library not found.)],)
|
||||
AC_SEARCH_LIBS(svn_ra_initialize, svn_ra-1, , [AC_MSG_ERROR(svn_ra-1 library not found.)],)
|
||||
svn_LIBS=$LIBS
|
||||
svn_CPPFLAGS=$CPPFLAGS
|
||||
AC_SUBST(svn_LIBS)
|
||||
AC_SUBST(svn_CPPFLAGS)
|
||||
else
|
||||
echo "Libsvn not found. Will use command line subversion for scenery downloads."
|
||||
svn_LIBS=""
|
||||
svn_CPPFLAGS=""
|
||||
fi
|
||||
else
|
||||
echo "Libsvn explicitly disabled. Will use command line subversion for scenery downloads."
|
||||
svn_LIBS=""
|
||||
svn_CPPFLAGS=""
|
||||
fi
|
||||
LIBS=$save_LIBS
|
||||
CPPFLAGS=$save_CPPFLAGS
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS( \
|
||||
fcntl.h getopt.h malloc.h memory.h stdint.h stdlib.h sys/param.h \
|
||||
sys/stat.h sys/time.h sys/timeb.h unistd.h values.h )
|
||||
|
||||
if test "x$ac_cv_header_stdint_h" = "xyes"; then
|
||||
AC_DEFINE([HAVE_STDINT_H], 1, [Define if stdint.h exists])
|
||||
fi
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_MODE_T
|
||||
AC_HEADER_TIME
|
||||
AC_STRUCT_TM
|
||||
|
||||
dnl Checks for library functions.
|
||||
old_LIBS=$LIBS
|
||||
LIBS="$base_LIBS $network_LIBS $opengl_LIBS"
|
||||
AC_TYPE_SIGNAL
|
||||
AC_FUNC_VPRINTF
|
||||
AC_CHECK_FUNCS( [ \
|
||||
ftime gettimeofday timegm memcpy bcopy mktime strstr rand \
|
||||
random drand48 setitimer getitimer signal GetLocalTime rint getrusage ] )
|
||||
LIBS=$old_LIBS
|
||||
|
||||
AM_CONFIG_HEADER(simgear/simgear_config.h)
|
||||
|
||||
AC_CONFIG_FILES([ \
|
||||
Makefile \
|
||||
SimGear.spec \
|
||||
simgear/Makefile \
|
||||
simgear/version.h \
|
||||
simgear/compatibility/Makefile \
|
||||
simgear/compatibility/MIPSpro721/Makefile \
|
||||
simgear/compatibility/MIPSpro740/Makefile \
|
||||
simgear/bucket/Makefile \
|
||||
simgear/debug/Makefile \
|
||||
simgear/ephemeris/Makefile \
|
||||
simgear/hla/Makefile \
|
||||
simgear/io/Makefile \
|
||||
simgear/magvar/Makefile \
|
||||
simgear/math/Makefile \
|
||||
simgear/environment/Makefile \
|
||||
simgear/misc/Makefile \
|
||||
simgear/nasal/Makefile \
|
||||
simgear/props/Makefile \
|
||||
simgear/route/Makefile \
|
||||
simgear/scene/Makefile \
|
||||
simgear/scene/bvh/Makefile \
|
||||
simgear/scene/material/Makefile \
|
||||
simgear/scene/model/Makefile \
|
||||
simgear/scene/sky/Makefile \
|
||||
simgear/scene/tgdb/Makefile \
|
||||
simgear/scene/util/Makefile \
|
||||
simgear/scene/tsync/Makefile \
|
||||
simgear/screen/Makefile \
|
||||
simgear/serial/Makefile \
|
||||
simgear/sound/Makefile \
|
||||
simgear/structure/Makefile \
|
||||
simgear/threads/Makefile \
|
||||
simgear/timing/Makefile \
|
||||
simgear/xml/Makefile \
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
|
||||
echo ""
|
||||
echo "Configure Summary"
|
||||
echo "================="
|
||||
|
||||
echo "Prefix: $prefix"
|
||||
|
||||
if test "x$with_logging" != "x"; then
|
||||
echo "Debug messages: $with_logging"
|
||||
else
|
||||
echo "Debug messages: yes"
|
||||
fi
|
||||
|
||||
echo -n "Automake version: "
|
||||
automake --version | head -1
|
||||
|
||||
if test "x$with_jpeg_factory" = "xyes"; then
|
||||
echo "With JPEG Factory support"
|
||||
else
|
||||
echo "Without JPEG Factory support"
|
||||
fi
|
||||
|
||||
if test "x$ac_cv_header_pthread_h" = "xyes"; then
|
||||
echo "Threads: pthread lib found."
|
||||
else
|
||||
echo "Threads: no threads (pthread lib not found.)"
|
||||
fi
|
||||
|
||||
@@ -439,22 +439,6 @@
|
||||
<Filter
|
||||
Name="Lib_sgio"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\simgear\io\HTTPClient.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\io\HTTPClient.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\io\HTTPRequest.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\io\HTTPRequest.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\io\iochannel.cxx"
|
||||
>
|
||||
@@ -599,6 +583,14 @@
|
||||
RelativePath="..\..\simgear\math\localconsts.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\project.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\project.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\sg_geodesy.hxx"
|
||||
>
|
||||
@@ -643,6 +635,14 @@
|
||||
RelativePath="..\..\simgear\misc\interpolator.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\misc\PathOptions.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\misc\PathOptions.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\misc\ResourceManager.cxx"
|
||||
>
|
||||
@@ -667,6 +667,14 @@
|
||||
RelativePath="..\..\simgear\misc\sg_path.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\misc\sg_sleep.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\misc\sg_sleep.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\misc\sgstream.cxx"
|
||||
>
|
||||
@@ -1007,6 +1015,10 @@
|
||||
RelativePath="..\..\simgear\props\propertyObject.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\props\tiedpropertylist.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\props\props.cxx"
|
||||
>
|
||||
@@ -1023,10 +1035,6 @@
|
||||
RelativePath="..\..\simgear\props\props_io.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\props\tiedpropertylist.hxx"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Lib_sgmodel"
|
||||
@@ -1135,6 +1143,14 @@
|
||||
RelativePath="..\..\simgear\scene\model\SGOffsetTransform.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\SGPagedLOD.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\SGPagedLOD.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\SGReaderWriterXML.cxx"
|
||||
>
|
||||
@@ -1143,6 +1159,10 @@
|
||||
RelativePath="..\..\simgear\scene\model\SGReaderWriterXML.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\SGReaderWriterXMLOptions.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\SGRotateTransform.cxx"
|
||||
>
|
||||
@@ -1339,10 +1359,6 @@
|
||||
RelativePath="..\..\simgear\scene\tgdb\apt_signs.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\BucketBox.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\GroundLightManager.cxx"
|
||||
>
|
||||
@@ -1367,14 +1383,6 @@
|
||||
RelativePath="..\..\simgear\scene\tgdb\pt_lights.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\ReaderWriterSPT.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\ReaderWriterSPT.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\ReaderWriterSTG.cxx"
|
||||
>
|
||||
@@ -1399,6 +1407,10 @@
|
||||
RelativePath="..\..\simgear\scene\tgdb\SGReaderWriterBTG.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\SGReaderWriterBTGOptions.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\SGVasiDrawable.cxx"
|
||||
>
|
||||
@@ -1447,7 +1459,7 @@
|
||||
RelativePath="..\..\simgear\scene\tgdb\userdata.hxx"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Lib_sgtsync"
|
||||
>
|
||||
@@ -1471,14 +1483,6 @@
|
||||
RelativePath="..\..\simgear\threads\SGQueue.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\threads\SGThread.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\threads\SGThread.hxx"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Lib_sgstructure"
|
||||
@@ -1547,14 +1551,6 @@
|
||||
RelativePath="..\..\simgear\structure\OSGVersion.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\structure\SGAtomic.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\structure\SGAtomic.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\structure\SGBinding.cxx"
|
||||
>
|
||||
@@ -1571,14 +1567,6 @@
|
||||
RelativePath="..\..\simgear\structure\SGExpression.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\structure\SGPerfMon.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\structure\SGPerfMon.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\structure\SGReferenced.hxx"
|
||||
>
|
||||
@@ -1603,10 +1591,6 @@
|
||||
RelativePath="..\..\simgear\structure\SGSmplstat.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\structure\Singleton.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\structure\subsystem_mgr.cxx"
|
||||
>
|
||||
@@ -1793,14 +1777,6 @@
|
||||
RelativePath="..\..\simgear\scene\util\NodeAndDrawableVisitor.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\PathOptions.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\PathOptions.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\PrimitiveUtils.cxx"
|
||||
>
|
||||
@@ -1809,14 +1785,6 @@
|
||||
RelativePath="..\..\simgear\scene\util\PrimitiveUtils.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\project.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\project.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\QuadTreeBuilder.cxx"
|
||||
>
|
||||
|
||||
1
simgear/.gitignore
vendored
1
simgear/.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
simgear_config.h
|
||||
simgear_config.h.*
|
||||
stamp-h1
|
||||
version.h
|
||||
|
||||
@@ -5,6 +5,7 @@ foreach( mylibfolder
|
||||
bucket
|
||||
debug
|
||||
ephemeris
|
||||
hla
|
||||
io
|
||||
magvar
|
||||
math
|
||||
@@ -23,75 +24,35 @@ foreach( mylibfolder
|
||||
|
||||
endforeach( mylibfolder )
|
||||
|
||||
if(NOT SIMGEAR_HEADLESS)
|
||||
if (NOT SIMGEAR_HEADLESS)
|
||||
add_subdirectory(environment)
|
||||
add_subdirectory(screen)
|
||||
add_subdirectory(scene)
|
||||
add_subdirectory(sound)
|
||||
endif(NOT SIMGEAR_HEADLESS)
|
||||
endif()
|
||||
|
||||
|
||||
if(ENABLE_RTI)
|
||||
add_subdirectory(hla)
|
||||
endif(ENABLE_RTI)
|
||||
|
||||
|
||||
set(HEADERS compiler.h constants.h sg_inlines.h ${PROJECT_BINARY_DIR}/simgear/version.h)
|
||||
install (FILES ${HEADERS} DESTINATION include/simgear/)
|
||||
|
||||
if(SIMGEAR_SHARED)
|
||||
message(STATUS "building shared library")
|
||||
get_property(coreSources GLOBAL PROPERTY CORE_SOURCES)
|
||||
get_property(sceneSources GLOBAL PROPERTY SCENE_SOURCES)
|
||||
get_property(allSources GLOBAL PROPERTY ALL_SOURCES)
|
||||
get_property(publicHeaders GLOBAL PROPERTY PUBLIC_HEADERS)
|
||||
|
||||
add_library(SimGearCore SHARED ${coreSources})
|
||||
set_property(TARGET SimGearCore PROPERTY COMPILE_FLAGS "-DNO_OPENSCENEGRAPH_INTERFACE=1")
|
||||
|
||||
# set_property(TARGET SimGearCore PROPERTY FRAMEWORK 1)
|
||||
# message(STATUS "public header: ${publicHeaders}")
|
||||
# set_property(TARGET SimGearCore PROPERTY PUBLIC_HEADER "${publicHeaders}")
|
||||
set_property(TARGET SimGearCore PROPERTY LINKER_LANGUAGE CXX)
|
||||
|
||||
set_property(TARGET SimGearCore PROPERTY VERSION ${SIMGEAR_VERSION})
|
||||
set_property(TARGET SimGearCore PROPERTY SOVERSION ${SIMGEAR_SOVERSION})
|
||||
|
||||
target_link_libraries(SimGearCore ${ZLIB_LIBRARY} ${RT_LIBRARY})
|
||||
install(TARGETS SimGearCore LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
if(NOT SIMGEAR_HEADLESS)
|
||||
if(LIBSVN_FOUND)
|
||||
add_definitions(${APR_CFLAGS})
|
||||
|
||||
IF(APPLE)
|
||||
set_property(SOURCE scene/tsync/terrasync.cxx PROPERTY COMPILE_FLAGS "-iwithsysroot ${LIBSVN_INCLUDE_DIR}")
|
||||
ELSE()
|
||||
include_directories(${LIBSVN_INCLUDE_DIR})
|
||||
ENDIF(APPLE)
|
||||
endif(LIBSVN_FOUND)
|
||||
|
||||
list(APPEND sceneSources scene/util/SGCoreOSGDependant.cxx)
|
||||
|
||||
add_library(SimGearScene SHARED ${sceneSources})
|
||||
# set_property(TARGET SimGearScene PROPERTY FRAMEWORK 1)
|
||||
# set_property(TARGET SimGearScene PROPERTY PUBLIC_HEADER "${publicHeaders}")
|
||||
set_property(TARGET SimGearScene PROPERTY LINKER_LANGUAGE CXX)
|
||||
set_property(TARGET SimGearScene PROPERTY VERSION ${SIMGEAR_VERSION})
|
||||
set_property(TARGET SimGearScene PROPERTY SOVERSION ${SIMGEAR_SOVERSION})
|
||||
|
||||
target_link_libraries(SimGearScene
|
||||
SimGearCore
|
||||
${ZLIB_LIBRARY}
|
||||
${OPENSCENEGRAPH_LIBRARIES}
|
||||
${OPENAL_LIBRARY} ${ALUT_LIBRARY}
|
||||
${OPENGL_LIBRARY})
|
||||
|
||||
if(LIBSVN_FOUND)
|
||||
target_link_libraries(SimGearScene ${LIBSVN_LIBRARIES})
|
||||
endif(LIBSVN_FOUND)
|
||||
|
||||
install(TARGETS SimGearScene LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
|
||||
add_library(SimGear SHARED ${allSources})
|
||||
set_property(TARGET SimGear PROPERTY FRAMEWORK 1)
|
||||
message(STATUS "public header: ${publicHeaders}")
|
||||
set_property(TARGET SimGear PROPERTY PUBLIC_HEADER "${publicHeaders}")
|
||||
set_property(TARGET SimGear PROPERTY LINKER_LANGUAGE CXX)
|
||||
|
||||
target_link_libraries(SimGear ${ZLIB_LIBRARY}
|
||||
${OPENSCENEGRAPH_LIBRARIES}
|
||||
${OPENAL_LIBRARY} ${ALUT_LIBRARY}
|
||||
${OPENGL_LIBRARY})
|
||||
|
||||
install(TARGETS SimGear LIBRARY DESTINATION lib${LIB_SUFFIX}
|
||||
PUBLIC_HEADER DESTINATION include/simgear)
|
||||
endif(SIMGEAR_SHARED)
|
||||
|
||||
|
||||
50
simgear/Makefile.am
Normal file
50
simgear/Makefile.am
Normal file
@@ -0,0 +1,50 @@
|
||||
if ENABLE_HLA
|
||||
HLA_DIR = hla
|
||||
else
|
||||
HLA_DIR =
|
||||
endif
|
||||
|
||||
EXTRA_DIST = simgear_config.h.vc5 simgear_config.h-msvc71 version.h.in
|
||||
|
||||
include_HEADERS = \
|
||||
compiler.h constants.h sg_inlines.h version.h
|
||||
|
||||
if WANT_HEADLESS
|
||||
SG_EXTRA_DIRS =
|
||||
METAR_DIRS =
|
||||
else
|
||||
SG_EXTRA_DIRS = scene sound screen
|
||||
METAR_DIRS = environment
|
||||
endif
|
||||
|
||||
if HAVE_THREADS
|
||||
SGTHREAD_DIR = threads
|
||||
else
|
||||
SGTHREAD_DIR =
|
||||
endif
|
||||
|
||||
SUBDIRS_ALWAYS = \
|
||||
xml \
|
||||
debug \
|
||||
misc \
|
||||
structure \
|
||||
bucket \
|
||||
ephemeris \
|
||||
$(HLA_DIR) \
|
||||
io \
|
||||
magvar \
|
||||
math \
|
||||
nasal \
|
||||
props \
|
||||
route \
|
||||
serial \
|
||||
timing
|
||||
|
||||
SUBDIRS = $(SUBDIRS_ALWAYS) \
|
||||
$(compatibility_DIR) \
|
||||
$(METAR_DIRS) \
|
||||
$(SG_EXTRA_DIRS) \
|
||||
$(SGTHREAD_DIR)
|
||||
|
||||
DIST_SUBDIRS = $(SUBDIRS_ALWAYS) compatibility scene sound screen environment threads
|
||||
|
||||
17
simgear/bucket/Makefile.am
Normal file
17
simgear/bucket/Makefile.am
Normal file
@@ -0,0 +1,17 @@
|
||||
includedir = @includedir@/bucket
|
||||
|
||||
lib_LIBRARIES = libsgbucket.a
|
||||
|
||||
include_HEADERS = newbucket.hxx
|
||||
|
||||
libsgbucket_a_SOURCES = newbucket.cxx
|
||||
|
||||
# noinst_PROGRAMS = testbucket
|
||||
|
||||
# testbucket_SOURCES = testbucket.cxx
|
||||
|
||||
# testbucket_LDADD = \
|
||||
# libsgbucket.a \
|
||||
# $(top_builddir)/misc/libsgmisc.a
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
14
simgear/compatibility/MIPSpro721/Makefile.am
Normal file
14
simgear/compatibility/MIPSpro721/Makefile.am
Normal file
@@ -0,0 +1,14 @@
|
||||
includedir = @includedir@/compatibility/
|
||||
|
||||
include_HEADERS = \
|
||||
iostream \
|
||||
strstream \
|
||||
sstream \
|
||||
istream \
|
||||
fstream \
|
||||
iterator \
|
||||
iomanip \
|
||||
new \
|
||||
streambuf \
|
||||
\
|
||||
irix_string
|
||||
22
simgear/compatibility/MIPSpro740/Makefile.am
Normal file
22
simgear/compatibility/MIPSpro740/Makefile.am
Normal file
@@ -0,0 +1,22 @@
|
||||
includedir = @includedir@/compatibility
|
||||
|
||||
EXTRA_DIST = README
|
||||
|
||||
include_HEADERS = \
|
||||
cfloat \
|
||||
csetjmp \
|
||||
cstdio \
|
||||
cwchar \
|
||||
cassert \
|
||||
climits \
|
||||
csignal \
|
||||
cstdlib \
|
||||
cwctype \
|
||||
cctype \
|
||||
clocale \
|
||||
cstdarg \
|
||||
cstring \
|
||||
cerrno \
|
||||
cmath \
|
||||
cstddef \
|
||||
ctime
|
||||
3
simgear/compatibility/Makefile.am
Normal file
3
simgear/compatibility/Makefile.am
Normal file
@@ -0,0 +1,3 @@
|
||||
SUBDIRS = $(MIPSpro_DIRS)
|
||||
|
||||
DIST_SUBDIRS = MIPSpro721 MIPSpro740
|
||||
11
simgear/debug/Makefile.am
Normal file
11
simgear/debug/Makefile.am
Normal file
@@ -0,0 +1,11 @@
|
||||
includedir = @includedir@/debug
|
||||
|
||||
EXTRA_DIST = logtest.cxx
|
||||
|
||||
lib_LIBRARIES = libsgdebug.a
|
||||
|
||||
include_HEADERS = debug_types.h logstream.hxx
|
||||
|
||||
libsgdebug_a_SOURCES = logstream.cxx
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
@@ -1,38 +1,35 @@
|
||||
/** \file debug_types.h
|
||||
* Define the various logging classes and priorities
|
||||
* Define the various logging classes and prioritiess
|
||||
*/
|
||||
|
||||
/**
|
||||
* Define the possible classes/categories of logging messages
|
||||
*/
|
||||
typedef enum {
|
||||
SG_NONE = 0x00000000,
|
||||
SG_NONE = 0x00000000,
|
||||
|
||||
SG_TERRAIN = 0x00000001,
|
||||
SG_ASTRO = 0x00000002,
|
||||
SG_FLIGHT = 0x00000004,
|
||||
SG_INPUT = 0x00000008,
|
||||
SG_GL = 0x00000010,
|
||||
SG_VIEW = 0x00000020,
|
||||
SG_COCKPIT = 0x00000040,
|
||||
SG_GENERAL = 0x00000080,
|
||||
SG_MATH = 0x00000100,
|
||||
SG_EVENT = 0x00000200,
|
||||
SG_AIRCRAFT = 0x00000400,
|
||||
SG_AUTOPILOT = 0x00000800,
|
||||
SG_IO = 0x00001000,
|
||||
SG_CLIPPER = 0x00002000,
|
||||
SG_NETWORK = 0x00004000,
|
||||
SG_ATC = 0x00008000,
|
||||
SG_NASAL = 0x00010000,
|
||||
SG_INSTR = 0x00020000,
|
||||
SG_SYSTEMS = 0x00040000,
|
||||
SG_AI = 0x00080000,
|
||||
SG_ENVIRONMENT = 0x00100000,
|
||||
SG_SOUND = 0x00200000,
|
||||
SG_UNDEFD = 0x00400000, // For range checking
|
||||
SG_TERRAIN = 0x00000001,
|
||||
SG_ASTRO = 0x00000002,
|
||||
SG_FLIGHT = 0x00000004,
|
||||
SG_INPUT = 0x00000008,
|
||||
SG_GL = 0x00000010,
|
||||
SG_VIEW = 0x00000020,
|
||||
SG_COCKPIT = 0x00000040,
|
||||
SG_GENERAL = 0x00000080,
|
||||
SG_MATH = 0x00000100,
|
||||
SG_EVENT = 0x00000200,
|
||||
SG_AIRCRAFT = 0x00000400,
|
||||
SG_AUTOPILOT = 0x00000800,
|
||||
SG_IO = 0x00001000,
|
||||
SG_CLIPPER = 0x00002000,
|
||||
SG_NETWORK = 0x00004000,
|
||||
SG_ATC = 0x00008000,
|
||||
SG_NASAL = 0x00010000,
|
||||
SG_INSTR = 0x00020000,
|
||||
SG_SYSTEMS = 0x00040000,
|
||||
SG_UNDEFD = 0x00080000, // For range checking
|
||||
|
||||
SG_ALL = 0xFFFFFFFF
|
||||
SG_ALL = 0xFFFFFFFF
|
||||
} sgDebugClass;
|
||||
|
||||
|
||||
|
||||
@@ -4,20 +4,4 @@ include (SimGearComponent)
|
||||
set(HEADERS metar.hxx precipitation.hxx)
|
||||
set(SOURCES metar.cxx precipitation.cxx)
|
||||
|
||||
simgear_scene_component(environment environment "${SOURCES}" "${HEADERS}")
|
||||
|
||||
if(ENABLE_TESTS)
|
||||
add_executable(test_metar test_metar.cxx)
|
||||
|
||||
if (SIMGEAR_SHARED)
|
||||
target_link_libraries(test_metar SimGearScene)
|
||||
else()
|
||||
target_link_libraries(test_metar
|
||||
sgenvironment sgstructure sgmisc sgdebug
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${ZLIB_LIBRARY}
|
||||
${RT_LIBRARY})
|
||||
endif()
|
||||
|
||||
add_test(metar ${EXECUTABLE_OUTPUT_PATH}/test_metar)
|
||||
endif(ENABLE_TESTS)
|
||||
simgear_component(environment environment "${SOURCES}" "${HEADERS}")
|
||||
|
||||
9
simgear/environment/Makefile.am
Normal file
9
simgear/environment/Makefile.am
Normal file
@@ -0,0 +1,9 @@
|
||||
includedir = @includedir@/environment
|
||||
|
||||
lib_LIBRARIES = libsgenvironment.a
|
||||
|
||||
include_HEADERS = metar.hxx precipitation.hxx
|
||||
|
||||
libsgenvironment_a_SOURCES = metar.cxx precipitation.cxx
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <time.h>
|
||||
#include <cstring>
|
||||
|
||||
#include <simgear/io/sg_socket.hxx>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
|
||||
@@ -39,28 +40,32 @@
|
||||
|
||||
#define NaN SGMetarNaN
|
||||
|
||||
using std::string;
|
||||
using std::map;
|
||||
using std::vector;
|
||||
|
||||
/**
|
||||
* The constructor takes a Metar string
|
||||
* The constructor takes a Metar string, or a four-letter ICAO code. In the
|
||||
* latter case the metar string is downloaded from
|
||||
* http://weather.noaa.gov/pub/data/observations/metar/stations/.
|
||||
* The constructor throws sg_io_exceptions on failure. The "METAR"
|
||||
* keyword has no effect (apart from incrementing the group counter
|
||||
* @a grpcount) and can be left away. A keyword "SPECI" is
|
||||
* likewise accepted.
|
||||
*
|
||||
* @param m ICAO station id or metar string
|
||||
* @param proxy proxy host (optional; default: "")
|
||||
* @param port proxy port (optional; default: "80")
|
||||
* @param auth proxy authorization information (optional; default: "")
|
||||
*
|
||||
* @par Examples:
|
||||
* @code
|
||||
* SGMetar *m = new SGMetar("METAR KSFO 061656Z 19004KT 9SM SCT100 OVC200 08/03 A3013");
|
||||
* double t = m->getTemperature_F();
|
||||
* delete m;
|
||||
|
||||
*
|
||||
* SGMetar n("KSFO", "proxy.provider.foo", "3128", "proxy-password");
|
||||
* double d = n.getDewpoint_C();
|
||||
* @endcode
|
||||
*/
|
||||
SGMetar::SGMetar(const string& m) :
|
||||
SGMetar::SGMetar(const string& m, const string& proxy, const string& port,
|
||||
const string& auth, const time_t time) :
|
||||
_grpcount(0),
|
||||
_x_proxy(false),
|
||||
_year(-1),
|
||||
@@ -82,10 +87,16 @@ SGMetar::SGMetar(const string& m) :
|
||||
_snow(false),
|
||||
_cavok(false)
|
||||
{
|
||||
_data = new char[m.length() + 2]; // make room for " \0"
|
||||
strcpy(_data, m.c_str());
|
||||
_url = _data;
|
||||
|
||||
if (m.length() == 4 && isalnum(m[0]) && isalnum(m[1]) && isalnum(m[2]) && isalnum(m[3])) {
|
||||
for (int i = 0; i < 4; i++)
|
||||
_icao[i] = toupper(m[i]);
|
||||
_icao[4] = '\0';
|
||||
_data = loadData(_icao, proxy, port, auth, time);
|
||||
} else {
|
||||
_data = new char[m.length() + 2]; // make room for " \0"
|
||||
strcpy(_data, m.c_str());
|
||||
_url = _data;
|
||||
}
|
||||
normalizeData();
|
||||
|
||||
_m = _data;
|
||||
@@ -158,6 +169,85 @@ void SGMetar::useCurrentDate()
|
||||
_month = now.tm_mon + 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If called with "KSFO" loads data from
|
||||
* @code
|
||||
* http://weather.noaa.gov/pub/data/observations/metar/stations/KSFO.TXT.
|
||||
* @endcode
|
||||
* Throws sg_io_exception on failure. Gives up after waiting longer than 10 seconds.
|
||||
*
|
||||
* @param id four-letter ICAO Metar station code, e.g. "KSFO".
|
||||
* @param proxy proxy host (optional; default: "")
|
||||
* @param port proxy port (optional; default: "80")
|
||||
* @param auth proxy authorization information (optional; default: "")
|
||||
* @return pointer to Metar data string, allocated by new char[].
|
||||
* @see rfc2068.txt for proxy spec ("Proxy-Authorization")
|
||||
*/
|
||||
char *SGMetar::loadData(const char *id, const string& proxy, const string& port,
|
||||
const string& auth, time_t time)
|
||||
{
|
||||
const int buflen = 512;
|
||||
char buf[2 * buflen];
|
||||
|
||||
string metar_server = "weather.noaa.gov";
|
||||
string host = proxy.empty() ? metar_server : proxy;
|
||||
string path = "/pub/data/observations/metar/stations/";
|
||||
|
||||
path += string(id) + ".TXT";
|
||||
_url = "http://" + metar_server + path;
|
||||
|
||||
SGSocket *sock = new SGSocket(host, port.empty() ? "80" : port, "tcp");
|
||||
sock->set_timeout(10000);
|
||||
if (!sock->open(SG_IO_OUT)) {
|
||||
delete sock;
|
||||
throw sg_io_exception("cannot connect to ", sg_location(host));
|
||||
}
|
||||
|
||||
string get = "GET ";
|
||||
if (!proxy.empty())
|
||||
get += "http://" + metar_server;
|
||||
|
||||
sprintf(buf, "%ld", time);
|
||||
get += path + " HTTP/1.0\015\012X-Time: " + buf + "\015\012";
|
||||
get += "Host: " + metar_server + "\015\012";
|
||||
|
||||
if (!auth.empty())
|
||||
get += "Proxy-Authorization: " + auth + "\015\012";
|
||||
|
||||
get += "\015\012";
|
||||
sock->writestring(get.c_str());
|
||||
|
||||
int i;
|
||||
|
||||
// skip HTTP header
|
||||
while ((i = sock->readline(buf, buflen))) {
|
||||
if (i <= 2 && isspace(buf[0]) && (!buf[1] || isspace(buf[1])))
|
||||
break;
|
||||
if (!strncmp(buf, "X-MetarProxy: ", 13))
|
||||
_x_proxy = true;
|
||||
}
|
||||
if (i) {
|
||||
i = sock->readline(buf, buflen);
|
||||
if (i)
|
||||
sock->readline(&buf[i], buflen);
|
||||
}
|
||||
|
||||
sock->close();
|
||||
delete sock;
|
||||
|
||||
char *b = buf;
|
||||
scanBoundary(&b);
|
||||
if (*b == '<')
|
||||
throw sg_io_exception("no metar data available from ",
|
||||
sg_location(_url));
|
||||
|
||||
char *metar = new char[strlen(b) + 2]; // make room for " \0"
|
||||
strcpy(metar, b);
|
||||
return metar;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replace any number of subsequent spaces by just one space, and add
|
||||
* a trailing space. This makes scanning for things like "ALL RWY" easier.
|
||||
|
||||
@@ -29,12 +29,18 @@
|
||||
|
||||
#include <simgear/constants.h>
|
||||
|
||||
using std::vector;
|
||||
using std::map;
|
||||
using std::string;
|
||||
|
||||
const double SGMetarNaN = -1E20;
|
||||
#define NaN SGMetarNaN
|
||||
|
||||
struct Token {
|
||||
const char *id;
|
||||
const char *text;
|
||||
};
|
||||
|
||||
const double SGMetarNaN = -1E20;
|
||||
|
||||
class SGMetar;
|
||||
|
||||
@@ -42,7 +48,7 @@ class SGMetarVisibility {
|
||||
friend class SGMetar;
|
||||
public:
|
||||
SGMetarVisibility() :
|
||||
_distance(SGMetarNaN),
|
||||
_distance(NaN),
|
||||
_direction(-1),
|
||||
_modifier(EQUALS),
|
||||
_tendency(NONE) {}
|
||||
@@ -64,8 +70,8 @@ public:
|
||||
void set(double dist, int dir = -1, int mod = -1, int tend = -1);
|
||||
|
||||
inline double getVisibility_m() const { return _distance; }
|
||||
inline double getVisibility_ft() const { return _distance == SGMetarNaN ? SGMetarNaN : _distance * SG_METER_TO_FEET; }
|
||||
inline double getVisibility_sm() const { return _distance == SGMetarNaN ? SGMetarNaN : _distance * SG_METER_TO_SM; }
|
||||
inline double getVisibility_ft() const { return _distance == NaN ? NaN : _distance * SG_METER_TO_FEET; }
|
||||
inline double getVisibility_sm() const { return _distance == NaN ? NaN : _distance * SG_METER_TO_SM; }
|
||||
inline int getDirection() const { return _direction; }
|
||||
inline int getModifier() const { return _modifier; }
|
||||
inline int getTendency() const { return _tendency; }
|
||||
@@ -87,8 +93,8 @@ public:
|
||||
_deposit_string(0),
|
||||
_extent(-1),
|
||||
_extent_string(0),
|
||||
_depth(SGMetarNaN),
|
||||
_friction(SGMetarNaN),
|
||||
_depth(NaN),
|
||||
_friction(NaN),
|
||||
_friction_string(0),
|
||||
_comment(0),
|
||||
_wind_shear(false) {}
|
||||
@@ -101,7 +107,7 @@ public:
|
||||
inline double getFriction() const { return _friction; }
|
||||
inline const char *getFrictionString() const { return _friction_string; }
|
||||
inline const char *getComment() const { return _comment; }
|
||||
inline bool getWindShear() const { return _wind_shear; }
|
||||
inline const bool getWindShear() const { return _wind_shear; }
|
||||
inline const SGMetarVisibility& getMinVisibility() const { return _min_visibility; }
|
||||
inline const SGMetarVisibility& getMaxVisibility() const { return _max_visibility; }
|
||||
|
||||
@@ -140,14 +146,14 @@ public:
|
||||
static const char * COVERAGE_BROKEN_STRING;
|
||||
static const char * COVERAGE_OVERCAST_STRING;
|
||||
|
||||
SGMetarCloud() : _coverage(COVERAGE_NIL), _altitude(SGMetarNaN), _type(0), _type_long(0) {}
|
||||
SGMetarCloud() : _coverage(COVERAGE_NIL), _altitude(NaN), _type(0), _type_long(0) {}
|
||||
|
||||
void set(double alt, Coverage cov = COVERAGE_NIL );
|
||||
|
||||
inline Coverage getCoverage() const { return _coverage; }
|
||||
static Coverage getCoverage( const std::string & coverage );
|
||||
inline double getAltitude_m() const { return _altitude; }
|
||||
inline double getAltitude_ft() const { return _altitude == SGMetarNaN ? SGMetarNaN : _altitude * SG_METER_TO_FEET; }
|
||||
inline double getAltitude_ft() const { return _altitude == NaN ? NaN : _altitude * SG_METER_TO_FEET; }
|
||||
inline const char *getTypeString() const { return _type; }
|
||||
inline const char *getTypeLongString() const { return _type_long; }
|
||||
|
||||
@@ -161,7 +167,8 @@ protected:
|
||||
|
||||
class SGMetar {
|
||||
public:
|
||||
SGMetar(const std::string& m);
|
||||
SGMetar(const string& m, const string& proxy = "", const string& port = "",
|
||||
const string &auth = "", const time_t time = 0);
|
||||
~SGMetar();
|
||||
|
||||
enum ReportType {
|
||||
@@ -182,13 +189,13 @@ public:
|
||||
Weather() { intensity = NIL; vincinity = false; }
|
||||
Intensity intensity;
|
||||
bool vincinity;
|
||||
std::vector<std::string> descriptions;
|
||||
std::vector<std::string> phenomena;
|
||||
vector<string> descriptions;
|
||||
vector<string> phenomena;
|
||||
};
|
||||
|
||||
inline const char *getData() const { return _data; }
|
||||
inline const char *getUnusedData() const { return _m; }
|
||||
inline bool getProxy() const { return _x_proxy; }
|
||||
inline const bool getProxy() const { return _x_proxy; }
|
||||
inline const char *getId() const { return _icao; }
|
||||
inline int getYear() const { return _year; }
|
||||
inline int getMonth() const { return _month; }
|
||||
@@ -199,14 +206,14 @@ public:
|
||||
|
||||
inline int getWindDir() const { return _wind_dir; }
|
||||
inline double getWindSpeed_mps() const { return _wind_speed; }
|
||||
inline double getWindSpeed_kmh() const { return _wind_speed == SGMetarNaN ? SGMetarNaN : _wind_speed * SG_MPS_TO_KMH; }
|
||||
inline double getWindSpeed_kt() const { return _wind_speed == SGMetarNaN ? SGMetarNaN : _wind_speed * SG_MPS_TO_KT; }
|
||||
inline double getWindSpeed_mph() const { return _wind_speed == SGMetarNaN ? SGMetarNaN : _wind_speed * SG_MPS_TO_MPH; }
|
||||
inline double getWindSpeed_kmh() const { return _wind_speed == NaN ? NaN : _wind_speed * SG_MPS_TO_KMH; }
|
||||
inline double getWindSpeed_kt() const { return _wind_speed == NaN ? NaN : _wind_speed * SG_MPS_TO_KT; }
|
||||
inline double getWindSpeed_mph() const { return _wind_speed == NaN ? NaN : _wind_speed * SG_MPS_TO_MPH; }
|
||||
|
||||
inline double getGustSpeed_mps() const { return _gust_speed; }
|
||||
inline double getGustSpeed_kmh() const { return _gust_speed == SGMetarNaN ? SGMetarNaN : _gust_speed * SG_MPS_TO_KMH; }
|
||||
inline double getGustSpeed_kt() const { return _gust_speed == SGMetarNaN ? SGMetarNaN : _gust_speed * SG_MPS_TO_KT; }
|
||||
inline double getGustSpeed_mph() const { return _gust_speed == SGMetarNaN ? SGMetarNaN : _gust_speed * SG_MPS_TO_MPH; }
|
||||
inline double getGustSpeed_kmh() const { return _gust_speed == NaN ? NaN : _gust_speed * SG_MPS_TO_KMH; }
|
||||
inline double getGustSpeed_kt() const { return _gust_speed == NaN ? NaN : _gust_speed * SG_MPS_TO_KT; }
|
||||
inline double getGustSpeed_mph() const { return _gust_speed == NaN ? NaN : _gust_speed * SG_MPS_TO_MPH; }
|
||||
|
||||
inline int getWindRangeFrom() const { return _wind_range_from; }
|
||||
inline int getWindRangeTo() const { return _wind_range_to; }
|
||||
@@ -217,11 +224,11 @@ public:
|
||||
inline const SGMetarVisibility *getDirVisibility() const { return _dir_visibility; }
|
||||
|
||||
inline double getTemperature_C() const { return _temp; }
|
||||
inline double getTemperature_F() const { return _temp == SGMetarNaN ? SGMetarNaN : 1.8 * _temp + 32; }
|
||||
inline double getTemperature_F() const { return _temp == NaN ? NaN : 1.8 * _temp + 32; }
|
||||
inline double getDewpoint_C() const { return _dewp; }
|
||||
inline double getDewpoint_F() const { return _dewp == SGMetarNaN ? SGMetarNaN : 1.8 * _dewp + 32; }
|
||||
inline double getPressure_hPa() const { return _pressure == SGMetarNaN ? SGMetarNaN : _pressure / 100; }
|
||||
inline double getPressure_inHg() const { return _pressure == SGMetarNaN ? SGMetarNaN : _pressure * SG_PA_TO_INHG; }
|
||||
inline double getDewpoint_F() const { return _dewp == NaN ? NaN : 1.8 * _dewp + 32; }
|
||||
inline double getPressure_hPa() const { return _pressure == NaN ? NaN : _pressure / 100; }
|
||||
inline double getPressure_inHg() const { return _pressure == NaN ? NaN : _pressure * SG_PA_TO_INHG; }
|
||||
|
||||
inline int getRain() const { return _rain; }
|
||||
inline int getHail() const { return _hail; }
|
||||
@@ -230,13 +237,13 @@ public:
|
||||
|
||||
double getRelHumidity() const;
|
||||
|
||||
inline const std::vector<SGMetarCloud>& getClouds() const { return _clouds; }
|
||||
inline const std::map<std::string, SGMetarRunway>& getRunways() const { return _runways; }
|
||||
inline const std::vector<std::string>& getWeather() const { return _weather; }
|
||||
inline const std::vector<struct Weather> getWeather2() const { return _weather2; }
|
||||
inline const vector<SGMetarCloud>& getClouds() const { return _clouds; }
|
||||
inline const map<string, SGMetarRunway>& getRunways() const { return _runways; }
|
||||
inline const vector<string>& getWeather() const { return _weather; }
|
||||
inline const vector<struct Weather> getWeather2() const { return _weather2; }
|
||||
|
||||
protected:
|
||||
std::string _url;
|
||||
string _url;
|
||||
int _grpcount;
|
||||
bool _x_proxy;
|
||||
char *_data;
|
||||
@@ -260,15 +267,15 @@ protected:
|
||||
int _hail;
|
||||
int _snow;
|
||||
bool _cavok;
|
||||
std::vector<struct Weather> _weather2;
|
||||
vector<struct Weather> _weather2;
|
||||
|
||||
SGMetarVisibility _min_visibility;
|
||||
SGMetarVisibility _max_visibility;
|
||||
SGMetarVisibility _vert_visibility;
|
||||
SGMetarVisibility _dir_visibility[8];
|
||||
std::vector<SGMetarCloud> _clouds;
|
||||
std::map<std::string, SGMetarRunway> _runways;
|
||||
std::vector<std::string> _weather;
|
||||
vector<SGMetarCloud> _clouds;
|
||||
map<string, SGMetarRunway> _runways;
|
||||
vector<string> _weather;
|
||||
|
||||
bool scanPreambleDate();
|
||||
bool scanPreambleTime();
|
||||
@@ -296,7 +303,10 @@ protected:
|
||||
int scanNumber(char **str, int *num, int min, int max = 0);
|
||||
bool scanBoundary(char **str);
|
||||
const struct Token *scanToken(char **str, const struct Token *list);
|
||||
char *loadData(const char *id, const string& proxy, const string& port,
|
||||
const string &auth, time_t time);
|
||||
void normalizeData();
|
||||
};
|
||||
|
||||
#undef NaN
|
||||
#endif // _METAR_HXX
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define random rand
|
||||
#endif
|
||||
|
||||
#include <simgear/misc/sg_dir.hxx>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
|
||||
#include "metar.hxx"
|
||||
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
|
||||
#define COMPARE(a, b) \
|
||||
if ((a) != (b)) { \
|
||||
cerr << "failed:" << #a << " != " << #b << endl; \
|
||||
cerr << "\tgot:" << a << endl; \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
#define FUZZY_COMPARE(a, b, epsilon) \
|
||||
if (fabs(a - b) > epsilon) { \
|
||||
cerr << "failed:" << #a << " != " << #b << endl; \
|
||||
cerr << "\tgot:" << a << endl; \
|
||||
cerr << "\tepsilon:" << epsilon << endl; \
|
||||
}
|
||||
|
||||
#define VERIFY(a) \
|
||||
if (!(a)) { \
|
||||
cerr << "failed:" << #a << endl; \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
const double TEST_EPSILON = 1e-9;
|
||||
|
||||
void test_basic()
|
||||
{
|
||||
SGMetar m1("2011/10/20 11:25 EHAM 201125Z 27012KT 240V300 9999 VCSH FEW025CB SCT048 10/05 Q1025 TEMPO VRB03KT");
|
||||
COMPARE(m1.getYear(), 2011);
|
||||
COMPARE(m1.getMonth(), 10);
|
||||
COMPARE(m1.getDay(), 20);
|
||||
COMPARE(m1.getHour(), 11);
|
||||
COMPARE(m1.getMinute(), 25);
|
||||
COMPARE(m1.getReportType(), -1); // should default to NIL?
|
||||
|
||||
COMPARE(m1.getWindDir(), 270);
|
||||
FUZZY_COMPARE(m1.getWindSpeed_kt(), 12, TEST_EPSILON);
|
||||
|
||||
FUZZY_COMPARE(m1.getTemperature_C(), 10, TEST_EPSILON);
|
||||
FUZZY_COMPARE(m1.getDewpoint_C(), 5, TEST_EPSILON);
|
||||
FUZZY_COMPARE(m1.getPressure_hPa(), 1025, TEST_EPSILON);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
try {
|
||||
test_basic();
|
||||
} catch (sg_exception& e) {
|
||||
cerr << "got exception:" << e.getMessage() << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
34
simgear/ephemeris/Makefile.am
Normal file
34
simgear/ephemeris/Makefile.am
Normal file
@@ -0,0 +1,34 @@
|
||||
includedir = @includedir@/ephemeris
|
||||
|
||||
lib_LIBRARIES = libsgephem.a
|
||||
|
||||
include_HEADERS = \
|
||||
celestialBody.hxx \
|
||||
ephemeris.hxx \
|
||||
jupiter.hxx \
|
||||
mars.hxx \
|
||||
mercury.hxx \
|
||||
moonpos.hxx \
|
||||
neptune.hxx \
|
||||
saturn.hxx \
|
||||
star.hxx \
|
||||
stardata.hxx \
|
||||
uranus.hxx \
|
||||
venus.hxx
|
||||
|
||||
libsgephem_a_SOURCES = \
|
||||
celestialBody.cxx \
|
||||
ephemeris.cxx \
|
||||
jupiter.cxx \
|
||||
mars.cxx \
|
||||
mercury.cxx \
|
||||
moonpos.cxx \
|
||||
neptune.cxx \
|
||||
pluto.hxx \
|
||||
saturn.cxx \
|
||||
star.cxx \
|
||||
stardata.cxx \
|
||||
uranus.cxx \
|
||||
venus.cxx
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
@@ -7,7 +7,6 @@ set(HLA_HEADERS
|
||||
HLABasicDataElement.hxx
|
||||
HLABasicDataType.hxx
|
||||
HLADataElement.hxx
|
||||
HLADataElementVisitor.hxx
|
||||
HLADataType.hxx
|
||||
HLADataTypeVisitor.hxx
|
||||
HLAEnumeratedDataElement.hxx
|
||||
@@ -27,13 +26,15 @@ set(HLA_HEADERS
|
||||
)
|
||||
|
||||
set(HLA_SOURCES
|
||||
RTIObjectClass.cxx
|
||||
RTIObjectInstance.cxx
|
||||
RTIFederate.cxx
|
||||
HLAArrayDataElement.cxx
|
||||
HLAArrayDataType.cxx
|
||||
HLABasicDataElement.cxx
|
||||
HLABasicDataType.cxx
|
||||
HLADataElement.cxx
|
||||
HLADataType.cxx
|
||||
HLADataTypeVisitor.cxx
|
||||
HLAEnumeratedDataElement.cxx
|
||||
HLAEnumeratedDataType.cxx
|
||||
HLAFederate.cxx
|
||||
@@ -50,18 +51,15 @@ set(HLA_SOURCES
|
||||
simgear_component(hla hla "${HLA_SOURCES}" "${HLA_HEADERS}")
|
||||
|
||||
if(RTI_FOUND)
|
||||
set(RTI13_SOURCES
|
||||
set(HLA13_HEADERS
|
||||
HLA13Federate.hxx
|
||||
)
|
||||
set(HLA13_SOURCES
|
||||
RTI13ObjectClass.cxx
|
||||
RTI13ObjectInstance.cxx
|
||||
RTI13Federate.cxx
|
||||
HLA13Federate.cxx
|
||||
)
|
||||
simgear_component(rti13 hla "${RTI13_SOURCES}" "")
|
||||
set_property(TARGET sgrti13 APPEND PROPERTY COMPILE_FLAGS "-I${RTI_INCLUDE_DIR}")
|
||||
simgear_component(hla13 hla "${HLA13_SOURCES}" "${HLA13_HEADERS}")
|
||||
set_property(TARGET sghla13 APPEND PROPERTY COMPILE_FLAGS "-I${RTI_INCLUDE_DIR}")
|
||||
endif()
|
||||
|
||||
set(RTI_SOURCES
|
||||
RTIObjectClass.cxx
|
||||
RTIObjectInstance.cxx
|
||||
RTIFederate.cxx
|
||||
)
|
||||
simgear_component(rti hla "${RTI_SOURCES}" "")
|
||||
|
||||
33
simgear/hla/HLA13Federate.cxx
Normal file
33
simgear/hla/HLA13Federate.cxx
Normal file
@@ -0,0 +1,33 @@
|
||||
// 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
|
||||
33
simgear/hla/HLA13Federate.hxx
Normal file
33
simgear/hla/HLA13Federate.hxx
Normal file
@@ -0,0 +1,33 @@
|
||||
// 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
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include "HLADataElementVisitor.hxx"
|
||||
|
||||
namespace simgear {
|
||||
|
||||
HLAAbstractArrayDataElement::HLAAbstractArrayDataElement(const HLAArrayDataType* dataType) :
|
||||
@@ -32,18 +30,6 @@ HLAAbstractArrayDataElement::~HLAAbstractArrayDataElement()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HLAAbstractArrayDataElement::accept(HLADataElementVisitor& visitor)
|
||||
{
|
||||
visitor.apply(*this);
|
||||
}
|
||||
|
||||
void
|
||||
HLAAbstractArrayDataElement::accept(HLAConstDataElementVisitor& visitor) const
|
||||
{
|
||||
visitor.apply(*this);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAAbstractArrayDataElement::decode(HLADecodeStream& stream)
|
||||
{
|
||||
|
||||
@@ -33,9 +33,6 @@ public:
|
||||
HLAAbstractArrayDataElement(const HLAArrayDataType* dataType);
|
||||
virtual ~HLAAbstractArrayDataElement();
|
||||
|
||||
virtual void accept(HLADataElementVisitor& visitor);
|
||||
virtual void accept(HLAConstDataElementVisitor& visitor) const;
|
||||
|
||||
virtual bool decode(HLADecodeStream& stream);
|
||||
virtual bool encode(HLAEncodeStream& stream) const;
|
||||
|
||||
@@ -251,43 +248,6 @@ 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:
|
||||
@@ -343,43 +303,6 @@ 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:
|
||||
@@ -435,43 +358,6 @@ 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:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
// 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
|
||||
@@ -22,9 +22,7 @@
|
||||
namespace simgear {
|
||||
|
||||
HLAArrayDataType::HLAArrayDataType(const std::string& name) :
|
||||
HLADataType(name),
|
||||
_isOpaque(false),
|
||||
_isString(false)
|
||||
HLADataType(name)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -53,18 +51,6 @@ HLAArrayDataType::setElementDataType(const HLADataType* elementDataType)
|
||||
_elementDataType = elementDataType;
|
||||
}
|
||||
|
||||
void
|
||||
HLAArrayDataType::setIsOpaque(bool isOpaque)
|
||||
{
|
||||
_isOpaque = isOpaque;
|
||||
}
|
||||
|
||||
void
|
||||
HLAArrayDataType::setIsString(bool isString)
|
||||
{
|
||||
_isString = isString;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HLAFixedArrayDataType::HLAFixedArrayDataType(const std::string& name) :
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
// 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
|
||||
@@ -42,18 +42,8 @@ public:
|
||||
const HLADataType* getElementDataType() const
|
||||
{ return _elementDataType.get(); }
|
||||
|
||||
void setIsOpaque(bool isOpaque);
|
||||
bool getIsOpaque() const
|
||||
{ return _isOpaque; }
|
||||
|
||||
void setIsString(bool isString);
|
||||
bool getIsString() const
|
||||
{ return _isString; }
|
||||
|
||||
private:
|
||||
SGSharedPtr<const HLADataType> _elementDataType;
|
||||
bool _isOpaque;
|
||||
bool _isString;
|
||||
};
|
||||
|
||||
class HLAFixedArrayDataType : public HLAArrayDataType {
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
#include "HLABasicDataElement.hxx"
|
||||
|
||||
#include "HLADataElementVisitor.hxx"
|
||||
#include "HLADataTypeVisitor.hxx"
|
||||
|
||||
namespace simgear {
|
||||
@@ -31,18 +30,6 @@ HLABasicDataElement::~HLABasicDataElement()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HLABasicDataElement::accept(HLADataElementVisitor& visitor)
|
||||
{
|
||||
visitor.apply(*this);
|
||||
}
|
||||
|
||||
void
|
||||
HLABasicDataElement::accept(HLAConstDataElementVisitor& visitor) const
|
||||
{
|
||||
visitor.apply(*this);
|
||||
}
|
||||
|
||||
const HLABasicDataType*
|
||||
HLABasicDataElement::getDataType() const
|
||||
{
|
||||
|
||||
@@ -28,12 +28,6 @@ public:
|
||||
HLABasicDataElement(const HLABasicDataType* dataType);
|
||||
virtual ~HLABasicDataElement();
|
||||
|
||||
virtual void accept(HLADataElementVisitor& visitor);
|
||||
virtual void accept(HLAConstDataElementVisitor& visitor) const;
|
||||
|
||||
virtual bool encode(HLAEncodeStream& stream) const = 0;
|
||||
virtual bool decode(HLADecodeStream& stream) = 0;
|
||||
|
||||
virtual const HLABasicDataType* getDataType() const;
|
||||
virtual bool setDataType(const HLADataType* dataType);
|
||||
void setDataType(const HLABasicDataType* dataType);
|
||||
@@ -47,7 +41,6 @@ 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); \
|
||||
\
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include "HLADataElementVisitor.hxx"
|
||||
|
||||
namespace simgear {
|
||||
|
||||
HLADataElement::PathElement::Data::~Data()
|
||||
@@ -131,18 +129,6 @@ HLADataElement::~HLADataElement()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HLADataElement::accept(HLADataElementVisitor& visitor)
|
||||
{
|
||||
visitor.apply(*this);
|
||||
}
|
||||
|
||||
void
|
||||
HLADataElement::accept(HLAConstDataElementVisitor& visitor) const
|
||||
{
|
||||
visitor.apply(*this);
|
||||
}
|
||||
|
||||
std::string
|
||||
HLADataElement::toString(const Path& path)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
// 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
|
||||
@@ -30,16 +30,10 @@ class SGTimeStamp;
|
||||
|
||||
namespace simgear {
|
||||
|
||||
class HLADataElementVisitor;
|
||||
class HLAConstDataElementVisitor;
|
||||
|
||||
class HLADataElement : public SGReferenced {
|
||||
public:
|
||||
virtual ~HLADataElement();
|
||||
|
||||
virtual void accept(HLADataElementVisitor& visitor) = 0;
|
||||
virtual void accept(HLAConstDataElementVisitor& visitor) const = 0;
|
||||
|
||||
virtual bool encode(HLAEncodeStream& stream) const = 0;
|
||||
virtual bool decode(HLADecodeStream& stream) = 0;
|
||||
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
// Copyright (C) 2009 - 2011 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 HLADataElementVisitor_hxx
|
||||
#define HLADataElementVisitor_hxx
|
||||
|
||||
namespace simgear {
|
||||
|
||||
class HLABasicDataElement;
|
||||
class HLAAbstractEnumeratedDataElement;
|
||||
class HLAAbstractFixedRecordDataElement;
|
||||
class HLAAbstractArrayDataElement;
|
||||
class HLAAbstractVariantDataElement;
|
||||
|
||||
class HLADataElementVisitor {
|
||||
public:
|
||||
virtual ~HLADataElementVisitor() {}
|
||||
|
||||
virtual void apply(HLADataElement&);
|
||||
|
||||
virtual void apply(HLABasicDataElement&);
|
||||
virtual void apply(HLAAbstractEnumeratedDataElement&);
|
||||
virtual void apply(HLAAbstractArrayDataElement&);
|
||||
virtual void apply(HLAAbstractFixedRecordDataElement&);
|
||||
virtual void apply(HLAAbstractVariantDataElement&);
|
||||
};
|
||||
|
||||
class HLAConstDataElementVisitor {
|
||||
public:
|
||||
virtual ~HLAConstDataElementVisitor() {}
|
||||
|
||||
virtual void apply(const HLADataElement&);
|
||||
|
||||
virtual void apply(const HLABasicDataElement&);
|
||||
virtual void apply(const HLAAbstractEnumeratedDataElement&);
|
||||
virtual void apply(const HLAAbstractArrayDataElement&);
|
||||
virtual void apply(const HLAAbstractFixedRecordDataElement&);
|
||||
virtual void apply(const HLAAbstractVariantDataElement&);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,188 +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 "HLADataTypeVisitor.hxx"
|
||||
|
||||
#include "HLAArrayDataElement.hxx"
|
||||
#include "HLABasicDataElement.hxx"
|
||||
#include "HLADataTypeVisitor.hxx"
|
||||
#include "HLAEnumeratedDataElement.hxx"
|
||||
#include "HLAFixedRecordDataElement.hxx"
|
||||
#include "HLAVariantDataElement.hxx"
|
||||
|
||||
namespace simgear {
|
||||
|
||||
HLADataElementFactoryVisitor::~HLADataElementFactoryVisitor()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HLADataElementFactoryVisitor::apply(const HLADataType& dataType)
|
||||
{
|
||||
SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Can not find a suitable data element for data type \""
|
||||
<< dataType.getName() << "\"");
|
||||
}
|
||||
|
||||
void
|
||||
HLADataElementFactoryVisitor::apply(const HLAInt8DataType& dataType)
|
||||
{
|
||||
_dataElement = new HLASCharDataElement(&dataType);
|
||||
}
|
||||
|
||||
void
|
||||
HLADataElementFactoryVisitor::apply(const HLAUInt8DataType& dataType)
|
||||
{
|
||||
_dataElement = new HLAUCharDataElement(&dataType);
|
||||
}
|
||||
|
||||
void
|
||||
HLADataElementFactoryVisitor::apply(const HLAInt16DataType& dataType)
|
||||
{
|
||||
_dataElement = new HLAShortDataElement(&dataType);
|
||||
}
|
||||
|
||||
void
|
||||
HLADataElementFactoryVisitor::apply(const HLAUInt16DataType& dataType)
|
||||
{
|
||||
_dataElement = new HLAUShortDataElement(&dataType);
|
||||
}
|
||||
|
||||
void
|
||||
HLADataElementFactoryVisitor::apply(const HLAInt32DataType& dataType)
|
||||
{
|
||||
_dataElement = new HLAIntDataElement(&dataType);
|
||||
}
|
||||
|
||||
void
|
||||
HLADataElementFactoryVisitor::apply(const HLAUInt32DataType& dataType)
|
||||
{
|
||||
_dataElement = new HLAUIntDataElement(&dataType);
|
||||
}
|
||||
|
||||
void
|
||||
HLADataElementFactoryVisitor::apply(const HLAInt64DataType& dataType)
|
||||
{
|
||||
_dataElement = new HLALongDataElement(&dataType);
|
||||
}
|
||||
|
||||
void
|
||||
HLADataElementFactoryVisitor::apply(const HLAUInt64DataType& dataType)
|
||||
{
|
||||
_dataElement = new HLAULongDataElement(&dataType);
|
||||
}
|
||||
|
||||
void
|
||||
HLADataElementFactoryVisitor::apply(const HLAFloat32DataType& dataType)
|
||||
{
|
||||
_dataElement = new HLAFloatDataElement(&dataType);
|
||||
}
|
||||
|
||||
void
|
||||
HLADataElementFactoryVisitor::apply(const HLAFloat64DataType& dataType)
|
||||
{
|
||||
_dataElement = new HLADoubleDataElement(&dataType);
|
||||
}
|
||||
|
||||
class HLADataElementFactoryVisitor::ArrayDataElementFactory : public HLAArrayDataElement::DataElementFactory {
|
||||
public:
|
||||
virtual HLADataElement* createElement(const HLAArrayDataElement& element, unsigned index)
|
||||
{
|
||||
const HLADataType* dataType = element.getElementDataType();
|
||||
if (!dataType)
|
||||
return 0;
|
||||
|
||||
HLADataElementFactoryVisitor visitor;
|
||||
dataType->accept(visitor);
|
||||
return visitor.getDataElement();
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
HLADataElementFactoryVisitor::apply(const HLAFixedArrayDataType& dataType)
|
||||
{
|
||||
if (dataType.getIsString()) {
|
||||
_dataElement = new HLAStringDataElement(&dataType);
|
||||
} else {
|
||||
SGSharedPtr<HLAArrayDataElement> arrayDataElement;
|
||||
arrayDataElement = new HLAArrayDataElement(&dataType);
|
||||
arrayDataElement->setDataElementFactory(new ArrayDataElementFactory);
|
||||
arrayDataElement->setNumElements(dataType.getNumElements());
|
||||
_dataElement = arrayDataElement;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HLADataElementFactoryVisitor::apply(const HLAVariableArrayDataType& dataType)
|
||||
{
|
||||
if (dataType.getIsString()) {
|
||||
_dataElement = new HLAStringDataElement(&dataType);
|
||||
} else {
|
||||
SGSharedPtr<HLAArrayDataElement> arrayDataElement;
|
||||
arrayDataElement = new HLAArrayDataElement(&dataType);
|
||||
arrayDataElement->setDataElementFactory(new ArrayDataElementFactory);
|
||||
_dataElement = arrayDataElement;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HLADataElementFactoryVisitor::apply(const HLAEnumeratedDataType& dataType)
|
||||
{
|
||||
_dataElement = new HLAEnumeratedDataElement(&dataType);
|
||||
}
|
||||
|
||||
void
|
||||
HLADataElementFactoryVisitor::apply(const HLAFixedRecordDataType& dataType)
|
||||
{
|
||||
SGSharedPtr<HLAFixedRecordDataElement> recordDataElement;
|
||||
recordDataElement = new HLAFixedRecordDataElement(&dataType);
|
||||
|
||||
unsigned numFields = dataType.getNumFields();
|
||||
for (unsigned i = 0; i < numFields; ++i) {
|
||||
HLADataElementFactoryVisitor visitor;
|
||||
dataType.getFieldDataType(i)->accept(visitor);
|
||||
recordDataElement->setField(i, visitor._dataElement.get());
|
||||
}
|
||||
|
||||
_dataElement = recordDataElement;
|
||||
}
|
||||
|
||||
class HLADataElementFactoryVisitor::VariantDataElementFactory : public HLAVariantDataElement::DataElementFactory {
|
||||
public:
|
||||
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;
|
||||
HLADataElementFactoryVisitor visitor;
|
||||
alternativeDataType->accept(visitor);
|
||||
return visitor.getDataElement();
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
HLADataElementFactoryVisitor::apply(const HLAVariantDataType& dataType)
|
||||
{
|
||||
SGSharedPtr<HLAVariantDataElement> variantDataElement;
|
||||
variantDataElement = new HLAVariantDataElement(&dataType);
|
||||
variantDataElement->setDataElementFactory(new VariantDataElementFactory);
|
||||
_dataElement = variantDataElement;
|
||||
}
|
||||
|
||||
} // namespace simgear
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
#include "HLAArrayDataType.hxx"
|
||||
#include "HLABasicDataType.hxx"
|
||||
#include "HLADataElement.hxx"
|
||||
#include "HLADataTypeVisitor.hxx"
|
||||
#include "HLAEnumeratedDataType.hxx"
|
||||
#include "HLAFixedRecordDataType.hxx"
|
||||
#include "HLAVariantDataType.hxx"
|
||||
@@ -629,43 +629,6 @@ inline void HLADataTypeEncodeVisitor::apply(const HLAVariableArrayDataType& data
|
||||
dataType.getSizeDataType()->accept(numElementsVisitor);
|
||||
}
|
||||
|
||||
/// Generate standard data elements according to the traversed type
|
||||
class HLADataElementFactoryVisitor : public HLADataTypeVisitor {
|
||||
public:
|
||||
virtual ~HLADataElementFactoryVisitor();
|
||||
|
||||
virtual void apply(const HLADataType& dataType);
|
||||
|
||||
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);
|
||||
virtual void apply(const HLAVariableArrayDataType& dataType);
|
||||
|
||||
virtual void apply(const HLAEnumeratedDataType& dataType);
|
||||
|
||||
virtual void apply(const HLAFixedRecordDataType& dataType);
|
||||
|
||||
virtual void apply(const HLAVariantDataType& dataType);
|
||||
|
||||
HLADataElement* getDataElement()
|
||||
{ return _dataElement.release(); }
|
||||
|
||||
protected:
|
||||
class ArrayDataElementFactory;
|
||||
class VariantDataElementFactory;
|
||||
|
||||
SGSharedPtr<HLADataElement> _dataElement;
|
||||
};
|
||||
|
||||
} // namespace simgear
|
||||
|
||||
#endif
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include "HLADataElementVisitor.hxx"
|
||||
|
||||
namespace simgear {
|
||||
|
||||
HLAAbstractEnumeratedDataElement::HLAAbstractEnumeratedDataElement(const HLAEnumeratedDataType* dataType) :
|
||||
@@ -32,18 +30,6 @@ HLAAbstractEnumeratedDataElement::~HLAAbstractEnumeratedDataElement()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HLAAbstractEnumeratedDataElement::accept(HLADataElementVisitor& visitor)
|
||||
{
|
||||
visitor.apply(*this);
|
||||
}
|
||||
|
||||
void
|
||||
HLAAbstractEnumeratedDataElement::accept(HLAConstDataElementVisitor& visitor) const
|
||||
{
|
||||
visitor.apply(*this);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAAbstractEnumeratedDataElement::decode(HLADecodeStream& stream)
|
||||
{
|
||||
|
||||
@@ -28,9 +28,6 @@ public:
|
||||
HLAAbstractEnumeratedDataElement(const HLAEnumeratedDataType* dataType);
|
||||
virtual ~HLAAbstractEnumeratedDataElement();
|
||||
|
||||
virtual void accept(HLADataElementVisitor& visitor);
|
||||
virtual void accept(HLAConstDataElementVisitor& visitor) const;
|
||||
|
||||
virtual bool decode(HLADecodeStream& stream);
|
||||
virtual bool encode(HLAEncodeStream& stream) const;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
// 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
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
#include "HLAFederate.hxx"
|
||||
|
||||
#include "RTI13Federate.hxx"
|
||||
#include "RTIFederate.hxx"
|
||||
#include "RTIInteractionClass.hxx"
|
||||
#include "RTIObjectClass.hxx"
|
||||
@@ -27,13 +26,8 @@
|
||||
|
||||
namespace simgear {
|
||||
|
||||
HLAFederate::HLAFederate() :
|
||||
_version(RTI13),
|
||||
_createFederationExecution(true),
|
||||
_timeConstrained(false),
|
||||
_timeRegulating(false),
|
||||
_timeConstrainedByLocalClock(false),
|
||||
_done(false)
|
||||
HLAFederate::HLAFederate(const SGSharedPtr<RTIFederate>& rtiFederate) :
|
||||
_rtiFederate(rtiFederate)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -41,707 +35,88 @@ HLAFederate::~HLAFederate()
|
||||
{
|
||||
}
|
||||
|
||||
HLAFederate::Version
|
||||
HLAFederate::getVersion() const
|
||||
{
|
||||
return _version;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::setVersion(HLAFederate::Version version)
|
||||
{
|
||||
if (_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
|
||||
return false;
|
||||
}
|
||||
_version = version;
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::list<std::string>&
|
||||
HLAFederate::getConnectArguments() const
|
||||
{
|
||||
return _connectArguments;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::setConnectArguments(const std::list<std::string>& connectArguments)
|
||||
{
|
||||
if (_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
|
||||
return false;
|
||||
}
|
||||
_connectArguments = connectArguments;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::getCreateFederationExecution() const
|
||||
{
|
||||
return _createFederationExecution;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::setCreateFederationExecution(bool createFederationExecution)
|
||||
{
|
||||
_createFederationExecution = createFederationExecution;
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
HLAFederate::getFederationExecutionName() const
|
||||
{
|
||||
return _federationExecutionName;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::setFederationExecutionName(const std::string& federationExecutionName)
|
||||
{
|
||||
if (_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
|
||||
return false;
|
||||
}
|
||||
_federationExecutionName = federationExecutionName;
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
HLAFederate::getFederationObjectModel() const
|
||||
{
|
||||
return _federationObjectModel;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::setFederationObjectModel(const std::string& federationObjectModel)
|
||||
{
|
||||
if (_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
|
||||
return false;
|
||||
}
|
||||
_federationObjectModel = federationObjectModel;
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
HLAFederate::getFederateType() const
|
||||
{
|
||||
return _federateType;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::setFederateType(const std::string& federateType)
|
||||
{
|
||||
if (_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
|
||||
return false;
|
||||
}
|
||||
_federateType = federateType;
|
||||
return true;
|
||||
return _rtiFederate->getFederateType();
|
||||
}
|
||||
|
||||
const std::string&
|
||||
HLAFederate::getFederateName() const
|
||||
HLAFederate::getFederationName() const
|
||||
{
|
||||
return _federateName;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::setFederateName(const std::string& federateName)
|
||||
{
|
||||
if (_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
|
||||
return false;
|
||||
}
|
||||
_federateName = federateName;
|
||||
return true;
|
||||
}
|
||||
|
||||
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);
|
||||
_version = version;
|
||||
_connectArguments = stringList;
|
||||
break;
|
||||
case RTI1516:
|
||||
SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516 not yet(!?) supported.");
|
||||
// _rtiFederate = new RTI1516Federate(stringList);
|
||||
break;
|
||||
case RTI1516E:
|
||||
SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516E not yet(!?) supported.");
|
||||
// _rtiFederate = new RTI1516eFederate(stringList);
|
||||
break;
|
||||
default:
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Unknown rti version in connect!");
|
||||
}
|
||||
return _rtiFederate.valid();
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::connect()
|
||||
{
|
||||
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(_connectArguments);
|
||||
break;
|
||||
case RTI1516:
|
||||
SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516 not yet(!?) supported.");
|
||||
// _rtiFederate = new RTI1516Federate(_connectArguments);
|
||||
break;
|
||||
case RTI1516E:
|
||||
SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516E not yet(!?) supported.");
|
||||
// _rtiFederate = new RTI1516eFederate(_connectArguments);
|
||||
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;
|
||||
return _rtiFederate->getFederationName();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
RTIFederate::FederationManagementResult createResult;
|
||||
createResult = _rtiFederate->createFederationExecution(federation, objectModel);
|
||||
if (createResult == RTIFederate::FederationManagementFatal)
|
||||
return false;
|
||||
|
||||
_federationExecutionName = federation;
|
||||
_federationObjectModel = objectModel;
|
||||
return true;
|
||||
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;
|
||||
}
|
||||
|
||||
RTIFederate::FederationManagementResult destroyResult;
|
||||
destroyResult = _rtiFederate->destroyFederationExecution(federation);
|
||||
if (destroyResult == RTIFederate::FederationManagementFatal)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::createFederationExecution()
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
|
||||
RTIFederate::FederationManagementResult createResult;
|
||||
createResult = _rtiFederate->createFederationExecution(_federationExecutionName, _federationObjectModel);
|
||||
if (createResult != RTIFederate::FederationManagementSuccess)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::destroyFederationExecution()
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
|
||||
RTIFederate::FederationManagementResult destroyResult;
|
||||
destroyResult = _rtiFederate->destroyFederationExecution(_federationExecutionName);
|
||||
if (destroyResult != RTIFederate::FederationManagementSuccess)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
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;
|
||||
}
|
||||
|
||||
RTIFederate::FederationManagementResult joinResult;
|
||||
joinResult = _rtiFederate->join(federateType, federation);
|
||||
if (joinResult == RTIFederate::FederationManagementFatal)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::join()
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
|
||||
RTIFederate::FederationManagementResult joinResult;
|
||||
joinResult = _rtiFederate->join(_federateType, _federationExecutionName);
|
||||
if (joinResult != RTIFederate::FederationManagementSuccess)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
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::createJoinFederationExecution()
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
// Try to join.
|
||||
RTIFederate::FederationManagementResult joinResult;
|
||||
joinResult = _rtiFederate->join(_federateType, _federationExecutionName);
|
||||
switch (joinResult) {
|
||||
case RTIFederate::FederationManagementSuccess:
|
||||
// Fast return on success
|
||||
return true;
|
||||
case RTIFederate::FederationManagementFatal:
|
||||
// Abort on fatal errors
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
// If not already joinable, try to create the requested federation
|
||||
RTIFederate::FederationManagementResult createResult;
|
||||
createResult = _rtiFederate->createFederationExecution(_federationExecutionName, _federationObjectModel);
|
||||
switch (createResult) {
|
||||
case RTIFederate::FederationManagementFatal:
|
||||
// Abort on fatal errors
|
||||
return false;
|
||||
default:
|
||||
// Try again to join
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::resignDestroyFederationExecution()
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Resign ourselves
|
||||
bool success = _rtiFederate->resign();
|
||||
|
||||
// and try to destroy, non fatal if still some federates joined
|
||||
if (_rtiFederate->destroyFederationExecution(_federationExecutionName) == RTIFederate::FederationManagementFatal)
|
||||
success = false;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::getTimeConstrained() const
|
||||
{
|
||||
return _timeConstrained;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::setTimeConstrained(bool timeConstrained)
|
||||
{
|
||||
_timeConstrained = timeConstrained;
|
||||
|
||||
if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
|
||||
if (_timeConstrained && !_rtiFederate->getTimeConstrainedEnabled()) {
|
||||
if (!enableTimeConstrained())
|
||||
return false;
|
||||
} else if (!_timeConstrained && _rtiFederate->getTimeConstrainedEnabled()) {
|
||||
if (!disableTimeConstrained())
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::getTimeConstrainedByLocalClock() const
|
||||
{
|
||||
return _timeConstrainedByLocalClock;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::setTimeConstrainedByLocalClock(bool timeConstrainedByLocalClock)
|
||||
{
|
||||
_timeConstrainedByLocalClock = timeConstrainedByLocalClock;
|
||||
|
||||
if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
|
||||
if (_timeConstrainedByLocalClock) {
|
||||
if (!enableTimeConstrainedByLocalClock())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::getTimeRegulating() const
|
||||
{
|
||||
return _timeRegulating;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::setTimeRegulating(bool timeRegulating)
|
||||
{
|
||||
_timeRegulating = timeRegulating;
|
||||
|
||||
if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
|
||||
if (_timeRegulating && !_rtiFederate->getTimeRegulationEnabled()) {
|
||||
if (!enableTimeRegulation())
|
||||
return false;
|
||||
} else if (!_timeRegulating && _rtiFederate->getTimeRegulationEnabled()) {
|
||||
if (!disableTimeRegulation())
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::setLeadTime(const SGTimeStamp& leadTime)
|
||||
{
|
||||
if (leadTime < SGTimeStamp::fromSec(0)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Ignoring negative lead time!");
|
||||
return false;
|
||||
}
|
||||
|
||||
_leadTime = leadTime;
|
||||
|
||||
if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
|
||||
if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const SGTimeStamp&
|
||||
HLAFederate::getLeadTime() const
|
||||
{
|
||||
return _leadTime;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::setTimeIncrement(const SGTimeStamp& timeIncrement)
|
||||
{
|
||||
if (timeIncrement < SGTimeStamp::fromSec(0)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Ignoring negative time increment!");
|
||||
return false;
|
||||
}
|
||||
|
||||
_timeIncrement = timeIncrement;
|
||||
|
||||
if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
|
||||
if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const SGTimeStamp&
|
||||
HLAFederate::getTimeIncrement() const
|
||||
{
|
||||
return _timeIncrement;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::enableTimeConstrained()
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_rtiFederate->enableTimeConstrained()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not enable time constrained!");
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!_rtiFederate->getTimeConstrainedEnabled()) {
|
||||
_rtiFederate->processMessage();
|
||||
}
|
||||
|
||||
return true;
|
||||
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::enableTimeConstrainedByLocalClock()
|
||||
{
|
||||
// Compute the time offset from the system time to the simulation time
|
||||
SGTimeStamp federateTime;
|
||||
if (!queryFederateTime(federateTime)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Cannot get federate time!");
|
||||
return false;
|
||||
}
|
||||
_localClockOffset = SGTimeStamp::now() - federateTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::enableTimeRegulation(const SGTimeStamp& lookahead)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_rtiFederate->enableTimeRegulation(lookahead)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not enable time regulation!");
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!_rtiFederate->getTimeRegulationEnabled()) {
|
||||
_rtiFederate->processMessage();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::enableTimeRegulation()
|
||||
{
|
||||
if (!enableTimeRegulation(SGTimeStamp::fromSec(0))) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Cannot enable time regulation!");
|
||||
return false;
|
||||
}
|
||||
if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
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::modifyLookahead(const SGTimeStamp& timeStamp)
|
||||
HLAFederate::timeAdvanceRequestBy(const SGTimeStamp& dt)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->modifyLookahead(timeStamp);
|
||||
return _rtiFederate->timeAdvanceRequestBy(dt);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::timeAdvanceBy(const SGTimeStamp& timeIncrement)
|
||||
HLAFederate::timeAdvanceRequest(const SGTimeStamp& dt)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
|
||||
SGTimeStamp timeStamp;
|
||||
if (!_rtiFederate->queryFederateTime(timeStamp)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not query federate time!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_rtiFederate->timeAdvanceRequest(timeStamp + timeIncrement)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return processMessages();
|
||||
return _rtiFederate->timeAdvanceRequest(dt);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::timeAdvance(const SGTimeStamp& timeStamp)
|
||||
HLAFederate::tick()
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_rtiFederate->timeAdvanceRequest(timeStamp)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return processMessages();
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::timeAdvanceAvailable()
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
|
||||
SGTimeStamp timeStamp;
|
||||
if (!_rtiFederate->queryGALT(timeStamp)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not query GALT!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_rtiFederate->timeAdvanceRequestAvailable(timeStamp)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return processMessages();
|
||||
}
|
||||
|
||||
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::queryLookahead(SGTimeStamp& timeStamp)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->queryLookahead(timeStamp);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::processMessage()
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->processMessage();
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::processMessage(const SGTimeStamp& timeout)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->processMessages(timeout.toSecs(), 0);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::processMessages()
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
|
||||
while (_rtiFederate->getTimeAdvancePending()) {
|
||||
_rtiFederate->processMessage();
|
||||
}
|
||||
|
||||
if (_timeConstrainedByLocalClock) {
|
||||
SGTimeStamp federateTime;
|
||||
if (!_rtiFederate->queryFederateTime(federateTime)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Error querying federate time!");
|
||||
return false;
|
||||
}
|
||||
SGTimeStamp systemTime = federateTime + _localClockOffset;
|
||||
for (;;) {
|
||||
double rest = (systemTime - SGTimeStamp::now()).toSecs();
|
||||
if (rest < 0)
|
||||
break;
|
||||
_rtiFederate->processMessages(rest, rest);
|
||||
}
|
||||
}
|
||||
|
||||
// Now flush just what is left
|
||||
while (_rtiFederate->processMessages(0, 0));
|
||||
|
||||
return true;
|
||||
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->processMessages(minimum, maximum);
|
||||
return _rtiFederate->tick(minimum, maximum);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -749,7 +124,8 @@ HLAFederate::readObjectModelTemplate(const std::string& objectModel,
|
||||
HLAFederate::ObjectModelFactory& objectModelFactory)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
SG_LOG(SG_IO, SG_ALERT, "Could not process HLA XML object model file: "
|
||||
"No rti federate available!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -867,146 +243,4 @@ HLAFederate::getInteractionClass(const std::string& name) const
|
||||
return i->second.get();
|
||||
}
|
||||
|
||||
void
|
||||
HLAFederate::setDone(bool done)
|
||||
{
|
||||
_done = done;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::getDone() const
|
||||
{
|
||||
return _done;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::readObjectModel()
|
||||
{
|
||||
/// Currently empty, but is called at the right time so that
|
||||
/// the object model is present when it is needed
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::subscribe()
|
||||
{
|
||||
/// Currently empty, but is called at the right time
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::publish()
|
||||
{
|
||||
/// Currently empty, but is called at the right time
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::init()
|
||||
{
|
||||
// We need to talk to the rti
|
||||
if (!connect())
|
||||
return false;
|
||||
// Join ...
|
||||
if (_createFederationExecution) {
|
||||
if (!createJoinFederationExecution())
|
||||
return false;
|
||||
} else {
|
||||
if (!join())
|
||||
return false;
|
||||
}
|
||||
// Read the xml file containing the object model
|
||||
if (!readObjectModel()) {
|
||||
shutdown();
|
||||
return false;
|
||||
}
|
||||
// start being time constrained if required
|
||||
if (_timeConstrained) {
|
||||
if (!enableTimeConstrained()) {
|
||||
shutdown();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Now that we are potentially time constrained, we can subscribe.
|
||||
// This is to make sure we do not get any time stamped message
|
||||
// converted to a non time stamped message by the rti.
|
||||
if (!subscribe()) {
|
||||
shutdown();
|
||||
return false;
|
||||
}
|
||||
// Before we publish anything start getting regulating if required
|
||||
if (_timeRegulating) {
|
||||
if (!enableTimeRegulation()) {
|
||||
shutdown();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Note that starting from here, we need to be careful with things
|
||||
// requireing unbounded time. The rest of the federation might wait
|
||||
// for us to finish!
|
||||
|
||||
// Compute the time offset from the system time to the simulation time
|
||||
if (_timeConstrainedByLocalClock) {
|
||||
if (!enableTimeConstrainedByLocalClock()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Cannot enable time constrained by local clock!");
|
||||
shutdown();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Publish what we want to write
|
||||
if (!publish()) {
|
||||
shutdown();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::update()
|
||||
{
|
||||
return timeAdvanceBy(_timeIncrement);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::shutdown()
|
||||
{
|
||||
// On shutdown, just try all in order.
|
||||
// If something goes wrong, continue and try to get out here as good as possible.
|
||||
bool ret = true;
|
||||
|
||||
if (_createFederationExecution) {
|
||||
if (!resignDestroyFederationExecution())
|
||||
ret = false;
|
||||
} else {
|
||||
if (!resign())
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if (!disconnect())
|
||||
ret = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::exec()
|
||||
{
|
||||
if (!init())
|
||||
return false;
|
||||
|
||||
while (!getDone()) {
|
||||
if (!update()) {
|
||||
shutdown();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!shutdown())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace simgear
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
// 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
|
||||
@@ -32,136 +32,34 @@ class RTIFederate;
|
||||
|
||||
class HLAFederate : public SGWeakReferenced {
|
||||
public:
|
||||
HLAFederate();
|
||||
virtual ~HLAFederate();
|
||||
|
||||
enum Version {
|
||||
RTI13,
|
||||
RTI1516,
|
||||
RTI1516E
|
||||
};
|
||||
|
||||
/// The rti version backend to connect
|
||||
Version getVersion() const;
|
||||
bool setVersion(HLAFederate::Version version);
|
||||
|
||||
/// The rti backends connect arguments, depends on the version
|
||||
const std::list<std::string>& getConnectArguments() const;
|
||||
bool setConnectArguments(const std::list<std::string>& connectArguments);
|
||||
|
||||
/// If true try to create on join and try to destroy on resign
|
||||
bool getCreateFederationExecution() const;
|
||||
bool setCreateFederationExecution(bool createFederationExecution);
|
||||
|
||||
/// The federation execution name to use on create, join and destroy
|
||||
const std::string& getFederationExecutionName() const;
|
||||
bool setFederationExecutionName(const std::string& federationExecutionName);
|
||||
|
||||
/// The federation object model name to use on create and possibly join
|
||||
const std::string& getFederationObjectModel() const;
|
||||
bool setFederationObjectModel(const std::string& federationObjectModel);
|
||||
|
||||
/// The federate type used on join
|
||||
/// Get the name of the joined federate/federation
|
||||
const std::string& getFederateType() const;
|
||||
bool setFederateType(const std::string& federateType);
|
||||
|
||||
/// The federate name possibly used on join
|
||||
const std::string& getFederateName() const;
|
||||
bool setFederateName(const std::string& federateName);
|
||||
|
||||
/// connect to an rti
|
||||
bool connect(Version version, const std::list<std::string>& stringList);
|
||||
bool connect();
|
||||
bool disconnect();
|
||||
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);
|
||||
bool createFederationExecution();
|
||||
bool destroyFederationExecution();
|
||||
|
||||
/// Join with federateType the federation execution
|
||||
bool join(const std::string& federateType, const std::string& federation);
|
||||
bool join();
|
||||
bool resign();
|
||||
|
||||
/// Try to create and join the federation execution.
|
||||
bool createJoinFederationExecution();
|
||||
bool resignDestroyFederationExecution();
|
||||
|
||||
|
||||
/// Time management
|
||||
|
||||
/// If set to true, time constrained mode is entered on init
|
||||
bool getTimeConstrained() const;
|
||||
bool setTimeConstrained(bool timeConstrained);
|
||||
|
||||
/// If set to true, time advance is constrained by the local system clock
|
||||
bool getTimeConstrainedByLocalClock() const;
|
||||
bool setTimeConstrainedByLocalClock(bool timeConstrainedByLocalClock);
|
||||
|
||||
/// If set to true, time regulation mode is entered on init
|
||||
bool getTimeRegulating() const;
|
||||
bool setTimeRegulating(bool timeRegulating);
|
||||
|
||||
/// If set to a non zero value, this federate leads the federations
|
||||
/// locical time advance by this amount of time.
|
||||
const SGTimeStamp& getLeadTime() const;
|
||||
bool setLeadTime(const SGTimeStamp& leadTime);
|
||||
|
||||
/// The time increment for use in the default update method.
|
||||
const SGTimeStamp& getTimeIncrement() const;
|
||||
bool setTimeIncrement(const SGTimeStamp& timeIncrement);
|
||||
|
||||
/// Actually enable time constrained mode.
|
||||
/// This method blocks until time constrained mode is enabled.
|
||||
bool enableTimeConstrained();
|
||||
/// Actually disable time constrained mode.
|
||||
bool disableTimeConstrained();
|
||||
|
||||
/// Actually enable time constrained by local clock mode.
|
||||
bool enableTimeConstrainedByLocalClock();
|
||||
|
||||
/// Actually enable time regulation mode.
|
||||
/// This method blocks until time regulation mode is enabled.
|
||||
bool enableTimeRegulation(const SGTimeStamp& lookahead);
|
||||
bool enableTimeRegulation();
|
||||
/// Actually disable time regulation mode.
|
||||
bool disableTimeRegulation();
|
||||
/// Actually modify the lookahead time.
|
||||
bool modifyLookahead(const SGTimeStamp& lookahead);
|
||||
|
||||
/// Advance the logical time by the given time increment.
|
||||
/// Depending on the time constrained mode, this might
|
||||
/// block until the time advance is granted.
|
||||
bool timeAdvanceBy(const SGTimeStamp& timeIncrement);
|
||||
/// Advance the logical time to the given time.
|
||||
/// Depending on the time constrained mode, this might
|
||||
/// block until the time advance is granted.
|
||||
bool timeAdvance(const SGTimeStamp& timeStamp);
|
||||
/// Advance the logical time as far as time advances are available.
|
||||
/// This call should not block and advance the logical time
|
||||
/// as far as currently possible.
|
||||
bool timeAdvanceAvailable();
|
||||
bool timeAdvanceRequestBy(const SGTimeStamp& dt);
|
||||
bool timeAdvanceRequest(const SGTimeStamp& dt);
|
||||
|
||||
/// Get the current federates time
|
||||
bool queryFederateTime(SGTimeStamp& timeStamp);
|
||||
/// Get the current federates lookahead
|
||||
bool queryLookahead(SGTimeStamp& timeStamp);
|
||||
|
||||
/// Process one messsage
|
||||
bool processMessage();
|
||||
/// Process one message but do not wait longer than the relative timeout.
|
||||
bool processMessage(const SGTimeStamp& timeout);
|
||||
/// Process messages until the federate can proceed with the
|
||||
/// next simulation step. That is flush all pending messages and
|
||||
/// depending on the time constrained mode process messages until
|
||||
/// a pending time advance is granted.
|
||||
bool processMessages();
|
||||
|
||||
/// Legacy tick call
|
||||
/// Process messages
|
||||
bool tick();
|
||||
bool tick(const double& minimum, const double& maximum);
|
||||
|
||||
class ObjectModelFactory {
|
||||
@@ -186,67 +84,18 @@ public:
|
||||
bool readObjectModelTemplate(const std::string& objectModel,
|
||||
ObjectModelFactory& objectModelFactory);
|
||||
|
||||
/// Get the object class of a given name
|
||||
HLAObjectClass* getObjectClass(const std::string& name);
|
||||
const HLAObjectClass* getObjectClass(const std::string& name) const;
|
||||
|
||||
/// Get the interaction class of a given name
|
||||
HLAInteractionClass* getInteractionClass(const std::string& name);
|
||||
const HLAInteractionClass* getInteractionClass(const std::string& name) const;
|
||||
|
||||
/// Tells the main exec loop to continue or not.
|
||||
void setDone(bool done);
|
||||
bool getDone() const;
|
||||
|
||||
virtual bool readObjectModel();
|
||||
|
||||
virtual bool subscribe();
|
||||
virtual bool publish();
|
||||
|
||||
virtual bool init();
|
||||
virtual bool update();
|
||||
virtual bool shutdown();
|
||||
|
||||
virtual bool exec();
|
||||
protected:
|
||||
HLAFederate(const SGSharedPtr<RTIFederate>& rtiFederate);
|
||||
|
||||
private:
|
||||
HLAFederate(const HLAFederate&);
|
||||
HLAFederate& operator=(const HLAFederate&);
|
||||
|
||||
/// The underlying interface to the rti implementation
|
||||
SGSharedPtr<RTIFederate> _rtiFederate;
|
||||
|
||||
/// Parameters required to connect to an rti
|
||||
Version _version;
|
||||
std::list<std::string> _connectArguments;
|
||||
|
||||
/// Parameters for the federation execution
|
||||
std::string _federationExecutionName;
|
||||
std::string _federationObjectModel;
|
||||
bool _createFederationExecution;
|
||||
|
||||
/// Parameters for the federate
|
||||
std::string _federateType;
|
||||
std::string _federateName;
|
||||
|
||||
/// Time management related parameters
|
||||
/// If true, the federate is expected to enter time constrained mode
|
||||
bool _timeConstrained;
|
||||
/// If true, the federate is expected to enter time regulating mode
|
||||
bool _timeRegulating;
|
||||
/// The amount of time this federate leads the others.
|
||||
SGTimeStamp _leadTime;
|
||||
/// The regular time increment we do on calling update()
|
||||
SGTimeStamp _timeIncrement;
|
||||
/// The reference system time at initialization time.
|
||||
/// Is used to implement being time constrained on the
|
||||
/// local system time.
|
||||
bool _timeConstrainedByLocalClock;
|
||||
SGTimeStamp _localClockOffset;
|
||||
|
||||
/// If true the exec method returns.
|
||||
bool _done;
|
||||
|
||||
typedef std::map<std::string, SGSharedPtr<HLAObjectClass> > ObjectClassMap;
|
||||
ObjectClassMap _objectClassMap;
|
||||
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include "HLADataElementVisitor.hxx"
|
||||
#include "HLADataTypeVisitor.hxx"
|
||||
|
||||
namespace simgear {
|
||||
@@ -35,18 +33,6 @@ HLAAbstractFixedRecordDataElement::~HLAAbstractFixedRecordDataElement()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HLAAbstractFixedRecordDataElement::accept(HLADataElementVisitor& visitor)
|
||||
{
|
||||
visitor.apply(*this);
|
||||
}
|
||||
|
||||
void
|
||||
HLAAbstractFixedRecordDataElement::accept(HLAConstDataElementVisitor& visitor) const
|
||||
{
|
||||
visitor.apply(*this);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAAbstractFixedRecordDataElement::decode(HLADecodeStream& stream)
|
||||
{
|
||||
|
||||
@@ -30,9 +30,6 @@ public:
|
||||
HLAAbstractFixedRecordDataElement(const HLAFixedRecordDataType* dataType);
|
||||
virtual ~HLAAbstractFixedRecordDataElement();
|
||||
|
||||
virtual void accept(HLADataElementVisitor& visitor);
|
||||
virtual void accept(HLAConstDataElementVisitor& visitor) const;
|
||||
|
||||
virtual bool decode(HLADecodeStream& stream);
|
||||
virtual bool encode(HLAEncodeStream& stream) const;
|
||||
|
||||
|
||||
@@ -25,10 +25,6 @@ class RTIInteractionClass;
|
||||
class HLAInteractionClass : public SGWeakReferenced {
|
||||
public:
|
||||
virtual ~HLAInteractionClass() {}
|
||||
|
||||
private:
|
||||
HLAInteractionClass(const HLAInteractionClass&);
|
||||
HLAInteractionClass& operator=(const HLAInteractionClass&);
|
||||
};
|
||||
|
||||
} // namespace simgear
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
// 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
|
||||
@@ -439,15 +439,6 @@ HLAOMTXmlVisitor::getArrayDataType(const std::string& dataTypeName, HLAOMTXmlVis
|
||||
}
|
||||
arrayDataType->setElementDataType(elementDataType.get());
|
||||
|
||||
// Check if this should be a string data type
|
||||
if (elementDataType->toBasicDataType()) {
|
||||
if (dataTypeName == "HLAopaqueData") {
|
||||
arrayDataType->setIsOpaque(true);
|
||||
} else if (dataTypeName.find("String") != std::string::npos || dataTypeName.find("string") != std::string::npos) {
|
||||
arrayDataType->setIsString(true);
|
||||
}
|
||||
}
|
||||
|
||||
return arrayDataType;
|
||||
}
|
||||
|
||||
|
||||
@@ -95,9 +95,6 @@ protected:
|
||||
virtual HLAObjectInstance* createObjectInstance(RTIObjectInstance* rtiObjectInstance);
|
||||
|
||||
private:
|
||||
HLAObjectClass(const HLAObjectClass&);
|
||||
HLAObjectClass& operator=(const HLAObjectClass&);
|
||||
|
||||
// The internal entry points from the RTILObjectClass callback functions
|
||||
void discoverInstance(RTIObjectInstance* objectInstance, const RTIData& tag);
|
||||
void removeInstance(HLAObjectInstance& objectInstance, const RTIData& tag);
|
||||
|
||||
@@ -123,7 +123,7 @@ HLAObjectInstance::getAttributeDataElement(unsigned index) const
|
||||
return _rtiObjectInstance->getDataElement(index);
|
||||
}
|
||||
|
||||
class HLAObjectInstance::DataElementFactoryVisitor : public HLADataElementFactoryVisitor {
|
||||
class HLAObjectInstance::DataElementFactoryVisitor : public HLADataTypeVisitor {
|
||||
public:
|
||||
DataElementFactoryVisitor(const HLAPathElementMap& pathElementMap) :
|
||||
_pathElementMap(pathElementMap)
|
||||
@@ -150,7 +150,7 @@ public:
|
||||
if (_dataElement.valid())
|
||||
return;
|
||||
|
||||
HLADataElementFactoryVisitor::apply(dataType);
|
||||
_dataElement = new HLASCharDataElement(&dataType);
|
||||
}
|
||||
virtual void apply(const HLAUInt8DataType& dataType)
|
||||
{
|
||||
@@ -158,7 +158,7 @@ public:
|
||||
if (_dataElement.valid())
|
||||
return;
|
||||
|
||||
HLADataElementFactoryVisitor::apply(dataType);
|
||||
_dataElement = new HLAUCharDataElement(&dataType);
|
||||
}
|
||||
virtual void apply(const HLAInt16DataType& dataType)
|
||||
{
|
||||
@@ -166,7 +166,7 @@ public:
|
||||
if (_dataElement.valid())
|
||||
return;
|
||||
|
||||
HLADataElementFactoryVisitor::apply(dataType);
|
||||
_dataElement = new HLAShortDataElement(&dataType);
|
||||
}
|
||||
virtual void apply(const HLAUInt16DataType& dataType)
|
||||
{
|
||||
@@ -174,7 +174,7 @@ public:
|
||||
if (_dataElement.valid())
|
||||
return;
|
||||
|
||||
HLADataElementFactoryVisitor::apply(dataType);
|
||||
_dataElement = new HLAUShortDataElement(&dataType);
|
||||
}
|
||||
virtual void apply(const HLAInt32DataType& dataType)
|
||||
{
|
||||
@@ -182,7 +182,7 @@ public:
|
||||
if (_dataElement.valid())
|
||||
return;
|
||||
|
||||
HLADataElementFactoryVisitor::apply(dataType);
|
||||
_dataElement = new HLAIntDataElement(&dataType);
|
||||
}
|
||||
virtual void apply(const HLAUInt32DataType& dataType)
|
||||
{
|
||||
@@ -190,7 +190,7 @@ public:
|
||||
if (_dataElement.valid())
|
||||
return;
|
||||
|
||||
HLADataElementFactoryVisitor::apply(dataType);
|
||||
_dataElement = new HLAUIntDataElement(&dataType);
|
||||
}
|
||||
virtual void apply(const HLAInt64DataType& dataType)
|
||||
{
|
||||
@@ -198,7 +198,7 @@ public:
|
||||
if (_dataElement.valid())
|
||||
return;
|
||||
|
||||
HLADataElementFactoryVisitor::apply(dataType);
|
||||
_dataElement = new HLALongDataElement(&dataType);
|
||||
}
|
||||
virtual void apply(const HLAUInt64DataType& dataType)
|
||||
{
|
||||
@@ -206,7 +206,7 @@ public:
|
||||
if (_dataElement.valid())
|
||||
return;
|
||||
|
||||
HLADataElementFactoryVisitor::apply(dataType);
|
||||
_dataElement = new HLAULongDataElement(&dataType);
|
||||
}
|
||||
virtual void apply(const HLAFloat32DataType& dataType)
|
||||
{
|
||||
@@ -214,7 +214,7 @@ public:
|
||||
if (_dataElement.valid())
|
||||
return;
|
||||
|
||||
HLADataElementFactoryVisitor::apply(dataType);
|
||||
_dataElement = new HLAFloatDataElement(&dataType);
|
||||
}
|
||||
virtual void apply(const HLAFloat64DataType& dataType)
|
||||
{
|
||||
@@ -222,7 +222,7 @@ public:
|
||||
if (_dataElement.valid())
|
||||
return;
|
||||
|
||||
HLADataElementFactoryVisitor::apply(dataType);
|
||||
_dataElement = new HLADoubleDataElement(&dataType);
|
||||
}
|
||||
|
||||
class ArrayDataElementFactory : public HLAArrayDataElement::DataElementFactory {
|
||||
@@ -287,7 +287,7 @@ public:
|
||||
if (_dataElement.valid())
|
||||
return;
|
||||
|
||||
HLADataElementFactoryVisitor::apply(dataType);
|
||||
_dataElement = new HLAEnumeratedDataElement(&dataType);
|
||||
}
|
||||
|
||||
virtual void apply(const HLAFixedRecordDataType& dataType)
|
||||
@@ -357,6 +357,9 @@ public:
|
||||
_dataElement = variantDataElement;
|
||||
}
|
||||
|
||||
const SGSharedPtr<HLADataElement>& getDataElement() const
|
||||
{ return _dataElement; }
|
||||
|
||||
private:
|
||||
SGSharedPtr<HLADataElement> createDataElement(const HLADataElement::Path& path, const HLADataType& dataType)
|
||||
{
|
||||
@@ -378,6 +381,7 @@ private:
|
||||
return dataElement;
|
||||
}
|
||||
|
||||
SGSharedPtr<HLADataElement> _dataElement;
|
||||
const HLAPathElementMap& _pathElementMap;
|
||||
HLADataElement::Path _path;
|
||||
};
|
||||
@@ -409,6 +413,26 @@ HLAObjectInstance::setAttributes(const HLAAttributePathElementMap& attributePath
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
@@ -447,6 +471,16 @@ HLAObjectInstance::deleteInstance(const RTIData& tag)
|
||||
_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)
|
||||
{
|
||||
@@ -471,6 +505,16 @@ HLAObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const RTI
|
||||
_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)
|
||||
{
|
||||
|
||||
@@ -52,8 +52,13 @@ public:
|
||||
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:
|
||||
@@ -80,6 +85,11 @@ public:
|
||||
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);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
// 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
|
||||
@@ -17,416 +17,195 @@
|
||||
|
||||
#include "HLAPropertyDataElement.hxx"
|
||||
|
||||
#include "HLAArrayDataElement.hxx"
|
||||
#include "HLABasicDataElement.hxx"
|
||||
#include "HLADataElementVisitor.hxx"
|
||||
#include "HLADataTypeVisitor.hxx"
|
||||
#include "HLAFixedRecordDataElement.hxx"
|
||||
#include "HLAVariantDataElement.hxx"
|
||||
|
||||
namespace simgear {
|
||||
|
||||
class HLAPropertyDataElement::ScalarDecodeVisitor : public HLADataTypeDecodeVisitor {
|
||||
class HLAPropertyDataElement::DecodeVisitor : public HLADataTypeDecodeVisitor {
|
||||
public:
|
||||
ScalarDecodeVisitor(HLADecodeStream& stream, SGPropertyNode& propertyNode) :
|
||||
DecodeVisitor(HLADecodeStream& stream, HLAPropertyReference& propertyReference) :
|
||||
HLADataTypeDecodeVisitor(stream),
|
||||
_propertyNode(propertyNode)
|
||||
{ }
|
||||
virtual ~ScalarDecodeVisitor()
|
||||
_propertyReference(propertyReference)
|
||||
{ }
|
||||
|
||||
virtual void apply(const HLAInt8DataType& dataType)
|
||||
{
|
||||
int8_t value = 0;
|
||||
dataType.decode(_stream, value);
|
||||
_propertyNode.setIntValue(value);
|
||||
_propertyReference.setIntValue(value);
|
||||
}
|
||||
virtual void apply(const HLAUInt8DataType& dataType)
|
||||
{
|
||||
uint8_t value = 0;
|
||||
dataType.decode(_stream, value);
|
||||
_propertyNode.setIntValue(value);
|
||||
_propertyReference.setIntValue(value);
|
||||
}
|
||||
virtual void apply(const HLAInt16DataType& dataType)
|
||||
{
|
||||
int16_t value = 0;
|
||||
dataType.decode(_stream, value);
|
||||
_propertyNode.setIntValue(value);
|
||||
_propertyReference.setIntValue(value);
|
||||
}
|
||||
virtual void apply(const HLAUInt16DataType& dataType)
|
||||
{
|
||||
uint16_t value = 0;
|
||||
dataType.decode(_stream, value);
|
||||
_propertyNode.setIntValue(value);
|
||||
_propertyReference.setIntValue(value);
|
||||
}
|
||||
virtual void apply(const HLAInt32DataType& dataType)
|
||||
{
|
||||
int32_t value = 0;
|
||||
dataType.decode(_stream, value);
|
||||
_propertyNode.setIntValue(value);
|
||||
_propertyReference.setIntValue(value);
|
||||
}
|
||||
virtual void apply(const HLAUInt32DataType& dataType)
|
||||
{
|
||||
uint32_t value = 0;
|
||||
dataType.decode(_stream, value);
|
||||
_propertyNode.setIntValue(value);
|
||||
_propertyReference.setIntValue(value);
|
||||
}
|
||||
virtual void apply(const HLAInt64DataType& dataType)
|
||||
{
|
||||
int64_t value = 0;
|
||||
dataType.decode(_stream, value);
|
||||
_propertyNode.setLongValue(value);
|
||||
_propertyReference.setLongValue(value);
|
||||
}
|
||||
virtual void apply(const HLAUInt64DataType& dataType)
|
||||
{
|
||||
uint64_t value = 0;
|
||||
dataType.decode(_stream, value);
|
||||
_propertyNode.setLongValue(value);
|
||||
_propertyReference.setLongValue(value);
|
||||
}
|
||||
virtual void apply(const HLAFloat32DataType& dataType)
|
||||
{
|
||||
float value = 0;
|
||||
dataType.decode(_stream, value);
|
||||
_propertyNode.setFloatValue(value);
|
||||
_propertyReference.setFloatValue(value);
|
||||
}
|
||||
virtual void apply(const HLAFloat64DataType& dataType)
|
||||
{
|
||||
double value = 0;
|
||||
dataType.decode(_stream, value);
|
||||
_propertyNode.setDoubleValue(value);
|
||||
_propertyReference.setDoubleValue(value);
|
||||
}
|
||||
|
||||
protected:
|
||||
SGPropertyNode& _propertyNode;
|
||||
};
|
||||
|
||||
class HLAPropertyDataElement::ScalarEncodeVisitor : public HLADataTypeEncodeVisitor {
|
||||
public:
|
||||
ScalarEncodeVisitor(HLAEncodeStream& stream, const SGPropertyNode& propertyNode) :
|
||||
HLADataTypeEncodeVisitor(stream),
|
||||
_propertyNode(propertyNode)
|
||||
{ }
|
||||
virtual ~ScalarEncodeVisitor()
|
||||
{ }
|
||||
|
||||
virtual void apply(const HLAInt8DataType& dataType)
|
||||
{
|
||||
dataType.encode(_stream, _propertyNode.getIntValue());
|
||||
}
|
||||
virtual void apply(const HLAUInt8DataType& dataType)
|
||||
{
|
||||
dataType.encode(_stream, _propertyNode.getIntValue());
|
||||
}
|
||||
virtual void apply(const HLAInt16DataType& dataType)
|
||||
{
|
||||
dataType.encode(_stream, _propertyNode.getIntValue());
|
||||
}
|
||||
virtual void apply(const HLAUInt16DataType& dataType)
|
||||
{
|
||||
dataType.encode(_stream, _propertyNode.getIntValue());
|
||||
}
|
||||
virtual void apply(const HLAInt32DataType& dataType)
|
||||
{
|
||||
dataType.encode(_stream, _propertyNode.getIntValue());
|
||||
}
|
||||
virtual void apply(const HLAUInt32DataType& dataType)
|
||||
{
|
||||
dataType.encode(_stream, _propertyNode.getIntValue());
|
||||
}
|
||||
virtual void apply(const HLAInt64DataType& dataType)
|
||||
{
|
||||
dataType.encode(_stream, _propertyNode.getLongValue());
|
||||
}
|
||||
virtual void apply(const HLAUInt64DataType& dataType)
|
||||
{
|
||||
dataType.encode(_stream, _propertyNode.getLongValue());
|
||||
}
|
||||
virtual void apply(const HLAFloat32DataType& dataType)
|
||||
{
|
||||
dataType.encode(_stream, _propertyNode.getFloatValue());
|
||||
}
|
||||
virtual void apply(const HLAFloat64DataType& dataType)
|
||||
{
|
||||
dataType.encode(_stream, _propertyNode.getDoubleValue());
|
||||
}
|
||||
|
||||
protected:
|
||||
const SGPropertyNode& _propertyNode;
|
||||
};
|
||||
|
||||
class HLAPropertyDataElement::ScalarDataElement : public HLABasicDataElement {
|
||||
public:
|
||||
ScalarDataElement(const HLABasicDataType* dataType, SGPropertyNode* propertyNode);
|
||||
virtual ~ScalarDataElement();
|
||||
|
||||
virtual bool encode(HLAEncodeStream& stream) const;
|
||||
virtual bool decode(HLADecodeStream& stream);
|
||||
|
||||
private:
|
||||
SGSharedPtr<SGPropertyNode> _propertyNode;
|
||||
};
|
||||
|
||||
HLAPropertyDataElement::ScalarDataElement::ScalarDataElement(const HLABasicDataType* dataType, SGPropertyNode* propertyNode) :
|
||||
HLABasicDataElement(dataType),
|
||||
_propertyNode(propertyNode)
|
||||
{
|
||||
}
|
||||
|
||||
HLAPropertyDataElement::ScalarDataElement::~ScalarDataElement()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
HLAPropertyDataElement::ScalarDataElement::encode(HLAEncodeStream& stream) const
|
||||
{
|
||||
ScalarEncodeVisitor visitor(stream, *_propertyNode);
|
||||
_dataType->accept(visitor);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAPropertyDataElement::ScalarDataElement::decode(HLADecodeStream& stream)
|
||||
{
|
||||
ScalarDecodeVisitor visitor(stream, *_propertyNode);
|
||||
_dataType->accept(visitor);
|
||||
return true;
|
||||
}
|
||||
|
||||
class HLAPropertyDataElement::StringDataElement : public HLAStringDataElement {
|
||||
public:
|
||||
StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode);
|
||||
virtual ~StringDataElement();
|
||||
|
||||
virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
|
||||
|
||||
class Listener : public SGPropertyChangeListener {
|
||||
public:
|
||||
Listener(StringDataElement* stringDataElement);
|
||||
virtual ~Listener();
|
||||
virtual void valueChanged (SGPropertyNode * node);
|
||||
private:
|
||||
StringDataElement* _stringDataElement;
|
||||
};
|
||||
|
||||
private:
|
||||
SGSharedPtr<SGPropertyNode> _propertyNode;
|
||||
Listener* _listener;
|
||||
};
|
||||
|
||||
HLAPropertyDataElement::StringDataElement::Listener::Listener(StringDataElement* stringDataElement) :
|
||||
_stringDataElement(stringDataElement)
|
||||
{
|
||||
}
|
||||
|
||||
HLAPropertyDataElement::StringDataElement::Listener::~Listener()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HLAPropertyDataElement::StringDataElement::Listener::valueChanged (SGPropertyNode * node)
|
||||
{
|
||||
_stringDataElement->setValue(node->getStringValue());
|
||||
}
|
||||
|
||||
HLAPropertyDataElement::StringDataElement::StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode) :
|
||||
HLAStringDataElement(dataType),
|
||||
_propertyNode(propertyNode),
|
||||
_listener(new Listener(this))
|
||||
{
|
||||
_propertyNode->addChangeListener(_listener, true);
|
||||
}
|
||||
|
||||
HLAPropertyDataElement::StringDataElement::~StringDataElement()
|
||||
{
|
||||
_propertyNode->removeChangeListener(_listener);
|
||||
delete _listener;
|
||||
_listener = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAPropertyDataElement::StringDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
|
||||
{
|
||||
if (!HLAStringDataElement::decodeElement(stream, i))
|
||||
return false;
|
||||
if (i + 1 == getValue().size())
|
||||
_propertyNode->setStringValue(getValue());
|
||||
return true;
|
||||
}
|
||||
|
||||
class HLAPropertyDataElement::DataElementFactoryVisitor : public HLADataTypeVisitor {
|
||||
public:
|
||||
DataElementFactoryVisitor(SGPropertyNode* propertyNode) :
|
||||
_propertyNode(propertyNode)
|
||||
{ }
|
||||
virtual ~DataElementFactoryVisitor()
|
||||
{ }
|
||||
|
||||
virtual void apply(const HLADataType& dataType)
|
||||
{
|
||||
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 = new ScalarDataElement(&dataType, _propertyNode.get());
|
||||
}
|
||||
virtual void apply(const HLAUInt8DataType& dataType)
|
||||
{
|
||||
_dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
|
||||
}
|
||||
virtual void apply(const HLAInt16DataType& dataType)
|
||||
{
|
||||
_dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
|
||||
}
|
||||
virtual void apply(const HLAUInt16DataType& dataType)
|
||||
{
|
||||
_dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
|
||||
}
|
||||
virtual void apply(const HLAInt32DataType& dataType)
|
||||
{
|
||||
_dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
|
||||
}
|
||||
virtual void apply(const HLAUInt32DataType& dataType)
|
||||
{
|
||||
_dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
|
||||
}
|
||||
virtual void apply(const HLAInt64DataType& dataType)
|
||||
{
|
||||
_dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
|
||||
}
|
||||
virtual void apply(const HLAUInt64DataType& dataType)
|
||||
{
|
||||
_dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
|
||||
}
|
||||
virtual void apply(const HLAFloat32DataType& dataType)
|
||||
{
|
||||
_dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
|
||||
}
|
||||
virtual void apply(const HLAFloat64DataType& dataType)
|
||||
{
|
||||
_dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
|
||||
}
|
||||
|
||||
class ArrayDataElementFactory : public HLAArrayDataElement::DataElementFactory {
|
||||
public:
|
||||
ArrayDataElementFactory(SGPropertyNode* propertyNode) :
|
||||
_propertyNode(propertyNode)
|
||||
{ }
|
||||
virtual HLADataElement* createElement(const HLAArrayDataElement& element, unsigned index)
|
||||
{
|
||||
const HLADataType* dataType = element.getElementDataType();
|
||||
if (!dataType)
|
||||
return 0;
|
||||
|
||||
SGPropertyNode* parent = _propertyNode->getParent();
|
||||
DataElementFactoryVisitor visitor(parent->getChild(_propertyNode->getNameString(), index, true));
|
||||
dataType->accept(visitor);
|
||||
return visitor.getDataElement();
|
||||
}
|
||||
private:
|
||||
SGSharedPtr<SGPropertyNode> _propertyNode;
|
||||
};
|
||||
|
||||
virtual void apply(const HLAFixedArrayDataType& dataType)
|
||||
{
|
||||
if (dataType.getIsString()) {
|
||||
_dataElement = new StringDataElement(&dataType, _propertyNode.get());
|
||||
} else {
|
||||
SGSharedPtr<HLAArrayDataElement> arrayDataElement;
|
||||
arrayDataElement = new HLAArrayDataElement(&dataType);
|
||||
arrayDataElement->setDataElementFactory(new ArrayDataElementFactory(_propertyNode.get()));
|
||||
arrayDataElement->setNumElements(dataType.getNumElements());
|
||||
_dataElement = arrayDataElement;
|
||||
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)
|
||||
{
|
||||
if (dataType.getIsString()) {
|
||||
_dataElement = new StringDataElement(&dataType, _propertyNode.get());
|
||||
} else {
|
||||
SGSharedPtr<HLAArrayDataElement> arrayDataElement;
|
||||
arrayDataElement = new HLAArrayDataElement(&dataType);
|
||||
arrayDataElement->setDataElementFactory(new ArrayDataElementFactory(_propertyNode.get()));
|
||||
_dataElement = arrayDataElement;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void apply(const HLAEnumeratedDataType& dataType)
|
||||
{
|
||||
_dataElement = new ScalarDataElement(dataType.getRepresentation(), _propertyNode.get());
|
||||
}
|
||||
|
||||
virtual void apply(const HLAFixedRecordDataType& dataType)
|
||||
{
|
||||
SGSharedPtr<HLAFixedRecordDataElement> recordDataElement;
|
||||
recordDataElement = new HLAFixedRecordDataElement(&dataType);
|
||||
|
||||
unsigned numFields = dataType.getNumFields();
|
||||
for (unsigned i = 0; i < numFields; ++i) {
|
||||
DataElementFactoryVisitor visitor(_propertyNode->getChild(dataType.getFieldName(i), 0, true));
|
||||
dataType.getFieldDataType(i)->accept(visitor);
|
||||
recordDataElement->setField(i, visitor._dataElement.get());
|
||||
}
|
||||
|
||||
_dataElement = recordDataElement;
|
||||
}
|
||||
|
||||
class VariantDataElementFactory : public HLAVariantDataElement::DataElementFactory {
|
||||
public:
|
||||
VariantDataElementFactory(SGPropertyNode* propertyNode) :
|
||||
_propertyNode(propertyNode)
|
||||
{ }
|
||||
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;
|
||||
DataElementFactoryVisitor visitor(_propertyNode->getChild(dataType->getAlternativeName(index), 0, true));
|
||||
alternativeDataType->accept(visitor);
|
||||
return visitor.getDataElement();
|
||||
}
|
||||
private:
|
||||
SGSharedPtr<SGPropertyNode> _propertyNode;
|
||||
};
|
||||
|
||||
virtual void apply(const HLAVariantDataType& dataType)
|
||||
{
|
||||
SGSharedPtr<HLAVariantDataElement> variantDataElement;
|
||||
variantDataElement = new HLAVariantDataElement(&dataType);
|
||||
variantDataElement->setDataElementFactory(new VariantDataElementFactory(_propertyNode.get()));
|
||||
_dataElement = variantDataElement;
|
||||
}
|
||||
|
||||
HLADataElement* getDataElement()
|
||||
{ return _dataElement.release(); }
|
||||
|
||||
private:
|
||||
SGSharedPtr<SGPropertyNode> _propertyNode;
|
||||
SGSharedPtr<HLADataElement> _dataElement;
|
||||
protected:
|
||||
const HLAPropertyReference& _propertyReference;
|
||||
};
|
||||
|
||||
HLAPropertyDataElement::HLAPropertyDataElement()
|
||||
HLAPropertyDataElement::HLAPropertyDataElement(HLAPropertyReference* propertyReference) :
|
||||
_propertyReference(propertyReference)
|
||||
{
|
||||
}
|
||||
|
||||
HLAPropertyDataElement::HLAPropertyDataElement(SGPropertyNode* propertyNode)
|
||||
{
|
||||
setPropertyNode(propertyNode);
|
||||
}
|
||||
|
||||
HLAPropertyDataElement::HLAPropertyDataElement(const HLADataType* dataType, SGPropertyNode* propertyNode) :
|
||||
_dataType(dataType)
|
||||
{
|
||||
setPropertyNode(propertyNode);
|
||||
}
|
||||
|
||||
HLAPropertyDataElement::HLAPropertyDataElement(const HLADataType* dataType) :
|
||||
_dataType(dataType)
|
||||
HLAPropertyDataElement::HLAPropertyDataElement(const simgear::HLADataType* dataType, HLAPropertyReference* propertyReference) :
|
||||
_dataType(dataType),
|
||||
_propertyReference(propertyReference)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -434,72 +213,34 @@ HLAPropertyDataElement::~HLAPropertyDataElement()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HLAPropertyDataElement::accept(HLADataElementVisitor& visitor)
|
||||
{
|
||||
if (_dataElement.valid()) {
|
||||
visitor.apply(*_dataElement);
|
||||
} else {
|
||||
// We cant do anything if the data type is not valid
|
||||
if (_dataType.valid()) {
|
||||
HLADataElementFactoryVisitor factoryVisitor;
|
||||
_dataType->accept(factoryVisitor);
|
||||
_dataElement = factoryVisitor.getDataElement();
|
||||
if (_dataElement.valid()) {
|
||||
visitor.apply(*_dataElement);
|
||||
} else {
|
||||
HLADataElement::accept(visitor);
|
||||
}
|
||||
} else {
|
||||
HLADataElement::accept(visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HLAPropertyDataElement::accept(HLAConstDataElementVisitor& visitor) const
|
||||
{
|
||||
if (_dataElement.valid()) {
|
||||
visitor.apply(*_dataElement);
|
||||
} else {
|
||||
HLADataElement::accept(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
HLAPropertyDataElement::encode(HLAEncodeStream& stream) const
|
||||
{
|
||||
if (_dataElement.valid()) {
|
||||
return _dataElement->encode(stream);
|
||||
if (!_dataType.valid())
|
||||
return false;
|
||||
if (_propertyReference.valid()) {
|
||||
EncodeVisitor visitor(stream, *_propertyReference);
|
||||
_dataType->accept(visitor);
|
||||
} else {
|
||||
if (!_dataType.valid())
|
||||
return false;
|
||||
HLADataTypeEncodeVisitor visitor(stream);
|
||||
_dataType->accept(visitor);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAPropertyDataElement::decode(HLADecodeStream& stream)
|
||||
{
|
||||
if (_dataElement.valid()) {
|
||||
return _dataElement->decode(stream);
|
||||
} else if (!_dataType.valid()) {
|
||||
// We cant do anything if the data type is not valid
|
||||
if (!_dataType.valid())
|
||||
return false;
|
||||
} else {
|
||||
HLADataElementFactoryVisitor visitor;
|
||||
if (_propertyReference.valid()) {
|
||||
DecodeVisitor visitor(stream, *_propertyReference);
|
||||
_dataType->accept(visitor);
|
||||
} else {
|
||||
HLADataTypeDecodeVisitor visitor(stream);
|
||||
_dataType->accept(visitor);
|
||||
_dataElement = visitor.getDataElement();
|
||||
if (_dataElement.valid()) {
|
||||
return _dataElement->decode(stream);
|
||||
} else {
|
||||
HLADataTypeDecodeVisitor visitor(stream);
|
||||
_dataType->accept(visitor);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const HLADataType*
|
||||
@@ -511,52 +252,18 @@ HLAPropertyDataElement::getDataType() const
|
||||
bool
|
||||
HLAPropertyDataElement::setDataType(const HLADataType* dataType)
|
||||
{
|
||||
_dataType = dataType;
|
||||
if (_dataType.valid() && _propertyNode.valid())
|
||||
_dataElement = createDataElement(_dataType, _propertyNode);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
HLAPropertyDataElement::setPropertyNode(SGPropertyNode* propertyNode)
|
||||
{
|
||||
_propertyNode = propertyNode;
|
||||
if (_dataType.valid() && _propertyNode.valid())
|
||||
_dataElement = createDataElement(_dataType, _propertyNode);
|
||||
}
|
||||
|
||||
SGPropertyNode*
|
||||
HLAPropertyDataElement::getPropertyNode()
|
||||
{
|
||||
return _propertyNode.get();
|
||||
}
|
||||
|
||||
const SGPropertyNode*
|
||||
HLAPropertyDataElement::getPropertyNode() const
|
||||
{
|
||||
return _propertyNode.get();
|
||||
}
|
||||
|
||||
HLADataElement*
|
||||
HLAPropertyDataElement::createDataElement(const SGSharedPtr<const HLADataType>& dataType,
|
||||
const SGSharedPtr<SGPropertyNode>& propertyNode)
|
||||
{
|
||||
DataElementFactoryVisitor visitor(propertyNode);
|
||||
dataType->accept(visitor);
|
||||
SGSharedPtr<HLADataElement> dataElement = visitor.getDataElement();
|
||||
|
||||
// Copy over the content of the previous data element if there is any.
|
||||
if (_dataElement.valid()) {
|
||||
// FIXME is encode/decode the right tool here??
|
||||
RTIData data;
|
||||
HLAEncodeStream encodeStream(data);
|
||||
if (_dataElement->encode(encodeStream)) {
|
||||
HLADecodeStream decodeStream(data);
|
||||
dataElement->decode(decodeStream);
|
||||
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 dataElement.release();
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace simgear
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
// 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
|
||||
@@ -18,21 +18,140 @@
|
||||
#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();
|
||||
HLAPropertyDataElement(SGPropertyNode* propertyNode);
|
||||
HLAPropertyDataElement(const HLADataType* dataType, SGPropertyNode* propertyNode);
|
||||
HLAPropertyDataElement(const HLADataType* dataType);
|
||||
virtual ~HLAPropertyDataElement();
|
||||
|
||||
virtual void accept(HLADataElementVisitor& visitor);
|
||||
virtual void accept(HLAConstDataElementVisitor& visitor) const;
|
||||
HLAPropertyDataElement(HLAPropertyReference* propertyReference);
|
||||
HLAPropertyDataElement(const simgear::HLADataType* dataType, HLAPropertyReference* propertyReference);
|
||||
~HLAPropertyDataElement();
|
||||
|
||||
virtual bool encode(HLAEncodeStream& stream) const;
|
||||
virtual bool decode(HLADecodeStream& stream);
|
||||
@@ -40,25 +159,12 @@ public:
|
||||
virtual const HLADataType* getDataType() const;
|
||||
virtual bool setDataType(const HLADataType* dataType);
|
||||
|
||||
void setPropertyNode(SGPropertyNode* propertyNode);
|
||||
SGPropertyNode* getPropertyNode();
|
||||
const SGPropertyNode* getPropertyNode() const;
|
||||
|
||||
private:
|
||||
HLADataElement*
|
||||
createDataElement(const SGSharedPtr<const HLADataType>& dataType, const SGSharedPtr<SGPropertyNode>& propertyNode);
|
||||
|
||||
class ScalarDecodeVisitor;
|
||||
class ScalarEncodeVisitor;
|
||||
class ScalarDataElement;
|
||||
class StringDecodeVisitor;
|
||||
class StringEncodeVisitor;
|
||||
class StringDataElement;
|
||||
class DataElementFactoryVisitor;
|
||||
class DecodeVisitor;
|
||||
class EncodeVisitor;
|
||||
|
||||
SGSharedPtr<const HLADataType> _dataType;
|
||||
SGSharedPtr<HLADataElement> _dataElement;
|
||||
SGSharedPtr<SGPropertyNode> _propertyNode;
|
||||
SGSharedPtr<HLAPropertyReference> _propertyReference;
|
||||
};
|
||||
|
||||
} // namespace simgear
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include "HLADataElementVisitor.hxx"
|
||||
|
||||
namespace simgear {
|
||||
|
||||
HLAAbstractVariantDataElement::HLAAbstractVariantDataElement(const HLAVariantDataType* dataType) :
|
||||
@@ -32,18 +30,6 @@ HLAAbstractVariantDataElement::~HLAAbstractVariantDataElement()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HLAAbstractVariantDataElement::accept(HLADataElementVisitor& visitor)
|
||||
{
|
||||
visitor.apply(*this);
|
||||
}
|
||||
|
||||
void
|
||||
HLAAbstractVariantDataElement::accept(HLAConstDataElementVisitor& visitor) const
|
||||
{
|
||||
visitor.apply(*this);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAAbstractVariantDataElement::decode(HLADecodeStream& stream)
|
||||
{
|
||||
|
||||
@@ -30,9 +30,6 @@ public:
|
||||
HLAAbstractVariantDataElement(const HLAVariantDataType* dataType);
|
||||
virtual ~HLAAbstractVariantDataElement();
|
||||
|
||||
virtual void accept(HLADataElementVisitor& visitor);
|
||||
virtual void accept(HLAConstDataElementVisitor& visitor) const;
|
||||
|
||||
virtual bool decode(HLADecodeStream& stream);
|
||||
virtual bool encode(HLAEncodeStream& stream) const;
|
||||
|
||||
|
||||
69
simgear/hla/Makefile.am
Normal file
69
simgear/hla/Makefile.am
Normal file
@@ -0,0 +1,69 @@
|
||||
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
|
||||
@@ -15,8 +15,8 @@
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifndef RTI13Ambassador_hxx
|
||||
#define RTI13Ambassador_hxx
|
||||
#ifndef RTIAmbassador_hxx
|
||||
#define RTIAmbassador_hxx
|
||||
|
||||
#include <cstdlib>
|
||||
#include <list>
|
||||
@@ -45,20 +45,58 @@
|
||||
|
||||
namespace simgear {
|
||||
|
||||
class RTI13Federate;
|
||||
|
||||
class RTI13Ambassador : public SGReferenced {
|
||||
class RTI13Ambassador : public SGWeakReferenced {
|
||||
public:
|
||||
~RTI13Ambassador()
|
||||
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, RTI::FederateAmbassador* federateAmbassador)
|
||||
{ return _rtiAmbassador.joinFederationExecution(federate.c_str(), federation.c_str(), federateAmbassador); }
|
||||
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); }
|
||||
|
||||
@@ -76,8 +114,13 @@ public:
|
||||
void unsubscribeObjectClass(const RTI::ObjectClassHandle& handle)
|
||||
{ _rtiAmbassador.unsubscribeObjectClass(handle); }
|
||||
|
||||
RTI::ObjectHandle registerObjectInstance(const RTI::ObjectClassHandle& handle)
|
||||
{ return _rtiAmbassador.registerObjectInstance(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()); }
|
||||
@@ -90,11 +133,38 @@ public:
|
||||
// { _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()); }
|
||||
{
|
||||
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()); }
|
||||
{
|
||||
_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); }
|
||||
{
|
||||
_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); }
|
||||
@@ -281,62 +351,81 @@ public:
|
||||
|
||||
/// Time Management
|
||||
|
||||
void enableTimeRegulation(const SGTimeStamp& lookahead)
|
||||
{
|
||||
RTIfedTime federateTime;
|
||||
federateTime.setZero();
|
||||
_rtiAmbassador.enableTimeRegulation(federateTime, toFedTime(lookahead));
|
||||
}
|
||||
void enableTimeRegulation(const SGTimeStamp& federateTime, const SGTimeStamp& lookahead)
|
||||
{ _rtiAmbassador.enableTimeRegulation(toFedTime(federateTime), toFedTime(lookahead)); }
|
||||
void disableTimeRegulation()
|
||||
{ _rtiAmbassador.disableTimeRegulation();}
|
||||
{ _rtiAmbassador.disableTimeRegulation(); _timeRegulationEnabled = false; }
|
||||
|
||||
void enableTimeConstrained()
|
||||
{ _rtiAmbassador.enableTimeConstrained(); }
|
||||
void disableTimeConstrained()
|
||||
{ _rtiAmbassador.disableTimeConstrained(); }
|
||||
{ _rtiAmbassador.disableTimeConstrained(); _timeConstrainedEnabled = false; }
|
||||
|
||||
void timeAdvanceRequest(const SGTimeStamp& time)
|
||||
{ _rtiAmbassador.timeAdvanceRequest(toFedTime(time)); }
|
||||
{ _rtiAmbassador.timeAdvanceRequest(toFedTime(time)); _timeAdvancePending = true; }
|
||||
void timeAdvanceRequestAvailable(const SGTimeStamp& time)
|
||||
{ _rtiAmbassador.timeAdvanceRequestAvailable(toFedTime(time)); }
|
||||
void flushQueueRequest(const SGTimeStamp& time)
|
||||
{ _rtiAmbassador.flushQueueRequest(toFedTime(time)); }
|
||||
{ _rtiAmbassador.timeAdvanceRequestAvailable(toFedTime(time)); _timeAdvancePending = true; }
|
||||
|
||||
bool queryGALT(SGTimeStamp& timeStamp)
|
||||
{
|
||||
RTIfedTime fedTime;
|
||||
fedTime.setPositiveInfinity();
|
||||
_rtiAmbassador.queryLBTS(fedTime);
|
||||
if (fedTime.isPositiveInfinity())
|
||||
return false;
|
||||
timeStamp = toTimeStamp(fedTime);
|
||||
return true;
|
||||
}
|
||||
bool queryLITS(SGTimeStamp& timeStamp)
|
||||
{
|
||||
RTIfedTime fedTime;
|
||||
fedTime.setPositiveInfinity();
|
||||
_rtiAmbassador.queryMinNextEventTime(fedTime);
|
||||
if (fedTime.isPositiveInfinity())
|
||||
return false;
|
||||
timeStamp = toTimeStamp(fedTime);
|
||||
return true;
|
||||
}
|
||||
void queryFederateTime(SGTimeStamp& timeStamp)
|
||||
{
|
||||
RTIfedTime fedTime;
|
||||
_rtiAmbassador.queryFederateTime(fedTime);
|
||||
timeStamp = toTimeStamp(fedTime);
|
||||
}
|
||||
void modifyLookahead(const SGTimeStamp& timeStamp)
|
||||
{ _rtiAmbassador.modifyLookahead(toFedTime(timeStamp)); }
|
||||
void queryLookahead(SGTimeStamp& timeStamp)
|
||||
{
|
||||
RTIfedTime fedTime;
|
||||
_rtiAmbassador.queryLookahead(fedTime);
|
||||
timeStamp = toTimeStamp(fedTime);
|
||||
}
|
||||
// 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)
|
||||
@@ -397,6 +486,17 @@ public:
|
||||
// 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)
|
||||
@@ -452,6 +552,498 @@ public:
|
||||
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)
|
||||
{
|
||||
@@ -477,9 +1069,45 @@ public:
|
||||
return s;
|
||||
}
|
||||
|
||||
static std::string toStdString(const char* n)
|
||||
{
|
||||
if (!n)
|
||||
return std::string();
|
||||
return std::string(n);
|
||||
}
|
||||
|
||||
// The connection class
|
||||
RTI::RTIambassador _rtiAmbassador;
|
||||
SGWeakPtr<RTI13Federate> _federate;
|
||||
|
||||
// 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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
// 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
|
||||
@@ -34,53 +34,39 @@ class RTI13Ambassador;
|
||||
|
||||
class RTI13Federate : public RTIFederate {
|
||||
public:
|
||||
RTI13Federate(const std::list<std::string>& stringList);
|
||||
RTI13Federate();
|
||||
virtual ~RTI13Federate();
|
||||
|
||||
/// Create a federation execution
|
||||
/// Semantically this methods should be static,
|
||||
virtual FederationManagementResult createFederationExecution(const std::string& federation, const std::string& objectModel);
|
||||
virtual FederationManagementResult destroyFederationExecution(const std::string& federation);
|
||||
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 FederationManagementResult join(const std::string& federateType, const std::string& federation);
|
||||
virtual bool join(const std::string& federateType, const std::string& federation);
|
||||
virtual bool resign();
|
||||
virtual bool getJoined() const;
|
||||
|
||||
/// Synchronization Point handling
|
||||
virtual bool registerFederationSynchronizationPoint(const std::string& label, const RTIData& tag);
|
||||
virtual bool getFederationSynchronizationPointAnnounced(const std::string& label);
|
||||
virtual bool waitForFederationSynchronizationPointAnnounced(const std::string& label);
|
||||
virtual bool synchronizationPointAchieved(const std::string& label);
|
||||
virtual bool getFederationSynchronized(const std::string& label);
|
||||
virtual bool waitForFederationSynchronized(const std::string& label);
|
||||
|
||||
/// Time management
|
||||
virtual bool enableTimeConstrained();
|
||||
virtual bool disableTimeConstrained();
|
||||
virtual bool getTimeConstrainedEnabled();
|
||||
|
||||
virtual bool enableTimeRegulation(const SGTimeStamp& lookahead);
|
||||
virtual bool disableTimeRegulation();
|
||||
virtual bool modifyLookahead(const SGTimeStamp& timeStamp);
|
||||
virtual bool getTimeRegulationEnabled();
|
||||
|
||||
virtual bool timeAdvanceRequest(const SGTimeStamp& timeStamp);
|
||||
virtual bool timeAdvanceRequestAvailable(const SGTimeStamp& timeStamp);
|
||||
virtual bool flushQueueRequest(const SGTimeStamp& timeStamp);
|
||||
virtual bool getTimeAdvancePending();
|
||||
|
||||
virtual bool queryFederateTime(SGTimeStamp& timeStamp);
|
||||
virtual bool queryLookahead(SGTimeStamp& timeStamp);
|
||||
virtual bool queryGALT(SGTimeStamp& timeStamp);
|
||||
virtual bool queryLITS(SGTimeStamp& timeStamp);
|
||||
virtual bool timeAdvanceRequestBy(const SGTimeStamp& dt);
|
||||
virtual bool timeAdvanceRequest(const SGTimeStamp& fedTime);
|
||||
|
||||
/// Process messages
|
||||
virtual bool processMessage();
|
||||
virtual bool processMessages(const double& minimum, const double& maximum);
|
||||
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);
|
||||
void insertObjectInstance(RTI13ObjectInstance* objectInstance);
|
||||
|
||||
private:
|
||||
RTI13Federate(const RTI13Federate&);
|
||||
@@ -88,14 +74,13 @@ private:
|
||||
|
||||
/// The federate handle
|
||||
RTI::FederateHandle _federateHandle;
|
||||
bool _joined;
|
||||
|
||||
/// 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;
|
||||
|
||||
/// Callbacks from the rti are handled here.
|
||||
struct FederateAmbassador;
|
||||
FederateAmbassador* _federateAmbassador;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -37,11 +37,12 @@ RTI13ObjectClass::~RTI13ObjectClass()
|
||||
std::string
|
||||
RTI13ObjectClass::getName() const
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
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);
|
||||
return ambassador->getObjectClassName(_handle);
|
||||
}
|
||||
|
||||
unsigned
|
||||
@@ -53,13 +54,14 @@ RTI13ObjectClass::getNumAttributes() const
|
||||
unsigned
|
||||
RTI13ObjectClass::getAttributeIndex(const std::string& name) const
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
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);
|
||||
RTI::AttributeHandle attributeHandle = ambassador->getAttributeHandle(name, _handle);
|
||||
|
||||
AttributeHandleIndexMap::const_iterator i = _attributeHandleIndexMap.find(attributeHandle);
|
||||
if (i != _attributeHandleIndexMap.end())
|
||||
@@ -91,13 +93,14 @@ RTI13ObjectClass::getAttributeIndex(const std::string& name) const
|
||||
unsigned
|
||||
RTI13ObjectClass::getOrCreateAttributeIndex(const std::string& name)
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
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);
|
||||
RTI::AttributeHandle attributeHandle = ambassador->getAttributeHandle(name, _handle);
|
||||
|
||||
AttributeHandleIndexMap::const_iterator i = _attributeHandleIndexMap.find(attributeHandle);
|
||||
if (i != _attributeHandleIndexMap.end())
|
||||
@@ -166,7 +169,8 @@ RTI13ObjectClass::getOrCreateAttributeIndex(const std::string& name)
|
||||
bool
|
||||
RTI13ObjectClass::publish(const std::set<unsigned>& indexSet)
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
|
||||
if (!ambassador.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
|
||||
return false;
|
||||
}
|
||||
@@ -181,7 +185,7 @@ RTI13ObjectClass::publish(const std::set<unsigned>& indexSet)
|
||||
attributeHandleSet->add(_attributeHandleVector[*i]);
|
||||
}
|
||||
|
||||
_ambassador->publishObjectClass(_handle, *attributeHandleSet);
|
||||
ambassador->publishObjectClass(_handle, *attributeHandleSet);
|
||||
|
||||
for (unsigned i = 0; i < getNumAttributes(); ++i) {
|
||||
_attributeDataVector[i]._published = true;
|
||||
@@ -221,13 +225,14 @@ RTI13ObjectClass::publish(const std::set<unsigned>& indexSet)
|
||||
bool
|
||||
RTI13ObjectClass::unpublish()
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
|
||||
if (!ambassador.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
_ambassador->unpublishObjectClass(_handle);
|
||||
ambassador->unpublishObjectClass(_handle);
|
||||
|
||||
for (unsigned i = 0; i < getNumAttributes(); ++i) {
|
||||
_attributeDataVector[i]._published = false;
|
||||
@@ -267,7 +272,8 @@ RTI13ObjectClass::unpublish()
|
||||
bool
|
||||
RTI13ObjectClass::subscribe(const std::set<unsigned>& indexSet, bool active)
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
|
||||
if (!ambassador.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
|
||||
return false;
|
||||
}
|
||||
@@ -283,7 +289,7 @@ RTI13ObjectClass::subscribe(const std::set<unsigned>& indexSet, bool active)
|
||||
attributeHandleSet->add(_attributeHandleVector[*i]);
|
||||
}
|
||||
|
||||
_ambassador->subscribeObjectClassAttributes(_handle, *attributeHandleSet, active);
|
||||
ambassador->subscribeObjectClassAttributes(_handle, *attributeHandleSet, active);
|
||||
|
||||
for (unsigned i = 0; i < getNumAttributes(); ++i) {
|
||||
_attributeDataVector[i]._subscribed = true;
|
||||
@@ -320,13 +326,14 @@ RTI13ObjectClass::subscribe(const std::set<unsigned>& indexSet, bool active)
|
||||
bool
|
||||
RTI13ObjectClass::unsubscribe()
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
|
||||
if (!ambassador.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
_ambassador->unsubscribeObjectClass(_handle);
|
||||
ambassador->unsubscribeObjectClass(_handle);
|
||||
|
||||
for (unsigned i = 0; i < getNumAttributes(); ++i) {
|
||||
_attributeDataVector[i]._subscribed = false;
|
||||
@@ -363,22 +370,14 @@ RTI13ObjectClass::unsubscribe()
|
||||
RTIObjectInstance*
|
||||
RTI13ObjectClass::registerObjectInstance(HLAObjectInstance* hlaObjectInstance)
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
|
||||
if (!ambassador.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
SGSharedPtr<RTI13Federate> federate = _ambassador->_federate.lock();
|
||||
if (!federate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Error: Federate is zero.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
RTI::ObjectHandle objectHandle = _ambassador->registerObjectInstance(getHandle());
|
||||
RTI13ObjectInstance* objectInstance = new RTI13ObjectInstance(objectHandle, hlaObjectInstance, this, _ambassador.get(), true);
|
||||
federate->insertObjectInstance(objectInstance);
|
||||
return objectInstance;
|
||||
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;
|
||||
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
|
||||
private:
|
||||
RTI::ObjectClassHandle _handle;
|
||||
SGSharedPtr<RTI13Ambassador> _ambassador;
|
||||
SGWeakPtr<RTI13Ambassador> _ambassador;
|
||||
|
||||
typedef std::map<RTI::AttributeHandle, unsigned> AttributeHandleIndexMap;
|
||||
AttributeHandleIndexMap _attributeHandleIndexMap;
|
||||
|
||||
@@ -50,13 +50,14 @@ RTI13ObjectInstance::get13ObjectClass() const
|
||||
std::string
|
||||
RTI13ObjectInstance::getName() const
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
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);
|
||||
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();
|
||||
@@ -76,21 +77,28 @@ RTI13ObjectInstance::getName() const
|
||||
}
|
||||
|
||||
void
|
||||
RTI13ObjectInstance::deleteObjectInstance(const RTIData& tag)
|
||||
RTI13ObjectInstance::addToRequestQueue()
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
|
||||
if (!ambassador.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
|
||||
return;
|
||||
}
|
||||
|
||||
SGSharedPtr<RTI13Federate> federate = _ambassador->_federate.lock();
|
||||
if (!federate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Error: Federate is zero.");
|
||||
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);
|
||||
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) {
|
||||
@@ -111,19 +119,14 @@ RTI13ObjectInstance::deleteObjectInstance(const RTIData& tag)
|
||||
void
|
||||
RTI13ObjectInstance::deleteObjectInstance(const SGTimeStamp& timeStamp, const RTIData& tag)
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
|
||||
if (!ambassador.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
|
||||
return;
|
||||
}
|
||||
|
||||
SGSharedPtr<RTI13Federate> federate = _ambassador->_federate.lock();
|
||||
if (!federate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Error: Federate is zero.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
_ambassador->deleteObjectInstance(_handle, timeStamp, tag);
|
||||
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) {
|
||||
@@ -146,19 +149,14 @@ RTI13ObjectInstance::deleteObjectInstance(const SGTimeStamp& timeStamp, const RT
|
||||
void
|
||||
RTI13ObjectInstance::localDeleteObjectInstance()
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
|
||||
if (!ambassador.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
|
||||
return;
|
||||
}
|
||||
|
||||
SGSharedPtr<RTI13Federate> federate = _ambassador->_federate.lock();
|
||||
if (!federate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Error: Federate is zero.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
_ambassador->localDeleteObjectInstance(_handle);
|
||||
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) {
|
||||
@@ -177,62 +175,54 @@ RTI13ObjectInstance::localDeleteObjectInstance()
|
||||
}
|
||||
|
||||
void
|
||||
RTI13ObjectInstance::reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList, const RTIData& tag)
|
||||
RTI13ObjectInstance::reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const RTIData& tag)
|
||||
{
|
||||
// Retrieve an empty update struct from the memory pool
|
||||
RTIIndexDataPairList indexDataPairList;
|
||||
for (RTI13AttributeHandleDataPairList::iterator i = attributeHandleDataPairList.begin();
|
||||
i != attributeHandleDataPairList.end(); ++i) {
|
||||
unsigned index = getAttributeIndex(i->first);
|
||||
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(indexDataPairList);
|
||||
indexDataPairList.back().first = index;
|
||||
indexDataPairList.back().second.swap(i->second);
|
||||
}
|
||||
|
||||
RTIObjectInstance::reflectAttributeValues(indexDataPairList, tag);
|
||||
|
||||
RTIIndexDataPairList::iterator j = indexDataPairList.begin();
|
||||
for (RTI13AttributeHandleDataPairList::iterator i = attributeHandleDataPairList.begin();
|
||||
i != attributeHandleDataPairList.end(); ++i, ++j) {
|
||||
i->second.swap(j->second);
|
||||
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
|
||||
putDataToPool(indexDataPairList);
|
||||
putUpdateToPool(updateList);
|
||||
}
|
||||
|
||||
void
|
||||
RTI13ObjectInstance::reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList,
|
||||
const SGTimeStamp& timeStamp, const RTIData& tag)
|
||||
RTI13ObjectInstance::reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const SGTimeStamp& timeStamp, const RTIData& tag)
|
||||
{
|
||||
// Retrieve an empty update struct from the memory pool
|
||||
RTIIndexDataPairList indexDataPairList;
|
||||
for (RTI13AttributeHandleDataPairList::iterator i = attributeHandleDataPairList.begin();
|
||||
i != attributeHandleDataPairList.end(); ++i) {
|
||||
unsigned index = getAttributeIndex(i->first);
|
||||
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(indexDataPairList);
|
||||
indexDataPairList.back().first = index;
|
||||
indexDataPairList.back().second.swap(i->second);
|
||||
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(indexDataPairList, timeStamp, tag);
|
||||
|
||||
RTIIndexDataPairList::iterator j = indexDataPairList.begin();
|
||||
for (RTI13AttributeHandleDataPairList::iterator i = attributeHandleDataPairList.begin();
|
||||
i != attributeHandleDataPairList.end(); ++i, ++j) {
|
||||
i->second.swap(j->second);
|
||||
}
|
||||
|
||||
// Return the update data back to the pool
|
||||
putDataToPool(indexDataPairList);
|
||||
scheduleUpdates(timeStamp, updateList);
|
||||
}
|
||||
|
||||
void
|
||||
RTI13ObjectInstance::requestObjectAttributeValueUpdate()
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
|
||||
if (!ambassador.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
|
||||
return;
|
||||
}
|
||||
@@ -248,7 +238,7 @@ RTI13ObjectInstance::requestObjectAttributeValueUpdate()
|
||||
if (!attributeHandleSet->size())
|
||||
return;
|
||||
|
||||
_ambassador->requestObjectAttributeValueUpdate(_handle, *attributeHandleSet);
|
||||
ambassador->requestObjectAttributeValueUpdate(_handle, *attributeHandleSet);
|
||||
|
||||
for (unsigned i = 0; i < numAttributes; ++i)
|
||||
setRequestAttributeUpdate(i, false);
|
||||
@@ -282,12 +272,12 @@ RTI13ObjectInstance::requestObjectAttributeValueUpdate()
|
||||
}
|
||||
|
||||
void
|
||||
RTI13ObjectInstance::provideAttributeValueUpdate(const std::vector<RTI::AttributeHandle>& attributeHandleSet)
|
||||
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
|
||||
size_t numAttribs = attributeHandleSet.size();
|
||||
RTI::ULong numAttribs = attributes.size();
|
||||
for (RTI::ULong i = 0; i < numAttribs; ++i) {
|
||||
unsigned index = getAttributeIndex(attributeHandleSet[i]);
|
||||
unsigned index = getAttributeIndex(attributes.getHandle(i));
|
||||
setAttributeForceUpdate(index);
|
||||
}
|
||||
}
|
||||
@@ -295,7 +285,8 @@ RTI13ObjectInstance::provideAttributeValueUpdate(const std::vector<RTI::Attribut
|
||||
void
|
||||
RTI13ObjectInstance::updateAttributeValues(const RTIData& tag)
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
|
||||
if (!ambassador.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
|
||||
return;
|
||||
}
|
||||
@@ -321,28 +312,28 @@ RTI13ObjectInstance::updateAttributeValues(const RTIData& tag)
|
||||
if (!_attributeValuePairSet->size())
|
||||
return;
|
||||
|
||||
_ambassador->updateAttributeValues(_handle, *_attributeValuePairSet, tag);
|
||||
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 update attribute values object instance: " << e._name << " " << e._reason);
|
||||
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 update attribute values object instance: " << e._name << " " << e._reason);
|
||||
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 update attribute values object instance: " << e._name << " " << e._reason);
|
||||
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 update attribute values object instance: " << e._name << " " << e._reason);
|
||||
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 update attribute values object instance: " << e._name << " " << e._reason);
|
||||
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 update attribute values object instance: " << e._name << " " << e._reason);
|
||||
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 update attribute values object instance: " << e._name << " " << e._reason);
|
||||
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 update attribute values object instance: " << e._name << " " << e._reason);
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
|
||||
}
|
||||
|
||||
// That means clear()
|
||||
@@ -352,7 +343,8 @@ RTI13ObjectInstance::updateAttributeValues(const RTIData& tag)
|
||||
void
|
||||
RTI13ObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag)
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
|
||||
if (!ambassador.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
|
||||
return;
|
||||
}
|
||||
@@ -378,30 +370,30 @@ RTI13ObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const R
|
||||
if (!_attributeValuePairSet->size())
|
||||
return;
|
||||
|
||||
_ambassador->updateAttributeValues(_handle, *_attributeValuePairSet, timeStamp, tag);
|
||||
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 update attribute values object instance: " << e._name << " " << e._reason);
|
||||
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 update attribute values object instance: " << e._name << " " << e._reason);
|
||||
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 update attribute values object instance: " << e._name << " " << e._reason);
|
||||
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 update attribute values object instance: " << e._name << " " << e._reason);
|
||||
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 update attribute values object instance: " << e._name << " " << e._reason);
|
||||
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 update attribute values object instance: " << e._name << " " << e._reason);
|
||||
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 update attribute values object instance: " << e._name << " " << e._reason);
|
||||
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 update attribute values object instance: " << e._name << " " << e._reason);
|
||||
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 update attribute values object instance: " << e._name << " " << e._reason);
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
|
||||
}
|
||||
|
||||
// That means clear()
|
||||
@@ -409,72 +401,72 @@ RTI13ObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const R
|
||||
}
|
||||
|
||||
void
|
||||
RTI13ObjectInstance::attributesInScope(const std::vector<RTI::AttributeHandle>& attributeHandleSet)
|
||||
RTI13ObjectInstance::attributesInScope(const RTI::AttributeHandleSet& attributeHandleSet)
|
||||
{
|
||||
size_t numAttribs = attributeHandleSet.size();
|
||||
RTI::ULong numAttribs = attributeHandleSet.size();
|
||||
for (RTI::ULong i = 0; i < numAttribs; ++i) {
|
||||
RTI::AttributeHandle attributeHandle = attributeHandleSet[i];
|
||||
RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
|
||||
setAttributeInScope(getAttributeIndex(attributeHandle), true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RTI13ObjectInstance::attributesOutOfScope(const std::vector<RTI::AttributeHandle>& attributeHandleSet)
|
||||
RTI13ObjectInstance::attributesOutOfScope(const RTI::AttributeHandleSet& attributeHandleSet)
|
||||
{
|
||||
size_t numAttribs = attributeHandleSet.size();
|
||||
RTI::ULong numAttribs = attributeHandleSet.size();
|
||||
for (RTI::ULong i = 0; i < numAttribs; ++i) {
|
||||
RTI::AttributeHandle attributeHandle = attributeHandleSet[i];
|
||||
RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
|
||||
setAttributeInScope(getAttributeIndex(attributeHandle), false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RTI13ObjectInstance::turnUpdatesOnForObjectInstance(const std::vector<RTI::AttributeHandle>& attributeHandleSet)
|
||||
RTI13ObjectInstance::turnUpdatesOnForObjectInstance(const RTI::AttributeHandleSet& attributeHandleSet)
|
||||
{
|
||||
size_t numAttribs = attributeHandleSet.size();
|
||||
RTI::ULong numAttribs = attributeHandleSet.size();
|
||||
for (RTI::ULong i = 0; i < numAttribs; ++i) {
|
||||
RTI::AttributeHandle attributeHandle = attributeHandleSet[i];
|
||||
RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
|
||||
setAttributeUpdateEnabled(getAttributeIndex(attributeHandle), true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RTI13ObjectInstance::turnUpdatesOffForObjectInstance(const std::vector<RTI::AttributeHandle>& attributeHandleSet)
|
||||
RTI13ObjectInstance::turnUpdatesOffForObjectInstance(const RTI::AttributeHandleSet& attributeHandleSet)
|
||||
{
|
||||
size_t numAttribs = attributeHandleSet.size();
|
||||
RTI::ULong numAttribs = attributeHandleSet.size();
|
||||
for (RTI::ULong i = 0; i < numAttribs; ++i) {
|
||||
RTI::AttributeHandle attributeHandle = attributeHandleSet[i];
|
||||
RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
|
||||
setAttributeUpdateEnabled(getAttributeIndex(attributeHandle), false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RTI13ObjectInstance::requestAttributeOwnershipAssumption(const std::vector<RTI::AttributeHandle>& attributes, const RTIData& tag)
|
||||
RTI13ObjectInstance::requestAttributeOwnershipAssumption(const RTI::AttributeHandleSet& attributes, const RTIData& tag)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
RTI13ObjectInstance::attributeOwnershipDivestitureNotification(const std::vector<RTI::AttributeHandle>& attributes)
|
||||
RTI13ObjectInstance::attributeOwnershipDivestitureNotification(const RTI::AttributeHandleSet& attributes)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
RTI13ObjectInstance::attributeOwnershipAcquisitionNotification(const std::vector<RTI::AttributeHandle>& attributes)
|
||||
RTI13ObjectInstance::attributeOwnershipAcquisitionNotification(const RTI::AttributeHandleSet& attributes)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
RTI13ObjectInstance::attributeOwnershipUnavailable(const std::vector<RTI::AttributeHandle>& attributes)
|
||||
RTI13ObjectInstance::attributeOwnershipUnavailable(const RTI::AttributeHandleSet& attributes)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
RTI13ObjectInstance::requestAttributeOwnershipRelease(const std::vector<RTI::AttributeHandle>& attributes, const RTIData& tag)
|
||||
RTI13ObjectInstance::requestAttributeOwnershipRelease(const RTI::AttributeHandleSet& attributes, const RTIData& tag)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
RTI13ObjectInstance::confirmAttributeOwnershipAcquisitionCancellation(const std::vector<RTI::AttributeHandle>& attributes)
|
||||
RTI13ObjectInstance::confirmAttributeOwnershipAcquisitionCancellation(const RTI::AttributeHandleSet& attributes)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -37,9 +37,6 @@ namespace simgear {
|
||||
class RTI13Ambassador;
|
||||
class RTI13ObjectClass;
|
||||
|
||||
typedef std::pair<RTI::AttributeHandle, RTIData> RTI13AttributeHandleDataPair;
|
||||
typedef std::list<RTI13AttributeHandleDataPair> RTI13AttributeHandleDataPairList;
|
||||
|
||||
class RTI13ObjectInstance : public RTIObjectInstance {
|
||||
public:
|
||||
RTI13ObjectInstance(const RTI::ObjectHandle& handle, HLAObjectInstance* hlaObjectInstance, const RTI13ObjectClass* objectClass, RTI13Ambassador* ambassador, bool owned);
|
||||
@@ -64,31 +61,33 @@ public:
|
||||
|
||||
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(RTI13AttributeHandleDataPairList& attributeHandleDataPairList, const RTIData& tag);
|
||||
void reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList, const SGTimeStamp& timeStamp, const RTIData& tag);
|
||||
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 std::vector<RTI::AttributeHandle>& attributes);
|
||||
void provideAttributeValueUpdate(const RTI::AttributeHandleSet& attributes);
|
||||
|
||||
virtual void updateAttributeValues(const RTIData& tag);
|
||||
virtual void updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag);
|
||||
|
||||
void attributesInScope(const std::vector<RTI::AttributeHandle>& attributes);
|
||||
void attributesOutOfScope(const std::vector<RTI::AttributeHandle>& attributes);
|
||||
void attributesInScope(const RTI::AttributeHandleSet& attributes);
|
||||
void attributesOutOfScope(const RTI::AttributeHandleSet& attributes);
|
||||
|
||||
void turnUpdatesOnForObjectInstance(const std::vector<RTI::AttributeHandle>& attributes);
|
||||
void turnUpdatesOffForObjectInstance(const std::vector<RTI::AttributeHandle>& 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 std::vector<RTI::AttributeHandle>& attributes, const RTIData& tag);
|
||||
void attributeOwnershipDivestitureNotification(const std::vector<RTI::AttributeHandle>& attributes);
|
||||
void attributeOwnershipAcquisitionNotification(const std::vector<RTI::AttributeHandle>& attributes);
|
||||
void attributeOwnershipUnavailable(const std::vector<RTI::AttributeHandle>& attributes);
|
||||
void requestAttributeOwnershipRelease(const std::vector<RTI::AttributeHandle>& attributes, const RTIData& tag);
|
||||
void confirmAttributeOwnershipAcquisitionCancellation(const std::vector<RTI::AttributeHandle>& attributes);
|
||||
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);
|
||||
@@ -96,7 +95,7 @@ public:
|
||||
private:
|
||||
RTI::ObjectHandle _handle;
|
||||
SGSharedPtr<const RTI13ObjectClass> _objectClass;
|
||||
SGSharedPtr<RTI13Ambassador> _ambassador;
|
||||
SGWeakPtr<RTI13Ambassador> _ambassador;
|
||||
|
||||
// cached storage for updates
|
||||
std::auto_ptr<RTI::AttributeHandleValuePairSet> _attributeValuePairSet;
|
||||
|
||||
@@ -115,13 +115,6 @@ public:
|
||||
ensureCapacity(capacity);
|
||||
}
|
||||
|
||||
void swap(RTIData& data)
|
||||
{
|
||||
std::swap(_data, data._data);
|
||||
std::swap(_size, data._size);
|
||||
std::swap(_capacity, data._capacity);
|
||||
}
|
||||
|
||||
void setData(char* data, unsigned size)
|
||||
{
|
||||
if (_capacity)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
// 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
|
||||
@@ -32,60 +32,63 @@ 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,
|
||||
enum FederationManagementResult {
|
||||
FederationManagementSuccess,
|
||||
FederationManagementFail,
|
||||
FederationManagementFatal
|
||||
};
|
||||
|
||||
virtual FederationManagementResult createFederationExecution(const std::string& federation, const std::string& objectModel) = 0;
|
||||
virtual FederationManagementResult destroyFederationExecution(const std::string& federation) = 0;
|
||||
/// 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 FederationManagementResult join(const std::string& federateType, const std::string& federation) = 0;
|
||||
virtual bool join(const std::string& federateType, const std::string& federation) = 0;
|
||||
virtual bool resign() = 0;
|
||||
virtual bool getJoined() const = 0;
|
||||
|
||||
/// Synchronization Point handling
|
||||
virtual bool registerFederationSynchronizationPoint(const std::string& label, const RTIData& tag) = 0;
|
||||
virtual bool getFederationSynchronizationPointAnnounced(const std::string& label) = 0;
|
||||
virtual bool waitForFederationSynchronizationPointAnnounced(const std::string& label) = 0;
|
||||
virtual bool synchronizationPointAchieved(const std::string& label) = 0;
|
||||
virtual bool getFederationSynchronized(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 getTimeConstrainedEnabled() = 0;
|
||||
|
||||
virtual bool enableTimeRegulation(const SGTimeStamp& lookahead) = 0;
|
||||
virtual bool disableTimeRegulation() = 0;
|
||||
virtual bool modifyLookahead(const SGTimeStamp& timeStamp) = 0;
|
||||
virtual bool getTimeRegulationEnabled() = 0;
|
||||
|
||||
virtual bool timeAdvanceRequestBy(const SGTimeStamp& dt) = 0;
|
||||
virtual bool timeAdvanceRequest(const SGTimeStamp& fedTime) = 0;
|
||||
virtual bool timeAdvanceRequestAvailable(const SGTimeStamp& timeStamp) = 0;
|
||||
virtual bool flushQueueRequest(const SGTimeStamp& timeStamp) = 0;
|
||||
virtual bool getTimeAdvancePending() = 0;
|
||||
|
||||
virtual bool queryFederateTime(SGTimeStamp& timeStamp) = 0;
|
||||
virtual bool queryLookahead(SGTimeStamp& timeStamp) = 0;
|
||||
virtual bool queryGALT(SGTimeStamp& timeStamp) = 0;
|
||||
virtual bool queryLITS(SGTimeStamp& timeStamp) = 0;
|
||||
|
||||
/// Process messages
|
||||
virtual bool processMessage() = 0;
|
||||
virtual bool processMessages(const double& minimum, const double& maximum) = 0;
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ RTIObjectClass::discoverInstance(RTIObjectInstance* objectInstance, const RTIDat
|
||||
return;
|
||||
}
|
||||
hlaObjectClass->discoverInstance(objectInstance, tag);
|
||||
objectInstance->requestObjectAttributeValueUpdate();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -50,6 +50,9 @@ public:
|
||||
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;
|
||||
@@ -60,6 +63,20 @@ public:
|
||||
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)
|
||||
@@ -119,8 +136,6 @@ public:
|
||||
} else {
|
||||
_attributeData[i].setUpdateEnabled(false);
|
||||
_attributeData[i].setOwned(false);
|
||||
if (getAttributeSubscribed(i))
|
||||
_attributeData[i].setRequestUpdate(true);
|
||||
}
|
||||
}
|
||||
_attributeData.resize(numAttributes);
|
||||
@@ -128,13 +143,9 @@ public:
|
||||
if (getAttributePublished(i)) {
|
||||
_attributeData[i].setUpdateEnabled(true);
|
||||
_attributeData[i].setOwned(owned);
|
||||
if (!owned && getAttributeSubscribed(i))
|
||||
_attributeData[i].setRequestUpdate(true);
|
||||
} else {
|
||||
_attributeData[i].setUpdateEnabled(false);
|
||||
_attributeData[i].setOwned(false);
|
||||
if (getAttributeSubscribed(i))
|
||||
_attributeData[i].setRequestUpdate(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,6 +213,7 @@ public:
|
||||
if (request) {
|
||||
if (!_pendingAttributeUpdateRequest) {
|
||||
_pendingAttributeUpdateRequest = true;
|
||||
addToRequestQueue();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -227,25 +239,80 @@ protected:
|
||||
// Is true if we should emit a requestattr
|
||||
bool _pendingAttributeUpdateRequest;
|
||||
|
||||
// Pool of update list entries
|
||||
RTIIndexDataPairList _indexDataPairList;
|
||||
// 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(RTIIndexDataPairList& 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 (_indexDataPairList.empty()) {
|
||||
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(), _indexDataPairList, _indexDataPairList.begin());
|
||||
dataPairList.splice(dataPairList.end(),
|
||||
_attributeData[i]._indexDataPairList,
|
||||
_attributeData[i]._indexDataPairList.begin());
|
||||
}
|
||||
|
||||
void putDataToPool(RTIIndexDataPairList& dataPairList)
|
||||
{
|
||||
_indexDataPairList.splice(_indexDataPairList.begin(), 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 {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
include (SimGearComponent)
|
||||
|
||||
set(HEADERS
|
||||
set(HEADERS
|
||||
iochannel.hxx
|
||||
lowlevel.hxx
|
||||
raw_socket.hxx
|
||||
@@ -14,11 +14,9 @@ set(HEADERS
|
||||
sg_serial.hxx
|
||||
sg_socket.hxx
|
||||
sg_socket_udp.hxx
|
||||
HTTPClient.hxx
|
||||
HTTPRequest.hxx
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
set(SOURCES
|
||||
iochannel.cxx
|
||||
lowlevel.cxx
|
||||
raw_socket.cxx
|
||||
@@ -30,41 +28,6 @@ set(SOURCES
|
||||
sg_serial.cxx
|
||||
sg_socket.cxx
|
||||
sg_socket_udp.cxx
|
||||
HTTPClient.cxx
|
||||
HTTPRequest.cxx
|
||||
)
|
||||
|
||||
simgear_component(io io "${SOURCES}" "${HEADERS}")
|
||||
|
||||
if(ENABLE_TESTS)
|
||||
|
||||
if (SIMGEAR_SHARED)
|
||||
set(TEST_LIBS SimGearCore)
|
||||
else()
|
||||
set(TEST_LIBS
|
||||
sgio sgbucket sgstructure sgthreads sgtiming sgmisc sgdebug
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${WINSOCK_LIBRARY}
|
||||
${ZLIB_LIBRARY}
|
||||
${RT_LIBRARY})
|
||||
endif()
|
||||
|
||||
add_executable(test_sock socktest.cxx)
|
||||
target_link_libraries(test_sock ${TEST_LIBS})
|
||||
|
||||
add_executable(test_http test_HTTP.cxx)
|
||||
target_link_libraries(test_http ${TEST_LIBS})
|
||||
|
||||
add_test(http ${EXECUTABLE_OUTPUT_PATH}/test_http)
|
||||
|
||||
add_executable(httpget httpget.cxx)
|
||||
target_link_libraries(httpget ${TEST_LIBS})
|
||||
|
||||
add_executable(decode_binobj decode_binobj.cxx)
|
||||
target_link_libraries(decode_binobj ${TEST_LIBS})
|
||||
|
||||
add_executable(test_binobj test_binobj.cxx)
|
||||
target_link_libraries(test_binobj ${TEST_LIBS})
|
||||
|
||||
add_test(binobj ${EXECUTABLE_OUTPUT_PATH}/test_binobj)
|
||||
endif(ENABLE_TESTS)
|
||||
simgear_component(io io "${SOURCES}" "${HEADERS}")
|
||||
@@ -1,450 +0,0 @@
|
||||
#include "HTTPClient.hxx"
|
||||
|
||||
#include <sstream>
|
||||
#include <cassert>
|
||||
#include <list>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
||||
#include <simgear/io/sg_netChat.hxx>
|
||||
#include <simgear/misc/strutils.hxx>
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/timing/timestamp.hxx>
|
||||
|
||||
#if defined( HAVE_VERSION_H ) && HAVE_VERSION_H
|
||||
#include "version.h"
|
||||
#else
|
||||
# if !defined(SIMGEAR_VERSION)
|
||||
# define SIMGEAR_VERSION "simgear-development"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
using std::string;
|
||||
using std::stringstream;
|
||||
using std::vector;
|
||||
|
||||
//#include <iostream>
|
||||
//using namespace std;
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
|
||||
namespace HTTP
|
||||
{
|
||||
|
||||
extern const int DEFAULT_HTTP_PORT = 80;
|
||||
|
||||
class Connection : public NetChat
|
||||
{
|
||||
public:
|
||||
Connection(Client* pr) :
|
||||
client(pr),
|
||||
state(STATE_CLOSED),
|
||||
port(DEFAULT_HTTP_PORT)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void setServer(const string& h, short p)
|
||||
{
|
||||
host = h;
|
||||
port = p;
|
||||
}
|
||||
|
||||
// socket-level errors
|
||||
virtual void handleError(int error)
|
||||
{
|
||||
NetChat::handleError(error);
|
||||
if (activeRequest) {
|
||||
SG_LOG(SG_IO, SG_INFO, "HTTP socket error");
|
||||
activeRequest->setFailure(error, "socket error");
|
||||
activeRequest = NULL;
|
||||
}
|
||||
|
||||
state = STATE_SOCKET_ERROR;
|
||||
}
|
||||
|
||||
virtual void handleClose()
|
||||
{
|
||||
NetChat::handleClose();
|
||||
|
||||
if ((state == STATE_GETTING_BODY) && activeRequest) {
|
||||
// force state here, so responseComplete can avoid closing the
|
||||
// socket again
|
||||
state = STATE_CLOSED;
|
||||
responseComplete();
|
||||
} else {
|
||||
state = STATE_CLOSED;
|
||||
}
|
||||
}
|
||||
|
||||
void queueRequest(const Request_ptr& r)
|
||||
{
|
||||
if (!activeRequest) {
|
||||
startRequest(r);
|
||||
} else {
|
||||
queuedRequests.push_back(r);
|
||||
}
|
||||
}
|
||||
|
||||
void startRequest(const Request_ptr& r)
|
||||
{
|
||||
if (state == STATE_CLOSED) {
|
||||
if (!connectToHost()) {
|
||||
return;
|
||||
}
|
||||
|
||||
state = STATE_IDLE;
|
||||
}
|
||||
|
||||
activeRequest = r;
|
||||
state = STATE_SENT_REQUEST;
|
||||
bodyTransferSize = -1;
|
||||
chunkedTransfer = false;
|
||||
setTerminator("\r\n");
|
||||
|
||||
stringstream headerData;
|
||||
string path = r->path();
|
||||
if (!client->proxyHost().empty()) {
|
||||
path = r->url();
|
||||
}
|
||||
|
||||
headerData << r->method() << " " << path << " HTTP/1.1\r\n";
|
||||
headerData << "Host: " << r->hostAndPort() << "\r\n";
|
||||
headerData << "User-Agent:" << client->userAgent() << "\r\n";
|
||||
if (!client->proxyAuth().empty()) {
|
||||
headerData << "Proxy-Authorization: " << client->proxyAuth() << "\r\n";
|
||||
}
|
||||
|
||||
BOOST_FOREACH(string h, r->requestHeaders()) {
|
||||
headerData << h << ": " << r->header(h) << "\r\n";
|
||||
}
|
||||
|
||||
headerData << "\r\n"; // final CRLF to terminate the headers
|
||||
|
||||
// TODO - add request body support for PUT, etc operations
|
||||
|
||||
bool ok = push(headerData.str().c_str());
|
||||
if (!ok) {
|
||||
SG_LOG(SG_IO, SG_WARN, "HTTP writing to socket failed");
|
||||
state = STATE_SOCKET_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void collectIncomingData(const char* s, int n)
|
||||
{
|
||||
if ((state == STATE_GETTING_BODY) || (state == STATE_GETTING_CHUNKED_BYTES)) {
|
||||
activeRequest->processBodyBytes(s, n);
|
||||
} else {
|
||||
buffer += string(s, n);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void foundTerminator(void)
|
||||
{
|
||||
switch (state) {
|
||||
case STATE_SENT_REQUEST:
|
||||
activeRequest->responseStart(buffer);
|
||||
state = STATE_GETTING_HEADERS;
|
||||
buffer.clear();
|
||||
break;
|
||||
|
||||
case STATE_GETTING_HEADERS:
|
||||
processHeader();
|
||||
buffer.clear();
|
||||
break;
|
||||
|
||||
case STATE_GETTING_BODY:
|
||||
responseComplete();
|
||||
break;
|
||||
|
||||
case STATE_GETTING_CHUNKED:
|
||||
processChunkHeader();
|
||||
break;
|
||||
|
||||
case STATE_GETTING_CHUNKED_BYTES:
|
||||
setTerminator("\r\n");
|
||||
state = STATE_GETTING_CHUNKED;
|
||||
break;
|
||||
|
||||
|
||||
case STATE_GETTING_TRAILER:
|
||||
processTrailer();
|
||||
buffer.clear();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool hasIdleTimeout() const
|
||||
{
|
||||
if (state != STATE_IDLE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return idleTime.elapsedMSec() > 1000 * 10; // ten seconds
|
||||
}
|
||||
|
||||
bool hasError() const
|
||||
{
|
||||
return (state == STATE_SOCKET_ERROR);
|
||||
}
|
||||
|
||||
bool shouldStartNext() const
|
||||
{
|
||||
return !activeRequest && !queuedRequests.empty() &&
|
||||
((state == STATE_CLOSED) || (state == STATE_IDLE));
|
||||
}
|
||||
|
||||
void startNext()
|
||||
{
|
||||
Request_ptr next = queuedRequests.front();
|
||||
queuedRequests.pop_front();
|
||||
startRequest(next);
|
||||
}
|
||||
private:
|
||||
bool connectToHost()
|
||||
{
|
||||
SG_LOG(SG_IO, SG_INFO, "HTTP connecting to " << host << ":" << port);
|
||||
|
||||
if (!open()) {
|
||||
SG_LOG(SG_ALL, SG_WARN, "HTTP::Connection: connectToHost: open() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (connect(host.c_str(), port) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void processHeader()
|
||||
{
|
||||
string h = strutils::simplify(buffer);
|
||||
if (h.empty()) { // blank line terminates headers
|
||||
headersComplete();
|
||||
|
||||
if (chunkedTransfer) {
|
||||
state = STATE_GETTING_CHUNKED;
|
||||
} else {
|
||||
setByteCount(bodyTransferSize); // may be -1, that's fine
|
||||
state = STATE_GETTING_BODY;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int colonPos = buffer.find(':');
|
||||
if (colonPos < 0) {
|
||||
SG_LOG(SG_IO, SG_WARN, "malformed HTTP response header:" << h);
|
||||
return;
|
||||
}
|
||||
|
||||
string key = strutils::simplify(buffer.substr(0, colonPos));
|
||||
string lkey = boost::to_lower_copy(key);
|
||||
string value = strutils::strip(buffer.substr(colonPos + 1));
|
||||
|
||||
// only consider these if getting headers (as opposed to trailers
|
||||
// of a chunked transfer)
|
||||
if (state == STATE_GETTING_HEADERS) {
|
||||
if (lkey == "content-length") {
|
||||
int sz = strutils::to_int(value);
|
||||
if (bodyTransferSize <= 0) {
|
||||
bodyTransferSize = sz;
|
||||
}
|
||||
activeRequest->setResponseLength(sz);
|
||||
} else if (lkey == "transfer-length") {
|
||||
bodyTransferSize = strutils::to_int(value);
|
||||
} else if (lkey == "transfer-encoding") {
|
||||
processTransferEncoding(value);
|
||||
}
|
||||
}
|
||||
|
||||
activeRequest->responseHeader(lkey, value);
|
||||
}
|
||||
|
||||
void processTransferEncoding(const string& te)
|
||||
{
|
||||
if (te == "chunked") {
|
||||
chunkedTransfer = true;
|
||||
} else {
|
||||
SG_LOG(SG_IO, SG_WARN, "unsupported transfer encoding:" << te);
|
||||
// failure
|
||||
}
|
||||
}
|
||||
|
||||
void processChunkHeader()
|
||||
{
|
||||
if (buffer.empty()) {
|
||||
// blank line after chunk data
|
||||
return;
|
||||
}
|
||||
|
||||
int chunkSize = 0;
|
||||
int semiPos = buffer.find(';');
|
||||
if (semiPos >= 0) {
|
||||
// extensions ignored for the moment
|
||||
chunkSize = strutils::to_int(buffer.substr(0, semiPos), 16);
|
||||
} else {
|
||||
chunkSize = strutils::to_int(buffer, 16);
|
||||
}
|
||||
|
||||
buffer.clear();
|
||||
if (chunkSize == 0) { // trailer start
|
||||
state = STATE_GETTING_TRAILER;
|
||||
return;
|
||||
}
|
||||
|
||||
state = STATE_GETTING_CHUNKED_BYTES;
|
||||
setByteCount(chunkSize);
|
||||
}
|
||||
|
||||
void processTrailer()
|
||||
{
|
||||
if (buffer.empty()) {
|
||||
// end of trailers
|
||||
responseComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
// process as a normal header
|
||||
processHeader();
|
||||
}
|
||||
|
||||
void headersComplete()
|
||||
{
|
||||
activeRequest->responseHeadersComplete();
|
||||
}
|
||||
|
||||
void responseComplete()
|
||||
{
|
||||
activeRequest->responseComplete();
|
||||
client->requestFinished(this);
|
||||
//cout << "response complete: " << activeRequest->url() << endl;
|
||||
|
||||
bool doClose = activeRequest->closeAfterComplete();
|
||||
activeRequest = NULL;
|
||||
if (state == STATE_GETTING_BODY) {
|
||||
state = STATE_IDLE;
|
||||
if (doClose) {
|
||||
// this will bring us into handleClose() above, which updates
|
||||
// state to STATE_CLOSED
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
setTerminator("\r\n");
|
||||
|
||||
// if we have more requests, and we're idle, can start the next
|
||||
// request immediately. Note we cannot do this if we're in STATE_CLOSED,
|
||||
// since NetChannel::close cleans up state after calling handleClose;
|
||||
// instead we pick up waiting requests in update()
|
||||
if (!queuedRequests.empty() && (state == STATE_IDLE)) {
|
||||
startNext();
|
||||
} else {
|
||||
idleTime.stamp();
|
||||
}
|
||||
}
|
||||
|
||||
enum ConnectionState {
|
||||
STATE_IDLE = 0,
|
||||
STATE_SENT_REQUEST,
|
||||
STATE_GETTING_HEADERS,
|
||||
STATE_GETTING_BODY,
|
||||
STATE_GETTING_CHUNKED,
|
||||
STATE_GETTING_CHUNKED_BYTES,
|
||||
STATE_GETTING_TRAILER,
|
||||
STATE_SOCKET_ERROR,
|
||||
STATE_CLOSED ///< connection should be closed now
|
||||
};
|
||||
|
||||
Client* client;
|
||||
Request_ptr activeRequest;
|
||||
ConnectionState state;
|
||||
string host;
|
||||
short port;
|
||||
std::string buffer;
|
||||
int bodyTransferSize;
|
||||
SGTimeStamp idleTime;
|
||||
bool chunkedTransfer;
|
||||
|
||||
std::list<Request_ptr> queuedRequests;
|
||||
};
|
||||
|
||||
Client::Client()
|
||||
{
|
||||
setUserAgent("SimGear-" SG_STRINGIZE(SIMGEAR_VERSION));
|
||||
}
|
||||
|
||||
void Client::update()
|
||||
{
|
||||
NetChannel::poll();
|
||||
|
||||
ConnectionDict::iterator it = _connections.begin();
|
||||
for (; it != _connections.end(); ) {
|
||||
if (it->second->hasIdleTimeout() || it->second->hasError()) {
|
||||
// connection has been idle for a while, clean it up
|
||||
// (or has an error condition, again clean it up)
|
||||
SG_LOG(SG_IO, SG_INFO, "cleaning up " << it->second);
|
||||
ConnectionDict::iterator del = it++;
|
||||
delete del->second;
|
||||
_connections.erase(del);
|
||||
} else {
|
||||
if (it->second->shouldStartNext()) {
|
||||
it->second->startNext();
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
} // of connecion iteration
|
||||
}
|
||||
|
||||
void Client::makeRequest(const Request_ptr& r)
|
||||
{
|
||||
string host = r->host();
|
||||
int port = r->port();
|
||||
if (!_proxy.empty()) {
|
||||
host = _proxy;
|
||||
port = _proxyPort;
|
||||
}
|
||||
|
||||
stringstream ss;
|
||||
ss << host << "-" << port;
|
||||
string connectionId = ss.str();
|
||||
|
||||
if (_connections.find(connectionId) == _connections.end()) {
|
||||
Connection* con = new Connection(this);
|
||||
con->setServer(host, port);
|
||||
_connections[connectionId] = con;
|
||||
}
|
||||
|
||||
_connections[connectionId]->queueRequest(r);
|
||||
}
|
||||
|
||||
void Client::requestFinished(Connection* con)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Client::setUserAgent(const string& ua)
|
||||
{
|
||||
_userAgent = ua;
|
||||
}
|
||||
|
||||
void Client::setProxy(const string& proxy, int port, const string& auth)
|
||||
{
|
||||
_proxy = proxy;
|
||||
_proxyPort = port;
|
||||
_proxyAuth = auth;
|
||||
}
|
||||
|
||||
} // of namespace HTTP
|
||||
|
||||
} // of namespace simgear
|
||||
@@ -1,56 +0,0 @@
|
||||
#ifndef SG_HTTP_CLIENT_HXX
|
||||
#define SG_HTTP_CLIENT_HXX
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <simgear/io/HTTPRequest.hxx>
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
|
||||
namespace HTTP
|
||||
{
|
||||
|
||||
class Connection;
|
||||
|
||||
class Client
|
||||
{
|
||||
public:
|
||||
Client();
|
||||
|
||||
void update();
|
||||
|
||||
void makeRequest(const Request_ptr& r);
|
||||
|
||||
void setUserAgent(const std::string& ua);
|
||||
void setProxy(const std::string& proxy, int port, const std::string& auth = "");
|
||||
|
||||
const std::string& userAgent() const
|
||||
{ return _userAgent; }
|
||||
|
||||
const std::string& proxyHost() const
|
||||
{ return _proxy; }
|
||||
|
||||
const std::string& proxyAuth() const
|
||||
{ return _proxyAuth; }
|
||||
private:
|
||||
void requestFinished(Connection* con);
|
||||
|
||||
friend class Connection;
|
||||
friend class Request;
|
||||
|
||||
std::string _userAgent;
|
||||
std::string _proxy;
|
||||
int _proxyPort;
|
||||
std::string _proxyAuth;
|
||||
|
||||
// connections by host
|
||||
typedef std::map<std::string, Connection*> ConnectionDict;
|
||||
ConnectionDict _connections;
|
||||
};
|
||||
|
||||
} // of namespace HTTP
|
||||
|
||||
} // of namespace simgear
|
||||
|
||||
#endif // of SG_HTTP_CLIENT_HXX
|
||||
@@ -1,210 +0,0 @@
|
||||
#include "HTTPRequest.hxx"
|
||||
|
||||
#include <simgear/misc/strutils.hxx>
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
using std::string;
|
||||
using std::map;
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
|
||||
namespace HTTP
|
||||
{
|
||||
|
||||
extern const int DEFAULT_HTTP_PORT;
|
||||
|
||||
Request::Request(const string& url, const string method) :
|
||||
_method(method),
|
||||
_url(url),
|
||||
_responseVersion(HTTP_VERSION_UNKNOWN),
|
||||
_responseStatus(0),
|
||||
_responseLength(0),
|
||||
_receivedBodyBytes(0),
|
||||
_willClose(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Request::~Request()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Request::setUrl(const string& url)
|
||||
{
|
||||
_url = url;
|
||||
}
|
||||
|
||||
string_list Request::requestHeaders() const
|
||||
{
|
||||
string_list r;
|
||||
return r;
|
||||
}
|
||||
|
||||
string Request::header(const std::string& name) const
|
||||
{
|
||||
return string();
|
||||
}
|
||||
|
||||
void Request::responseStart(const string& r)
|
||||
{
|
||||
const int maxSplit = 2; // HTTP/1.1 nnn reason-string
|
||||
string_list parts = strutils::split(r, NULL, maxSplit);
|
||||
if (parts.size() != 3) {
|
||||
SG_LOG(SG_IO, SG_WARN, "HTTP::Request: malformed response start:" << r);
|
||||
setFailure(400, "malformed HTTP response header");
|
||||
return;
|
||||
}
|
||||
|
||||
_responseVersion = decodeVersion(parts[0]);
|
||||
_responseStatus = strutils::to_int(parts[1]);
|
||||
_responseReason = parts[2];
|
||||
}
|
||||
|
||||
void Request::responseHeader(const string& key, const string& value)
|
||||
{
|
||||
if (key == "connection") {
|
||||
_willClose = (value.find("close") != string::npos);
|
||||
}
|
||||
|
||||
_responseHeaders[key] = value;
|
||||
}
|
||||
|
||||
void Request::responseHeadersComplete()
|
||||
{
|
||||
// no op
|
||||
}
|
||||
|
||||
void Request::processBodyBytes(const char* s, int n)
|
||||
{
|
||||
_receivedBodyBytes += n;
|
||||
gotBodyData(s, n);
|
||||
}
|
||||
|
||||
void Request::gotBodyData(const char* s, int n)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Request::responseComplete()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
string Request::scheme() const
|
||||
{
|
||||
int firstColon = url().find(":");
|
||||
if (firstColon > 0) {
|
||||
return url().substr(0, firstColon);
|
||||
}
|
||||
|
||||
return ""; // couldn't parse scheme
|
||||
}
|
||||
|
||||
string Request::path() const
|
||||
{
|
||||
string u(url());
|
||||
int schemeEnd = u.find("://");
|
||||
if (schemeEnd < 0) {
|
||||
return ""; // couldn't parse scheme
|
||||
}
|
||||
|
||||
int hostEnd = u.find('/', schemeEnd + 3);
|
||||
if (hostEnd < 0) {
|
||||
return ""; // couldn't parse host
|
||||
}
|
||||
|
||||
int query = u.find('?', hostEnd + 1);
|
||||
if (query < 0) {
|
||||
// all remainder of URL is path
|
||||
return u.substr(hostEnd);
|
||||
}
|
||||
|
||||
return u.substr(hostEnd, query - hostEnd);
|
||||
}
|
||||
|
||||
string Request::host() const
|
||||
{
|
||||
string hp(hostAndPort());
|
||||
int colonPos = hp.find(':');
|
||||
if (colonPos >= 0) {
|
||||
return hp.substr(0, colonPos); // trim off the colon and port
|
||||
} else {
|
||||
return hp; // no port specifier
|
||||
}
|
||||
}
|
||||
|
||||
unsigned short Request::port() const
|
||||
{
|
||||
string hp(hostAndPort());
|
||||
int colonPos = hp.find(':');
|
||||
if (colonPos >= 0) {
|
||||
return (unsigned short) strutils::to_int(hp.substr(colonPos + 1));
|
||||
} else {
|
||||
return DEFAULT_HTTP_PORT;
|
||||
}
|
||||
}
|
||||
|
||||
string Request::hostAndPort() const
|
||||
{
|
||||
string u(url());
|
||||
int schemeEnd = u.find("://");
|
||||
if (schemeEnd < 0) {
|
||||
return ""; // couldn't parse scheme
|
||||
}
|
||||
|
||||
int hostEnd = u.find('/', schemeEnd + 3);
|
||||
if (hostEnd < 0) { // all remainder of URL is host
|
||||
return u.substr(schemeEnd + 3);
|
||||
}
|
||||
|
||||
return u.substr(schemeEnd + 3, hostEnd - (schemeEnd + 3));
|
||||
}
|
||||
|
||||
void Request::setResponseLength(unsigned int l)
|
||||
{
|
||||
_responseLength = l;
|
||||
}
|
||||
|
||||
unsigned int Request::responseLength() const
|
||||
{
|
||||
// if the server didn't supply a content length, use the number
|
||||
// of bytes we actually received (so far)
|
||||
if ((_responseLength == 0) && (_receivedBodyBytes > 0)) {
|
||||
return _receivedBodyBytes;
|
||||
}
|
||||
|
||||
return _responseLength;
|
||||
}
|
||||
|
||||
void Request::setFailure(int code, const std::string& reason)
|
||||
{
|
||||
_responseStatus = code;
|
||||
_responseReason = reason;
|
||||
failed();
|
||||
}
|
||||
|
||||
void Request::failed()
|
||||
{
|
||||
// no-op in base class
|
||||
}
|
||||
|
||||
Request::HTTPVersion Request::decodeVersion(const string& v)
|
||||
{
|
||||
if (v == "HTTP/1.1") return HTTP_1_1;
|
||||
if (v == "HTTP/1.0") return HTTP_1_0;
|
||||
if (strutils::starts_with(v, "HTTP/0.")) return HTTP_0_x;
|
||||
return HTTP_VERSION_UNKNOWN;
|
||||
}
|
||||
|
||||
bool Request::closeAfterComplete() const
|
||||
{
|
||||
// for non HTTP/1.1 connections, assume server closes
|
||||
return _willClose || (_responseVersion != HTTP_1_1);
|
||||
}
|
||||
|
||||
} // of namespace HTTP
|
||||
|
||||
} // of namespace simgear
|
||||
@@ -1,103 +0,0 @@
|
||||
#ifndef SG_HTTP_REQUEST_HXX
|
||||
#define SG_HTTP_REQUEST_HXX
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <simgear/structure/SGReferenced.hxx>
|
||||
#include <simgear/structure/SGSharedPtr.hxx>
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
|
||||
namespace HTTP
|
||||
{
|
||||
|
||||
class Request : public SGReferenced
|
||||
{
|
||||
public:
|
||||
virtual ~Request();
|
||||
|
||||
virtual void setUrl(const std::string& url);
|
||||
|
||||
virtual std::string method() const
|
||||
{ return _method; }
|
||||
virtual std::string url() const
|
||||
{ return _url; }
|
||||
|
||||
virtual std::string scheme() const;
|
||||
virtual std::string path() const;
|
||||
virtual std::string host() const;
|
||||
virtual std::string hostAndPort() const;
|
||||
virtual unsigned short port() const;
|
||||
|
||||
virtual string_list requestHeaders() const;
|
||||
virtual std::string header(const std::string& name) const;
|
||||
|
||||
virtual int responseCode() const
|
||||
{ return _responseStatus; }
|
||||
|
||||
virtual std::string responseReason() const
|
||||
{ return _responseReason; }
|
||||
|
||||
void setResponseLength(unsigned int l);
|
||||
virtual unsigned int responseLength() const;
|
||||
|
||||
/**
|
||||
* running total of body bytes received so far. Can be used
|
||||
* to generate a completion percentage, if the response length is
|
||||
* known.
|
||||
*/
|
||||
unsigned int responseBytesReceived() const
|
||||
{ return _receivedBodyBytes; }
|
||||
|
||||
enum HTTPVersion {
|
||||
HTTP_VERSION_UNKNOWN = 0,
|
||||
HTTP_0_x, // 0.9 or similar
|
||||
HTTP_1_0,
|
||||
HTTP_1_1
|
||||
};
|
||||
|
||||
HTTPVersion responseVersion() const
|
||||
{ return _responseVersion; }
|
||||
|
||||
static HTTPVersion decodeVersion(const std::string& v);
|
||||
|
||||
bool closeAfterComplete() const;
|
||||
protected:
|
||||
Request(const std::string& url, const std::string method = "GET");
|
||||
|
||||
virtual void responseStart(const std::string& r);
|
||||
virtual void responseHeader(const std::string& key, const std::string& value);
|
||||
virtual void responseHeadersComplete();
|
||||
virtual void responseComplete();
|
||||
virtual void failed();
|
||||
virtual void gotBodyData(const char* s, int n);
|
||||
private:
|
||||
friend class Client;
|
||||
friend class Connection;
|
||||
|
||||
void processBodyBytes(const char* s, int n);
|
||||
void setFailure(int code, const std::string& reason);
|
||||
|
||||
std::string _method;
|
||||
std::string _url;
|
||||
HTTPVersion _responseVersion;
|
||||
int _responseStatus;
|
||||
std::string _responseReason;
|
||||
unsigned int _responseLength;
|
||||
unsigned int _receivedBodyBytes;
|
||||
bool _willClose;
|
||||
|
||||
typedef std::map<std::string, std::string> HeaderDict;
|
||||
HeaderDict _responseHeaders;
|
||||
};
|
||||
|
||||
typedef SGSharedPtr<Request> Request_ptr;
|
||||
|
||||
} // of namespace HTTP
|
||||
|
||||
} // of namespace simgear
|
||||
|
||||
#endif // of SG_HTTP_REQUEST_HXX
|
||||
|
||||
88
simgear/io/Makefile.am
Normal file
88
simgear/io/Makefile.am
Normal file
@@ -0,0 +1,88 @@
|
||||
includedir = @includedir@/io
|
||||
|
||||
lib_LIBRARIES = libsgio.a
|
||||
|
||||
include_HEADERS = \
|
||||
iochannel.hxx \
|
||||
lowlevel.hxx \
|
||||
sg_binobj.hxx \
|
||||
sg_file.hxx \
|
||||
sg_serial.hxx \
|
||||
sg_socket.hxx \
|
||||
sg_socket_udp.hxx \
|
||||
raw_socket.hxx \
|
||||
sg_netBuffer.hxx \
|
||||
sg_netChannel.hxx \
|
||||
sg_netChat.hxx
|
||||
|
||||
libsgio_a_SOURCES = \
|
||||
iochannel.cxx \
|
||||
lowlevel.cxx \
|
||||
sg_binobj.cxx \
|
||||
sg_file.cxx \
|
||||
sg_serial.cxx \
|
||||
sg_socket.cxx \
|
||||
sg_socket_udp.cxx \
|
||||
raw_socket.cxx \
|
||||
sg_netBuffer.cxx \
|
||||
sg_netChannel.cxx \
|
||||
sg_netChat.cxx
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
|
||||
noinst_PROGRAMS = decode_binobj socktest lowtest tcp_server tcp_client
|
||||
|
||||
tcp_server_SOURCES = tcp_server.cxx
|
||||
|
||||
tcp_server_LDADD = \
|
||||
libsgio.a \
|
||||
$(top_builddir)/simgear/structure/libsgstructure.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/bucket/libsgbucket.a \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
-lz \
|
||||
$(network_LIBS) \
|
||||
$(base_LIBS)
|
||||
|
||||
tcp_client_SOURCES = tcp_client.cxx
|
||||
|
||||
tcp_client_LDADD = \
|
||||
libsgio.a \
|
||||
$(top_builddir)/simgear/structure/libsgstructure.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/bucket/libsgbucket.a \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
-lz \
|
||||
$(network_LIBS) \
|
||||
$(base_LIBS)
|
||||
|
||||
socktest_SOURCES = socktest.cxx
|
||||
|
||||
socktest_LDADD = \
|
||||
libsgio.a \
|
||||
$(top_builddir)/simgear/structure/libsgstructure.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/bucket/libsgbucket.a \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
-lz \
|
||||
$(network_LIBS) \
|
||||
$(base_LIBS)
|
||||
|
||||
lowtest_SOURCES = lowtest.cxx
|
||||
|
||||
lowtest_LDADD = \
|
||||
libsgio.a \
|
||||
$(top_builddir)/simgear/structure/libsgstructure.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/bucket/libsgbucket.a \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
$(base_LIBS) -lz
|
||||
|
||||
decode_binobj_SOURCES = decode_binobj.cxx
|
||||
|
||||
decode_binobj_LDADD = \
|
||||
libsgio.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/bucket/libsgbucket.a \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
$(base_LIBS) -lz
|
||||
@@ -4,13 +4,9 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
#include "sg_binobj.hxx"
|
||||
|
||||
|
||||
@@ -1,169 +0,0 @@
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <signal.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
|
||||
#include <simgear/io/sg_file.hxx>
|
||||
#include <simgear/io/HTTPClient.hxx>
|
||||
#include <simgear/io/HTTPRequest.hxx>
|
||||
#include <simgear/io/sg_netChannel.hxx>
|
||||
#include <simgear/misc/strutils.hxx>
|
||||
#include <simgear/timing/timestamp.hxx>
|
||||
|
||||
using namespace simgear;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::cerr;
|
||||
using std::string;
|
||||
|
||||
class ARequest : public HTTP::Request
|
||||
{
|
||||
public:
|
||||
ARequest(string& url) :
|
||||
Request(url),
|
||||
_complete(false),
|
||||
_file(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void setFile(SGFile* f)
|
||||
{
|
||||
_file = f;
|
||||
}
|
||||
|
||||
bool complete() const
|
||||
{ return _complete; }
|
||||
|
||||
void addHeader(const string& h)
|
||||
{
|
||||
int colonPos = h.find(':');
|
||||
if (colonPos < 0) {
|
||||
cerr << "malformed header: " << h << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
string key = h.substr(0, colonPos);
|
||||
_headers[key] = h.substr(colonPos + 1);
|
||||
}
|
||||
|
||||
virtual string_list requestHeaders() const
|
||||
{
|
||||
string_list r;
|
||||
std::map<string, string>::const_iterator it;
|
||||
for (it = _headers.begin(); it != _headers.end(); ++it) {
|
||||
r.push_back(it->first);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
virtual string header(const string& name) const
|
||||
{
|
||||
std::map<string, string>::const_iterator it = _headers.find(name);
|
||||
if (it == _headers.end()) {
|
||||
return string();
|
||||
}
|
||||
|
||||
return it->second;
|
||||
}
|
||||
protected:
|
||||
virtual void responseHeadersComplete()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void responseComplete()
|
||||
{
|
||||
_complete = true;
|
||||
}
|
||||
|
||||
virtual void gotBodyData(const char* s, int n)
|
||||
{
|
||||
_file->write(s, n);
|
||||
}
|
||||
private:
|
||||
bool _complete;
|
||||
SGFile* _file;
|
||||
std::map<string, string> _headers;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
HTTP::Client cl;
|
||||
SGFile* outFile = 0;
|
||||
string proxy, proxyAuth;
|
||||
string_list headers;
|
||||
string url;
|
||||
|
||||
for (int a=0; a<argc;++a) {
|
||||
if (argv[a][0] == '-') {
|
||||
if (!strcmp(argv[a], "--user-agent")) {
|
||||
cl.setUserAgent(argv[++a]);
|
||||
} else if (!strcmp(argv[a], "--proxy")) {
|
||||
proxy = argv[++a];
|
||||
} else if (!strcmp(argv[a], "--auth")) {
|
||||
proxyAuth = argv[++a];
|
||||
} else if (!strcmp(argv[a], "-f") || !strcmp(argv[a], "--file")) {
|
||||
outFile = new SGFile(argv[++a]);
|
||||
if (!outFile->open(SG_IO_OUT)) {
|
||||
cerr << "failed to open output for writing:" << outFile->get_file_name() << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
} else if (!strcmp(argv[a], "--header")) {
|
||||
headers.push_back(argv[++a]);
|
||||
}
|
||||
} else { // of argument starts with a hyphen
|
||||
url = argv[a];
|
||||
}
|
||||
} // of arguments iteration
|
||||
|
||||
if (!proxy.empty()) {
|
||||
int colonPos = proxy.find(':');
|
||||
string proxyHost = proxy;
|
||||
int proxyPort = 8800;
|
||||
if (colonPos >= 0) {
|
||||
proxyHost = proxy.substr(0, colonPos);
|
||||
proxyPort = strutils::to_int(proxy.substr(colonPos + 1));
|
||||
}
|
||||
|
||||
cl.setProxy(proxyHost, proxyPort, proxyAuth);
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
|
||||
if (!outFile) {
|
||||
outFile = new SGFile(fileno(stdout));
|
||||
}
|
||||
|
||||
if (url.empty()) {
|
||||
cerr << "no URL argument specificed" << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ARequest* req = new ARequest(url);
|
||||
BOOST_FOREACH(string h, headers) {
|
||||
req->addHeader(h);
|
||||
}
|
||||
|
||||
req->setFile(outFile);
|
||||
cl.makeRequest(req);
|
||||
|
||||
while (!req->complete()) {
|
||||
cl.update();
|
||||
SGTimeStamp::sleepForMSec(100);
|
||||
}
|
||||
|
||||
if (req->responseCode() != 200) {
|
||||
cerr << "got response:" << req->responseCode() << endl;
|
||||
cerr << "\treason:" << req->responseReason() << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -73,6 +73,6 @@ bool SGIOChannel::close() {
|
||||
|
||||
|
||||
// dummy eof routine
|
||||
bool SGIOChannel::eof() const {
|
||||
bool SGIOChannel::eof() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,15 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
// #include "protocol.hxx"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
|
||||
#define SG_IO_MAX_MSG_SIZE 16384
|
||||
|
||||
/**
|
||||
@@ -149,7 +158,7 @@ public:
|
||||
* false.
|
||||
* @return result of eof check
|
||||
*/
|
||||
virtual bool eof() const;
|
||||
virtual bool eof();
|
||||
|
||||
inline void set_type( SGChannelType t ) { type = t; }
|
||||
inline SGChannelType get_type() const { return type; }
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
simgear::Socket, adapted from PLIB Socket by James Turner
|
||||
Copyright (C) 2010 James Turner
|
||||
|
||||
|
||||
PLIB - A Suite of Portable Game Libraries
|
||||
Copyright (C) 1998,2002 Steve Baker
|
||||
|
||||
|
||||
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 Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
@@ -25,7 +25,8 @@
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include "raw_socket.hxx"
|
||||
|
||||
#include "sg_socket.hxx"
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
# define WINSOCK // use winsock convetions, otherwise standard POSIX
|
||||
@@ -36,18 +37,16 @@
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <cstdio> // for snprintf
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(WINSOCK)
|
||||
# include <winsock2.h>
|
||||
# include <ws2tcpip.h>
|
||||
# include <winsock.h>
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <sys/types.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/inet.h>
|
||||
# include <sys/time.h>
|
||||
# include <sys/time.h>
|
||||
# include <unistd.h>
|
||||
# include <netdb.h>
|
||||
# include <fcntl.h>
|
||||
@@ -57,306 +56,87 @@
|
||||
#define socklen_t int
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
#include <simgear/threads/SGThread.hxx>
|
||||
|
||||
namespace {
|
||||
|
||||
class Resolver : public SGThread
|
||||
{
|
||||
public:
|
||||
static Resolver* instance()
|
||||
{
|
||||
if (!static_instance) {
|
||||
static_instance = new Resolver;
|
||||
atexit(&Resolver::cleanup);
|
||||
static_instance->start();
|
||||
}
|
||||
|
||||
return static_instance;
|
||||
}
|
||||
|
||||
static void cleanup()
|
||||
{
|
||||
static_instance->shutdown();
|
||||
static_instance->join();
|
||||
}
|
||||
|
||||
Resolver() :
|
||||
_done(false)
|
||||
{
|
||||
}
|
||||
|
||||
void shutdown()
|
||||
{
|
||||
_lock.lock();
|
||||
_done = true;
|
||||
_wait.signal();
|
||||
_lock.unlock();
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
_lock.lock();
|
||||
while (!_done) {
|
||||
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
|
||||
_wait.wait(_lock);
|
||||
} // of thread run loop
|
||||
_lock.unlock();
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
SGMutex _lock;
|
||||
SGWaitCondition _wait;
|
||||
|
||||
typedef std::map<string, simgear::IPAddress*> AddressCache;
|
||||
AddressCache _cache;
|
||||
bool _done;
|
||||
};
|
||||
|
||||
Resolver* Resolver::static_instance = NULL;
|
||||
|
||||
} // of anonymous namespace
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
|
||||
|
||||
IPAddress::IPAddress ( const char* host, int port )
|
||||
{
|
||||
set ( host, port ) ;
|
||||
}
|
||||
|
||||
IPAddress::IPAddress( const IPAddress& other ) :
|
||||
addr(NULL)
|
||||
{
|
||||
if (other.addr) {
|
||||
addr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
|
||||
memcpy(addr, other.addr, sizeof(struct sockaddr_in));
|
||||
}
|
||||
}
|
||||
|
||||
const IPAddress& IPAddress::operator=(const IPAddress& other)
|
||||
{
|
||||
if (addr) {
|
||||
free(addr);
|
||||
addr = NULL;
|
||||
}
|
||||
|
||||
if (other.addr) {
|
||||
addr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
|
||||
memcpy(addr, other.addr, sizeof(struct sockaddr_in));
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void IPAddress::set ( const char* host, int port )
|
||||
{
|
||||
addr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
|
||||
memset(addr, 0, sizeof(struct sockaddr_in));
|
||||
memset(this, 0, sizeof(IPAddress));
|
||||
|
||||
addr->sin_family = AF_INET ;
|
||||
addr->sin_port = htons (port);
|
||||
sin_family = AF_INET ;
|
||||
sin_port = htons (port);
|
||||
|
||||
/* Convert a string specifying a host name or one of a few symbolic
|
||||
** names to a numeric IP address. This usually calls getaddrinfo()
|
||||
** names to a numeric IP address. This usually calls gethostbyname()
|
||||
** to do the work; the names "" and "<broadcast>" are special.
|
||||
*/
|
||||
|
||||
if (!host || host[0] == '\0') {
|
||||
addr->sin_addr.s_addr = INADDR_ANY;
|
||||
sin_addr = INADDR_ANY;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (strcmp(host, "<broadcast>") == 0) {
|
||||
addr->sin_addr.s_addr = INADDR_BROADCAST;
|
||||
sin_addr = INADDR_BROADCAST;
|
||||
return;
|
||||
}
|
||||
|
||||
// check the cache
|
||||
IPAddress* cached = Resolver::instance()->lookupSync(host);
|
||||
if (cached) {
|
||||
memcpy(addr, cached->getAddr(), cached->getAddrLen());
|
||||
|
||||
sin_addr = inet_addr ( host ) ;
|
||||
if (sin_addr != INADDR_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
addr->sin_port = htons (port); // fix up port after getaddrinfo
|
||||
}
|
||||
|
||||
IPAddress::~IPAddress()
|
||||
{
|
||||
if (addr) {
|
||||
free (addr);
|
||||
}
|
||||
}
|
||||
|
||||
bool IPAddress::lookupNonblocking(const char* host, IPAddress& addr)
|
||||
{
|
||||
IPAddress* cached = Resolver::instance()->lookup(host);
|
||||
if (!cached) {
|
||||
return false;
|
||||
// finally, try gethostbyname
|
||||
struct hostent *hp = gethostbyname ( host ) ;
|
||||
if (!hp) {
|
||||
SG_LOG(SG_IO, SG_WARN, "gethostbyname failed for " << host);
|
||||
sin_addr = INADDR_ANY ;
|
||||
return;
|
||||
}
|
||||
|
||||
addr = *cached;
|
||||
return true;
|
||||
|
||||
memcpy ( (char *) &sin_addr, hp->h_addr, hp->h_length ) ;
|
||||
}
|
||||
|
||||
|
||||
/* Create a string object representing an IP address.
|
||||
This is always a string of the form 'dd.dd.dd.dd' (with variable
|
||||
size numbers). */
|
||||
|
||||
const char* IPAddress::getHost () const
|
||||
{
|
||||
if (!addr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
const char* buf = inet_ntoa ( sin_addr ) ;
|
||||
#else
|
||||
static char buf [32];
|
||||
long x = ntohl(addr->sin_addr.s_addr);
|
||||
long x = ntohl(sin_addr);
|
||||
sprintf(buf, "%d.%d.%d.%d",
|
||||
(int) (x>>24) & 0xff, (int) (x>>16) & 0xff,
|
||||
(int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff );
|
||||
#endif
|
||||
return buf;
|
||||
}
|
||||
|
||||
unsigned int IPAddress::getIP () const
|
||||
{
|
||||
if (!addr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return addr->sin_addr.s_addr;
|
||||
unsigned int IPAddress::getIP () const
|
||||
{
|
||||
return sin_addr;
|
||||
}
|
||||
|
||||
unsigned int IPAddress::getPort() const
|
||||
{
|
||||
if (!addr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ntohs(addr->sin_port);
|
||||
return ntohs(sin_port);
|
||||
}
|
||||
|
||||
void IPAddress::setPort(int port)
|
||||
{
|
||||
if (!addr) {
|
||||
return;
|
||||
}
|
||||
|
||||
addr->sin_port = htons(port);
|
||||
}
|
||||
|
||||
unsigned int IPAddress::getFamily () const
|
||||
{
|
||||
if (!addr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return addr->sin_family;
|
||||
unsigned int IPAddress::getFamily () const
|
||||
{
|
||||
return sin_family;
|
||||
}
|
||||
|
||||
const char* IPAddress::getLocalHost ()
|
||||
@@ -383,32 +163,9 @@ const char* IPAddress::getLocalHost ()
|
||||
|
||||
bool IPAddress::getBroadcast () const
|
||||
{
|
||||
if (!addr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (addr->sin_addr.s_addr == INADDR_BROADCAST);
|
||||
return sin_addr == INADDR_BROADCAST;
|
||||
}
|
||||
|
||||
unsigned int IPAddress::getAddrLen() const
|
||||
{
|
||||
return sizeof(struct sockaddr_in);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool IPAddress::isValid() const
|
||||
{
|
||||
return (addr != NULL);
|
||||
}
|
||||
|
||||
Socket::Socket ()
|
||||
{
|
||||
@@ -491,7 +248,7 @@ void Socket::setBroadcast ( bool broadcast )
|
||||
} else {
|
||||
result = ::setsockopt( handle, SOL_SOCKET, SO_BROADCAST, NULL, 0 );
|
||||
}
|
||||
|
||||
|
||||
if ( result < 0 ) {
|
||||
throw sg_exception("Socket::setBroadcast failed");
|
||||
}
|
||||
@@ -505,13 +262,13 @@ int Socket::bind ( const char* host, int port )
|
||||
IPAddress addr ( host, port ) ;
|
||||
|
||||
#if !defined(WINSOCK)
|
||||
if( (result = ::bind(handle, addr.getAddr(), addr.getAddrLen() ) ) < 0 ) {
|
||||
SG_LOG(SG_IO, SG_ALERT, "bind(" << addr.getHost() << ":" << addr.getPort() << ") failed. Errno " << errno << " (" << strerror(errno) << ")");
|
||||
if( (result = ::bind(handle,(const sockaddr*)&addr,sizeof(IPAddress))) < 0 ) {
|
||||
SG_LOG(SG_IO, SG_ALERT, "bind(" << host << ":" << port << ") failed. Errno " << errno << " (" << strerror(errno) << ")");
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
// 224.0.0.0 - 239.255.255.255 are multicast
|
||||
// 224.0.0.0 - 239.255.255.255 are multicast
|
||||
// Usage of 239.x.x.x is recommended for local scope
|
||||
// Reference: http://tools.ietf.org/html/rfc5771
|
||||
if( ntohl(addr.getIP()) >= 0xe0000000 && ntohl(addr.getIP()) <= 0xefffffff ) {
|
||||
@@ -521,7 +278,7 @@ int Socket::bind ( const char* host, int port )
|
||||
a.sin_addr.S_un.S_addr = INADDR_ANY;
|
||||
a.sin_family = AF_INET;
|
||||
a.sin_port = htons(port);
|
||||
|
||||
|
||||
if( (result = ::bind(handle,(const sockaddr*)&a,sizeof(a))) < 0 ) {
|
||||
SG_LOG(SG_IO, SG_ALERT, "bind(any:" << port << ") failed. Errno " << errno << " (" << strerror(errno) << ")");
|
||||
return result;
|
||||
@@ -537,7 +294,7 @@ int Socket::bind ( const char* host, int port )
|
||||
}
|
||||
}
|
||||
#if defined(WINSOCK)
|
||||
else if( (result = ::bind(handle,addr.getAddr(), addr.getAddrLen())) < 0 ) {
|
||||
else if( (result = ::bind(handle,(const sockaddr*)&addr,sizeof(IPAddress))) < 0 ) {
|
||||
SG_LOG(SG_IO, SG_ALERT, "bind(" << host << ":" << port << ") failed. Errno " << errno << " (" << strerror(errno) << ")");
|
||||
return result;
|
||||
}
|
||||
@@ -564,26 +321,20 @@ int Socket::accept ( IPAddress* addr )
|
||||
}
|
||||
else
|
||||
{
|
||||
socklen_t addr_len = addr->getAddrLen(); ;
|
||||
return ::accept(handle, addr->getAddr(), &addr_len);
|
||||
socklen_t addr_len = (socklen_t) sizeof(IPAddress) ;
|
||||
return ::accept(handle,(sockaddr*)addr,&addr_len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Socket::connect ( const char* host, int port )
|
||||
{
|
||||
IPAddress addr ( host, port ) ;
|
||||
return connect ( &addr );
|
||||
}
|
||||
|
||||
|
||||
int Socket::connect ( IPAddress* addr )
|
||||
{
|
||||
assert ( handle != -1 ) ;
|
||||
if ( addr->getBroadcast() ) {
|
||||
IPAddress addr ( host, port ) ;
|
||||
if ( addr.getBroadcast() ) {
|
||||
setBroadcast( true );
|
||||
}
|
||||
return ::connect(handle, addr->getAddr(), addr->getAddrLen() );
|
||||
return ::connect(handle,(const sockaddr*)&addr,sizeof(IPAddress));
|
||||
}
|
||||
|
||||
|
||||
@@ -599,7 +350,7 @@ int Socket::sendto ( const void * buffer, int size,
|
||||
{
|
||||
assert ( handle != -1 ) ;
|
||||
return ::sendto(handle,(const char*)buffer,size,flags,
|
||||
(const sockaddr*) to->getAddr(), to->getAddrLen());
|
||||
(const sockaddr*)to,sizeof(IPAddress));
|
||||
}
|
||||
|
||||
|
||||
@@ -614,8 +365,8 @@ int Socket::recvfrom ( void * buffer, int size,
|
||||
int flags, IPAddress* from )
|
||||
{
|
||||
assert ( handle != -1 ) ;
|
||||
socklen_t fromlen = (socklen_t) from->getAddrLen() ;
|
||||
return ::recvfrom(handle,(char*)buffer,size,flags, from->getAddr(),&fromlen);
|
||||
socklen_t fromlen = (socklen_t) sizeof(IPAddress) ;
|
||||
return ::recvfrom(handle,(char*)buffer,size,flags,(sockaddr*)from,&fromlen);
|
||||
}
|
||||
|
||||
|
||||
@@ -671,7 +422,7 @@ int Socket::select ( Socket** reads, Socket** writes, int timeout )
|
||||
{
|
||||
fd_set r,w;
|
||||
int retval;
|
||||
|
||||
|
||||
FD_ZERO (&r);
|
||||
FD_ZERO (&w);
|
||||
|
||||
@@ -709,7 +460,7 @@ int Socket::select ( Socket** reads, Socket** writes, int timeout )
|
||||
// It bothers me that select()'s first argument does not appear to
|
||||
// work as advertised... [it hangs like this if called with
|
||||
// anything less than FD_SETSIZE, which seems wasteful?]
|
||||
|
||||
|
||||
// Note: we ignore the 'exception' fd_set - I have never had a
|
||||
// need to use it. The name is somewhat misleading - the only
|
||||
// thing I have ever seen it used for is to detect urgent data -
|
||||
@@ -775,6 +526,8 @@ static void netExit ( void )
|
||||
|
||||
int Socket::initSockets()
|
||||
{
|
||||
assert ( sizeof(sockaddr_in) == sizeof(IPAddress) ) ;
|
||||
|
||||
#if defined(WINSOCK)
|
||||
/* Start up the windows networking */
|
||||
WORD version_wanted = MAKEWORD(1,1);
|
||||
|
||||
@@ -23,15 +23,12 @@
|
||||
#ifndef SG_IO_SOCKET_HXX
|
||||
#define SG_IO_SOCKET_HXX
|
||||
|
||||
//#include <errno.h>
|
||||
#include <errno.h>
|
||||
|
||||
//#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||
//# include <netinet/in.h>
|
||||
//#endif
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
struct sockaddr_in;
|
||||
struct sockaddr;
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
|
||||
@@ -40,31 +37,32 @@ namespace simgear
|
||||
*/
|
||||
class IPAddress
|
||||
{
|
||||
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);
|
||||
/* DANGER!!! This MUST match 'struct sockaddr_in' exactly! */
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||
__uint8_t sin_len;
|
||||
__uint8_t sin_family;
|
||||
in_port_t sin_port;
|
||||
in_addr_t sin_addr;
|
||||
char sin_zero[8];
|
||||
#else
|
||||
short sin_family ;
|
||||
unsigned short sin_port ;
|
||||
unsigned int sin_addr ;
|
||||
char sin_zero [ 8 ] ;
|
||||
#endif
|
||||
|
||||
public:
|
||||
IPAddress () {}
|
||||
IPAddress ( const char* host, int port ) ;
|
||||
|
||||
bool isValid () const;
|
||||
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 () ;
|
||||
|
||||
bool getBroadcast () const ;
|
||||
|
||||
unsigned int getAddrLen() const;
|
||||
sockaddr* getAddr() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -74,7 +72,7 @@ public:
|
||||
class Socket
|
||||
{
|
||||
int handle ;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Socket () ;
|
||||
@@ -91,7 +89,6 @@ public:
|
||||
int listen ( int backlog ) ;
|
||||
int accept ( IPAddress* addr ) ;
|
||||
int connect ( const char* host, int port ) ;
|
||||
int connect ( IPAddress* addr ) ;
|
||||
int send ( const void * buffer, int size, int flags = 0 ) ;
|
||||
int sendto ( const void * buffer, int size, int flags, const IPAddress* to ) ;
|
||||
int recv ( void * buffer, int size, int flags = 0 ) ;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,24 +27,29 @@
|
||||
#ifndef _SG_BINOBJ_HXX
|
||||
#define _SG_BINOBJ_HXX
|
||||
|
||||
#include <zlib.h> // for gzFile
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
#include <simgear/bucket/newbucket.hxx>
|
||||
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
/** STL Structure used to store object information */
|
||||
typedef std::vector < int_list > group_list;
|
||||
typedef group_list::iterator group_list_iterator;
|
||||
typedef group_list::const_iterator const_group_list_iterator;
|
||||
|
||||
// forward decls
|
||||
class SGBucket;
|
||||
class SGPath;
|
||||
|
||||
/** Magic Number for our file format */
|
||||
#define SG_FILE_MAGIC_NUMBER ( ('S'<<24) + ('G'<<16) + SG_BINOBJ_VERSION )
|
||||
|
||||
|
||||
/**
|
||||
* A class to manipulate the simgear 3d object format.
|
||||
@@ -80,7 +85,6 @@ class SGPath;
|
||||
* - vertex: FLOAT, FLOAT, FLOAT
|
||||
*/
|
||||
class SGBinObject {
|
||||
private:
|
||||
unsigned short version;
|
||||
|
||||
SGVec3d gbs_center;
|
||||
@@ -115,24 +119,6 @@ private:
|
||||
group_list fans_tc; // fans texture coordinate index
|
||||
string_list fan_materials; // fans materials
|
||||
|
||||
void read_properties(gzFile fp, int nproperties);
|
||||
|
||||
void read_object( gzFile fp,
|
||||
int obj_type,
|
||||
int nproperties,
|
||||
int nelements,
|
||||
group_list& vertices,
|
||||
group_list& normals,
|
||||
group_list& colors,
|
||||
group_list& texCoords,
|
||||
string_list& materials);
|
||||
|
||||
void write_header(gzFile fp, int type, int nProps, int nElements);
|
||||
void write_objects(gzFile fp, int type, const group_list& verts,
|
||||
const group_list& normals, const group_list& colors,
|
||||
const group_list& texCoords, const string_list& materials);
|
||||
|
||||
unsigned int count_objects(const string_list& materials);
|
||||
public:
|
||||
|
||||
inline unsigned short get_version() const { return version; }
|
||||
@@ -221,9 +207,6 @@ public:
|
||||
*/
|
||||
bool write_bin( const std::string& base, const std::string& name, const SGBucket& b );
|
||||
|
||||
|
||||
bool write_bin_file(const SGPath& file);
|
||||
|
||||
/**
|
||||
* Write out the structures to an ASCII file. We assume that the
|
||||
* groups come to us sorted by material property. If not, things
|
||||
|
||||
@@ -31,14 +31,6 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/misc/stdint.hxx>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
@@ -46,20 +38,13 @@
|
||||
|
||||
using std::string;
|
||||
|
||||
|
||||
SGFile::SGFile(const string &file, int repeat_)
|
||||
: file_name(file), fp(-1), eof_flag(true), repeat(repeat_), iteration(0)
|
||||
{
|
||||
set_type( sgFileType );
|
||||
}
|
||||
|
||||
SGFile::SGFile( int existingFd ) :
|
||||
fp(existingFd),
|
||||
eof_flag(false),
|
||||
repeat(1),
|
||||
iteration(0)
|
||||
{
|
||||
set_type( sgFileType );
|
||||
}
|
||||
|
||||
SGFile::~SGFile() {
|
||||
}
|
||||
|
||||
@@ -26,19 +26,33 @@
|
||||
#ifndef _SG_FILE_HXX
|
||||
#define _SG_FILE_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <sys/types.h> // for open(), read(), write(), close()
|
||||
#include <sys/stat.h> // for open(), read(), write(), close()
|
||||
#include <fcntl.h> // for open(), read(), write(), close()
|
||||
#if !defined( _MSC_VER )
|
||||
# include <unistd.h> // for open(), read(), write(), close()
|
||||
#endif
|
||||
|
||||
#include "iochannel.hxx"
|
||||
|
||||
using std::string;
|
||||
|
||||
|
||||
/**
|
||||
* A file I/O class based on SGIOChannel.
|
||||
*/
|
||||
class SGFile : public SGIOChannel {
|
||||
|
||||
std::string file_name;
|
||||
string file_name;
|
||||
int fp;
|
||||
bool eof_flag;
|
||||
// Number of repetitions to play. -1 means loop infinitely.
|
||||
@@ -56,12 +70,7 @@ public:
|
||||
* @param file name of file to open
|
||||
* @param repeat On eof restart at the beginning of the file
|
||||
*/
|
||||
SGFile( const std::string& file, int repeat_ = 1 );
|
||||
|
||||
/**
|
||||
* Create an SGFile from an existing, open file-descriptor
|
||||
*/
|
||||
SGFile( int existingFd );
|
||||
SGFile( const string& file, int repeat_ = 1 );
|
||||
|
||||
/** Destructor */
|
||||
~SGFile();
|
||||
@@ -85,10 +94,10 @@ public:
|
||||
bool close();
|
||||
|
||||
/** @return the name of the file being manipulated. */
|
||||
inline std::string get_file_name() const { return file_name; }
|
||||
inline string get_file_name() const { return file_name; }
|
||||
|
||||
/** @return true of eof conditions exists */
|
||||
virtual bool eof() const { return eof_flag; };
|
||||
inline bool eof() const { return eof_flag; };
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -34,11 +34,9 @@
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <errno.h>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
|
||||
namespace simgear {
|
||||
|
||||
static NetChannel* channels = 0 ;
|
||||
@@ -47,7 +45,6 @@ NetChannel::NetChannel ()
|
||||
{
|
||||
closed = true ;
|
||||
connected = false ;
|
||||
resolving_host = false;
|
||||
accepting = false ;
|
||||
write_blocked = false ;
|
||||
should_delete = false ;
|
||||
@@ -85,6 +82,7 @@ NetChannel::setHandle (int handle, bool is_connected)
|
||||
close () ;
|
||||
Socket::setHandle ( handle ) ;
|
||||
connected = is_connected ;
|
||||
//if ( connected ) this->handleConnect();
|
||||
closed = false ;
|
||||
}
|
||||
|
||||
@@ -108,12 +106,21 @@ NetChannel::listen ( int backlog )
|
||||
}
|
||||
|
||||
int
|
||||
NetChannel::connect ( const char* h, int p )
|
||||
NetChannel::connect ( const char* host, int port )
|
||||
{
|
||||
host = h;
|
||||
port = p;
|
||||
resolving_host = true;
|
||||
return handleResolve();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
@@ -181,10 +188,12 @@ 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();
|
||||
@@ -196,42 +205,12 @@ 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
|
||||
}
|
||||
|
||||
if (!addr.isValid()) {
|
||||
SG_LOG(SG_IO, SG_WARN, "Network: host lookup failed:" << host);
|
||||
handleError (0);
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -256,12 +235,6 @@ 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,17 +54,14 @@
|
||||
#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, resolving_host ;
|
||||
bool closed, connected, accepting, write_blocked, should_delete ;
|
||||
NetChannel* next_channel ;
|
||||
std::string host;
|
||||
int port;
|
||||
|
||||
friend bool netPoll (unsigned int timeout);
|
||||
|
||||
@@ -99,7 +96,6 @@ public:
|
||||
|
||||
void handleReadEvent (void);
|
||||
void handleWriteEvent (void);
|
||||
int handleResolve (void);
|
||||
|
||||
// These are meant to be overridden.
|
||||
virtual void handleClose (void) {
|
||||
|
||||
@@ -26,16 +26,14 @@
|
||||
#include <simgear/io/sg_netChat.hxx>
|
||||
|
||||
#include <cstring> // for strdup
|
||||
#include <cstdlib>
|
||||
|
||||
namespace simgear {
|
||||
|
||||
void
|
||||
NetChat::setTerminator (const char* t)
|
||||
{
|
||||
if (terminator) free(terminator);
|
||||
if (terminator) delete[] terminator;
|
||||
terminator = strdup(t);
|
||||
bytesToCollect = -1;
|
||||
}
|
||||
|
||||
const char*
|
||||
@@ -44,15 +42,6 @@ NetChat::getTerminator (void)
|
||||
return terminator;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NetChat::setByteCount(int count)
|
||||
{
|
||||
if (terminator) free(terminator);
|
||||
terminator = NULL;
|
||||
bytesToCollect = count;
|
||||
}
|
||||
|
||||
// return the size of the largest prefix of needle at the end
|
||||
// of haystack
|
||||
|
||||
@@ -100,23 +89,13 @@ NetChat::handleBufferRead (NetBuffer& in_buffer)
|
||||
// necessary because we might read several data+terminator combos
|
||||
// with a single recv().
|
||||
|
||||
while (in_buffer.getLength()) {
|
||||
while (in_buffer.getLength()) {
|
||||
|
||||
// special case where we're not using a terminator
|
||||
if (terminator == 0 || *terminator == 0) {
|
||||
if ( bytesToCollect > 0) {
|
||||
const int toRead = std::min(in_buffer.getLength(), bytesToCollect);
|
||||
collectIncomingData(in_buffer.getData(), toRead);
|
||||
in_buffer.remove(0, toRead);
|
||||
bytesToCollect -= toRead;
|
||||
if (bytesToCollect == 0) { // read all requested bytes
|
||||
foundTerminator();
|
||||
}
|
||||
} else { // read the whole lot
|
||||
collectIncomingData (in_buffer.getData(),in_buffer.getLength());
|
||||
in_buffer.remove ();
|
||||
}
|
||||
|
||||
continue;
|
||||
if (terminator == 0 || *terminator == 0) {
|
||||
collectIncomingData (in_buffer.getData(),in_buffer.getLength());
|
||||
in_buffer.remove ();
|
||||
return;
|
||||
}
|
||||
|
||||
int terminator_len = strlen(terminator);
|
||||
|
||||
@@ -61,8 +61,6 @@
|
||||
#ifndef SG_NET_CHAT_H
|
||||
#define SG_NET_CHAT_H
|
||||
|
||||
#include <memory>
|
||||
#include <cstdlib>
|
||||
#include <simgear/io/sg_netBuffer.hxx>
|
||||
|
||||
namespace simgear
|
||||
@@ -71,25 +69,16 @@ namespace simgear
|
||||
class NetChat : public NetBufferChannel
|
||||
{
|
||||
char* terminator;
|
||||
int bytesToCollect;
|
||||
|
||||
virtual void handleBufferRead (NetBuffer& buffer) ;
|
||||
|
||||
public:
|
||||
|
||||
NetChat () :
|
||||
terminator (NULL),
|
||||
bytesToCollect(-1)
|
||||
{}
|
||||
NetChat () : terminator (0) {}
|
||||
|
||||
void setTerminator (const char* t);
|
||||
const char* getTerminator (void);
|
||||
|
||||
/**
|
||||
* set byte count to collect - 'foundTerminator' will be called once
|
||||
* this many bytes have been collected
|
||||
*/
|
||||
void setByteCount(int bytes);
|
||||
|
||||
bool push (const char* s);
|
||||
|
||||
virtual void collectIncomingData (const char* s, int n) {}
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include "sg_socket.hxx"
|
||||
|
||||
bool SGSocket::init = false;
|
||||
using std::string;
|
||||
|
||||
SGSocket::SGSocket( const string& host, const string& port_,
|
||||
const string& style ) :
|
||||
|
||||
@@ -33,8 +33,6 @@
|
||||
#include <cstring>
|
||||
#include <cstdlib> // for atoi
|
||||
|
||||
using std::string;
|
||||
|
||||
SGSocketUDP::SGSocketUDP( const string& host, const string& port ) :
|
||||
hostname(host),
|
||||
port_str(port),
|
||||
@@ -162,8 +160,11 @@ int SGSocketUDP::write( const char *buf, const int length ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool error_condition = false;
|
||||
|
||||
if ( sock.send( buf, length, 0 ) < 0 ) {
|
||||
SG_LOG( SG_IO, SG_WARN, "Error writing to socket: " << port );
|
||||
error_condition = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ public:
|
||||
* @param host name of host if direction is SG_IO_OUT or SG_IO_BI
|
||||
* @param port port number if we care to choose one.
|
||||
* @param style specify "udp" or "tcp" */
|
||||
SGSocketUDP( const std::string& host, const std::string& port );
|
||||
SGSocketUDP( const string& host, const string& port );
|
||||
|
||||
/** Destructor */
|
||||
~SGSocketUDP();
|
||||
|
||||
@@ -1,541 +0,0 @@
|
||||
#include <cstdlib>
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
||||
#include "HTTPClient.hxx"
|
||||
#include "HTTPRequest.hxx"
|
||||
|
||||
#include <simgear/io/sg_netChat.hxx>
|
||||
#include <simgear/misc/strutils.hxx>
|
||||
#include <simgear/timing/timestamp.hxx>
|
||||
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
using std::stringstream;
|
||||
|
||||
using namespace simgear;
|
||||
|
||||
const char* BODY1 = "The quick brown fox jumps over a lazy dog.";
|
||||
|
||||
const unsigned int body2Size = 8 * 1024;
|
||||
char body2[body2Size];
|
||||
|
||||
#define COMPARE(a, b) \
|
||||
if ((a) != (b)) { \
|
||||
cerr << "failed:" << #a << " != " << #b << endl; \
|
||||
cerr << "\tgot:" << a << endl; \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
#define VERIFY(a) \
|
||||
if (!(a)) { \
|
||||
cerr << "failed:" << #a << endl; \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
class TestRequest : public HTTP::Request
|
||||
{
|
||||
public:
|
||||
bool complete;
|
||||
bool failed;
|
||||
string bodyData;
|
||||
|
||||
TestRequest(const std::string& url) :
|
||||
HTTP::Request(url),
|
||||
complete(false)
|
||||
{
|
||||
}
|
||||
|
||||
std::map<string, string> sendHeaders;
|
||||
std::map<string, string> headers;
|
||||
protected:
|
||||
string_list requestHeaders() const
|
||||
{
|
||||
string_list r;
|
||||
std::map<string, string>::const_iterator it;
|
||||
for (it = sendHeaders.begin(); it != sendHeaders.end(); ++it) {
|
||||
r.push_back(it->first);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
string header(const string& name) const
|
||||
{
|
||||
std::map<string, string>::const_iterator it = sendHeaders.find(name);
|
||||
if (it == sendHeaders.end()) {
|
||||
return string();
|
||||
}
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
virtual void responseHeadersComplete()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void responseComplete()
|
||||
{
|
||||
complete = true;
|
||||
}
|
||||
|
||||
virtual void failure()
|
||||
{
|
||||
failed = true;
|
||||
}
|
||||
|
||||
virtual void gotBodyData(const char* s, int n)
|
||||
{
|
||||
bodyData += string(s, n);
|
||||
}
|
||||
|
||||
virtual void responseHeader(const string& header, const string& value)
|
||||
{
|
||||
headers[header] = value;
|
||||
}
|
||||
};
|
||||
|
||||
class TestServerChannel : public NetChat
|
||||
{
|
||||
public:
|
||||
enum State
|
||||
{
|
||||
STATE_IDLE = 0,
|
||||
STATE_HEADERS,
|
||||
STATE_REQUEST_BODY
|
||||
};
|
||||
|
||||
TestServerChannel()
|
||||
{
|
||||
state = STATE_IDLE;
|
||||
setTerminator("\r\n");
|
||||
}
|
||||
|
||||
virtual void collectIncomingData(const char* s, int n)
|
||||
{
|
||||
buffer += string(s, n);
|
||||
}
|
||||
|
||||
virtual void foundTerminator(void)
|
||||
{
|
||||
if (state == STATE_IDLE) {
|
||||
state = STATE_HEADERS;
|
||||
string_list line = strutils::split(buffer, NULL, 3);
|
||||
if (line.size() < 3) {
|
||||
cerr << "malformed request:" << buffer << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
method = line[0];
|
||||
path = line[1];
|
||||
httpVersion = line[2];
|
||||
requestHeaders.clear();
|
||||
buffer.clear();
|
||||
} else if (state == STATE_HEADERS) {
|
||||
string s = strutils::simplify(buffer);
|
||||
if (s.empty()) {
|
||||
buffer.clear();
|
||||
receivedRequestHeaders();
|
||||
return;
|
||||
}
|
||||
|
||||
int colonPos = buffer.find(':');
|
||||
if (colonPos < 0) {
|
||||
cerr << "malformed HTTP response header:" << buffer << endl;
|
||||
buffer.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
string key = strutils::simplify(buffer.substr(0, colonPos));
|
||||
string value = strutils::strip(buffer.substr(colonPos + 1));
|
||||
requestHeaders[key] = value;
|
||||
buffer.clear();
|
||||
} else if (state == STATE_REQUEST_BODY) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void receivedRequestHeaders()
|
||||
{
|
||||
state = STATE_IDLE;
|
||||
|
||||
if (path == "/test1") {
|
||||
string contentStr(BODY1);
|
||||
stringstream d;
|
||||
d << "HTTP/1.1 " << 200 << " " << reasonForCode(200) << "\r\n";
|
||||
d << "Content-Length:" << contentStr.size() << "\r\n";
|
||||
d << "\r\n"; // final CRLF to terminate the headers
|
||||
d << contentStr;
|
||||
push(d.str().c_str());
|
||||
} else if (path == "/test_headers") {
|
||||
COMPARE(requestHeaders["X-Foo"], string("Bar"));
|
||||
COMPARE(requestHeaders["X-AnotherHeader"], string("A longer value"));
|
||||
|
||||
string contentStr(BODY1);
|
||||
stringstream d;
|
||||
d << "HTTP/1.1 " << 200 << " " << reasonForCode(200) << "\r\n";
|
||||
d << "Content-Length:" << contentStr.size() << "\r\n";
|
||||
d << "\r\n"; // final CRLF to terminate the headers
|
||||
d << contentStr;
|
||||
push(d.str().c_str());
|
||||
} else if (path == "/test2") {
|
||||
sendBody2();
|
||||
} else if (path == "/testchunked") {
|
||||
stringstream d;
|
||||
d << "HTTP/1.1 " << 200 << " " << reasonForCode(200) << "\r\n";
|
||||
d << "Transfer-Encoding:chunked\r\n";
|
||||
d << "\r\n";
|
||||
d << "8\r\n"; // first chunk
|
||||
d << "ABCDEFGH\r\n";
|
||||
d << "6\r\n"; // second chunk
|
||||
d << "ABCDEF\r\n";
|
||||
d << "10\r\n"; // third chunk
|
||||
d << "ABCDSTUVABCDSTUV\r\n";
|
||||
d << "0\r\n"; // start of trailer
|
||||
d << "X-Foobar: wibble\r\n"; // trailer data
|
||||
d << "\r\n";
|
||||
push(d.str().c_str());
|
||||
} else if (path == "http://www.google.com/test2") {
|
||||
// proxy test
|
||||
if (requestHeaders["Host"] != "www.google.com") {
|
||||
sendErrorResponse(400, true, "bad destination");
|
||||
}
|
||||
|
||||
if (requestHeaders["Proxy-Authorization"] != string()) {
|
||||
sendErrorResponse(401, false, "bad auth"); // shouldn't supply auth
|
||||
}
|
||||
|
||||
sendBody2();
|
||||
} else if (path == "http://www.google.com/test3") {
|
||||
// proxy test
|
||||
if (requestHeaders["Host"] != "www.google.com") {
|
||||
sendErrorResponse(400, true, "bad destination");
|
||||
}
|
||||
|
||||
if (requestHeaders["Proxy-Authorization"] != "ABCDEF") {
|
||||
sendErrorResponse(401, false, "bad auth"); // forbidden
|
||||
}
|
||||
|
||||
sendBody2();
|
||||
} else if (strutils::starts_with(path, "/test_1_0")) {
|
||||
string contentStr(BODY1);
|
||||
stringstream d;
|
||||
d << "HTTP/1.0 " << 200 << " " << reasonForCode(200) << "\r\n";
|
||||
d << "\r\n"; // final CRLF to terminate the headers
|
||||
d << contentStr;
|
||||
push(d.str().c_str());
|
||||
closeWhenDone();
|
||||
} else if (path == "/test_close") {
|
||||
string contentStr(BODY1);
|
||||
stringstream d;
|
||||
d << "HTTP/1.1 " << 200 << " " << reasonForCode(200) << "\r\n";
|
||||
d << "Connection: close\r\n";
|
||||
d << "\r\n"; // final CRLF to terminate the headers
|
||||
d << contentStr;
|
||||
push(d.str().c_str());
|
||||
closeWhenDone();
|
||||
} else {
|
||||
sendErrorResponse(404, true, "");
|
||||
}
|
||||
}
|
||||
|
||||
void sendBody2()
|
||||
{
|
||||
stringstream d;
|
||||
d << "HTTP/1.1 " << 200 << " " << reasonForCode(200) << "\r\n";
|
||||
d << "Content-Length:" << body2Size << "\r\n";
|
||||
d << "\r\n"; // final CRLF to terminate the headers
|
||||
push(d.str().c_str());
|
||||
bufferSend(body2, body2Size);
|
||||
}
|
||||
|
||||
void sendErrorResponse(int code, bool close, string content)
|
||||
{
|
||||
cerr << "sending error " << code << " for " << path << endl;
|
||||
stringstream headerData;
|
||||
headerData << "HTTP/1.1 " << code << " " << reasonForCode(code) << "\r\n";
|
||||
headerData << "Content-Length:" << content.size() << "\r\n";
|
||||
headerData << "\r\n"; // final CRLF to terminate the headers
|
||||
push(headerData.str().c_str());
|
||||
push(content.c_str());
|
||||
|
||||
if (close) {
|
||||
closeWhenDone();
|
||||
}
|
||||
}
|
||||
|
||||
string reasonForCode(int code)
|
||||
{
|
||||
switch (code) {
|
||||
case 200: return "OK";
|
||||
case 404: return "not found";
|
||||
default: return "unknown code";
|
||||
}
|
||||
}
|
||||
|
||||
State state;
|
||||
string buffer;
|
||||
string method;
|
||||
string path;
|
||||
string httpVersion;
|
||||
std::map<string, string> requestHeaders;
|
||||
};
|
||||
|
||||
class TestServer : public NetChannel
|
||||
{
|
||||
public:
|
||||
TestServer()
|
||||
{
|
||||
open();
|
||||
bind(NULL, 2000); // localhost, any port
|
||||
listen(5);
|
||||
}
|
||||
|
||||
virtual ~TestServer()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool writable (void) { return false ; }
|
||||
|
||||
virtual void handleAccept (void)
|
||||
{
|
||||
simgear::IPAddress addr ;
|
||||
int handle = accept ( &addr ) ;
|
||||
//cout << "did accept from " << addr.getHost() << ":" << addr.getPort() << endl;
|
||||
TestServerChannel* chan = new TestServerChannel();
|
||||
chan->setHandle(handle);
|
||||
}
|
||||
};
|
||||
|
||||
void waitForComplete(HTTP::Client* cl, TestRequest* tr)
|
||||
{
|
||||
SGTimeStamp start(SGTimeStamp::now());
|
||||
while (start.elapsedMSec() < 1000) {
|
||||
cl->update();
|
||||
if (tr->complete) {
|
||||
return;
|
||||
}
|
||||
SGTimeStamp::sleepForMSec(1);
|
||||
}
|
||||
|
||||
cerr << "timed out" << endl;
|
||||
}
|
||||
|
||||
void waitForFailed(HTTP::Client* cl, TestRequest* tr)
|
||||
{
|
||||
SGTimeStamp start(SGTimeStamp::now());
|
||||
while (start.elapsedMSec() < 1000) {
|
||||
cl->update();
|
||||
if (tr->failed) {
|
||||
return;
|
||||
}
|
||||
SGTimeStamp::sleepForMSec(1);
|
||||
}
|
||||
|
||||
cerr << "timed out waiting for failure" << endl;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
TestServer s;
|
||||
|
||||
HTTP::Client cl;
|
||||
|
||||
// test URL parsing
|
||||
TestRequest* tr1 = new TestRequest("http://localhost.woo.zar:2000/test1?foo=bar");
|
||||
COMPARE(tr1->scheme(), "http");
|
||||
COMPARE(tr1->hostAndPort(), "localhost.woo.zar:2000");
|
||||
COMPARE(tr1->host(), "localhost.woo.zar");
|
||||
COMPARE(tr1->port(), 2000);
|
||||
COMPARE(tr1->path(), "/test1");
|
||||
|
||||
TestRequest* tr2 = new TestRequest("http://192.168.1.1/test1/dir/thing/file.png");
|
||||
COMPARE(tr2->scheme(), "http");
|
||||
COMPARE(tr2->hostAndPort(), "192.168.1.1");
|
||||
COMPARE(tr2->host(), "192.168.1.1");
|
||||
COMPARE(tr2->port(), 80);
|
||||
COMPARE(tr2->path(), "/test1/dir/thing/file.png");
|
||||
|
||||
// basic get request
|
||||
{
|
||||
TestRequest* tr = new TestRequest("http://localhost:2000/test1");
|
||||
HTTP::Request_ptr own(tr);
|
||||
cl.makeRequest(tr);
|
||||
|
||||
waitForComplete(&cl, tr);
|
||||
COMPARE(tr->responseCode(), 200);
|
||||
COMPARE(tr->responseReason(), string("OK"));
|
||||
COMPARE(tr->responseLength(), strlen(BODY1));
|
||||
COMPARE(tr->responseBytesReceived(), strlen(BODY1));
|
||||
COMPARE(tr->bodyData, string(BODY1));
|
||||
}
|
||||
|
||||
{
|
||||
TestRequest* tr = new TestRequest("http://localhost:2000/test_headers");
|
||||
HTTP::Request_ptr own(tr);
|
||||
tr->sendHeaders["X-Foo"] = "Bar";
|
||||
tr->sendHeaders["X-AnotherHeader"] = "A longer value";
|
||||
cl.makeRequest(tr);
|
||||
|
||||
waitForComplete(&cl, tr);
|
||||
COMPARE(tr->responseCode(), 200);
|
||||
COMPARE(tr->responseReason(), string("OK"));
|
||||
COMPARE(tr->responseLength(), strlen(BODY1));
|
||||
COMPARE(tr->responseBytesReceived(), strlen(BODY1));
|
||||
COMPARE(tr->bodyData, string(BODY1));
|
||||
}
|
||||
|
||||
// larger get request
|
||||
for (unsigned int i=0; i<body2Size; ++i) {
|
||||
body2[i] = (i << 4) | (i >> 2);
|
||||
}
|
||||
|
||||
{
|
||||
TestRequest* tr = new TestRequest("http://localhost:2000/test2");
|
||||
HTTP::Request_ptr own(tr);
|
||||
cl.makeRequest(tr);
|
||||
waitForComplete(&cl, tr);
|
||||
COMPARE(tr->responseCode(), 200);
|
||||
COMPARE(tr->responseBytesReceived(), body2Size);
|
||||
COMPARE(tr->bodyData, string(body2, body2Size));
|
||||
}
|
||||
|
||||
{
|
||||
TestRequest* tr = new TestRequest("http://localhost:2000/testchunked");
|
||||
HTTP::Request_ptr own(tr);
|
||||
cl.makeRequest(tr);
|
||||
|
||||
waitForComplete(&cl, tr);
|
||||
COMPARE(tr->responseCode(), 200);
|
||||
COMPARE(tr->responseReason(), string("OK"));
|
||||
COMPARE(tr->responseBytesReceived(), 30);
|
||||
COMPARE(tr->bodyData, "ABCDEFGHABCDEFABCDSTUVABCDSTUV");
|
||||
// check trailers made it too
|
||||
COMPARE(tr->headers["x-foobar"], string("wibble"));
|
||||
}
|
||||
|
||||
// test 404
|
||||
{
|
||||
TestRequest* tr = new TestRequest("http://localhost:2000/not-found");
|
||||
HTTP::Request_ptr own(tr);
|
||||
cl.makeRequest(tr);
|
||||
waitForComplete(&cl, tr);
|
||||
COMPARE(tr->responseCode(), 404);
|
||||
COMPARE(tr->responseReason(), string("not found"));
|
||||
COMPARE(tr->responseLength(), 0);
|
||||
}
|
||||
|
||||
cout << "done1" << endl;
|
||||
// test HTTP/1.0
|
||||
{
|
||||
TestRequest* tr = new TestRequest("http://localhost:2000/test_1_0");
|
||||
HTTP::Request_ptr own(tr);
|
||||
cl.makeRequest(tr);
|
||||
waitForComplete(&cl, tr);
|
||||
COMPARE(tr->responseCode(), 200);
|
||||
COMPARE(tr->responseLength(), strlen(BODY1));
|
||||
COMPARE(tr->bodyData, string(BODY1));
|
||||
}
|
||||
|
||||
cout << "done2" << endl;
|
||||
// test HTTP/1.1 Connection::close
|
||||
{
|
||||
TestRequest* tr = new TestRequest("http://localhost:2000/test_close");
|
||||
HTTP::Request_ptr own(tr);
|
||||
cl.makeRequest(tr);
|
||||
waitForComplete(&cl, tr);
|
||||
COMPARE(tr->responseCode(), 200);
|
||||
COMPARE(tr->responseLength(), strlen(BODY1));
|
||||
COMPARE(tr->bodyData, string(BODY1));
|
||||
}
|
||||
cout << "done3" << endl;
|
||||
// test connectToHost failure
|
||||
/*
|
||||
{
|
||||
TestRequest* tr = new TestRequest("http://not.found/something");
|
||||
HTTP::Request_ptr own(tr);
|
||||
cl.makeRequest(tr);
|
||||
waitForFailed(tr);
|
||||
COMPARE(tr->responseCode(), -1);
|
||||
}
|
||||
*/
|
||||
// test proxy
|
||||
{
|
||||
cl.setProxy("localhost", 2000);
|
||||
TestRequest* tr = new TestRequest("http://www.google.com/test2");
|
||||
HTTP::Request_ptr own(tr);
|
||||
cl.makeRequest(tr);
|
||||
waitForComplete(&cl, tr);
|
||||
COMPARE(tr->responseCode(), 200);
|
||||
COMPARE(tr->responseLength(), body2Size);
|
||||
COMPARE(tr->bodyData, string(body2, body2Size));
|
||||
}
|
||||
|
||||
{
|
||||
cl.setProxy("localhost", 2000, "ABCDEF");
|
||||
TestRequest* tr = new TestRequest("http://www.google.com/test3");
|
||||
HTTP::Request_ptr own(tr);
|
||||
cl.makeRequest(tr);
|
||||
waitForComplete(&cl, tr);
|
||||
COMPARE(tr->responseCode(), 200);
|
||||
COMPARE(tr->responseBytesReceived(), body2Size);
|
||||
COMPARE(tr->bodyData, string(body2, body2Size));
|
||||
}
|
||||
|
||||
// pipelining
|
||||
{
|
||||
cl.setProxy("", 80);
|
||||
TestRequest* tr = new TestRequest("http://localhost:2000/test1");
|
||||
HTTP::Request_ptr own(tr);
|
||||
cl.makeRequest(tr);
|
||||
|
||||
|
||||
TestRequest* tr2 = new TestRequest("http://localhost:2000/test1");
|
||||
HTTP::Request_ptr own2(tr2);
|
||||
cl.makeRequest(tr2);
|
||||
|
||||
TestRequest* tr3 = new TestRequest("http://localhost:2000/test1");
|
||||
HTTP::Request_ptr own3(tr3);
|
||||
cl.makeRequest(tr3);
|
||||
|
||||
waitForComplete(&cl, tr3);
|
||||
VERIFY(tr->complete);
|
||||
VERIFY(tr2->complete);
|
||||
COMPARE(tr->bodyData, string(BODY1));
|
||||
COMPARE(tr2->bodyData, string(BODY1));
|
||||
COMPARE(tr3->bodyData, string(BODY1));
|
||||
}
|
||||
|
||||
// multiple requests with an HTTP 1.0 server
|
||||
{
|
||||
cout << "http 1.0 multiple requests" << endl;
|
||||
|
||||
cl.setProxy("", 80);
|
||||
TestRequest* tr = new TestRequest("http://localhost:2000/test_1_0/A");
|
||||
HTTP::Request_ptr own(tr);
|
||||
cl.makeRequest(tr);
|
||||
|
||||
TestRequest* tr2 = new TestRequest("http://localhost:2000/test_1_0/B");
|
||||
HTTP::Request_ptr own2(tr2);
|
||||
cl.makeRequest(tr2);
|
||||
|
||||
TestRequest* tr3 = new TestRequest("http://localhost:2000/test_1_0/C");
|
||||
HTTP::Request_ptr own3(tr3);
|
||||
cl.makeRequest(tr3);
|
||||
|
||||
waitForComplete(&cl, tr3);
|
||||
VERIFY(tr->complete);
|
||||
VERIFY(tr2->complete);
|
||||
COMPARE(tr->bodyData, string(BODY1));
|
||||
COMPARE(tr2->bodyData, string(BODY1));
|
||||
COMPARE(tr3->bodyData, string(BODY1));
|
||||
}
|
||||
|
||||
cout << "all tests passed ok" << endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1,261 +0,0 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define random rand
|
||||
#endif
|
||||
|
||||
#include <simgear/misc/sg_dir.hxx>
|
||||
|
||||
#include "sg_binobj.hxx"
|
||||
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
|
||||
#define COMPARE(a, b) \
|
||||
if ((a) != (b)) { \
|
||||
cerr << "failed:" << #a << " != " << #b << endl; \
|
||||
cerr << "\tgot:" << a << endl; \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
#define VERIFY(a) \
|
||||
if (!(a)) { \
|
||||
cerr << "failed:" << #a << endl; \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
void generate_points(int count, std::vector<SGVec3d>& vec)
|
||||
{
|
||||
for (int i=0; i<count; ++i) {
|
||||
vec.push_back(SGVec3d(i * 0.5, i * i, i * 4));
|
||||
}
|
||||
}
|
||||
|
||||
void generate_normals(int count, std::vector<SGVec3f>& vec)
|
||||
{
|
||||
for (int i=0; i<count; ++i) {
|
||||
vec.push_back(normalize(SGVec3f(i, i * 2, i * -4)));
|
||||
}
|
||||
}
|
||||
|
||||
void generate_tcs(int count, std::vector<SGVec2f>& vec)
|
||||
{
|
||||
for (int i=0; i<count; ++i) {
|
||||
vec.push_back(SGVec2f(1.0 / i, 16.0 / i));
|
||||
}
|
||||
}
|
||||
|
||||
void test_empty()
|
||||
{
|
||||
SGBinObject empty;
|
||||
SGPath path(simgear::Dir::current().file("empty.btg.gz"));
|
||||
bool ok = empty.write_bin_file(path);
|
||||
VERIFY( ok );
|
||||
SGBinObject rd;
|
||||
ok = rd.read_bin(path.str()) ;
|
||||
VERIFY( ok);
|
||||
|
||||
COMPARE(rd.get_wgs84_nodes().size(), 0);
|
||||
VERIFY(rd.get_pt_materials().empty());
|
||||
}
|
||||
|
||||
void comparePoints(const SGBinObject& rd, const std::vector<SGVec3d>& b)
|
||||
{
|
||||
for (unsigned int i=1; i<b.size(); i += 10) {
|
||||
SGVec3d pos = rd.get_wgs84_nodes()[i];
|
||||
pos += rd.get_gbs_center();
|
||||
|
||||
if (!equivalent(pos, b[i], 0.1)) {
|
||||
cout << "i=" << i << endl;
|
||||
cout << b[i] << endl;
|
||||
cout << pos << endl;
|
||||
}
|
||||
|
||||
VERIFY(equivalent(pos, b[i], 0.1));
|
||||
}
|
||||
}
|
||||
|
||||
void compareTexCoords(const SGBinObject& rd, const std::vector<SGVec2f>& b)
|
||||
{
|
||||
for (unsigned int i=1; i<b.size(); i += 10) {
|
||||
SGVec2f pos = rd.get_texcoords()[i];
|
||||
VERIFY(equivalent(pos, b[i], 0.001f));
|
||||
}
|
||||
}
|
||||
|
||||
int_list make_tri(int maxIndex)
|
||||
{
|
||||
int_list r;
|
||||
r.push_back(random() % maxIndex);
|
||||
r.push_back(random() % maxIndex);
|
||||
r.push_back(random() % maxIndex);
|
||||
return r;
|
||||
}
|
||||
|
||||
void compareTris(const SGBinObject& a, const SGBinObject& b)
|
||||
{
|
||||
unsigned int count = a.get_tri_materials().size();
|
||||
for (unsigned int i=0; i<count; i += 39) {
|
||||
const int_list& vA(a.get_tris_v()[i]);
|
||||
const int_list& vB(b.get_tris_v()[i]);
|
||||
VERIFY(vA == vB);
|
||||
|
||||
COMPARE(a.get_tri_materials()[i], b.get_tri_materials()[i]);
|
||||
|
||||
const int_list& tA(a.get_tris_tc()[i]);
|
||||
const int_list& tB(b.get_tris_tc()[i]);
|
||||
VERIFY(tA == tB);
|
||||
}
|
||||
}
|
||||
|
||||
void generate_tris(SGBinObject& b, int count)
|
||||
{
|
||||
group_list v, n, tc;
|
||||
string_list materials;
|
||||
|
||||
int maxVertices = b.get_wgs84_nodes().size();
|
||||
int maxNormals = b.get_normals().size();
|
||||
int maxTCs = b.get_texcoords().size();
|
||||
|
||||
for (int t=0; t<count; ++t) {
|
||||
v.push_back(make_tri(maxVertices));
|
||||
n.push_back(make_tri(maxNormals));
|
||||
tc.push_back(make_tri(maxTCs));
|
||||
materials.push_back("material1");
|
||||
}
|
||||
|
||||
b.set_tris_v(v);
|
||||
b.set_tris_n(n);
|
||||
b.set_tris_tc(tc);
|
||||
b.set_tri_materials(materials);
|
||||
}
|
||||
|
||||
void test_basic()
|
||||
{
|
||||
SGBinObject basic;
|
||||
SGPath path(simgear::Dir::current().file("basic.btg.gz"));
|
||||
|
||||
SGVec3d center(1, 2, 3);
|
||||
basic.set_gbs_center(center);
|
||||
basic.set_gbs_radius(12345);
|
||||
|
||||
std::vector<SGVec3d> points;
|
||||
generate_points(1024, points);
|
||||
std::vector<SGVec3f> normals;
|
||||
generate_normals(1024, normals);
|
||||
std::vector<SGVec2f> texCoords;
|
||||
generate_tcs(10000, texCoords);
|
||||
|
||||
basic.set_wgs84_nodes(points);
|
||||
basic.set_normals(normals);
|
||||
basic.set_texcoords(texCoords);
|
||||
|
||||
bool ok = basic.write_bin_file(path);
|
||||
VERIFY( ok );
|
||||
|
||||
SGBinObject rd;
|
||||
ok = rd.read_bin(path.str()) ;
|
||||
VERIFY( ok);
|
||||
COMPARE(rd.get_version(), 7); // should be version 7 since indices are < 2^16
|
||||
COMPARE(rd.get_gbs_center(), center);
|
||||
COMPARE(rd.get_gbs_radius(), 12345);
|
||||
COMPARE(rd.get_wgs84_nodes().size(), points.size());
|
||||
|
||||
comparePoints(rd, points);
|
||||
compareTexCoords(rd, texCoords);
|
||||
}
|
||||
|
||||
void test_many_tcs()
|
||||
{
|
||||
SGBinObject basic;
|
||||
SGPath path(simgear::Dir::current().file("many_tex.btg.gz"));
|
||||
|
||||
SGVec3d center(1, 2, 3);
|
||||
basic.set_gbs_center(center);
|
||||
basic.set_gbs_radius(12345);
|
||||
|
||||
std::vector<SGVec3d> points;
|
||||
generate_points(10000, points);
|
||||
std::vector<SGVec3f> normals;
|
||||
generate_normals(1024, normals);
|
||||
std::vector<SGVec2f> texCoords;
|
||||
generate_tcs(100000, texCoords);
|
||||
|
||||
basic.set_wgs84_nodes(points);
|
||||
basic.set_normals(normals);
|
||||
basic.set_texcoords(texCoords);
|
||||
|
||||
generate_tris(basic, 20000);
|
||||
|
||||
bool ok = basic.write_bin_file(path);
|
||||
VERIFY( ok );
|
||||
|
||||
SGBinObject rd;
|
||||
ok = rd.read_bin(path.str()) ;
|
||||
VERIFY( ok);
|
||||
COMPARE(rd.get_version(), 10); // should be version 10 since indices are > 2^16
|
||||
COMPARE(rd.get_wgs84_nodes().size(), points.size());
|
||||
COMPARE(rd.get_texcoords().size(), texCoords.size());
|
||||
|
||||
comparePoints(rd, points);
|
||||
compareTexCoords(rd, texCoords);
|
||||
compareTris(basic, rd);
|
||||
}
|
||||
|
||||
void test_big()
|
||||
{
|
||||
SGBinObject basic;
|
||||
SGPath path(simgear::Dir::current().file("big.btg.gz"));
|
||||
|
||||
SGVec3d center(1, 2, 3);
|
||||
basic.set_gbs_center(center);
|
||||
basic.set_gbs_radius(12345);
|
||||
|
||||
std::vector<SGVec3d> points;
|
||||
generate_points(200000, points);
|
||||
std::vector<SGVec3f> normals;
|
||||
generate_normals(1024, normals);
|
||||
std::vector<SGVec2f> texCoords;
|
||||
generate_tcs(300000, texCoords);
|
||||
|
||||
basic.set_wgs84_nodes(points);
|
||||
basic.set_normals(normals);
|
||||
basic.set_texcoords(texCoords);
|
||||
|
||||
generate_tris(basic, 200000);
|
||||
|
||||
bool ok = basic.write_bin_file(path);
|
||||
VERIFY( ok );
|
||||
|
||||
SGBinObject rd;
|
||||
ok = rd.read_bin(path.str()) ;
|
||||
VERIFY( ok);
|
||||
COMPARE(rd.get_version(), 10); // should be version 10 since indices are > 2^16
|
||||
COMPARE(rd.get_wgs84_nodes().size(), points.size());
|
||||
COMPARE(rd.get_texcoords().size(), texCoords.size());
|
||||
|
||||
comparePoints(rd, points);
|
||||
compareTexCoords(rd, texCoords);
|
||||
compareTris(basic, rd);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
test_empty();
|
||||
test_basic();
|
||||
test_many_tcs();
|
||||
test_big();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -4,15 +4,4 @@ include (SimGearComponent)
|
||||
set(HEADERS magvar.hxx coremag.hxx)
|
||||
set(SOURCES magvar.cxx coremag.cxx)
|
||||
|
||||
simgear_component(magvar magvar "${SOURCES}" "${HEADERS}")
|
||||
|
||||
if(ENABLE_TESTS)
|
||||
add_executable(test_magvar testmagvar.cxx )
|
||||
|
||||
if (SIMGEAR_SHARED)
|
||||
target_link_libraries(test_magvar SimGearCore)
|
||||
else()
|
||||
target_link_libraries(test_magvar sgmagvar)
|
||||
endif()
|
||||
|
||||
endif(ENABLE_TESTS)
|
||||
simgear_component(magvar magvar "${SOURCES}" "${HEADERS}")
|
||||
17
simgear/magvar/Makefile.am
Normal file
17
simgear/magvar/Makefile.am
Normal file
@@ -0,0 +1,17 @@
|
||||
includedir = @includedir@/magvar
|
||||
|
||||
lib_LIBRARIES = libsgmagvar.a
|
||||
|
||||
include_HEADERS = magvar.hxx coremag.hxx
|
||||
|
||||
libsgmagvar_a_SOURCES = coremag.cxx magvar.cxx
|
||||
|
||||
noinst_PROGRAMS = testmagvar
|
||||
|
||||
testmagvar_SOURCES = testmagvar.cxx
|
||||
|
||||
testmagvar_LDADD = \
|
||||
libsgmagvar.a \
|
||||
$(base_LIBS)
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
@@ -16,7 +16,7 @@ int main(int argc, char *argv[])
|
||||
/* output N, E, down components of B (nTesla)
|
||||
dip angle (down positive), variation (E positive) */
|
||||
double lat_deg,lon_deg,h,var;
|
||||
int /* model,*/yy,mm,dd;
|
||||
int model,yy,mm,dd;
|
||||
double field[6];
|
||||
|
||||
if ((argc != 8) && (argc !=7)) {
|
||||
@@ -36,9 +36,9 @@ mm= (int)strtol(argv[4],NULL,10);
|
||||
dd= (int)strtol(argv[5],NULL,10);
|
||||
yy= (int)strtol(argv[6],NULL,10);
|
||||
if (argc == 8){
|
||||
// model= (int)strtol(argv[7],NULL,10);
|
||||
model= (int)strtol(argv[7],NULL,10);
|
||||
}else{
|
||||
// model=7;
|
||||
model=7;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ set(HEADERS
|
||||
beziercurve.hxx
|
||||
interpolater.hxx
|
||||
leastsqs.hxx
|
||||
project.hxx
|
||||
sg_geodesy.hxx
|
||||
sg_types.hxx
|
||||
sg_random.h
|
||||
@@ -38,25 +39,9 @@ set(SOURCES
|
||||
SGGeodesy.cxx
|
||||
interpolater.cxx
|
||||
leastsqs.cxx
|
||||
project.cxx
|
||||
sg_random.c
|
||||
)
|
||||
|
||||
simgear_component(math math "${SOURCES}" "${HEADERS}")
|
||||
|
||||
if(ENABLE_TESTS)
|
||||
|
||||
if (SIMGEAR_SHARED)
|
||||
set(TEST_LIBS SimGearCore)
|
||||
else()
|
||||
set(TEST_LIBS sgmath sgstructure sgdebug)
|
||||
endif()
|
||||
|
||||
|
||||
add_executable(math_test SGMathTest.cxx)
|
||||
target_link_libraries(math_test ${TEST_LIBS})
|
||||
add_test(math ${EXECUTABLE_OUTPUT_PATH}/math_test)
|
||||
|
||||
add_executable(geometry_test SGGeometryTest.cxx)
|
||||
target_link_libraries(geometry_test ${TEST_LIBS})
|
||||
add_test(geometry ${EXECUTABLE_OUTPUT_PATH}/geometry_test)
|
||||
endif(ENABLE_TESTS)
|
||||
|
||||
64
simgear/math/Makefile.am
Normal file
64
simgear/math/Makefile.am
Normal file
@@ -0,0 +1,64 @@
|
||||
includedir = @includedir@/math
|
||||
|
||||
check_PROGRAMS = SGMathTest SGGeometryTest
|
||||
TESTS = $(check_PROGRAMS)
|
||||
|
||||
SGMathTest_SOURCES = SGMathTest.cxx
|
||||
|
||||
SGMathTest_LDADD = \
|
||||
libsgmath.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/structure/libsgstructure.a \
|
||||
$(base_LIBS)
|
||||
|
||||
SGGeometryTest_SOURCES = SGGeometryTest.cxx
|
||||
|
||||
SGGeometryTest_LDADD = \
|
||||
libsgmath.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/structure/libsgstructure.a \
|
||||
$(base_LIBS)
|
||||
|
||||
lib_LIBRARIES = libsgmath.a
|
||||
|
||||
include_HEADERS = \
|
||||
interpolater.hxx \
|
||||
leastsqs.hxx \
|
||||
sg_geodesy.hxx \
|
||||
sg_random.h \
|
||||
sg_types.hxx \
|
||||
Math.hxx \
|
||||
SGBox.hxx \
|
||||
SGCMath.hxx \
|
||||
SGGeoc.hxx \
|
||||
SGGeod.hxx \
|
||||
SGGeodesy.hxx \
|
||||
SGGeometry.hxx \
|
||||
SGGeometryFwd.hxx \
|
||||
SGIntersect.hxx \
|
||||
SGLimits.hxx \
|
||||
SGLineSegment.hxx \
|
||||
SGMatrix.hxx \
|
||||
SGMath.hxx \
|
||||
SGMathFwd.hxx \
|
||||
SGMisc.hxx \
|
||||
SGPlane.hxx \
|
||||
SGQuat.hxx \
|
||||
SGRay.hxx \
|
||||
SGSphere.hxx \
|
||||
SGTriangle.hxx \
|
||||
SGVec2.hxx \
|
||||
SGVec3.hxx \
|
||||
SGVec4.hxx \
|
||||
beziercurve.hxx \
|
||||
project.hxx
|
||||
|
||||
libsgmath_a_SOURCES = \
|
||||
interpolater.cxx \
|
||||
leastsqs.cxx \
|
||||
sg_random.c \
|
||||
SGGeod.cxx \
|
||||
SGGeodesy.cxx \
|
||||
project.cxx
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
@@ -97,7 +97,7 @@ public:
|
||||
return (_max[0] - _min[0])*(_max[1] - _min[1])*(_max[2] - _min[2]);
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
const bool empty() const
|
||||
{ return !valid(); }
|
||||
|
||||
bool valid() const
|
||||
|
||||
@@ -15,10 +15,6 @@
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include "SGMath.hxx"
|
||||
|
||||
#ifndef NO_OPENSCENEGRAPH_INTERFACE
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user